aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/README.txt8
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/COPYING680
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/LICENSE100
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.mingw32260
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.sgi208
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.unx264
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.w32226
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/README372
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/makevms.com264
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.c622
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.h176
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.c1022
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.h232
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readppm.c358
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-win.c1456
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-x.c1808
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-win.c2506
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-x.c4214
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/wpng.c1706
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.c800
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.h266
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/libtests/pngvalid.c19674
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/README20
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/makefile300
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.dfa78
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.h48
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/README20
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/makefile298
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.dfa70
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.h48
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/README30
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/makefile330
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.dfa80
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.h48
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/README306
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.std130
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.tc376
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makevms.com184
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.bat82
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.c860
-rwxr-xr-xlibraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.sh84
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.bat8
-rwxr-xr-xlibraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.sh10
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.bat82
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.c1066
-rwxr-xr-xlibraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.sh84
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.c900
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.h60
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/README.txt122
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.c1938
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.rc304
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h496
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/resource.h46
53 files changed, 22715 insertions, 22715 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/README.txt b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/README.txt
index 7e9b7d0..bcd433d 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/README.txt
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/README.txt
@@ -1,4 +1,4 @@
1 1
2This "contrib" directory contains contributions which are not necessarily under 2This "contrib" directory contains contributions which are not necessarily under
3the libpng license, although all are open source. They are not part of 3the libpng license, although all are open source. They are not part of
4libpng proper and are not used for building the library. 4libpng proper and are not used for building the library.
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/COPYING b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/COPYING
index c2d382b..a3e9774 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/COPYING
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/COPYING
@@ -1,340 +1,340 @@
1 GNU GENERAL PUBLIC LICENSE 1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991 2 Version 2, June 1991
3 3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 5 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6 Everyone is permitted to copy and distribute verbatim copies 6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed. 7 of this license document, but changing it is not allowed.
8 8
9 Preamble 9 Preamble
10 10
11 The licenses for most software are designed to take away your 11 The licenses for most software are designed to take away your
12freedom to share and change it. By contrast, the GNU General Public 12freedom to share and change it. By contrast, the GNU General Public
13License is intended to guarantee your freedom to share and change free 13License is intended to guarantee your freedom to share and change free
14software--to make sure the software is free for all its users. This 14software--to make sure the software is free for all its users. This
15General Public License applies to most of the Free Software 15General Public License applies to most of the Free Software
16Foundation's software and to any other program whose authors commit to 16Foundation's software and to any other program whose authors commit to
17using it. (Some other Free Software Foundation software is covered by 17using it. (Some other Free Software Foundation software is covered by
18the GNU Library General Public License instead.) You can apply it to 18the GNU Library General Public License instead.) You can apply it to
19your programs, too. 19your programs, too.
20 20
21 When we speak of free software, we are referring to freedom, not 21 When we speak of free software, we are referring to freedom, not
22price. Our General Public Licenses are designed to make sure that you 22price. Our General Public Licenses are designed to make sure that you
23have the freedom to distribute copies of free software (and charge for 23have the freedom to distribute copies of free software (and charge for
24this service if you wish), that you receive source code or can get it 24this service if you wish), that you receive source code or can get it
25if you want it, that you can change the software or use pieces of it 25if you want it, that you can change the software or use pieces of it
26in new free programs; and that you know you can do these things. 26in new free programs; and that you know you can do these things.
27 27
28 To protect your rights, we need to make restrictions that forbid 28 To protect your rights, we need to make restrictions that forbid
29anyone to deny you these rights or to ask you to surrender the rights. 29anyone to deny you these rights or to ask you to surrender the rights.
30These restrictions translate to certain responsibilities for you if you 30These restrictions translate to certain responsibilities for you if you
31distribute copies of the software, or if you modify it. 31distribute copies of the software, or if you modify it.
32 32
33 For example, if you distribute copies of such a program, whether 33 For example, if you distribute copies of such a program, whether
34gratis or for a fee, you must give the recipients all the rights that 34gratis or for a fee, you must give the recipients all the rights that
35you have. You must make sure that they, too, receive or can get the 35you have. You must make sure that they, too, receive or can get the
36source code. And you must show them these terms so they know their 36source code. And you must show them these terms so they know their
37rights. 37rights.
38 38
39 We protect your rights with two steps: (1) copyright the software, and 39 We protect your rights with two steps: (1) copyright the software, and
40(2) offer you this license which gives you legal permission to copy, 40(2) offer you this license which gives you legal permission to copy,
41distribute and/or modify the software. 41distribute and/or modify the software.
42 42
43 Also, for each author's protection and ours, we want to make certain 43 Also, for each author's protection and ours, we want to make certain
44that everyone understands that there is no warranty for this free 44that everyone understands that there is no warranty for this free
45software. If the software is modified by someone else and passed on, we 45software. If the software is modified by someone else and passed on, we
46want its recipients to know that what they have is not the original, so 46want its recipients to know that what they have is not the original, so
47that any problems introduced by others will not reflect on the original 47that any problems introduced by others will not reflect on the original
48authors' reputations. 48authors' reputations.
49 49
50 Finally, any free program is threatened constantly by software 50 Finally, any free program is threatened constantly by software
51patents. We wish to avoid the danger that redistributors of a free 51patents. We wish to avoid the danger that redistributors of a free
52program will individually obtain patent licenses, in effect making the 52program will individually obtain patent licenses, in effect making the
53program proprietary. To prevent this, we have made it clear that any 53program proprietary. To prevent this, we have made it clear that any
54patent must be licensed for everyone's free use or not licensed at all. 54patent must be licensed for everyone's free use or not licensed at all.
55 55
56 The precise terms and conditions for copying, distribution and 56 The precise terms and conditions for copying, distribution and
57modification follow. 57modification follow.
58 58
59 GNU GENERAL PUBLIC LICENSE 59 GNU GENERAL PUBLIC LICENSE
60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 61
62 0. This License applies to any program or other work which contains 62 0. This License applies to any program or other work which contains
63a notice placed by the copyright holder saying it may be distributed 63a notice placed by the copyright holder saying it may be distributed
64under the terms of this General Public License. The "Program", below, 64under the terms of this General Public License. The "Program", below,
65refers to any such program or work, and a "work based on the Program" 65refers to any such program or work, and a "work based on the Program"
66means either the Program or any derivative work under copyright law: 66means either the Program or any derivative work under copyright law:
67that is to say, a work containing the Program or a portion of it, 67that is to say, a work containing the Program or a portion of it,
68either verbatim or with modifications and/or translated into another 68either verbatim or with modifications and/or translated into another
69language. (Hereinafter, translation is included without limitation in 69language. (Hereinafter, translation is included without limitation in
70the term "modification".) Each licensee is addressed as "you". 70the term "modification".) Each licensee is addressed as "you".
71 71
72Activities other than copying, distribution and modification are not 72Activities other than copying, distribution and modification are not
73covered by this License; they are outside its scope. The act of 73covered by this License; they are outside its scope. The act of
74running the Program is not restricted, and the output from the Program 74running the Program is not restricted, and the output from the Program
75is covered only if its contents constitute a work based on the 75is covered only if its contents constitute a work based on the
76Program (independent of having been made by running the Program). 76Program (independent of having been made by running the Program).
77Whether that is true depends on what the Program does. 77Whether that is true depends on what the Program does.
78 78
79 1. You may copy and distribute verbatim copies of the Program's 79 1. You may copy and distribute verbatim copies of the Program's
80source code as you receive it, in any medium, provided that you 80source code as you receive it, in any medium, provided that you
81conspicuously and appropriately publish on each copy an appropriate 81conspicuously and appropriately publish on each copy an appropriate
82copyright notice and disclaimer of warranty; keep intact all the 82copyright notice and disclaimer of warranty; keep intact all the
83notices that refer to this License and to the absence of any warranty; 83notices that refer to this License and to the absence of any warranty;
84and give any other recipients of the Program a copy of this License 84and give any other recipients of the Program a copy of this License
85along with the Program. 85along with the Program.
86 86
87You may charge a fee for the physical act of transferring a copy, and 87You may charge a fee for the physical act of transferring a copy, and
88you may at your option offer warranty protection in exchange for a fee. 88you may at your option offer warranty protection in exchange for a fee.
89 89
90 2. You may modify your copy or copies of the Program or any portion 90 2. You may modify your copy or copies of the Program or any portion
91of it, thus forming a work based on the Program, and copy and 91of it, thus forming a work based on the Program, and copy and
92distribute such modifications or work under the terms of Section 1 92distribute such modifications or work under the terms of Section 1
93above, provided that you also meet all of these conditions: 93above, provided that you also meet all of these conditions:
94 94
95 a) You must cause the modified files to carry prominent notices 95 a) You must cause the modified files to carry prominent notices
96 stating that you changed the files and the date of any change. 96 stating that you changed the files and the date of any change.
97 97
98 b) You must cause any work that you distribute or publish, that in 98 b) You must cause any work that you distribute or publish, that in
99 whole or in part contains or is derived from the Program or any 99 whole or in part contains or is derived from the Program or any
100 part thereof, to be licensed as a whole at no charge to all third 100 part thereof, to be licensed as a whole at no charge to all third
101 parties under the terms of this License. 101 parties under the terms of this License.
102 102
103 c) If the modified program normally reads commands interactively 103 c) If the modified program normally reads commands interactively
104 when run, you must cause it, when started running for such 104 when run, you must cause it, when started running for such
105 interactive use in the most ordinary way, to print or display an 105 interactive use in the most ordinary way, to print or display an
106 announcement including an appropriate copyright notice and a 106 announcement including an appropriate copyright notice and a
107 notice that there is no warranty (or else, saying that you provide 107 notice that there is no warranty (or else, saying that you provide
108 a warranty) and that users may redistribute the program under 108 a warranty) and that users may redistribute the program under
109 these conditions, and telling the user how to view a copy of this 109 these conditions, and telling the user how to view a copy of this
110 License. (Exception: if the Program itself is interactive but 110 License. (Exception: if the Program itself is interactive but
111 does not normally print such an announcement, your work based on 111 does not normally print such an announcement, your work based on
112 the Program is not required to print an announcement.) 112 the Program is not required to print an announcement.)
113 113
114These requirements apply to the modified work as a whole. If 114These requirements apply to the modified work as a whole. If
115identifiable sections of that work are not derived from the Program, 115identifiable sections of that work are not derived from the Program,
116and can be reasonably considered independent and separate works in 116and can be reasonably considered independent and separate works in
117themselves, then this License, and its terms, do not apply to those 117themselves, then this License, and its terms, do not apply to those
118sections when you distribute them as separate works. But when you 118sections when you distribute them as separate works. But when you
119distribute the same sections as part of a whole which is a work based 119distribute the same sections as part of a whole which is a work based
120on the Program, the distribution of the whole must be on the terms of 120on the Program, the distribution of the whole must be on the terms of
121this License, whose permissions for other licensees extend to the 121this License, whose permissions for other licensees extend to the
122entire whole, and thus to each and every part regardless of who wrote it. 122entire whole, and thus to each and every part regardless of who wrote it.
123 123
124Thus, it is not the intent of this section to claim rights or contest 124Thus, it is not the intent of this section to claim rights or contest
125your rights to work written entirely by you; rather, the intent is to 125your rights to work written entirely by you; rather, the intent is to
126exercise the right to control the distribution of derivative or 126exercise the right to control the distribution of derivative or
127collective works based on the Program. 127collective works based on the Program.
128 128
129In addition, mere aggregation of another work not based on the Program 129In addition, mere aggregation of another work not based on the Program
130with the Program (or with a work based on the Program) on a volume of 130with the Program (or with a work based on the Program) on a volume of
131a storage or distribution medium does not bring the other work under 131a storage or distribution medium does not bring the other work under
132the scope of this License. 132the scope of this License.
133 133
134 3. You may copy and distribute the Program (or a work based on it, 134 3. You may copy and distribute the Program (or a work based on it,
135under Section 2) in object code or executable form under the terms of 135under Section 2) in object code or executable form under the terms of
136Sections 1 and 2 above provided that you also do one of the following: 136Sections 1 and 2 above provided that you also do one of the following:
137 137
138 a) Accompany it with the complete corresponding machine-readable 138 a) Accompany it with the complete corresponding machine-readable
139 source code, which must be distributed under the terms of Sections 139 source code, which must be distributed under the terms of Sections
140 1 and 2 above on a medium customarily used for software interchange; or, 140 1 and 2 above on a medium customarily used for software interchange; or,
141 141
142 b) Accompany it with a written offer, valid for at least three 142 b) Accompany it with a written offer, valid for at least three
143 years, to give any third party, for a charge no more than your 143 years, to give any third party, for a charge no more than your
144 cost of physically performing source distribution, a complete 144 cost of physically performing source distribution, a complete
145 machine-readable copy of the corresponding source code, to be 145 machine-readable copy of the corresponding source code, to be
146 distributed under the terms of Sections 1 and 2 above on a medium 146 distributed under the terms of Sections 1 and 2 above on a medium
147 customarily used for software interchange; or, 147 customarily used for software interchange; or,
148 148
149 c) Accompany it with the information you received as to the offer 149 c) Accompany it with the information you received as to the offer
150 to distribute corresponding source code. (This alternative is 150 to distribute corresponding source code. (This alternative is
151 allowed only for noncommercial distribution and only if you 151 allowed only for noncommercial distribution and only if you
152 received the program in object code or executable form with such 152 received the program in object code or executable form with such
153 an offer, in accord with Subsection b above.) 153 an offer, in accord with Subsection b above.)
154 154
155The source code for a work means the preferred form of the work for 155The source code for a work means the preferred form of the work for
156making modifications to it. For an executable work, complete source 156making modifications to it. For an executable work, complete source
157code means all the source code for all modules it contains, plus any 157code means all the source code for all modules it contains, plus any
158associated interface definition files, plus the scripts used to 158associated interface definition files, plus the scripts used to
159control compilation and installation of the executable. However, as a 159control compilation and installation of the executable. However, as a
160special exception, the source code distributed need not include 160special exception, the source code distributed need not include
161anything that is normally distributed (in either source or binary 161anything that is normally distributed (in either source or binary
162form) with the major components (compiler, kernel, and so on) of the 162form) with the major components (compiler, kernel, and so on) of the
163operating system on which the executable runs, unless that component 163operating system on which the executable runs, unless that component
164itself accompanies the executable. 164itself accompanies the executable.
165 165
166If distribution of executable or object code is made by offering 166If distribution of executable or object code is made by offering
167access to copy from a designated place, then offering equivalent 167access to copy from a designated place, then offering equivalent
168access to copy the source code from the same place counts as 168access to copy the source code from the same place counts as
169distribution of the source code, even though third parties are not 169distribution of the source code, even though third parties are not
170compelled to copy the source along with the object code. 170compelled to copy the source along with the object code.
171 171
172 4. You may not copy, modify, sublicense, or distribute the Program 172 4. You may not copy, modify, sublicense, or distribute the Program
173except as expressly provided under this License. Any attempt 173except as expressly provided under this License. Any attempt
174otherwise to copy, modify, sublicense or distribute the Program is 174otherwise to copy, modify, sublicense or distribute the Program is
175void, and will automatically terminate your rights under this License. 175void, and will automatically terminate your rights under this License.
176However, parties who have received copies, or rights, from you under 176However, parties who have received copies, or rights, from you under
177this License will not have their licenses terminated so long as such 177this License will not have their licenses terminated so long as such
178parties remain in full compliance. 178parties remain in full compliance.
179 179
180 5. You are not required to accept this License, since you have not 180 5. You are not required to accept this License, since you have not
181signed it. However, nothing else grants you permission to modify or 181signed it. However, nothing else grants you permission to modify or
182distribute the Program or its derivative works. These actions are 182distribute the Program or its derivative works. These actions are
183prohibited by law if you do not accept this License. Therefore, by 183prohibited by law if you do not accept this License. Therefore, by
184modifying or distributing the Program (or any work based on the 184modifying or distributing the Program (or any work based on the
185Program), you indicate your acceptance of this License to do so, and 185Program), you indicate your acceptance of this License to do so, and
186all its terms and conditions for copying, distributing or modifying 186all its terms and conditions for copying, distributing or modifying
187the Program or works based on it. 187the Program or works based on it.
188 188
189 6. Each time you redistribute the Program (or any work based on the 189 6. Each time you redistribute the Program (or any work based on the
190Program), the recipient automatically receives a license from the 190Program), the recipient automatically receives a license from the
191original licensor to copy, distribute or modify the Program subject to 191original licensor to copy, distribute or modify the Program subject to
192these terms and conditions. You may not impose any further 192these terms and conditions. You may not impose any further
193restrictions on the recipients' exercise of the rights granted herein. 193restrictions on the recipients' exercise of the rights granted herein.
194You are not responsible for enforcing compliance by third parties to 194You are not responsible for enforcing compliance by third parties to
195this License. 195this License.
196 196
197 7. If, as a consequence of a court judgment or allegation of patent 197 7. If, as a consequence of a court judgment or allegation of patent
198infringement or for any other reason (not limited to patent issues), 198infringement or for any other reason (not limited to patent issues),
199conditions are imposed on you (whether by court order, agreement or 199conditions are imposed on you (whether by court order, agreement or
200otherwise) that contradict the conditions of this License, they do not 200otherwise) that contradict the conditions of this License, they do not
201excuse you from the conditions of this License. If you cannot 201excuse you from the conditions of this License. If you cannot
202distribute so as to satisfy simultaneously your obligations under this 202distribute so as to satisfy simultaneously your obligations under this
203License and any other pertinent obligations, then as a consequence you 203License and any other pertinent obligations, then as a consequence you
204may not distribute the Program at all. For example, if a patent 204may not distribute the Program at all. For example, if a patent
205license would not permit royalty-free redistribution of the Program by 205license would not permit royalty-free redistribution of the Program by
206all those who receive copies directly or indirectly through you, then 206all those who receive copies directly or indirectly through you, then
207the only way you could satisfy both it and this License would be to 207the only way you could satisfy both it and this License would be to
208refrain entirely from distribution of the Program. 208refrain entirely from distribution of the Program.
209 209
210If any portion of this section is held invalid or unenforceable under 210If any portion of this section is held invalid or unenforceable under
211any particular circumstance, the balance of the section is intended to 211any particular circumstance, the balance of the section is intended to
212apply and the section as a whole is intended to apply in other 212apply and the section as a whole is intended to apply in other
213circumstances. 213circumstances.
214 214
215It is not the purpose of this section to induce you to infringe any 215It is not the purpose of this section to induce you to infringe any
216patents or other property right claims or to contest validity of any 216patents or other property right claims or to contest validity of any
217such claims; this section has the sole purpose of protecting the 217such claims; this section has the sole purpose of protecting the
218integrity of the free software distribution system, which is 218integrity of the free software distribution system, which is
219implemented by public license practices. Many people have made 219implemented by public license practices. Many people have made
220generous contributions to the wide range of software distributed 220generous contributions to the wide range of software distributed
221through that system in reliance on consistent application of that 221through that system in reliance on consistent application of that
222system; it is up to the author/donor to decide if he or she is willing 222system; it is up to the author/donor to decide if he or she is willing
223to distribute software through any other system and a licensee cannot 223to distribute software through any other system and a licensee cannot
224impose that choice. 224impose that choice.
225 225
226This section is intended to make thoroughly clear what is believed to 226This section is intended to make thoroughly clear what is believed to
227be a consequence of the rest of this License. 227be a consequence of the rest of this License.
228 228
229 8. If the distribution and/or use of the Program is restricted in 229 8. If the distribution and/or use of the Program is restricted in
230certain countries either by patents or by copyrighted interfaces, the 230certain countries either by patents or by copyrighted interfaces, the
231original copyright holder who places the Program under this License 231original copyright holder who places the Program under this License
232may add an explicit geographical distribution limitation excluding 232may add an explicit geographical distribution limitation excluding
233those countries, so that distribution is permitted only in or among 233those countries, so that distribution is permitted only in or among
234countries not thus excluded. In such case, this License incorporates 234countries not thus excluded. In such case, this License incorporates
235the limitation as if written in the body of this License. 235the limitation as if written in the body of this License.
236 236
237 9. The Free Software Foundation may publish revised and/or new versions 237 9. The Free Software Foundation may publish revised and/or new versions
238of the General Public License from time to time. Such new versions will 238of the General Public License from time to time. Such new versions will
239be similar in spirit to the present version, but may differ in detail to 239be similar in spirit to the present version, but may differ in detail to
240address new problems or concerns. 240address new problems or concerns.
241 241
242Each version is given a distinguishing version number. If the Program 242Each version is given a distinguishing version number. If the Program
243specifies a version number of this License which applies to it and "any 243specifies a version number of this License which applies to it and "any
244later version", you have the option of following the terms and conditions 244later version", you have the option of following the terms and conditions
245either of that version or of any later version published by the Free 245either of that version or of any later version published by the Free
246Software Foundation. If the Program does not specify a version number of 246Software Foundation. If the Program does not specify a version number of
247this License, you may choose any version ever published by the Free Software 247this License, you may choose any version ever published by the Free Software
248Foundation. 248Foundation.
249 249
250 10. If you wish to incorporate parts of the Program into other free 250 10. If you wish to incorporate parts of the Program into other free
251programs whose distribution conditions are different, write to the author 251programs whose distribution conditions are different, write to the author
252to ask for permission. For software which is copyrighted by the Free 252to ask for permission. For software which is copyrighted by the Free
253Software Foundation, write to the Free Software Foundation; we sometimes 253Software Foundation, write to the Free Software Foundation; we sometimes
254make exceptions for this. Our decision will be guided by the two goals 254make exceptions for this. Our decision will be guided by the two goals
255of preserving the free status of all derivatives of our free software and 255of preserving the free status of all derivatives of our free software and
256of promoting the sharing and reuse of software generally. 256of promoting the sharing and reuse of software generally.
257 257
258 NO WARRANTY 258 NO WARRANTY
259 259
260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 261FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 262OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 263PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 264OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 265MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 266TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 267PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268REPAIR OR CORRECTION. 268REPAIR OR CORRECTION.
269 269
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 271WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 272REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 273INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 274OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 275TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 276YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 277PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278POSSIBILITY OF SUCH DAMAGES. 278POSSIBILITY OF SUCH DAMAGES.
279 279
280 END OF TERMS AND CONDITIONS 280 END OF TERMS AND CONDITIONS
281 281
282 How to Apply These Terms to Your New Programs 282 How to Apply These Terms to Your New Programs
283 283
284 If you develop a new program, and you want it to be of the greatest 284 If you develop a new program, and you want it to be of the greatest
285possible use to the public, the best way to achieve this is to make it 285possible use to the public, the best way to achieve this is to make it
286free software which everyone can redistribute and change under these terms. 286free software which everyone can redistribute and change under these terms.
287 287
288 To do so, attach the following notices to the program. It is safest 288 To do so, attach the following notices to the program. It is safest
289to attach them to the start of each source file to most effectively 289to attach them to the start of each source file to most effectively
290convey the exclusion of warranty; and each file should have at least 290convey the exclusion of warranty; and each file should have at least
291the "copyright" line and a pointer to where the full notice is found. 291the "copyright" line and a pointer to where the full notice is found.
292 292
293 <one line to give the program's name and a brief idea of what it does.> 293 <one line to give the program's name and a brief idea of what it does.>
294 Copyright (C) <year> <name of author> 294 Copyright (C) <year> <name of author>
295 295
296 This program is free software; you can redistribute it and/or modify 296 This program is free software; you can redistribute it and/or modify
297 it under the terms of the GNU General Public License as published by 297 it under the terms of the GNU General Public License as published by
298 the Free Software Foundation; either version 2 of the License, or 298 the Free Software Foundation; either version 2 of the License, or
299 (at your option) any later version. 299 (at your option) any later version.
300 300
301 This program is distributed in the hope that it will be useful, 301 This program is distributed in the hope that it will be useful,
302 but WITHOUT ANY WARRANTY; without even the implied warranty of 302 but WITHOUT ANY WARRANTY; without even the implied warranty of
303 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 303 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 GNU General Public License for more details. 304 GNU General Public License for more details.
305 305
306 You should have received a copy of the GNU General Public License 306 You should have received a copy of the GNU General Public License
307 along with this program; if not, write to the Free Software 307 along with this program; if not, write to the Free Software
308 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 308 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
309 309
310 310
311Also add information on how to contact you by electronic and paper mail. 311Also add information on how to contact you by electronic and paper mail.
312 312
313If the program is interactive, make it output a short notice like this 313If the program is interactive, make it output a short notice like this
314when it starts in an interactive mode: 314when it starts in an interactive mode:
315 315
316 Gnomovision version 69, Copyright (C) year name of author 316 Gnomovision version 69, Copyright (C) year name of author
317 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318 This is free software, and you are welcome to redistribute it 318 This is free software, and you are welcome to redistribute it
319 under certain conditions; type `show c' for details. 319 under certain conditions; type `show c' for details.
320 320
321The hypothetical commands `show w' and `show c' should show the appropriate 321The hypothetical commands `show w' and `show c' should show the appropriate
322parts of the General Public License. Of course, the commands you use may 322parts of the General Public License. Of course, the commands you use may
323be called something other than `show w' and `show c'; they could even be 323be called something other than `show w' and `show c'; they could even be
324mouse-clicks or menu items--whatever suits your program. 324mouse-clicks or menu items--whatever suits your program.
325 325
326You should also get your employer (if you work as a programmer) or your 326You should also get your employer (if you work as a programmer) or your
327school, if any, to sign a "copyright disclaimer" for the program, if 327school, if any, to sign a "copyright disclaimer" for the program, if
328necessary. Here is a sample; alter the names: 328necessary. Here is a sample; alter the names:
329 329
330 Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331 `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 `Gnomovision' (which makes passes at compilers) written by James Hacker.
332 332
333 <signature of Ty Coon>, 1 April 1989 333 <signature of Ty Coon>, 1 April 1989
334 Ty Coon, President of Vice 334 Ty Coon, President of Vice
335 335
336This General Public License does not permit incorporating your program into 336This General Public License does not permit incorporating your program into
337proprietary programs. If your program is a subroutine library, you may 337proprietary programs. If your program is a subroutine library, you may
338consider it more useful to permit linking proprietary applications with the 338consider it more useful to permit linking proprietary applications with the
339library. If this is what you want to do, use the GNU Library General 339library. If this is what you want to do, use the GNU Library General
340Public License instead of this License. 340Public License instead of this License.
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/LICENSE b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/LICENSE
index 40a0c8e..d956717 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/LICENSE
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/LICENSE
@@ -1,50 +1,50 @@
1 --------------------------------------------------------------------------- 1 ---------------------------------------------------------------------------
2 2
3 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. 3 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved.
4 4
5 This software is provided "as is," without warranty of any kind, 5 This software is provided "as is," without warranty of any kind,
6 express or implied. In no event shall the author or contributors 6 express or implied. In no event shall the author or contributors
7 be held liable for any damages arising in any way from the use of 7 be held liable for any damages arising in any way from the use of
8 this software. 8 this software.
9 9
10 The contents of this file are DUAL-LICENSED. You may modify and/or 10 The contents of this file are DUAL-LICENSED. You may modify and/or
11 redistribute this software according to the terms of one of the 11 redistribute this software according to the terms of one of the
12 following two licenses (at your option): 12 following two licenses (at your option):
13 13
14 14
15 LICENSE 1 ("BSD-like with advertising clause"): 15 LICENSE 1 ("BSD-like with advertising clause"):
16 16
17 Permission is granted to anyone to use this software for any purpose, 17 Permission is granted to anyone to use this software for any purpose,
18 including commercial applications, and to alter it and redistribute 18 including commercial applications, and to alter it and redistribute
19 it freely, subject to the following restrictions: 19 it freely, subject to the following restrictions:
20 20
21 1. Redistributions of source code must retain the above copyright 21 1. Redistributions of source code must retain the above copyright
22 notice, disclaimer, and this list of conditions. 22 notice, disclaimer, and this list of conditions.
23 2. Redistributions in binary form must reproduce the above copyright 23 2. Redistributions in binary form must reproduce the above copyright
24 notice, disclaimer, and this list of conditions in the documenta- 24 notice, disclaimer, and this list of conditions in the documenta-
25 tion and/or other materials provided with the distribution. 25 tion and/or other materials provided with the distribution.
26 3. All advertising materials mentioning features or use of this 26 3. All advertising materials mentioning features or use of this
27 software must display the following acknowledgment: 27 software must display the following acknowledgment:
28 28
29 This product includes software developed by Greg Roelofs 29 This product includes software developed by Greg Roelofs
30 and contributors for the book, "PNG: The Definitive Guide," 30 and contributors for the book, "PNG: The Definitive Guide,"
31 published by O'Reilly and Associates. 31 published by O'Reilly and Associates.
32 32
33 33
34 LICENSE 2 (GNU GPL v2 or later): 34 LICENSE 2 (GNU GPL v2 or later):
35 35
36 This program is free software; you can redistribute it and/or modify 36 This program is free software; you can redistribute it and/or modify
37 it under the terms of the GNU General Public License as published by 37 it under the terms of the GNU General Public License as published by
38 the Free Software Foundation; either version 2 of the License, or 38 the Free Software Foundation; either version 2 of the License, or
39 (at your option) any later version. 39 (at your option) any later version.
40 40
41 This program is distributed in the hope that it will be useful, 41 This program is distributed in the hope that it will be useful,
42 but WITHOUT ANY WARRANTY; without even the implied warranty of 42 but WITHOUT ANY WARRANTY; without even the implied warranty of
43 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 43 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44 GNU General Public License for more details. 44 GNU General Public License for more details.
45 45
46 You should have received a copy of the GNU General Public License 46 You should have received a copy of the GNU General Public License
47 along with this program; if not, write to the Free Software Foundation, 47 along with this program; if not, write to the Free Software Foundation,
48 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 48 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
49 49
50 --------------------------------------------------------------------------- 50 ---------------------------------------------------------------------------
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.mingw32 b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.mingw32
index a736556..e70a59a 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.mingw32
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.mingw32
@@ -1,130 +1,130 @@
1# Sample makefile for rpng-win / rpng2-win / wpng using mingw32-gcc and make. 1# Sample makefile for rpng-win / rpng2-win / wpng using mingw32-gcc and make.
2# Greg Roelofs 2# Greg Roelofs
3# Last modified: 2 June 2007 3# Last modified: 2 June 2007
4# 4#
5# The programs built by this makefile are described in the book, 5# The programs built by this makefile are described in the book,
6# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and 6# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
7# Associates, 1999). Go buy a copy, eh? Well, OK, it's not 7# Associates, 1999). Go buy a copy, eh? Well, OK, it's not
8# generally for sale anymore, but it's the thought that counts, 8# generally for sale anymore, but it's the thought that counts,
9# right? (Hint: http://www.libpng.org/pub/png/book/ ) 9# right? (Hint: http://www.libpng.org/pub/png/book/ )
10# 10#
11# Invoke this makefile from a DOS-prompt window via: 11# Invoke this makefile from a DOS-prompt window via:
12# 12#
13# make -f Makefile.mingw32 13# make -f Makefile.mingw32
14# 14#
15# This makefile assumes libpng and zlib have already been built or downloaded 15# This makefile assumes libpng and zlib have already been built or downloaded
16# and are in subdirectories at the same level as the current subdirectory 16# and are in subdirectories at the same level as the current subdirectory
17# (as indicated by the PNGDIR and ZDIR macros below). It makes no assumptions 17# (as indicated by the PNGDIR and ZDIR macros below). It makes no assumptions
18# at all about the mingw32 installation tree (W32DIR). Edit as appropriate. 18# at all about the mingw32 installation tree (W32DIR). Edit as appropriate.
19# 19#
20# Note that the names of the dynamic and static libpng and zlib libraries 20# Note that the names of the dynamic and static libpng and zlib libraries
21# used below may change in later releases of the libraries. This makefile 21# used below may change in later releases of the libraries. This makefile
22# builds both statically and dynamically linked executables by default. 22# builds both statically and dynamically linked executables by default.
23# (You need only one set, but for testing it can be handy to have both.) 23# (You need only one set, but for testing it can be handy to have both.)
24 24
25 25
26# macros -------------------------------------------------------------------- 26# macros --------------------------------------------------------------------
27 27
28#PNGDIR = ../..# for libpng-x.y.z/contrib/gregbook builds 28#PNGDIR = ../..# for libpng-x.y.z/contrib/gregbook builds
29PNGDIR = ../libpng-win32 29PNGDIR = ../libpng-win32
30PNGINC = -I$(PNGDIR) 30PNGINC = -I$(PNGDIR)
31PNGLIBd = $(PNGDIR)/libpng.dll.a # dynamically linked 31PNGLIBd = $(PNGDIR)/libpng.dll.a # dynamically linked
32PNGLIBs = $(PNGDIR)/libpng.a # statically linked, local libpng 32PNGLIBs = $(PNGDIR)/libpng.a # statically linked, local libpng
33 33
34#ZDIR = ../../../zlib-win32# for libpng-x.y.z/contrib/gregbook builds 34#ZDIR = ../../../zlib-win32# for libpng-x.y.z/contrib/gregbook builds
35ZDIR = ../zlib-win32 35ZDIR = ../zlib-win32
36ZINC = -I$(ZDIR) 36ZINC = -I$(ZDIR)
37ZLIBd = $(ZDIR)/libzdll.a 37ZLIBd = $(ZDIR)/libzdll.a
38ZLIBs = $(ZDIR)/libz.a 38ZLIBs = $(ZDIR)/libz.a
39 39
40# change this to be the path where mingw32 installs its stuff: 40# change this to be the path where mingw32 installs its stuff:
41W32DIR = 41W32DIR =
42#W32DIR = /usr/local/cross-tools/i386-mingw32msvc 42#W32DIR = /usr/local/cross-tools/i386-mingw32msvc
43W32INC = -I$(W32DIR)/include 43W32INC = -I$(W32DIR)/include
44W32LIB = $(W32DIR)/lib/libuser32.a $(W32DIR)/lib/libgdi32.a 44W32LIB = $(W32DIR)/lib/libuser32.a $(W32DIR)/lib/libgdi32.a
45 45
46CC = gcc 46CC = gcc
47#CC = i386-mingw32msvc-gcc # e.g., Linux -> Win32 cross-compilation 47#CC = i386-mingw32msvc-gcc # e.g., Linux -> Win32 cross-compilation
48LD = $(CC) 48LD = $(CC)
49RM = rm -f 49RM = rm -f
50CFLAGS = -O -Wall $(INCS) $(MINGW_CCFLAGS) 50CFLAGS = -O -Wall $(INCS) $(MINGW_CCFLAGS)
51# [note that -Wall is a gcc-specific compilation flag ("most warnings on")] 51# [note that -Wall is a gcc-specific compilation flag ("most warnings on")]
52# [-ansi, -pedantic and -W can also be used] 52# [-ansi, -pedantic and -W can also be used]
53LDFLAGS = $(MINGW_LDFLAGS) 53LDFLAGS = $(MINGW_LDFLAGS)
54O = .o 54O = .o
55E = .exe 55E = .exe
56 56
57INCS = $(PNGINC) $(ZINC) $(W32INC) 57INCS = $(PNGINC) $(ZINC) $(W32INC)
58RLIBSd = $(PNGLIBd) $(ZLIBd) $(W32LIB) -lm 58RLIBSd = $(PNGLIBd) $(ZLIBd) $(W32LIB) -lm
59RLIBSs = $(PNGLIBs) $(ZLIBs) $(W32LIB) -lm 59RLIBSs = $(PNGLIBs) $(ZLIBs) $(W32LIB) -lm
60WLIBSd = $(PNGLIBd) $(ZLIBd) 60WLIBSd = $(PNGLIBd) $(ZLIBd)
61WLIBSs = $(PNGLIBs) $(ZLIBs) 61WLIBSs = $(PNGLIBs) $(ZLIBs)
62 62
63RPNG = rpng-win 63RPNG = rpng-win
64RPNG2 = rpng2-win 64RPNG2 = rpng2-win
65WPNG = wpng 65WPNG = wpng
66 66
67ROBJSd = $(RPNG)$(O) readpng.pic$(O) 67ROBJSd = $(RPNG)$(O) readpng.pic$(O)
68ROBJS2d = $(RPNG2)$(O) readpng2.pic$(O) 68ROBJS2d = $(RPNG2)$(O) readpng2.pic$(O)
69WOBJSd = $(WPNG)$(O) writepng.pic$(O) 69WOBJSd = $(WPNG)$(O) writepng.pic$(O)
70 70
71RPNGs = $(RPNG)-static 71RPNGs = $(RPNG)-static
72RPNG2s = $(RPNG2)-static 72RPNG2s = $(RPNG2)-static
73WPNGs = $(WPNG)-static 73WPNGs = $(WPNG)-static
74 74
75ROBJSs = $(RPNG)$(O) readpng$(O) 75ROBJSs = $(RPNG)$(O) readpng$(O)
76ROBJS2s = $(RPNG2)$(O) readpng2$(O) 76ROBJS2s = $(RPNG2)$(O) readpng2$(O)
77WOBJSs = $(WPNG)$(O) writepng$(O) 77WOBJSs = $(WPNG)$(O) writepng$(O)
78 78
79STATIC_EXES = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E) 79STATIC_EXES = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E)
80DYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) 80DYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
81 81
82EXES = $(STATIC_EXES) $(DYNAMIC_EXES) 82EXES = $(STATIC_EXES) $(DYNAMIC_EXES)
83 83
84 84
85# implicit make rules ------------------------------------------------------- 85# implicit make rules -------------------------------------------------------
86 86
87.c$(O): 87.c$(O):
88 $(CC) -c $(CFLAGS) $< 88 $(CC) -c $(CFLAGS) $<
89 89
90%.pic$(O): %.c 90%.pic$(O): %.c
91 $(CC) -c $(CFLAGS) -DPNG_BUILD_DLL -o $@ $< 91 $(CC) -c $(CFLAGS) -DPNG_BUILD_DLL -o $@ $<
92 92
93 93
94# dependencies -------------------------------------------------------------- 94# dependencies --------------------------------------------------------------
95 95
96all: $(EXES) 96all: $(EXES)
97 97
98$(RPNGs)$(E): $(ROBJSs) 98$(RPNGs)$(E): $(ROBJSs)
99 $(LD) $(LDFLAGS) -o $@ $(ROBJSs) $(RLIBSs) 99 $(LD) $(LDFLAGS) -o $@ $(ROBJSs) $(RLIBSs)
100 100
101$(RPNG)$(E): $(ROBJSd) 101$(RPNG)$(E): $(ROBJSd)
102 $(LD) $(LDFLAGS) -o $@ $(ROBJSd) $(RLIBSd) 102 $(LD) $(LDFLAGS) -o $@ $(ROBJSd) $(RLIBSd)
103 103
104$(RPNG2s)$(E): $(ROBJS2s) 104$(RPNG2s)$(E): $(ROBJS2s)
105 $(LD) $(LDFLAGS) -o $@ $(ROBJS2s) $(RLIBSs) 105 $(LD) $(LDFLAGS) -o $@ $(ROBJS2s) $(RLIBSs)
106 106
107$(RPNG2)$(E): $(ROBJS2d) 107$(RPNG2)$(E): $(ROBJS2d)
108 $(LD) $(LDFLAGS) -o $@ $(ROBJS2d) $(RLIBSd) 108 $(LD) $(LDFLAGS) -o $@ $(ROBJS2d) $(RLIBSd)
109 109
110$(WPNGs)$(E): $(WOBJSs) 110$(WPNGs)$(E): $(WOBJSs)
111 $(LD) $(LDFLAGS) -o $@ $(WOBJSs) $(WLIBSs) 111 $(LD) $(LDFLAGS) -o $@ $(WOBJSs) $(WLIBSs)
112 112
113$(WPNG)$(E): $(WOBJSd) 113$(WPNG)$(E): $(WOBJSd)
114 $(LD) $(LDFLAGS) -o $@ $(WOBJSd) $(WLIBSd) 114 $(LD) $(LDFLAGS) -o $@ $(WOBJSd) $(WLIBSd)
115 115
116$(RPNG)$(O): $(RPNG).c readpng.h 116$(RPNG)$(O): $(RPNG).c readpng.h
117$(RPNG2)$(O): $(RPNG2).c readpng2.h 117$(RPNG2)$(O): $(RPNG2).c readpng2.h
118$(WPNG)$(O): $(WPNG).c writepng.h 118$(WPNG)$(O): $(WPNG).c writepng.h
119 119
120readpng$(O) readpng.pic$(O): readpng.c readpng.h 120readpng$(O) readpng.pic$(O): readpng.c readpng.h
121readpng2$(O) readpng2.pic$(O): readpng2.c readpng2.h 121readpng2$(O) readpng2.pic$(O): readpng2.c readpng2.h
122writepng$(O) writepng.pic$(O): writepng.c writepng.h 122writepng$(O) writepng.pic$(O): writepng.c writepng.h
123 123
124 124
125# maintenance --------------------------------------------------------------- 125# maintenance ---------------------------------------------------------------
126 126
127clean: 127clean:
128 $(RM) $(EXES) 128 $(RM) $(EXES)
129 $(RM) $(ROBJSs) $(ROBJS2s) $(WOBJSs) 129 $(RM) $(ROBJSs) $(ROBJS2s) $(WOBJSs)
130 $(RM) $(ROBJSd) $(ROBJS2d) $(WOBJSd) 130 $(RM) $(ROBJSd) $(ROBJS2d) $(WOBJSd)
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.sgi b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.sgi
index 8773a00..91623ac 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.sgi
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.sgi
@@ -1,104 +1,104 @@
1# Sample makefile for rpng-x / rpng2-x / wpng for SGI using cc and make. 1# Sample makefile for rpng-x / rpng2-x / wpng for SGI using cc and make.
2# Greg Roelofs 2# Greg Roelofs
3# Last modified: 7 March 2002 3# Last modified: 7 March 2002
4# 4#
5# The programs built by this makefile are described in the book, 5# The programs built by this makefile are described in the book,
6# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and 6# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
7# Associates, 1999). Go buy a copy, eh? Buy some for friends 7# Associates, 1999). Go buy a copy, eh? Buy some for friends
8# and family, too. (Not that this is a blatant plug or anything.) 8# and family, too. (Not that this is a blatant plug or anything.)
9# 9#
10# Invoke this makefile from a shell prompt in the usual way; for example: 10# Invoke this makefile from a shell prompt in the usual way; for example:
11# 11#
12# make -f Makefile.sgi 12# make -f Makefile.sgi
13# 13#
14# This makefile assumes libpng and zlib have already been built or downloaded 14# This makefile assumes libpng and zlib have already been built or downloaded
15# and are both installed in /usr/local/{include,lib} (as indicated by the 15# and are both installed in /usr/local/{include,lib} (as indicated by the
16# PNG* and Z* macros below). Edit as appropriate--choose only ONE each of 16# PNG* and Z* macros below). Edit as appropriate--choose only ONE each of
17# the PNGINC, PNGLIB, ZINC and ZLIB lines. 17# the PNGINC, PNGLIB, ZINC and ZLIB lines.
18# 18#
19# This makefile builds dynamically linked executables (against libpng and zlib, 19# This makefile builds dynamically linked executables (against libpng and zlib,
20# that is), but that can be changed by uncommenting the appropriate PNGLIB and 20# that is), but that can be changed by uncommenting the appropriate PNGLIB and
21# ZLIB lines. 21# ZLIB lines.
22 22
23 23
24# macros -------------------------------------------------------------------- 24# macros --------------------------------------------------------------------
25 25
26PNGINC = -I/usr/local/include/libpng15 26PNGINC = -I/usr/local/include/libpng15
27PNGLIB = -L/usr/local/lib -lpng15 # dynamically linked against libpng 27PNGLIB = -L/usr/local/lib -lpng15 # dynamically linked against libpng
28#PNGLIB = /usr/local/lib/libpng15.a # statically linked against libpng 28#PNGLIB = /usr/local/lib/libpng15.a # statically linked against libpng
29# or: 29# or:
30#PNGINC = -I../.. 30#PNGINC = -I../..
31#PNGLIB = -L../.. -lpng 31#PNGLIB = -L../.. -lpng
32#PNGLIB = ../../libpng.a 32#PNGLIB = ../../libpng.a
33 33
34ZINC = -I/usr/local/include 34ZINC = -I/usr/local/include
35ZLIB = -L/usr/local/lib -lz # dynamically linked against zlib 35ZLIB = -L/usr/local/lib -lz # dynamically linked against zlib
36#ZLIB = /usr/local/lib/libz.a # statically linked against zlib 36#ZLIB = /usr/local/lib/libz.a # statically linked against zlib
37#ZINC = -I../zlib 37#ZINC = -I../zlib
38#ZLIB = -L../zlib -lz 38#ZLIB = -L../zlib -lz
39#ZLIB = ../../../zlib/libz.a 39#ZLIB = ../../../zlib/libz.a
40 40
41XINC = -I/usr/include/X11 # old-style, stock X distributions 41XINC = -I/usr/include/X11 # old-style, stock X distributions
42XLIB = -L/usr/lib/X11 -lX11 42XLIB = -L/usr/lib/X11 -lX11
43#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows) 43#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows)
44#XLIB = -L/usr/openwin/lib -lX11 44#XLIB = -L/usr/openwin/lib -lX11
45#XINC = -I/usr/X11R6/include # new X distributions (XFree86, etc.) 45#XINC = -I/usr/X11R6/include # new X distributions (XFree86, etc.)
46#XLIB = -L/usr/X11R6/lib -lX11 46#XLIB = -L/usr/X11R6/lib -lX11
47 47
48INCS = $(PNGINC) $(ZINC) $(XINC) 48INCS = $(PNGINC) $(ZINC) $(XINC)
49RLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm 49RLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm
50WLIBS = $(PNGLIB) $(ZLIB) 50WLIBS = $(PNGLIB) $(ZLIB)
51 51
52CC = cc 52CC = cc
53LD = cc 53LD = cc
54RM = rm -f 54RM = rm -f
55# ABI must be the same as that used to build libpng. 55# ABI must be the same as that used to build libpng.
56ABI= 56ABI=
57CFLAGS = $(ABI) -O -fullwarn $(INCS) 57CFLAGS = $(ABI) -O -fullwarn $(INCS)
58LDFLAGS = $(ABI) 58LDFLAGS = $(ABI)
59O = .o 59O = .o
60E = 60E =
61 61
62RPNG = rpng-x 62RPNG = rpng-x
63RPNG2 = rpng2-x 63RPNG2 = rpng2-x
64WPNG = wpng 64WPNG = wpng
65 65
66ROBJS = $(RPNG)$(O) readpng$(O) 66ROBJS = $(RPNG)$(O) readpng$(O)
67ROBJS2 = $(RPNG2)$(O) readpng2$(O) 67ROBJS2 = $(RPNG2)$(O) readpng2$(O)
68WOBJS = $(WPNG)$(O) writepng$(O) 68WOBJS = $(WPNG)$(O) writepng$(O)
69 69
70EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) 70EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
71 71
72 72
73# implicit make rules ------------------------------------------------------- 73# implicit make rules -------------------------------------------------------
74 74
75.c$(O): 75.c$(O):
76 $(CC) -c $(CFLAGS) $< 76 $(CC) -c $(CFLAGS) $<
77 77
78 78
79# dependencies -------------------------------------------------------------- 79# dependencies --------------------------------------------------------------
80 80
81all: $(EXES) 81all: $(EXES)
82 82
83$(RPNG)$(E): $(ROBJS) 83$(RPNG)$(E): $(ROBJS)
84 $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBS) 84 $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBS)
85 85
86$(RPNG2)$(E): $(ROBJS2) 86$(RPNG2)$(E): $(ROBJS2)
87 $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBS) 87 $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBS)
88 88
89$(WPNG)$(E): $(WOBJS) 89$(WPNG)$(E): $(WOBJS)
90 $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBS) 90 $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBS)
91 91
92$(RPNG)$(O): $(RPNG).c readpng.h 92$(RPNG)$(O): $(RPNG).c readpng.h
93$(RPNG2)$(O): $(RPNG2).c readpng2.h 93$(RPNG2)$(O): $(RPNG2).c readpng2.h
94$(WPNG)$(O): $(WPNG).c writepng.h 94$(WPNG)$(O): $(WPNG).c writepng.h
95 95
96readpng$(O): readpng.c readpng.h 96readpng$(O): readpng.c readpng.h
97readpng2$(O): readpng2.c readpng2.h 97readpng2$(O): readpng2.c readpng2.h
98writepng$(O): writepng.c writepng.h 98writepng$(O): writepng.c writepng.h
99 99
100 100
101# maintenance --------------------------------------------------------------- 101# maintenance ---------------------------------------------------------------
102 102
103clean: 103clean:
104 $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS) 104 $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.unx b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.unx
index 3bffc2f..b52d8b6 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.unx
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.unx
@@ -1,132 +1,132 @@
1# Sample makefile for rpng-x / rpng2-x / wpng using gcc and make. 1# Sample makefile for rpng-x / rpng2-x / wpng using gcc and make.
2# Greg Roelofs 2# Greg Roelofs
3# Last modified: 2 June 2007 3# Last modified: 2 June 2007
4# 4#
5# The programs built by this makefile are described in the book, 5# The programs built by this makefile are described in the book,
6# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and 6# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
7# Associates, 1999). Go buy a copy, eh? Well, OK, it's not 7# Associates, 1999). Go buy a copy, eh? Well, OK, it's not
8# generally for sale anymore, but it's the thought that counts, 8# generally for sale anymore, but it's the thought that counts,
9# right? (Hint: http://www.libpng.org/pub/png/book/ ) 9# right? (Hint: http://www.libpng.org/pub/png/book/ )
10# 10#
11# Invoke this makefile from a shell prompt in the usual way; for example: 11# Invoke this makefile from a shell prompt in the usual way; for example:
12# 12#
13# make -f Makefile.unx 13# make -f Makefile.unx
14# 14#
15# This makefile assumes libpng and zlib have already been built or downloaded 15# This makefile assumes libpng and zlib have already been built or downloaded
16# and are installed in /usr/local/{include,lib} or as otherwise indicated by 16# and are installed in /usr/local/{include,lib} or as otherwise indicated by
17# the PNG* and Z* macros below. Edit as appropriate--choose only ONE each of 17# the PNG* and Z* macros below. Edit as appropriate--choose only ONE each of
18# the PNGINC, PNGLIBd, PNGLIBs, ZINC, ZLIBd and ZLIBs lines. 18# the PNGINC, PNGLIBd, PNGLIBs, ZINC, ZLIBd and ZLIBs lines.
19# 19#
20# This makefile builds both dynamically and statically linked executables 20# This makefile builds both dynamically and statically linked executables
21# (against libpng and zlib, that is), but that can be changed by modifying 21# (against libpng and zlib, that is), but that can be changed by modifying
22# the "EXES =" line. (You need only one set, but for testing it can be handy 22# the "EXES =" line. (You need only one set, but for testing it can be handy
23# to have both.) 23# to have both.)
24 24
25 25
26# macros -------------------------------------------------------------------- 26# macros --------------------------------------------------------------------
27 27
28#PNGDIR = /usr/local/lib 28#PNGDIR = /usr/local/lib
29#PNGINC = -I/usr/local/include/libpng15 29#PNGINC = -I/usr/local/include/libpng15
30#PNGLIBd = -L$(PNGDIR) -lpng15 # dynamically linked, installed libpng 30#PNGLIBd = -L$(PNGDIR) -lpng15 # dynamically linked, installed libpng
31#PNGLIBs = $(PNGDIR)/libpng15.a # statically linked, installed libpng 31#PNGLIBs = $(PNGDIR)/libpng15.a # statically linked, installed libpng
32# or: 32# or:
33PNGDIR = ../..# this one is for libpng-x.y.z/contrib/gregbook builds 33PNGDIR = ../..# this one is for libpng-x.y.z/contrib/gregbook builds
34#PNGDIR = ../libpng 34#PNGDIR = ../libpng
35PNGINC = -I$(PNGDIR) 35PNGINC = -I$(PNGDIR)
36PNGLIBd = -Wl,-rpath,$(PNGDIR) -L$(PNGDIR) -lpng15 # dynamically linked 36PNGLIBd = -Wl,-rpath,$(PNGDIR) -L$(PNGDIR) -lpng15 # dynamically linked
37PNGLIBs = $(PNGDIR)/libpng.a # statically linked, local libpng 37PNGLIBs = $(PNGDIR)/libpng.a # statically linked, local libpng
38 38
39ZDIR = /usr/local/lib 39ZDIR = /usr/local/lib
40#ZDIR = /usr/lib64 40#ZDIR = /usr/lib64
41ZINC = -I/usr/local/include 41ZINC = -I/usr/local/include
42ZLIBd = -L$(ZDIR) -lz # dynamically linked against zlib 42ZLIBd = -L$(ZDIR) -lz # dynamically linked against zlib
43ZLIBs = $(ZDIR)/libz.a # statically linked against zlib 43ZLIBs = $(ZDIR)/libz.a # statically linked against zlib
44# or: 44# or:
45#ZDIR = ../zlib 45#ZDIR = ../zlib
46#ZINC = -I$(ZDIR) 46#ZINC = -I$(ZDIR)
47#ZLIBd = -Wl,-rpath,$(ZDIR) -L$(ZDIR) -lz # -rpath allows in-place testing 47#ZLIBd = -Wl,-rpath,$(ZDIR) -L$(ZDIR) -lz # -rpath allows in-place testing
48#ZLIBs = $(ZDIR)/libz.a 48#ZLIBs = $(ZDIR)/libz.a
49 49
50#XINC = -I/usr/include # old-style, stock X distributions 50#XINC = -I/usr/include # old-style, stock X distributions
51#XLIB = -L/usr/lib/X11 -lX11 # (including SGI IRIX) 51#XLIB = -L/usr/lib/X11 -lX11 # (including SGI IRIX)
52#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows) 52#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows)
53#XLIB = -L/usr/openwin/lib -lX11 53#XLIB = -L/usr/openwin/lib -lX11
54XINC = -I/usr/X11R6/include # new X distributions (X.org, etc.) 54XINC = -I/usr/X11R6/include # new X distributions (X.org, etc.)
55XLIB = -L/usr/X11R6/lib -lX11 55XLIB = -L/usr/X11R6/lib -lX11
56#XLIB = -L/usr/X11R6/lib64 -lX11 # e.g., Red Hat on AMD64 56#XLIB = -L/usr/X11R6/lib64 -lX11 # e.g., Red Hat on AMD64
57 57
58INCS = $(PNGINC) $(ZINC) $(XINC) 58INCS = $(PNGINC) $(ZINC) $(XINC)
59RLIBSd = $(PNGLIBd) $(ZLIBd) $(XLIB) -lm 59RLIBSd = $(PNGLIBd) $(ZLIBd) $(XLIB) -lm
60RLIBSs = $(PNGLIBs) $(ZLIBs) $(XLIB) -lm 60RLIBSs = $(PNGLIBs) $(ZLIBs) $(XLIB) -lm
61WLIBSd = $(PNGLIBd) $(ZLIBd) -lm 61WLIBSd = $(PNGLIBd) $(ZLIBd) -lm
62WLIBSs = $(PNGLIBs) $(ZLIBs) 62WLIBSs = $(PNGLIBs) $(ZLIBs)
63 63
64CC = gcc 64CC = gcc
65LD = gcc 65LD = gcc
66RM = rm -f 66RM = rm -f
67CFLAGS = -O -Wall $(INCS) -DFEATURE_LOOP 67CFLAGS = -O -Wall $(INCS) -DFEATURE_LOOP
68# [note that -Wall is a gcc-specific compilation flag ("most warnings on")] 68# [note that -Wall is a gcc-specific compilation flag ("most warnings on")]
69# [-ansi, -pedantic and -W can also be used] 69# [-ansi, -pedantic and -W can also be used]
70LDFLAGS = 70LDFLAGS =
71O = .o 71O = .o
72E = 72E =
73 73
74RPNG = rpng-x 74RPNG = rpng-x
75RPNG2 = rpng2-x 75RPNG2 = rpng2-x
76WPNG = wpng 76WPNG = wpng
77 77
78RPNGs = $(RPNG)-static 78RPNGs = $(RPNG)-static
79RPNG2s = $(RPNG2)-static 79RPNG2s = $(RPNG2)-static
80WPNGs = $(WPNG)-static 80WPNGs = $(WPNG)-static
81 81
82ROBJS = $(RPNG)$(O) readpng$(O) 82ROBJS = $(RPNG)$(O) readpng$(O)
83ROBJS2 = $(RPNG2)$(O) readpng2$(O) 83ROBJS2 = $(RPNG2)$(O) readpng2$(O)
84WOBJS = $(WPNG)$(O) writepng$(O) 84WOBJS = $(WPNG)$(O) writepng$(O)
85 85
86STATIC_EXES = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E) 86STATIC_EXES = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E)
87DYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) 87DYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
88 88
89EXES = $(STATIC_EXES) $(DYNAMIC_EXES) 89EXES = $(STATIC_EXES) $(DYNAMIC_EXES)
90 90
91 91
92# implicit make rules ------------------------------------------------------- 92# implicit make rules -------------------------------------------------------
93 93
94.c$(O): 94.c$(O):
95 $(CC) -c $(CFLAGS) $< 95 $(CC) -c $(CFLAGS) $<
96 96
97 97
98# dependencies -------------------------------------------------------------- 98# dependencies --------------------------------------------------------------
99 99
100all: $(EXES) 100all: $(EXES)
101 101
102$(RPNGs)$(E): $(ROBJS) 102$(RPNGs)$(E): $(ROBJS)
103 $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSs) 103 $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSs)
104 104
105$(RPNG)$(E): $(ROBJS) 105$(RPNG)$(E): $(ROBJS)
106 $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSd) 106 $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSd)
107 107
108$(RPNG2s)$(E): $(ROBJS2) 108$(RPNG2s)$(E): $(ROBJS2)
109 $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSs) 109 $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSs)
110 110
111$(RPNG2)$(E): $(ROBJS2) 111$(RPNG2)$(E): $(ROBJS2)
112 $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSd) 112 $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSd)
113 113
114$(WPNGs)$(E): $(WOBJS) 114$(WPNGs)$(E): $(WOBJS)
115 $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSs) 115 $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSs)
116 116
117$(WPNG)$(E): $(WOBJS) 117$(WPNG)$(E): $(WOBJS)
118 $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSd) 118 $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSd)
119 119
120$(RPNG)$(O): $(RPNG).c readpng.h 120$(RPNG)$(O): $(RPNG).c readpng.h
121$(RPNG2)$(O): $(RPNG2).c readpng2.h 121$(RPNG2)$(O): $(RPNG2).c readpng2.h
122$(WPNG)$(O): $(WPNG).c writepng.h 122$(WPNG)$(O): $(WPNG).c writepng.h
123 123
124readpng$(O): readpng.c readpng.h 124readpng$(O): readpng.c readpng.h
125readpng2$(O): readpng2.c readpng2.h 125readpng2$(O): readpng2.c readpng2.h
126writepng$(O): writepng.c writepng.h 126writepng$(O): writepng.c writepng.h
127 127
128 128
129# maintenance --------------------------------------------------------------- 129# maintenance ---------------------------------------------------------------
130 130
131clean: 131clean:
132 $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS) 132 $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.w32 b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.w32
index eced083..41cfb23 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.w32
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/Makefile.w32
@@ -1,113 +1,113 @@
1# Sample makefile for rpng-win / rpng2-win / wpng using MSVC and NMAKE. 1# Sample makefile for rpng-win / rpng2-win / wpng using MSVC and NMAKE.
2# Greg Roelofs 2# Greg Roelofs
3# Last modified: 2 June 2007 3# Last modified: 2 June 2007
4# 4#
5# The programs built by this makefile are described in the book, 5# The programs built by this makefile are described in the book,
6# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and 6# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
7# Associates, 1999). Go buy a copy, eh? Well, OK, it's not 7# Associates, 1999). Go buy a copy, eh? Well, OK, it's not
8# generally for sale anymore, but it's the thought that counts, 8# generally for sale anymore, but it's the thought that counts,
9# right? (Hint: http://www.libpng.org/pub/png/book/ ) 9# right? (Hint: http://www.libpng.org/pub/png/book/ )
10# 10#
11# Invoke this makefile from a DOS prompt window via: 11# Invoke this makefile from a DOS prompt window via:
12# 12#
13# %devstudio%\vc\bin\vcvars32.bat 13# %devstudio%\vc\bin\vcvars32.bat
14# nmake -nologo -f Makefile.w32 14# nmake -nologo -f Makefile.w32
15# 15#
16# where %devstudio% is the installation directory for MSVC / DevStudio. If 16# where %devstudio% is the installation directory for MSVC / DevStudio. If
17# you get "environment out of space" errors, create a desktop shortcut with 17# you get "environment out of space" errors, create a desktop shortcut with
18# "c:\windows\command.com /e:4096" as the program command line and set the 18# "c:\windows\command.com /e:4096" as the program command line and set the
19# working directory to this directory. Then double-click to open the new 19# working directory to this directory. Then double-click to open the new
20# DOS-prompt window with a bigger environment and retry the commands above. 20# DOS-prompt window with a bigger environment and retry the commands above.
21# 21#
22# This makefile assumes libpng and zlib have already been built or downloaded 22# This makefile assumes libpng and zlib have already been built or downloaded
23# and are in subdirectories at the same level as the current subdirectory 23# and are in subdirectories at the same level as the current subdirectory
24# (as indicated by the PNGPATH and ZPATH macros below). Edit as appropriate. 24# (as indicated by the PNGPATH and ZPATH macros below). Edit as appropriate.
25# 25#
26# Note that the names of the dynamic and static libpng and zlib libraries 26# Note that the names of the dynamic and static libpng and zlib libraries
27# used below may change in later releases of the libraries. This makefile 27# used below may change in later releases of the libraries. This makefile
28# builds statically linked executables, but that can be changed by uncom- 28# builds statically linked executables, but that can be changed by uncom-
29# menting the appropriate PNGLIB and ZLIB lines. 29# menting the appropriate PNGLIB and ZLIB lines.
30 30
31!include <ntwin32.mak> 31!include <ntwin32.mak>
32 32
33 33
34# macros -------------------------------------------------------------------- 34# macros --------------------------------------------------------------------
35 35
36PNGPATH = ../libpng 36PNGPATH = ../libpng
37PNGINC = -I$(PNGPATH) 37PNGINC = -I$(PNGPATH)
38#PNGLIB = $(PNGPATH)/pngdll.lib 38#PNGLIB = $(PNGPATH)/pngdll.lib
39PNGLIB = $(PNGPATH)/libpng.lib 39PNGLIB = $(PNGPATH)/libpng.lib
40 40
41ZPATH = ../zlib 41ZPATH = ../zlib
42ZINC = -I$(ZPATH) 42ZINC = -I$(ZPATH)
43#ZLIB = $(ZPATH)/zlibdll.lib 43#ZLIB = $(ZPATH)/zlibdll.lib
44ZLIB = $(ZPATH)/zlibstat.lib 44ZLIB = $(ZPATH)/zlibstat.lib
45 45
46WINLIBS = -defaultlib:user32.lib gdi32.lib 46WINLIBS = -defaultlib:user32.lib gdi32.lib
47# ["real" apps may also need comctl32.lib, comdlg32.lib, winmm.lib, etc.] 47# ["real" apps may also need comctl32.lib, comdlg32.lib, winmm.lib, etc.]
48 48
49INCS = $(PNGINC) $(ZINC) 49INCS = $(PNGINC) $(ZINC)
50RLIBS = $(PNGLIB) $(ZLIB) $(WINLIBS) 50RLIBS = $(PNGLIB) $(ZLIB) $(WINLIBS)
51WLIBS = $(PNGLIB) $(ZLIB) 51WLIBS = $(PNGLIB) $(ZLIB)
52 52
53CC = cl 53CC = cl
54LD = link 54LD = link
55RM = del 55RM = del
56CFLAGS = -nologo -O -W3 $(INCS) $(cvars) 56CFLAGS = -nologo -O -W3 $(INCS) $(cvars)
57# [note that -W3 is an MSVC-specific compilation flag ("all warnings on")] 57# [note that -W3 is an MSVC-specific compilation flag ("all warnings on")]
58# [see %devstudio%\vc\include\win32.mak for cvars macro definition] 58# [see %devstudio%\vc\include\win32.mak for cvars macro definition]
59O = .obj 59O = .obj
60E = .exe 60E = .exe
61 61
62RLDFLAGS = -nologo -subsystem:windows 62RLDFLAGS = -nologo -subsystem:windows
63WLDFLAGS = -nologo 63WLDFLAGS = -nologo
64 64
65RPNG = rpng-win 65RPNG = rpng-win
66RPNG2 = rpng2-win 66RPNG2 = rpng2-win
67WPNG = wpng 67WPNG = wpng
68 68
69ROBJS = $(RPNG)$(O) readpng$(O) 69ROBJS = $(RPNG)$(O) readpng$(O)
70ROBJS2 = $(RPNG2)$(O) readpng2$(O) 70ROBJS2 = $(RPNG2)$(O) readpng2$(O)
71WOBJS = $(WPNG)$(O) writepng$(O) 71WOBJS = $(WPNG)$(O) writepng$(O)
72 72
73EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) 73EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
74 74
75 75
76# implicit make rules ------------------------------------------------------- 76# implicit make rules -------------------------------------------------------
77 77
78.c$(O): 78.c$(O):
79 $(CC) -c $(CFLAGS) $< 79 $(CC) -c $(CFLAGS) $<
80 80
81 81
82# dependencies -------------------------------------------------------------- 82# dependencies --------------------------------------------------------------
83 83
84all: $(EXES) 84all: $(EXES)
85 85
86$(RPNG)$(E): $(ROBJS) 86$(RPNG)$(E): $(ROBJS)
87 $(LD) $(RLDFLAGS) -out:$@ $(ROBJS) $(RLIBS) 87 $(LD) $(RLDFLAGS) -out:$@ $(ROBJS) $(RLIBS)
88 88
89$(RPNG2)$(E): $(ROBJS2) 89$(RPNG2)$(E): $(ROBJS2)
90 $(LD) $(RLDFLAGS) -out:$@ $(ROBJS2) $(RLIBS) 90 $(LD) $(RLDFLAGS) -out:$@ $(ROBJS2) $(RLIBS)
91 91
92$(WPNG)$(E): $(WOBJS) 92$(WPNG)$(E): $(WOBJS)
93 $(LD) $(WLDFLAGS) -out:$@ $(WOBJS) $(WLIBS) 93 $(LD) $(WLDFLAGS) -out:$@ $(WOBJS) $(WLIBS)
94 94
95$(RPNG)$(O): $(RPNG).c readpng.h 95$(RPNG)$(O): $(RPNG).c readpng.h
96$(RPNG2)$(O): $(RPNG2).c readpng2.h 96$(RPNG2)$(O): $(RPNG2).c readpng2.h
97$(WPNG)$(O): $(WPNG).c writepng.h 97$(WPNG)$(O): $(WPNG).c writepng.h
98 98
99readpng$(O): readpng.c readpng.h 99readpng$(O): readpng.c readpng.h
100readpng2$(O): readpng2.c readpng2.h 100readpng2$(O): readpng2.c readpng2.h
101writepng$(O): writepng.c writepng.h 101writepng$(O): writepng.c writepng.h
102 102
103 103
104# maintenance --------------------------------------------------------------- 104# maintenance ---------------------------------------------------------------
105 105
106clean: 106clean:
107# ideally we could just do this: 107# ideally we could just do this:
108# $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS) 108# $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)
109# ...but the Windows "DEL" command is none too bright, so: 109# ...but the Windows "DEL" command is none too bright, so:
110 $(RM) r*$(E) 110 $(RM) r*$(E)
111 $(RM) w*$(E) 111 $(RM) w*$(E)
112 $(RM) r*$(O) 112 $(RM) r*$(O)
113 $(RM) w*$(O) 113 $(RM) w*$(O)
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/README b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/README
index 791fec8..7b1f6a3 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/README
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/README
@@ -1,186 +1,186 @@
1 =========================== 1 ===========================
2 PNG: The Definitive Guide 2 PNG: The Definitive Guide
3 =========================== 3 ===========================
4 4
5 Source Code 5 Source Code
6 6
7Chapters 13, 14 and 15 of "PNG: The Definitive Guide" discuss three free, 7Chapters 13, 14 and 15 of "PNG: The Definitive Guide" discuss three free,
8cross-platform demo programs that show how to use the libpng reference 8cross-platform demo programs that show how to use the libpng reference
9library: rpng, rpng2 and wpng. rpng and rpng2 are viewers; the first is 9library: rpng, rpng2 and wpng. rpng and rpng2 are viewers; the first is
10a very simple example that that shows how a standard file-viewer might use 10a very simple example that that shows how a standard file-viewer might use
11libpng, while the second is designed to process streaming data and shows 11libpng, while the second is designed to process streaming data and shows
12how a web browser might be written. wpng is a simple command-line program 12how a web browser might be written. wpng is a simple command-line program
13that reads binary PGM and PPM files (the ``raw'' grayscale and RGB subsets 13that reads binary PGM and PPM files (the ``raw'' grayscale and RGB subsets
14of PBMPLUS/NetPBM) and converts them to PNG. 14of PBMPLUS/NetPBM) and converts them to PNG.
15 15
16The source code for all three demo programs currently compiles under 16The source code for all three demo programs currently compiles under
17Unix, OpenVMS, and 32-bit Windows. (Special thanks to Martin Zinser, 17Unix, OpenVMS, and 32-bit Windows. (Special thanks to Martin Zinser,
18zinser@decus.de, for making the necessary changes for OpenVMS and for 18zinser@decus.de, for making the necessary changes for OpenVMS and for
19providing an appropriate build script.) Build instructions can be found 19providing an appropriate build script.) Build instructions can be found
20below. 20below.
21 21
22Files: 22Files:
23 23
24 README this file 24 README this file
25 LICENSE terms of distribution and reuse (BSD-like or GNU GPL) 25 LICENSE terms of distribution and reuse (BSD-like or GNU GPL)
26 COPYING GNU General Public License (GPL) 26 COPYING GNU General Public License (GPL)
27 27
28 Makefile.unx Unix makefile 28 Makefile.unx Unix makefile
29 Makefile.w32 Windows (MSVC) makefile 29 Makefile.w32 Windows (MSVC) makefile
30 makevms.com OpenVMS build script 30 makevms.com OpenVMS build script
31 31
32 rpng-win.c Windows front end for the basic viewer 32 rpng-win.c Windows front end for the basic viewer
33 rpng-x.c X Window System (Unix, OpenVMS) front end 33 rpng-x.c X Window System (Unix, OpenVMS) front end
34 readpng.c generic back end for the basic viewer 34 readpng.c generic back end for the basic viewer
35 readpng.h header file for the basic viewer 35 readpng.h header file for the basic viewer
36 36
37 rpng2-win.c Windows front end for the progressive viewer 37 rpng2-win.c Windows front end for the progressive viewer
38 rpng2-x.c X front end for the progressive viewer 38 rpng2-x.c X front end for the progressive viewer
39 readpng2.c generic back end for the progressive viewer 39 readpng2.c generic back end for the progressive viewer
40 readpng2.h header file for the progressive viewer 40 readpng2.h header file for the progressive viewer
41 41
42 wpng.c generic (text) front end for the converter 42 wpng.c generic (text) front end for the converter
43 writepng.c generic back end for the converter 43 writepng.c generic back end for the converter
44 writepng.h header file for the converter 44 writepng.h header file for the converter
45 45
46 toucan.png transparent PNG for testing (by Stefan Schneider) 46 toucan.png transparent PNG for testing (by Stefan Schneider)
47 47
48Note that, although the programs are designed to be functional, their 48Note that, although the programs are designed to be functional, their
49primary purpose is to illustrate how to use libpng to add PNG support to 49primary purpose is to illustrate how to use libpng to add PNG support to
50other programs. As such, their user interfaces are crude and definitely 50other programs. As such, their user interfaces are crude and definitely
51are not intended for everyday use. 51are not intended for everyday use.
52 52
53Please see http://www.libpng.org/pub/png/pngbook.html for further infor- 53Please see http://www.libpng.org/pub/png/pngbook.html for further infor-
54mation and links to the latest version of the source code, and Chapters 54mation and links to the latest version of the source code, and Chapters
5513-15 of the book for detailed discussion of the three programs. 5513-15 of the book for detailed discussion of the three programs.
56 56
57Greg Roelofs 57Greg Roelofs
58http://pobox.com/~newt/greg_contact.html 58http://pobox.com/~newt/greg_contact.html
5916 March 2008 5916 March 2008
60 60
61 61
62BUILD INSTRUCTIONS 62BUILD INSTRUCTIONS
63 63
64 - Prerequisites (in order of compilation): 64 - Prerequisites (in order of compilation):
65 65
66 - zlib http://zlib.net/ 66 - zlib http://zlib.net/
67 - libpng http://www.libpng.org/pub/png/libpng.html 67 - libpng http://www.libpng.org/pub/png/libpng.html
68 - pngbook http://www.libpng.org/pub/png/book/sources.html 68 - pngbook http://www.libpng.org/pub/png/book/sources.html
69 69
70 The pngbook demo programs are explicitly designed to demonstrate proper 70 The pngbook demo programs are explicitly designed to demonstrate proper
71 coding techniques for using the libpng reference library. As a result, 71 coding techniques for using the libpng reference library. As a result,
72 you need to download and build both zlib (on which libpng depends) and 72 you need to download and build both zlib (on which libpng depends) and
73 libpng. A common build setup is to place the zlib, libpng and pngbook 73 libpng. A common build setup is to place the zlib, libpng and pngbook
74 subdirectory trees ("folders") in the same parent directory. Then the 74 subdirectory trees ("folders") in the same parent directory. Then the
75 libpng build can refer to files in ../zlib (or ..\zlib or [-.zlib]), 75 libpng build can refer to files in ../zlib (or ..\zlib or [-.zlib]),
76 and similarly for the pngbook build. 76 and similarly for the pngbook build.
77 77
78 Note that all three packages are designed to be built from a command 78 Note that all three packages are designed to be built from a command
79 line by default; those who wish to use a graphical or other integrated 79 line by default; those who wish to use a graphical or other integrated
80 development environments are on their own. 80 development environments are on their own.
81 81
82 82
83 - Unix: 83 - Unix:
84 84
85 Unpack the latest pngbook sources (which should correspond to this 85 Unpack the latest pngbook sources (which should correspond to this
86 README file) into a directory and change into that directory. 86 README file) into a directory and change into that directory.
87 87
88 Copy Makefile.unx to Makefile and edit the PNG* and Z* variables 88 Copy Makefile.unx to Makefile and edit the PNG* and Z* variables
89 appropriately (possibly also the X* variables if necessary). 89 appropriately (possibly also the X* variables if necessary).
90 90
91 make 91 make
92 92
93 There is no "install" target, so copy the three executables somewhere 93 There is no "install" target, so copy the three executables somewhere
94 in your path or run them from the current directory. All three will 94 in your path or run them from the current directory. All three will
95 print a basic usage screen when run without any command-line arguments; 95 print a basic usage screen when run without any command-line arguments;
96 see the book for more details. 96 see the book for more details.
97 97
98 98
99 - Windows: 99 - Windows:
100 100
101 Unpack the latest pngbook sources (which should correspond to this 101 Unpack the latest pngbook sources (which should correspond to this
102 README file) into a folder, open a "DOS shell" or "command prompt" 102 README file) into a folder, open a "DOS shell" or "command prompt"
103 or equivalent command-line window, and cd into the folder where you 103 or equivalent command-line window, and cd into the folder where you
104 unpacked the source code. 104 unpacked the source code.
105 105
106 For MSVC, set up the necessary environment variables by invoking 106 For MSVC, set up the necessary environment variables by invoking
107 107
108 %devstudio%\vc\bin\vcvars32.bat 108 %devstudio%\vc\bin\vcvars32.bat
109 109
110 where where %devstudio% is the installation directory for MSVC / 110 where where %devstudio% is the installation directory for MSVC /
111 DevStudio. If you get "environment out of space" errors under 95/98, 111 DevStudio. If you get "environment out of space" errors under 95/98,
112 create a desktop shortcut with "c:\windows\command.com /e:4096" as 112 create a desktop shortcut with "c:\windows\command.com /e:4096" as
113 the program command line and set the working directory to the pngbook 113 the program command line and set the working directory to the pngbook
114 directory. Then double-click to open the new DOS-prompt window with 114 directory. Then double-click to open the new DOS-prompt window with
115 a bigger environment and retry the commands above. 115 a bigger environment and retry the commands above.
116 116
117 Copy Makefile.w32 to Makefile and edit the PNGPATH and ZPATH variables 117 Copy Makefile.w32 to Makefile and edit the PNGPATH and ZPATH variables
118 appropriately (possibly also the "INC" and "LIB" variables if needed). 118 appropriately (possibly also the "INC" and "LIB" variables if needed).
119 Note that the names of the dynamic and static libpng and zlib libraries 119 Note that the names of the dynamic and static libpng and zlib libraries
120 used in the makefile may change in later releases of the libraries. 120 used in the makefile may change in later releases of the libraries.
121 Also note that, as of libpng version 1.0.5, MSVC DLL builds do not work. 121 Also note that, as of libpng version 1.0.5, MSVC DLL builds do not work.
122 This makefile therefore builds statically linked executables, but if 122 This makefile therefore builds statically linked executables, but if
123 the DLL problems ever get fixed, uncommenting the appropriate PNGLIB 123 the DLL problems ever get fixed, uncommenting the appropriate PNGLIB
124 and ZLIB lines will build dynamically linked executables instead. 124 and ZLIB lines will build dynamically linked executables instead.
125 125
126 Do the build by typing 126 Do the build by typing
127 127
128 nmake 128 nmake
129 129
130 The result should be three executables: rpng-win.exe, rpng2-win.exe, 130 The result should be three executables: rpng-win.exe, rpng2-win.exe,
131 and wpng.exe. Copy them somewhere in your PATH or run them from the 131 and wpng.exe. Copy them somewhere in your PATH or run them from the
132 current folder. Like the Unix versions, the two windowed programs 132 current folder. Like the Unix versions, the two windowed programs
133 (rpng and rpng2) now display a usage screen in a console window when 133 (rpng and rpng2) now display a usage screen in a console window when
134 invoked without command-line arguments; this is new behavior as of 134 invoked without command-line arguments; this is new behavior as of
135 the June 2001 release. Note that the programs use the Unix-style "-" 135 the June 2001 release. Note that the programs use the Unix-style "-"
136 character to specify options, instead of the more common DOS/Windows 136 character to specify options, instead of the more common DOS/Windows
137 "/" character. (For example: "rpng2-win -bgpat 4 foo.png", not 137 "/" character. (For example: "rpng2-win -bgpat 4 foo.png", not
138 "rpng2-win /bgpat 4 foo.png") 138 "rpng2-win /bgpat 4 foo.png")
139 139
140 140
141 - OpenVMS: 141 - OpenVMS:
142 142
143 Unpack the pngbook sources into a subdirectory and change into that 143 Unpack the pngbook sources into a subdirectory and change into that
144 subdirectory. 144 subdirectory.
145 145
146 Edit makevms.com appropriately, specifically the zpath and pngpath 146 Edit makevms.com appropriately, specifically the zpath and pngpath
147 variables. 147 variables.
148 148
149 @makevms 149 @makevms
150 150
151 To run the programs, they probably first need to be set up as "foreign 151 To run the programs, they probably first need to be set up as "foreign
152 symbols," with "disk" and "dir" set appropriately: 152 symbols," with "disk" and "dir" set appropriately:
153 153
154 $ rpng == "$disk:[dir]rpng-x.exe" 154 $ rpng == "$disk:[dir]rpng-x.exe"
155 $ rpng2 == "$disk:[dir]rpng2-x.exe" 155 $ rpng2 == "$disk:[dir]rpng2-x.exe"
156 $ wpng == "$disk:[dir]wpng.exe" 156 $ wpng == "$disk:[dir]wpng.exe"
157 157
158 All three will print a basic usage screen when run without any command- 158 All three will print a basic usage screen when run without any command-
159 line arguments; see the book for more details. Note that the options 159 line arguments; see the book for more details. Note that the options
160 style is Unix-like, i.e., preceded by "-" rather than "/". 160 style is Unix-like, i.e., preceded by "-" rather than "/".
161 161
162 162
163RUNNING THE PROGRAMS: (VERY) BRIEF INTRO 163RUNNING THE PROGRAMS: (VERY) BRIEF INTRO
164 164
165 rpng is a simple PNG viewer that can display transparent PNGs with a 165 rpng is a simple PNG viewer that can display transparent PNGs with a
166 specified background color; for example, 166 specified background color; for example,
167 167
168 rpng -bgcolor \#ff0000 toucan.png 168 rpng -bgcolor \#ff0000 toucan.png
169 169
170 would display the image with a red background. rpng2 is a progressive 170 would display the image with a red background. rpng2 is a progressive
171 viewer that simulates a web browser in some respects; it can display 171 viewer that simulates a web browser in some respects; it can display
172 images against either a background color or a dynamically generated 172 images against either a background color or a dynamically generated
173 background image. For example: 173 background image. For example:
174 174
175 rpng2 -bgpat 16 toucan.png 175 rpng2 -bgpat 16 toucan.png
176 176
177 wpng is a purely command-line image converter from binary PBMPLUS/NetPBM 177 wpng is a purely command-line image converter from binary PBMPLUS/NetPBM
178 format (.pgm or .ppm) to PNG; for example, 178 format (.pgm or .ppm) to PNG; for example,
179 179
180 wpng -time < toucan-notrans.ppm > toucan-notrans.png 180 wpng -time < toucan-notrans.ppm > toucan-notrans.png
181 181
182 would convert the specified PPM file (using redirection) to PNG, auto- 182 would convert the specified PPM file (using redirection) to PNG, auto-
183 matically setting the PNG modification-time chunk. 183 matically setting the PNG modification-time chunk.
184 184
185 All options can be abbreviated to the shortest unique value; for example, 185 All options can be abbreviated to the shortest unique value; for example,
186 "-bgc" for -bgcolor (versus "-bgp" for -bgpat), or "-g" for -gamma. 186 "-bgc" for -bgcolor (versus "-bgp" for -bgpat), or "-g" for -gamma.
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/makevms.com b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/makevms.com
index 29a5727..f32bcab 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/makevms.com
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/makevms.com
@@ -1,132 +1,132 @@
1$!------------------------------------------------------------------------------ 1$!------------------------------------------------------------------------------
2$! make "PNG: The Definitive Guide" demo programs (for X) under OpenVMS 2$! make "PNG: The Definitive Guide" demo programs (for X) under OpenVMS
3$! 3$!
4$! Script created by Martin Zinser for libpng; modified by Greg Roelofs 4$! Script created by Martin Zinser for libpng; modified by Greg Roelofs
5$! for standalone pngbook source distribution. 5$! for standalone pngbook source distribution.
6$! 6$!
7$! 7$!
8$! Set locations where zlib and libpng sources live. 8$! Set locations where zlib and libpng sources live.
9$! 9$!
10$ zpath = "" 10$ zpath = ""
11$ pngpath = "" 11$ pngpath = ""
12$! 12$!
13$ if f$search("[---.zlib]zlib.h").nes."" then zpath = "[---.zlib]" 13$ if f$search("[---.zlib]zlib.h").nes."" then zpath = "[---.zlib]"
14$ if f$search("[--]png.h").nes."" then pngpath = "[--]" 14$ if f$search("[--]png.h").nes."" then pngpath = "[--]"
15$! 15$!
16$ if f$search("[-.zlib]zlib.h").nes."" then zpath = "[-.zlib]" 16$ if f$search("[-.zlib]zlib.h").nes."" then zpath = "[-.zlib]"
17$ if f$search("[-.libpng]png.h").nes."" then pngpath = "[-.libpng]" 17$ if f$search("[-.libpng]png.h").nes."" then pngpath = "[-.libpng]"
18$! 18$!
19$ if zpath .eqs. "" 19$ if zpath .eqs. ""
20$ then 20$ then
21$ write sys$output "zlib include not found. Exiting..." 21$ write sys$output "zlib include not found. Exiting..."
22$ exit 2 22$ exit 2
23$ endif 23$ endif
24$! 24$!
25$ if pngpath .eqs. "" 25$ if pngpath .eqs. ""
26$ then 26$ then
27$ write sys$output "libpng include not found. Exiting..." 27$ write sys$output "libpng include not found. Exiting..."
28$ exit 2 28$ exit 2
29$ endif 29$ endif
30$! 30$!
31$! Look for the compiler used. 31$! Look for the compiler used.
32$! 32$!
33$ ccopt="/include=(''zpath',''pngpath')" 33$ ccopt="/include=(''zpath',''pngpath')"
34$ if f$getsyi("HW_MODEL").ge.1024 34$ if f$getsyi("HW_MODEL").ge.1024
35$ then 35$ then
36$ ccopt = "/prefix=all"+ccopt 36$ ccopt = "/prefix=all"+ccopt
37$ comp = "__decc__=1" 37$ comp = "__decc__=1"
38$ if f$trnlnm("SYS").eqs."" then define sys sys$library: 38$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
39$ else 39$ else
40$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" 40$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs.""
41$ then 41$ then
42$ if f$trnlnm("SYS").eqs."" then define sys sys$library: 42$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
43$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs."" 43$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs.""
44$ then 44$ then
45$ comp = "__gcc__=1" 45$ comp = "__gcc__=1"
46$ CC :== GCC 46$ CC :== GCC
47$ else 47$ else
48$ comp = "__vaxc__=1" 48$ comp = "__vaxc__=1"
49$ endif 49$ endif
50$ else 50$ else
51$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: 51$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include:
52$ ccopt = "/decc/prefix=all"+ccopt 52$ ccopt = "/decc/prefix=all"+ccopt
53$ comp = "__decc__=1" 53$ comp = "__decc__=1"
54$ endif 54$ endif
55$ endif 55$ endif
56$ open/write lopt lib.opt 56$ open/write lopt lib.opt
57$ write lopt "''pngpath'libpng.olb/lib" 57$ write lopt "''pngpath'libpng.olb/lib"
58$ write lopt "''zpath'libz.olb/lib" 58$ write lopt "''zpath'libz.olb/lib"
59$ close lopt 59$ close lopt
60$ open/write xopt x11.opt 60$ open/write xopt x11.opt
61$ write xopt "sys$library:decw$xlibshr.exe/share" 61$ write xopt "sys$library:decw$xlibshr.exe/share"
62$ close xopt 62$ close xopt
63$! 63$!
64$! Build 'em. 64$! Build 'em.
65$! 65$!
66$ write sys$output "Compiling PNG book programs ..." 66$ write sys$output "Compiling PNG book programs ..."
67$ CALL MAKE readpng.OBJ "cc ''CCOPT' readpng" - 67$ CALL MAKE readpng.OBJ "cc ''CCOPT' readpng" -
68 readpng.c readpng.h 68 readpng.c readpng.h
69$ CALL MAKE readpng2.OBJ "cc ''CCOPT' readpng2" - 69$ CALL MAKE readpng2.OBJ "cc ''CCOPT' readpng2" -
70 readpng2.c readpng2.h 70 readpng2.c readpng2.h
71$ CALL MAKE writepng.OBJ "cc ''CCOPT' writepng" - 71$ CALL MAKE writepng.OBJ "cc ''CCOPT' writepng" -
72 writepng.c writepng.h 72 writepng.c writepng.h
73$ write sys$output "Building rpng-x..." 73$ write sys$output "Building rpng-x..."
74$ CALL MAKE rpng-x.OBJ "cc ''CCOPT' rpng-x" - 74$ CALL MAKE rpng-x.OBJ "cc ''CCOPT' rpng-x" -
75 rpng-x.c readpng.h 75 rpng-x.c readpng.h
76$ call make rpng-x.exe - 76$ call make rpng-x.exe -
77 "LINK rpng-x,readpng,lib.opt/opt,x11.opt/opt" - 77 "LINK rpng-x,readpng,lib.opt/opt,x11.opt/opt" -
78 rpng-x.obj readpng.obj 78 rpng-x.obj readpng.obj
79$ write sys$output "Building rpng2-x..." 79$ write sys$output "Building rpng2-x..."
80$ CALL MAKE rpng2-x.OBJ "cc ''CCOPT' rpng2-x" - 80$ CALL MAKE rpng2-x.OBJ "cc ''CCOPT' rpng2-x" -
81 rpng2-x.c readpng2.h 81 rpng2-x.c readpng2.h
82$ call make rpng2-x.exe - 82$ call make rpng2-x.exe -
83 "LINK rpng2-x,readpng2,lib.opt/opt,x11.opt/opt" - 83 "LINK rpng2-x,readpng2,lib.opt/opt,x11.opt/opt" -
84 rpng2-x.obj readpng2.obj 84 rpng2-x.obj readpng2.obj
85$ write sys$output "Building wpng..." 85$ write sys$output "Building wpng..."
86$ CALL MAKE wpng.OBJ "cc ''CCOPT' wpng" - 86$ CALL MAKE wpng.OBJ "cc ''CCOPT' wpng" -
87 wpng.c writepng.h 87 wpng.c writepng.h
88$ call make wpng.exe - 88$ call make wpng.exe -
89 "LINK wpng,writepng,lib.opt/opt" - 89 "LINK wpng,writepng,lib.opt/opt" -
90 wpng.obj writepng.obj 90 wpng.obj writepng.obj
91$ exit 91$ exit
92$! 92$!
93$! 93$!
94$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES 94$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
95$ V = 'F$Verify(0) 95$ V = 'F$Verify(0)
96$! P1 = What we are trying to make 96$! P1 = What we are trying to make
97$! P2 = Command to make it 97$! P2 = Command to make it
98$! P3 - P8 What it depends on 98$! P3 - P8 What it depends on
99$ 99$
100$ If F$Search(P1) .Eqs. "" Then Goto Makeit 100$ If F$Search(P1) .Eqs. "" Then Goto Makeit
101$ Time = F$CvTime(F$File(P1,"RDT")) 101$ Time = F$CvTime(F$File(P1,"RDT"))
102$arg=3 102$arg=3
103$Loop: 103$Loop:
104$ Argument = P'arg 104$ Argument = P'arg
105$ If Argument .Eqs. "" Then Goto Exit 105$ If Argument .Eqs. "" Then Goto Exit
106$ El=0 106$ El=0
107$Loop2: 107$Loop2:
108$ File = F$Element(El," ",Argument) 108$ File = F$Element(El," ",Argument)
109$ If File .Eqs. " " Then Goto Endl 109$ If File .Eqs. " " Then Goto Endl
110$ AFile = "" 110$ AFile = ""
111$Loop3: 111$Loop3:
112$ OFile = AFile 112$ OFile = AFile
113$ AFile = F$Search(File) 113$ AFile = F$Search(File)
114$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl 114$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
115$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit 115$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
116$ Goto Loop3 116$ Goto Loop3
117$NextEL: 117$NextEL:
118$ El = El + 1 118$ El = El + 1
119$ Goto Loop2 119$ Goto Loop2
120$EndL: 120$EndL:
121$ arg=arg+1 121$ arg=arg+1
122$ If arg .Le. 8 Then Goto Loop 122$ If arg .Le. 8 Then Goto Loop
123$ Goto Exit 123$ Goto Exit
124$ 124$
125$Makeit: 125$Makeit:
126$ VV=F$VERIFY(0) 126$ VV=F$VERIFY(0)
127$ write sys$output P2 127$ write sys$output P2
128$ 'P2 128$ 'P2
129$ VV='F$Verify(VV) 129$ VV='F$Verify(VV)
130$Exit: 130$Exit:
131$ If V Then Set Verify 131$ If V Then Set Verify
132$ENDSUBROUTINE 132$ENDSUBROUTINE
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.c
index 27a2f11..df42c30 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.c
@@ -1,311 +1,311 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 rpng - simple PNG display program readpng.c 3 rpng - simple PNG display program readpng.c
4 4
5 --------------------------------------------------------------------------- 5 ---------------------------------------------------------------------------
6 6
7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. 7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved.
8 8
9 This software is provided "as is," without warranty of any kind, 9 This software is provided "as is," without warranty of any kind,
10 express or implied. In no event shall the author or contributors 10 express or implied. In no event shall the author or contributors
11 be held liable for any damages arising in any way from the use of 11 be held liable for any damages arising in any way from the use of
12 this software. 12 this software.
13 13
14 The contents of this file are DUAL-LICENSED. You may modify and/or 14 The contents of this file are DUAL-LICENSED. You may modify and/or
15 redistribute this software according to the terms of one of the 15 redistribute this software according to the terms of one of the
16 following two licenses (at your option): 16 following two licenses (at your option):
17 17
18 18
19 LICENSE 1 ("BSD-like with advertising clause"): 19 LICENSE 1 ("BSD-like with advertising clause"):
20 20
21 Permission is granted to anyone to use this software for any purpose, 21 Permission is granted to anyone to use this software for any purpose,
22 including commercial applications, and to alter it and redistribute 22 including commercial applications, and to alter it and redistribute
23 it freely, subject to the following restrictions: 23 it freely, subject to the following restrictions:
24 24
25 1. Redistributions of source code must retain the above copyright 25 1. Redistributions of source code must retain the above copyright
26 notice, disclaimer, and this list of conditions. 26 notice, disclaimer, and this list of conditions.
27 2. Redistributions in binary form must reproduce the above copyright 27 2. Redistributions in binary form must reproduce the above copyright
28 notice, disclaimer, and this list of conditions in the documenta- 28 notice, disclaimer, and this list of conditions in the documenta-
29 tion and/or other materials provided with the distribution. 29 tion and/or other materials provided with the distribution.
30 3. All advertising materials mentioning features or use of this 30 3. All advertising materials mentioning features or use of this
31 software must display the following acknowledgment: 31 software must display the following acknowledgment:
32 32
33 This product includes software developed by Greg Roelofs 33 This product includes software developed by Greg Roelofs
34 and contributors for the book, "PNG: The Definitive Guide," 34 and contributors for the book, "PNG: The Definitive Guide,"
35 published by O'Reilly and Associates. 35 published by O'Reilly and Associates.
36 36
37 37
38 LICENSE 2 (GNU GPL v2 or later): 38 LICENSE 2 (GNU GPL v2 or later):
39 39
40 This program is free software; you can redistribute it and/or modify 40 This program is free software; you can redistribute it and/or modify
41 it under the terms of the GNU General Public License as published by 41 it under the terms of the GNU General Public License as published by
42 the Free Software Foundation; either version 2 of the License, or 42 the Free Software Foundation; either version 2 of the License, or
43 (at your option) any later version. 43 (at your option) any later version.
44 44
45 This program is distributed in the hope that it will be useful, 45 This program is distributed in the hope that it will be useful,
46 but WITHOUT ANY WARRANTY; without even the implied warranty of 46 but WITHOUT ANY WARRANTY; without even the implied warranty of
47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 GNU General Public License for more details. 48 GNU General Public License for more details.
49 49
50 You should have received a copy of the GNU General Public License 50 You should have received a copy of the GNU General Public License
51 along with this program; if not, write to the Free Software Foundation, 51 along with this program; if not, write to the Free Software Foundation,
52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53 53
54 ---------------------------------------------------------------------------*/ 54 ---------------------------------------------------------------------------*/
55 55
56#include <stdio.h> 56#include <stdio.h>
57#include <stdlib.h> 57#include <stdlib.h>
58 58
59#include "png.h" /* libpng header; includes zlib.h */ 59#include "png.h" /* libpng header; includes zlib.h */
60#include "readpng.h" /* typedefs, common macros, public prototypes */ 60#include "readpng.h" /* typedefs, common macros, public prototypes */
61 61
62/* future versions of libpng will provide this macro: */ 62/* future versions of libpng will provide this macro: */
63#ifndef png_jmpbuf 63#ifndef png_jmpbuf
64# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) 64# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
65#endif 65#endif
66 66
67 67
68static png_structp png_ptr = NULL; 68static png_structp png_ptr = NULL;
69static png_infop info_ptr = NULL; 69static png_infop info_ptr = NULL;
70 70
71png_uint_32 width, height; 71png_uint_32 width, height;
72int bit_depth, color_type; 72int bit_depth, color_type;
73uch *image_data = NULL; 73uch *image_data = NULL;
74 74
75 75
76void readpng_version_info(void) 76void readpng_version_info(void)
77{ 77{
78 fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n", 78 fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
79 PNG_LIBPNG_VER_STRING, png_libpng_ver); 79 PNG_LIBPNG_VER_STRING, png_libpng_ver);
80 fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n", 80 fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n",
81 ZLIB_VERSION, zlib_version); 81 ZLIB_VERSION, zlib_version);
82} 82}
83 83
84 84
85/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */ 85/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */
86 86
87int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight) 87int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)
88{ 88{
89 uch sig[8]; 89 uch sig[8];
90 90
91 91
92 /* first do a quick check that the file really is a PNG image; could 92 /* first do a quick check that the file really is a PNG image; could
93 * have used slightly more general png_sig_cmp() function instead */ 93 * have used slightly more general png_sig_cmp() function instead */
94 94
95 fread(sig, 1, 8, infile); 95 fread(sig, 1, 8, infile);
96 if (png_sig_cmp(sig, 0, 8)) 96 if (png_sig_cmp(sig, 0, 8))
97 return 1; /* bad signature */ 97 return 1; /* bad signature */
98 98
99 99
100 /* could pass pointers to user-defined error handlers instead of NULLs: */ 100 /* could pass pointers to user-defined error handlers instead of NULLs: */
101 101
102 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 102 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
103 if (!png_ptr) 103 if (!png_ptr)
104 return 4; /* out of memory */ 104 return 4; /* out of memory */
105 105
106 info_ptr = png_create_info_struct(png_ptr); 106 info_ptr = png_create_info_struct(png_ptr);
107 if (!info_ptr) { 107 if (!info_ptr) {
108 png_destroy_read_struct(&png_ptr, NULL, NULL); 108 png_destroy_read_struct(&png_ptr, NULL, NULL);
109 return 4; /* out of memory */ 109 return 4; /* out of memory */
110 } 110 }
111 111
112 112
113 /* we could create a second info struct here (end_info), but it's only 113 /* we could create a second info struct here (end_info), but it's only
114 * useful if we want to keep pre- and post-IDAT chunk info separated 114 * useful if we want to keep pre- and post-IDAT chunk info separated
115 * (mainly for PNG-aware image editors and converters) */ 115 * (mainly for PNG-aware image editors and converters) */
116 116
117 117
118 /* setjmp() must be called in every function that calls a PNG-reading 118 /* setjmp() must be called in every function that calls a PNG-reading
119 * libpng function */ 119 * libpng function */
120 120
121 if (setjmp(png_jmpbuf(png_ptr))) { 121 if (setjmp(png_jmpbuf(png_ptr))) {
122 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 122 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
123 return 2; 123 return 2;
124 } 124 }
125 125
126 126
127 png_init_io(png_ptr, infile); 127 png_init_io(png_ptr, infile);
128 png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */ 128 png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */
129 129
130 png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */ 130 png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */
131 131
132 132
133 /* alternatively, could make separate calls to png_get_image_width(), 133 /* alternatively, could make separate calls to png_get_image_width(),
134 * etc., but want bit_depth and color_type for later [don't care about 134 * etc., but want bit_depth and color_type for later [don't care about
135 * compression_type and filter_type => NULLs] */ 135 * compression_type and filter_type => NULLs] */
136 136
137 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 137 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
138 NULL, NULL, NULL); 138 NULL, NULL, NULL);
139 *pWidth = width; 139 *pWidth = width;
140 *pHeight = height; 140 *pHeight = height;
141 141
142 142
143 /* OK, that's all we need for now; return happy */ 143 /* OK, that's all we need for now; return happy */
144 144
145 return 0; 145 return 0;
146} 146}
147 147
148 148
149 149
150 150
151/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error; 151/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error;
152 * scales values to 8-bit if necessary */ 152 * scales values to 8-bit if necessary */
153 153
154int readpng_get_bgcolor(uch *red, uch *green, uch *blue) 154int readpng_get_bgcolor(uch *red, uch *green, uch *blue)
155{ 155{
156 png_color_16p pBackground; 156 png_color_16p pBackground;
157 157
158 158
159 /* setjmp() must be called in every function that calls a PNG-reading 159 /* setjmp() must be called in every function that calls a PNG-reading
160 * libpng function */ 160 * libpng function */
161 161
162 if (setjmp(png_jmpbuf(png_ptr))) { 162 if (setjmp(png_jmpbuf(png_ptr))) {
163 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 163 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
164 return 2; 164 return 2;
165 } 165 }
166 166
167 167
168 if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) 168 if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
169 return 1; 169 return 1;
170 170
171 /* it is not obvious from the libpng documentation, but this function 171 /* it is not obvious from the libpng documentation, but this function
172 * takes a pointer to a pointer, and it always returns valid red, green 172 * takes a pointer to a pointer, and it always returns valid red, green
173 * and blue values, regardless of color_type: */ 173 * and blue values, regardless of color_type: */
174 174
175 png_get_bKGD(png_ptr, info_ptr, &pBackground); 175 png_get_bKGD(png_ptr, info_ptr, &pBackground);
176 176
177 177
178 /* however, it always returns the raw bKGD data, regardless of any 178 /* however, it always returns the raw bKGD data, regardless of any
179 * bit-depth transformations, so check depth and adjust if necessary */ 179 * bit-depth transformations, so check depth and adjust if necessary */
180 180
181 if (bit_depth == 16) { 181 if (bit_depth == 16) {
182 *red = pBackground->red >> 8; 182 *red = pBackground->red >> 8;
183 *green = pBackground->green >> 8; 183 *green = pBackground->green >> 8;
184 *blue = pBackground->blue >> 8; 184 *blue = pBackground->blue >> 8;
185 } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { 185 } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
186 if (bit_depth == 1) 186 if (bit_depth == 1)
187 *red = *green = *blue = pBackground->gray? 255 : 0; 187 *red = *green = *blue = pBackground->gray? 255 : 0;
188 else if (bit_depth == 2) 188 else if (bit_depth == 2)
189 *red = *green = *blue = (255/3) * pBackground->gray; 189 *red = *green = *blue = (255/3) * pBackground->gray;
190 else /* bit_depth == 4 */ 190 else /* bit_depth == 4 */
191 *red = *green = *blue = (255/15) * pBackground->gray; 191 *red = *green = *blue = (255/15) * pBackground->gray;
192 } else { 192 } else {
193 *red = (uch)pBackground->red; 193 *red = (uch)pBackground->red;
194 *green = (uch)pBackground->green; 194 *green = (uch)pBackground->green;
195 *blue = (uch)pBackground->blue; 195 *blue = (uch)pBackground->blue;
196 } 196 }
197 197
198 return 0; 198 return 0;
199} 199}
200 200
201 201
202 202
203 203
204/* display_exponent == LUT_exponent * CRT_exponent */ 204/* display_exponent == LUT_exponent * CRT_exponent */
205 205
206uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes) 206uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
207{ 207{
208 double gamma; 208 double gamma;
209 png_uint_32 i, rowbytes; 209 png_uint_32 i, rowbytes;
210 png_bytepp row_pointers = NULL; 210 png_bytepp row_pointers = NULL;
211 211
212 212
213 /* setjmp() must be called in every function that calls a PNG-reading 213 /* setjmp() must be called in every function that calls a PNG-reading
214 * libpng function */ 214 * libpng function */
215 215
216 if (setjmp(png_jmpbuf(png_ptr))) { 216 if (setjmp(png_jmpbuf(png_ptr))) {
217 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 217 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
218 return NULL; 218 return NULL;
219 } 219 }
220 220
221 221
222 /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits, 222 /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
223 * transparency chunks to full alpha channel; strip 16-bit-per-sample 223 * transparency chunks to full alpha channel; strip 16-bit-per-sample
224 * images to 8 bits per sample; and convert grayscale to RGB[A] */ 224 * images to 8 bits per sample; and convert grayscale to RGB[A] */
225 225
226 if (color_type == PNG_COLOR_TYPE_PALETTE) 226 if (color_type == PNG_COLOR_TYPE_PALETTE)
227 png_set_expand(png_ptr); 227 png_set_expand(png_ptr);
228 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) 228 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
229 png_set_expand(png_ptr); 229 png_set_expand(png_ptr);
230 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) 230 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
231 png_set_expand(png_ptr); 231 png_set_expand(png_ptr);
232#ifdef PNG_READ_16_TO_8_SUPPORTED 232#ifdef PNG_READ_16_TO_8_SUPPORTED
233 if (bit_depth == 16) 233 if (bit_depth == 16)
234# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 234# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
235 png_set_scale_16(png_ptr); 235 png_set_scale_16(png_ptr);
236# else 236# else
237 png_set_strip_16(png_ptr); 237 png_set_strip_16(png_ptr);
238# endif 238# endif
239#endif 239#endif
240 if (color_type == PNG_COLOR_TYPE_GRAY || 240 if (color_type == PNG_COLOR_TYPE_GRAY ||
241 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 241 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
242 png_set_gray_to_rgb(png_ptr); 242 png_set_gray_to_rgb(png_ptr);
243 243
244 244
245 /* unlike the example in the libpng documentation, we have *no* idea where 245 /* unlike the example in the libpng documentation, we have *no* idea where
246 * this file may have come from--so if it doesn't have a file gamma, don't 246 * this file may have come from--so if it doesn't have a file gamma, don't
247 * do any correction ("do no harm") */ 247 * do any correction ("do no harm") */
248 248
249 if (png_get_gAMA(png_ptr, info_ptr, &gamma)) 249 if (png_get_gAMA(png_ptr, info_ptr, &gamma))
250 png_set_gamma(png_ptr, display_exponent, gamma); 250 png_set_gamma(png_ptr, display_exponent, gamma);
251 251
252 252
253 /* all transformations have been registered; now update info_ptr data, 253 /* all transformations have been registered; now update info_ptr data,
254 * get rowbytes and channels, and allocate image memory */ 254 * get rowbytes and channels, and allocate image memory */
255 255
256 png_read_update_info(png_ptr, info_ptr); 256 png_read_update_info(png_ptr, info_ptr);
257 257
258 *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr); 258 *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
259 *pChannels = (int)png_get_channels(png_ptr, info_ptr); 259 *pChannels = (int)png_get_channels(png_ptr, info_ptr);
260 260
261 if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { 261 if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
262 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 262 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
263 return NULL; 263 return NULL;
264 } 264 }
265 if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) { 265 if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) {
266 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 266 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
267 free(image_data); 267 free(image_data);
268 image_data = NULL; 268 image_data = NULL;
269 return NULL; 269 return NULL;
270 } 270 }
271 271
272 Trace((stderr, "readpng_get_image: channels = %d, rowbytes = %ld, height = %ld\n", 272 Trace((stderr, "readpng_get_image: channels = %d, rowbytes = %ld, height = %ld\n",
273 *pChannels, rowbytes, height)); 273 *pChannels, rowbytes, height));
274 274
275 275
276 /* set the individual row_pointers to point at the correct offsets */ 276 /* set the individual row_pointers to point at the correct offsets */
277 277
278 for (i = 0; i < height; ++i) 278 for (i = 0; i < height; ++i)
279 row_pointers[i] = image_data + i*rowbytes; 279 row_pointers[i] = image_data + i*rowbytes;
280 280
281 281
282 /* now we can go ahead and just read the whole image */ 282 /* now we can go ahead and just read the whole image */
283 283
284 png_read_image(png_ptr, row_pointers); 284 png_read_image(png_ptr, row_pointers);
285 285
286 286
287 /* and we're done! (png_read_end() can be omitted if no processing of 287 /* and we're done! (png_read_end() can be omitted if no processing of
288 * post-IDAT text/time/etc. is desired) */ 288 * post-IDAT text/time/etc. is desired) */
289 289
290 free(row_pointers); 290 free(row_pointers);
291 row_pointers = NULL; 291 row_pointers = NULL;
292 292
293 png_read_end(png_ptr, NULL); 293 png_read_end(png_ptr, NULL);
294 294
295 return image_data; 295 return image_data;
296} 296}
297 297
298 298
299void readpng_cleanup(int free_image_data) 299void readpng_cleanup(int free_image_data)
300{ 300{
301 if (free_image_data && image_data) { 301 if (free_image_data && image_data) {
302 free(image_data); 302 free(image_data);
303 image_data = NULL; 303 image_data = NULL;
304 } 304 }
305 305
306 if (png_ptr && info_ptr) { 306 if (png_ptr && info_ptr) {
307 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 307 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
308 png_ptr = NULL; 308 png_ptr = NULL;
309 info_ptr = NULL; 309 info_ptr = NULL;
310 } 310 }
311} 311}
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.h
index ec6b483..fad9fe3 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.h
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng.h
@@ -1,88 +1,88 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 rpng - simple PNG display program readpng.h 3 rpng - simple PNG display program readpng.h
4 4
5 --------------------------------------------------------------------------- 5 ---------------------------------------------------------------------------
6 6
7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. 7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved.
8 8
9 This software is provided "as is," without warranty of any kind, 9 This software is provided "as is," without warranty of any kind,
10 express or implied. In no event shall the author or contributors 10 express or implied. In no event shall the author or contributors
11 be held liable for any damages arising in any way from the use of 11 be held liable for any damages arising in any way from the use of
12 this software. 12 this software.
13 13
14 The contents of this file are DUAL-LICENSED. You may modify and/or 14 The contents of this file are DUAL-LICENSED. You may modify and/or
15 redistribute this software according to the terms of one of the 15 redistribute this software according to the terms of one of the
16 following two licenses (at your option): 16 following two licenses (at your option):
17 17
18 18
19 LICENSE 1 ("BSD-like with advertising clause"): 19 LICENSE 1 ("BSD-like with advertising clause"):
20 20
21 Permission is granted to anyone to use this software for any purpose, 21 Permission is granted to anyone to use this software for any purpose,
22 including commercial applications, and to alter it and redistribute 22 including commercial applications, and to alter it and redistribute
23 it freely, subject to the following restrictions: 23 it freely, subject to the following restrictions:
24 24
25 1. Redistributions of source code must retain the above copyright 25 1. Redistributions of source code must retain the above copyright
26 notice, disclaimer, and this list of conditions. 26 notice, disclaimer, and this list of conditions.
27 2. Redistributions in binary form must reproduce the above copyright 27 2. Redistributions in binary form must reproduce the above copyright
28 notice, disclaimer, and this list of conditions in the documenta- 28 notice, disclaimer, and this list of conditions in the documenta-
29 tion and/or other materials provided with the distribution. 29 tion and/or other materials provided with the distribution.
30 3. All advertising materials mentioning features or use of this 30 3. All advertising materials mentioning features or use of this
31 software must display the following acknowledgment: 31 software must display the following acknowledgment:
32 32
33 This product includes software developed by Greg Roelofs 33 This product includes software developed by Greg Roelofs
34 and contributors for the book, "PNG: The Definitive Guide," 34 and contributors for the book, "PNG: The Definitive Guide,"
35 published by O'Reilly and Associates. 35 published by O'Reilly and Associates.
36 36
37 37
38 LICENSE 2 (GNU GPL v2 or later): 38 LICENSE 2 (GNU GPL v2 or later):
39 39
40 This program is free software; you can redistribute it and/or modify 40 This program is free software; you can redistribute it and/or modify
41 it under the terms of the GNU General Public License as published by 41 it under the terms of the GNU General Public License as published by
42 the Free Software Foundation; either version 2 of the License, or 42 the Free Software Foundation; either version 2 of the License, or
43 (at your option) any later version. 43 (at your option) any later version.
44 44
45 This program is distributed in the hope that it will be useful, 45 This program is distributed in the hope that it will be useful,
46 but WITHOUT ANY WARRANTY; without even the implied warranty of 46 but WITHOUT ANY WARRANTY; without even the implied warranty of
47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 GNU General Public License for more details. 48 GNU General Public License for more details.
49 49
50 You should have received a copy of the GNU General Public License 50 You should have received a copy of the GNU General Public License
51 along with this program; if not, write to the Free Software Foundation, 51 along with this program; if not, write to the Free Software Foundation,
52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53 53
54 ---------------------------------------------------------------------------*/ 54 ---------------------------------------------------------------------------*/
55 55
56#ifndef TRUE 56#ifndef TRUE
57# define TRUE 1 57# define TRUE 1
58# define FALSE 0 58# define FALSE 0
59#endif 59#endif
60 60
61#ifndef MAX 61#ifndef MAX
62# define MAX(a,b) ((a) > (b)? (a) : (b)) 62# define MAX(a,b) ((a) > (b)? (a) : (b))
63# define MIN(a,b) ((a) < (b)? (a) : (b)) 63# define MIN(a,b) ((a) < (b)? (a) : (b))
64#endif 64#endif
65 65
66#ifdef DEBUG 66#ifdef DEBUG
67# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);} 67# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);}
68#else 68#else
69# define Trace(x) ; 69# define Trace(x) ;
70#endif 70#endif
71 71
72typedef unsigned char uch; 72typedef unsigned char uch;
73typedef unsigned short ush; 73typedef unsigned short ush;
74typedef unsigned long ulg; 74typedef unsigned long ulg;
75 75
76 76
77/* prototypes for public functions in readpng.c */ 77/* prototypes for public functions in readpng.c */
78 78
79void readpng_version_info(void); 79void readpng_version_info(void);
80 80
81int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight); 81int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight);
82 82
83int readpng_get_bgcolor(uch *bg_red, uch *bg_green, uch *bg_blue); 83int readpng_get_bgcolor(uch *bg_red, uch *bg_green, uch *bg_blue);
84 84
85uch *readpng_get_image(double display_exponent, int *pChannels, 85uch *readpng_get_image(double display_exponent, int *pChannels,
86 ulg *pRowbytes); 86 ulg *pRowbytes);
87 87
88void readpng_cleanup(int free_image_data); 88void readpng_cleanup(int free_image_data);
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.c
index 3bbd2ec..b9746b7 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.c
@@ -1,511 +1,511 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 rpng2 - progressive-model PNG display program readpng2.c 3 rpng2 - progressive-model PNG display program readpng2.c
4 4
5 --------------------------------------------------------------------------- 5 ---------------------------------------------------------------------------
6 6
7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. 7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved.
8 8
9 This software is provided "as is," without warranty of any kind, 9 This software is provided "as is," without warranty of any kind,
10 express or implied. In no event shall the author or contributors 10 express or implied. In no event shall the author or contributors
11 be held liable for any damages arising in any way from the use of 11 be held liable for any damages arising in any way from the use of
12 this software. 12 this software.
13 13
14 The contents of this file are DUAL-LICENSED. You may modify and/or 14 The contents of this file are DUAL-LICENSED. You may modify and/or
15 redistribute this software according to the terms of one of the 15 redistribute this software according to the terms of one of the
16 following two licenses (at your option): 16 following two licenses (at your option):
17 17
18 18
19 LICENSE 1 ("BSD-like with advertising clause"): 19 LICENSE 1 ("BSD-like with advertising clause"):
20 20
21 Permission is granted to anyone to use this software for any purpose, 21 Permission is granted to anyone to use this software for any purpose,
22 including commercial applications, and to alter it and redistribute 22 including commercial applications, and to alter it and redistribute
23 it freely, subject to the following restrictions: 23 it freely, subject to the following restrictions:
24 24
25 1. Redistributions of source code must retain the above copyright 25 1. Redistributions of source code must retain the above copyright
26 notice, disclaimer, and this list of conditions. 26 notice, disclaimer, and this list of conditions.
27 2. Redistributions in binary form must reproduce the above copyright 27 2. Redistributions in binary form must reproduce the above copyright
28 notice, disclaimer, and this list of conditions in the documenta- 28 notice, disclaimer, and this list of conditions in the documenta-
29 tion and/or other materials provided with the distribution. 29 tion and/or other materials provided with the distribution.
30 3. All advertising materials mentioning features or use of this 30 3. All advertising materials mentioning features or use of this
31 software must display the following acknowledgment: 31 software must display the following acknowledgment:
32 32
33 This product includes software developed by Greg Roelofs 33 This product includes software developed by Greg Roelofs
34 and contributors for the book, "PNG: The Definitive Guide," 34 and contributors for the book, "PNG: The Definitive Guide,"
35 published by O'Reilly and Associates. 35 published by O'Reilly and Associates.
36 36
37 37
38 LICENSE 2 (GNU GPL v2 or later): 38 LICENSE 2 (GNU GPL v2 or later):
39 39
40 This program is free software; you can redistribute it and/or modify 40 This program is free software; you can redistribute it and/or modify
41 it under the terms of the GNU General Public License as published by 41 it under the terms of the GNU General Public License as published by
42 the Free Software Foundation; either version 2 of the License, or 42 the Free Software Foundation; either version 2 of the License, or
43 (at your option) any later version. 43 (at your option) any later version.
44 44
45 This program is distributed in the hope that it will be useful, 45 This program is distributed in the hope that it will be useful,
46 but WITHOUT ANY WARRANTY; without even the implied warranty of 46 but WITHOUT ANY WARRANTY; without even the implied warranty of
47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 GNU General Public License for more details. 48 GNU General Public License for more details.
49 49
50 You should have received a copy of the GNU General Public License 50 You should have received a copy of the GNU General Public License
51 along with this program; if not, write to the Free Software Foundation, 51 along with this program; if not, write to the Free Software Foundation,
52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53 53
54 ---------------------------------------------------------------------------*/ 54 ---------------------------------------------------------------------------*/
55 55
56 56
57#include <stdlib.h> /* for exit() prototype */ 57#include <stdlib.h> /* for exit() prototype */
58#include <setjmp.h> 58#include <setjmp.h>
59 59
60#include <zlib.h> 60#include <zlib.h>
61#include "png.h" /* libpng header from the local directory */ 61#include "png.h" /* libpng header from the local directory */
62#include "readpng2.h" /* typedefs, common macros, public prototypes */ 62#include "readpng2.h" /* typedefs, common macros, public prototypes */
63 63
64 64
65/* local prototypes */ 65/* local prototypes */
66 66
67static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr); 67static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr);
68static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row, 68static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
69 png_uint_32 row_num, int pass); 69 png_uint_32 row_num, int pass);
70static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr); 70static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr);
71static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg); 71static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg);
72 72
73 73
74 74
75 75
76void readpng2_version_info(void) 76void readpng2_version_info(void)
77{ 77{
78 fprintf(stderr, " Compiled with libpng %s; using libpng %s\n", 78 fprintf(stderr, " Compiled with libpng %s; using libpng %s\n",
79 PNG_LIBPNG_VER_STRING, png_libpng_ver); 79 PNG_LIBPNG_VER_STRING, png_libpng_ver);
80 80
81 fprintf(stderr, " and with zlib %s; using zlib %s.\n", 81 fprintf(stderr, " and with zlib %s; using zlib %s.\n",
82 ZLIB_VERSION, zlib_version); 82 ZLIB_VERSION, zlib_version);
83} 83}
84 84
85 85
86 86
87 87
88int readpng2_check_sig(uch *sig, int num) 88int readpng2_check_sig(uch *sig, int num)
89{ 89{
90 return !png_sig_cmp(sig, 0, num); 90 return !png_sig_cmp(sig, 0, num);
91} 91}
92 92
93 93
94 94
95 95
96/* returns 0 for success, 2 for libpng problem, 4 for out of memory */ 96/* returns 0 for success, 2 for libpng problem, 4 for out of memory */
97 97
98int readpng2_init(mainprog_info *mainprog_ptr) 98int readpng2_init(mainprog_info *mainprog_ptr)
99{ 99{
100 png_structp png_ptr; /* note: temporary variables! */ 100 png_structp png_ptr; /* note: temporary variables! */
101 png_infop info_ptr; 101 png_infop info_ptr;
102 102
103 103
104 /* could also replace libpng warning-handler (final NULL), but no need: */ 104 /* could also replace libpng warning-handler (final NULL), but no need: */
105 105
106 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr, 106 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
107 readpng2_error_handler, NULL); 107 readpng2_error_handler, NULL);
108 if (!png_ptr) 108 if (!png_ptr)
109 return 4; /* out of memory */ 109 return 4; /* out of memory */
110 110
111 info_ptr = png_create_info_struct(png_ptr); 111 info_ptr = png_create_info_struct(png_ptr);
112 if (!info_ptr) { 112 if (!info_ptr) {
113 png_destroy_read_struct(&png_ptr, NULL, NULL); 113 png_destroy_read_struct(&png_ptr, NULL, NULL);
114 return 4; /* out of memory */ 114 return 4; /* out of memory */
115 } 115 }
116 116
117 117
118 /* we could create a second info struct here (end_info), but it's only 118 /* we could create a second info struct here (end_info), but it's only
119 * useful if we want to keep pre- and post-IDAT chunk info separated 119 * useful if we want to keep pre- and post-IDAT chunk info separated
120 * (mainly for PNG-aware image editors and converters) */ 120 * (mainly for PNG-aware image editors and converters) */
121 121
122 122
123 /* setjmp() must be called in every function that calls a PNG-reading 123 /* setjmp() must be called in every function that calls a PNG-reading
124 * libpng function, unless an alternate error handler was installed-- 124 * libpng function, unless an alternate error handler was installed--
125 * but compatible error handlers must either use longjmp() themselves 125 * but compatible error handlers must either use longjmp() themselves
126 * (as in this program) or exit immediately, so here we are: */ 126 * (as in this program) or exit immediately, so here we are: */
127 127
128 if (setjmp(mainprog_ptr->jmpbuf)) { 128 if (setjmp(mainprog_ptr->jmpbuf)) {
129 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 129 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
130 return 2; 130 return 2;
131 } 131 }
132 132
133 133
134#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 134#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
135 /* prepare the reader to ignore all recognized chunks whose data won't be 135 /* prepare the reader to ignore all recognized chunks whose data won't be
136 * used, i.e., all chunks recognized by libpng except for IHDR, PLTE, IDAT, 136 * used, i.e., all chunks recognized by libpng except for IHDR, PLTE, IDAT,
137 * IEND, tRNS, bKGD, gAMA, and sRGB (small performance improvement) */ 137 * IEND, tRNS, bKGD, gAMA, and sRGB (small performance improvement) */
138 { 138 {
139 /* These byte strings were copied from png.h. If a future libpng 139 /* These byte strings were copied from png.h. If a future libpng
140 * version recognizes more chunks, add them to this list. If a 140 * version recognizes more chunks, add them to this list. If a
141 * future version of readpng2.c recognizes more chunks, delete them 141 * future version of readpng2.c recognizes more chunks, delete them
142 * from this list. */ 142 * from this list. */
143 static /* const */ png_byte chunks_to_ignore[] = { 143 static /* const */ png_byte chunks_to_ignore[] = {
144 99, 72, 82, 77, '\0', /* cHRM */ 144 99, 72, 82, 77, '\0', /* cHRM */
145 104, 73, 83, 84, '\0', /* hIST */ 145 104, 73, 83, 84, '\0', /* hIST */
146 105, 67, 67, 80, '\0', /* iCCP */ 146 105, 67, 67, 80, '\0', /* iCCP */
147 105, 84, 88, 116, '\0', /* iTXt */ 147 105, 84, 88, 116, '\0', /* iTXt */
148 111, 70, 70, 115, '\0', /* oFFs */ 148 111, 70, 70, 115, '\0', /* oFFs */
149 112, 67, 65, 76, '\0', /* pCAL */ 149 112, 67, 65, 76, '\0', /* pCAL */
150 112, 72, 89, 115, '\0', /* pHYs */ 150 112, 72, 89, 115, '\0', /* pHYs */
151 115, 66, 73, 84, '\0', /* sBIT */ 151 115, 66, 73, 84, '\0', /* sBIT */
152 115, 67, 65, 76, '\0', /* sCAL */ 152 115, 67, 65, 76, '\0', /* sCAL */
153 115, 80, 76, 84, '\0', /* sPLT */ 153 115, 80, 76, 84, '\0', /* sPLT */
154 115, 84, 69, 82, '\0', /* sTER */ 154 115, 84, 69, 82, '\0', /* sTER */
155 116, 69, 88, 116, '\0', /* tEXt */ 155 116, 69, 88, 116, '\0', /* tEXt */
156 116, 73, 77, 69, '\0', /* tIME */ 156 116, 73, 77, 69, '\0', /* tIME */
157 122, 84, 88, 116, '\0' /* zTXt */ 157 122, 84, 88, 116, '\0' /* zTXt */
158 }; 158 };
159 159
160 png_set_keep_unknown_chunks(png_ptr, 1 /* PNG_HANDLE_CHUNK_NEVER */, 160 png_set_keep_unknown_chunks(png_ptr, 1 /* PNG_HANDLE_CHUNK_NEVER */,
161 chunks_to_ignore, sizeof(chunks_to_ignore)/5); 161 chunks_to_ignore, sizeof(chunks_to_ignore)/5);
162 } 162 }
163#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */ 163#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */
164 164
165 165
166 /* instead of doing png_init_io() here, now we set up our callback 166 /* instead of doing png_init_io() here, now we set up our callback
167 * functions for progressive decoding */ 167 * functions for progressive decoding */
168 168
169 png_set_progressive_read_fn(png_ptr, mainprog_ptr, 169 png_set_progressive_read_fn(png_ptr, mainprog_ptr,
170 readpng2_info_callback, readpng2_row_callback, readpng2_end_callback); 170 readpng2_info_callback, readpng2_row_callback, readpng2_end_callback);
171 171
172 172
173 /* make sure we save our pointers for use in readpng2_decode_data() */ 173 /* make sure we save our pointers for use in readpng2_decode_data() */
174 174
175 mainprog_ptr->png_ptr = png_ptr; 175 mainprog_ptr->png_ptr = png_ptr;
176 mainprog_ptr->info_ptr = info_ptr; 176 mainprog_ptr->info_ptr = info_ptr;
177 177
178 178
179 /* and that's all there is to initialization */ 179 /* and that's all there is to initialization */
180 180
181 return 0; 181 return 0;
182} 182}
183 183
184 184
185 185
186 186
187/* returns 0 for success, 2 for libpng (longjmp) problem */ 187/* returns 0 for success, 2 for libpng (longjmp) problem */
188 188
189int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length) 189int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length)
190{ 190{
191 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 191 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
192 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 192 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
193 193
194 194
195 /* setjmp() must be called in every function that calls a PNG-reading 195 /* setjmp() must be called in every function that calls a PNG-reading
196 * libpng function */ 196 * libpng function */
197 197
198 if (setjmp(mainprog_ptr->jmpbuf)) { 198 if (setjmp(mainprog_ptr->jmpbuf)) {
199 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 199 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
200 mainprog_ptr->png_ptr = NULL; 200 mainprog_ptr->png_ptr = NULL;
201 mainprog_ptr->info_ptr = NULL; 201 mainprog_ptr->info_ptr = NULL;
202 return 2; 202 return 2;
203 } 203 }
204 204
205 205
206 /* hand off the next chunk of input data to libpng for decoding */ 206 /* hand off the next chunk of input data to libpng for decoding */
207 207
208 png_process_data(png_ptr, info_ptr, rawbuf, length); 208 png_process_data(png_ptr, info_ptr, rawbuf, length);
209 209
210 return 0; 210 return 0;
211} 211}
212 212
213 213
214 214
215 215
216static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr) 216static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr)
217{ 217{
218 mainprog_info *mainprog_ptr; 218 mainprog_info *mainprog_ptr;
219 int color_type, bit_depth; 219 int color_type, bit_depth;
220 png_uint_32 width, height; 220 png_uint_32 width, height;
221#ifdef PNG_FLOATING_POINT_SUPPORTED 221#ifdef PNG_FLOATING_POINT_SUPPORTED
222 double gamma; 222 double gamma;
223#else 223#else
224 png_fixed_point gamma; 224 png_fixed_point gamma;
225#endif 225#endif
226 226
227 227
228 /* setjmp() doesn't make sense here, because we'd either have to exit(), 228 /* setjmp() doesn't make sense here, because we'd either have to exit(),
229 * longjmp() ourselves, or return control to libpng, which doesn't want 229 * longjmp() ourselves, or return control to libpng, which doesn't want
230 * to see us again. By not doing anything here, libpng will instead jump 230 * to see us again. By not doing anything here, libpng will instead jump
231 * to readpng2_decode_data(), which can return an error value to the main 231 * to readpng2_decode_data(), which can return an error value to the main
232 * program. */ 232 * program. */
233 233
234 234
235 /* retrieve the pointer to our special-purpose struct, using the png_ptr 235 /* retrieve the pointer to our special-purpose struct, using the png_ptr
236 * that libpng passed back to us (i.e., not a global this time--there's 236 * that libpng passed back to us (i.e., not a global this time--there's
237 * no real difference for a single image, but for a multithreaded browser 237 * no real difference for a single image, but for a multithreaded browser
238 * decoding several PNG images at the same time, one needs to avoid mixing 238 * decoding several PNG images at the same time, one needs to avoid mixing
239 * up different images' structs) */ 239 * up different images' structs) */
240 240
241 mainprog_ptr = png_get_progressive_ptr(png_ptr); 241 mainprog_ptr = png_get_progressive_ptr(png_ptr);
242 242
243 if (mainprog_ptr == NULL) { /* we be hosed */ 243 if (mainprog_ptr == NULL) { /* we be hosed */
244 fprintf(stderr, 244 fprintf(stderr,
245 "readpng2 error: main struct not recoverable in info_callback.\n"); 245 "readpng2 error: main struct not recoverable in info_callback.\n");
246 fflush(stderr); 246 fflush(stderr);
247 return; 247 return;
248 /* 248 /*
249 * Alternatively, we could call our error-handler just like libpng 249 * Alternatively, we could call our error-handler just like libpng
250 * does, which would effectively terminate the program. Since this 250 * does, which would effectively terminate the program. Since this
251 * can only happen if png_ptr gets redirected somewhere odd or the 251 * can only happen if png_ptr gets redirected somewhere odd or the
252 * main PNG struct gets wiped, we're probably toast anyway. (If 252 * main PNG struct gets wiped, we're probably toast anyway. (If
253 * png_ptr itself is NULL, we would not have been called.) 253 * png_ptr itself is NULL, we would not have been called.)
254 */ 254 */
255 } 255 }
256 256
257 257
258 /* this is just like in the non-progressive case */ 258 /* this is just like in the non-progressive case */
259 259
260 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 260 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
261 NULL, NULL, NULL); 261 NULL, NULL, NULL);
262 mainprog_ptr->width = (ulg)width; 262 mainprog_ptr->width = (ulg)width;
263 mainprog_ptr->height = (ulg)height; 263 mainprog_ptr->height = (ulg)height;
264 264
265 265
266 /* since we know we've read all of the PNG file's "header" (i.e., up 266 /* since we know we've read all of the PNG file's "header" (i.e., up
267 * to IDAT), we can check for a background color here */ 267 * to IDAT), we can check for a background color here */
268 268
269 if (mainprog_ptr->need_bgcolor && 269 if (mainprog_ptr->need_bgcolor &&
270 png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) 270 png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
271 { 271 {
272 png_color_16p pBackground; 272 png_color_16p pBackground;
273 273
274 /* it is not obvious from the libpng documentation, but this function 274 /* it is not obvious from the libpng documentation, but this function
275 * takes a pointer to a pointer, and it always returns valid red, 275 * takes a pointer to a pointer, and it always returns valid red,
276 * green and blue values, regardless of color_type: */ 276 * green and blue values, regardless of color_type: */
277 png_get_bKGD(png_ptr, info_ptr, &pBackground); 277 png_get_bKGD(png_ptr, info_ptr, &pBackground);
278 278
279 /* however, it always returns the raw bKGD data, regardless of any 279 /* however, it always returns the raw bKGD data, regardless of any
280 * bit-depth transformations, so check depth and adjust if necessary */ 280 * bit-depth transformations, so check depth and adjust if necessary */
281 if (bit_depth == 16) { 281 if (bit_depth == 16) {
282 mainprog_ptr->bg_red = pBackground->red >> 8; 282 mainprog_ptr->bg_red = pBackground->red >> 8;
283 mainprog_ptr->bg_green = pBackground->green >> 8; 283 mainprog_ptr->bg_green = pBackground->green >> 8;
284 mainprog_ptr->bg_blue = pBackground->blue >> 8; 284 mainprog_ptr->bg_blue = pBackground->blue >> 8;
285 } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { 285 } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
286 if (bit_depth == 1) 286 if (bit_depth == 1)
287 mainprog_ptr->bg_red = mainprog_ptr->bg_green = 287 mainprog_ptr->bg_red = mainprog_ptr->bg_green =
288 mainprog_ptr->bg_blue = pBackground->gray? 255 : 0; 288 mainprog_ptr->bg_blue = pBackground->gray? 255 : 0;
289 else if (bit_depth == 2) 289 else if (bit_depth == 2)
290 mainprog_ptr->bg_red = mainprog_ptr->bg_green = 290 mainprog_ptr->bg_red = mainprog_ptr->bg_green =
291 mainprog_ptr->bg_blue = (255/3) * pBackground->gray; 291 mainprog_ptr->bg_blue = (255/3) * pBackground->gray;
292 else /* bit_depth == 4 */ 292 else /* bit_depth == 4 */
293 mainprog_ptr->bg_red = mainprog_ptr->bg_green = 293 mainprog_ptr->bg_red = mainprog_ptr->bg_green =
294 mainprog_ptr->bg_blue = (255/15) * pBackground->gray; 294 mainprog_ptr->bg_blue = (255/15) * pBackground->gray;
295 } else { 295 } else {
296 mainprog_ptr->bg_red = (uch)pBackground->red; 296 mainprog_ptr->bg_red = (uch)pBackground->red;
297 mainprog_ptr->bg_green = (uch)pBackground->green; 297 mainprog_ptr->bg_green = (uch)pBackground->green;
298 mainprog_ptr->bg_blue = (uch)pBackground->blue; 298 mainprog_ptr->bg_blue = (uch)pBackground->blue;
299 } 299 }
300 } 300 }
301 301
302 302
303 /* as before, let libpng expand palette images to RGB, low-bit-depth 303 /* as before, let libpng expand palette images to RGB, low-bit-depth
304 * grayscale images to 8 bits, transparency chunks to full alpha channel; 304 * grayscale images to 8 bits, transparency chunks to full alpha channel;
305 * strip 16-bit-per-sample images to 8 bits per sample; and convert 305 * strip 16-bit-per-sample images to 8 bits per sample; and convert
306 * grayscale to RGB[A] */ 306 * grayscale to RGB[A] */
307 307
308 if (color_type == PNG_COLOR_TYPE_PALETTE) 308 if (color_type == PNG_COLOR_TYPE_PALETTE)
309 png_set_expand(png_ptr); 309 png_set_expand(png_ptr);
310 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) 310 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
311 png_set_expand(png_ptr); 311 png_set_expand(png_ptr);
312 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) 312 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
313 png_set_expand(png_ptr); 313 png_set_expand(png_ptr);
314#ifdef PNG_READ_16_TO_8_SUPPORTED 314#ifdef PNG_READ_16_TO_8_SUPPORTED
315 if (bit_depth == 16) 315 if (bit_depth == 16)
316# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 316# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
317 png_set_scale_16(png_ptr); 317 png_set_scale_16(png_ptr);
318# else 318# else
319 png_set_strip_16(png_ptr); 319 png_set_strip_16(png_ptr);
320# endif 320# endif
321#endif 321#endif
322 if (color_type == PNG_COLOR_TYPE_GRAY || 322 if (color_type == PNG_COLOR_TYPE_GRAY ||
323 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 323 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
324 png_set_gray_to_rgb(png_ptr); 324 png_set_gray_to_rgb(png_ptr);
325 325
326 326
327 /* Unlike the basic viewer, which was designed to operate on local files, 327 /* Unlike the basic viewer, which was designed to operate on local files,
328 * this program is intended to simulate a web browser--even though we 328 * this program is intended to simulate a web browser--even though we
329 * actually read from a local file, too. But because we are pretending 329 * actually read from a local file, too. But because we are pretending
330 * that most of the images originate on the Internet, we follow the recom- 330 * that most of the images originate on the Internet, we follow the recom-
331 * mendation of the sRGB proposal and treat unlabelled images (no gAMA 331 * mendation of the sRGB proposal and treat unlabelled images (no gAMA
332 * chunk) as existing in the sRGB color space. That is, we assume that 332 * chunk) as existing in the sRGB color space. That is, we assume that
333 * such images have a file gamma of 0.45455, which corresponds to a PC-like 333 * such images have a file gamma of 0.45455, which corresponds to a PC-like
334 * display system. This change in assumptions will have no effect on a 334 * display system. This change in assumptions will have no effect on a
335 * PC-like system, but on a Mac, SGI, NeXT or other system with a non- 335 * PC-like system, but on a Mac, SGI, NeXT or other system with a non-
336 * identity lookup table, it will darken unlabelled images, which effec- 336 * identity lookup table, it will darken unlabelled images, which effec-
337 * tively favors images from PC-like systems over those originating on 337 * tively favors images from PC-like systems over those originating on
338 * the local platform. Note that mainprog_ptr->display_exponent is the 338 * the local platform. Note that mainprog_ptr->display_exponent is the
339 * "gamma" value for the entire display system, i.e., the product of 339 * "gamma" value for the entire display system, i.e., the product of
340 * LUT_exponent and CRT_exponent. */ 340 * LUT_exponent and CRT_exponent. */
341 341
342#ifdef PNG_FLOATING_POINT_SUPPORTED 342#ifdef PNG_FLOATING_POINT_SUPPORTED
343 if (png_get_gAMA(png_ptr, info_ptr, &gamma)) 343 if (png_get_gAMA(png_ptr, info_ptr, &gamma))
344 png_set_gamma(png_ptr, mainprog_ptr->display_exponent, gamma); 344 png_set_gamma(png_ptr, mainprog_ptr->display_exponent, gamma);
345 else 345 else
346 png_set_gamma(png_ptr, mainprog_ptr->display_exponent, 0.45455); 346 png_set_gamma(png_ptr, mainprog_ptr->display_exponent, 0.45455);
347#else 347#else
348 if (png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) 348 if (png_get_gAMA_fixed(png_ptr, info_ptr, &gamma))
349 png_set_gamma_fixed(png_ptr, 349 png_set_gamma_fixed(png_ptr,
350 (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), gamma); 350 (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), gamma);
351 else 351 else
352 png_set_gamma_fixed(png_ptr, 352 png_set_gamma_fixed(png_ptr,
353 (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), 45455); 353 (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), 45455);
354#endif 354#endif
355 355
356 /* we'll let libpng expand interlaced images, too */ 356 /* we'll let libpng expand interlaced images, too */
357 357
358 mainprog_ptr->passes = png_set_interlace_handling(png_ptr); 358 mainprog_ptr->passes = png_set_interlace_handling(png_ptr);
359 359
360 360
361 /* all transformations have been registered; now update info_ptr data and 361 /* all transformations have been registered; now update info_ptr data and
362 * then get rowbytes and channels */ 362 * then get rowbytes and channels */
363 363
364 png_read_update_info(png_ptr, info_ptr); 364 png_read_update_info(png_ptr, info_ptr);
365 365
366 mainprog_ptr->rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr); 366 mainprog_ptr->rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr);
367 mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr); 367 mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr);
368 368
369 369
370 /* Call the main program to allocate memory for the image buffer and 370 /* Call the main program to allocate memory for the image buffer and
371 * initialize windows and whatnot. (The old-style function-pointer 371 * initialize windows and whatnot. (The old-style function-pointer
372 * invocation is used for compatibility with a few supposedly ANSI 372 * invocation is used for compatibility with a few supposedly ANSI
373 * compilers that nevertheless barf on "fn_ptr()"-style syntax.) */ 373 * compilers that nevertheless barf on "fn_ptr()"-style syntax.) */
374 374
375 (*mainprog_ptr->mainprog_init)(); 375 (*mainprog_ptr->mainprog_init)();
376 376
377 377
378 /* and that takes care of initialization */ 378 /* and that takes care of initialization */
379 379
380 return; 380 return;
381} 381}
382 382
383 383
384 384
385 385
386 386
387static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row, 387static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
388 png_uint_32 row_num, int pass) 388 png_uint_32 row_num, int pass)
389{ 389{
390 mainprog_info *mainprog_ptr; 390 mainprog_info *mainprog_ptr;
391 391
392 392
393 /* first check whether the row differs from the previous pass; if not, 393 /* first check whether the row differs from the previous pass; if not,
394 * nothing to combine or display */ 394 * nothing to combine or display */
395 395
396 if (!new_row) 396 if (!new_row)
397 return; 397 return;
398 398
399 399
400 /* retrieve the pointer to our special-purpose struct so we can access 400 /* retrieve the pointer to our special-purpose struct so we can access
401 * the old rows and image-display callback function */ 401 * the old rows and image-display callback function */
402 402
403 mainprog_ptr = png_get_progressive_ptr(png_ptr); 403 mainprog_ptr = png_get_progressive_ptr(png_ptr);
404 404
405 405
406 /* save the pass number for optional use by the front end */ 406 /* save the pass number for optional use by the front end */
407 407
408 mainprog_ptr->pass = pass; 408 mainprog_ptr->pass = pass;
409 409
410 410
411 /* have libpng either combine the new row data with the existing row data 411 /* have libpng either combine the new row data with the existing row data
412 * from previous passes (if interlaced) or else just copy the new row 412 * from previous passes (if interlaced) or else just copy the new row
413 * into the main program's image buffer */ 413 * into the main program's image buffer */
414 414
415 png_progressive_combine_row(png_ptr, mainprog_ptr->row_pointers[row_num], 415 png_progressive_combine_row(png_ptr, mainprog_ptr->row_pointers[row_num],
416 new_row); 416 new_row);
417 417
418 418
419 /* finally, call the display routine in the main program with the number 419 /* finally, call the display routine in the main program with the number
420 * of the row we just updated */ 420 * of the row we just updated */
421 421
422 (*mainprog_ptr->mainprog_display_row)(row_num); 422 (*mainprog_ptr->mainprog_display_row)(row_num);
423 423
424 424
425 /* and we're ready for more */ 425 /* and we're ready for more */
426 426
427 return; 427 return;
428} 428}
429 429
430 430
431 431
432 432
433 433
434static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr) 434static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr)
435{ 435{
436 mainprog_info *mainprog_ptr; 436 mainprog_info *mainprog_ptr;
437 437
438 438
439 /* retrieve the pointer to our special-purpose struct */ 439 /* retrieve the pointer to our special-purpose struct */
440 440
441 mainprog_ptr = png_get_progressive_ptr(png_ptr); 441 mainprog_ptr = png_get_progressive_ptr(png_ptr);
442 442
443 443
444 /* let the main program know that it should flush any buffered image 444 /* let the main program know that it should flush any buffered image
445 * data to the display now and set a "done" flag or whatever, but note 445 * data to the display now and set a "done" flag or whatever, but note
446 * that it SHOULD NOT DESTROY THE PNG STRUCTS YET--in other words, do 446 * that it SHOULD NOT DESTROY THE PNG STRUCTS YET--in other words, do
447 * NOT call readpng2_cleanup() either here or in the finish_display() 447 * NOT call readpng2_cleanup() either here or in the finish_display()
448 * routine; wait until control returns to the main program via 448 * routine; wait until control returns to the main program via
449 * readpng2_decode_data() */ 449 * readpng2_decode_data() */
450 450
451 (*mainprog_ptr->mainprog_finish_display)(); 451 (*mainprog_ptr->mainprog_finish_display)();
452 452
453 453
454 /* all done */ 454 /* all done */
455 455
456 return; 456 return;
457} 457}
458 458
459 459
460 460
461 461
462 462
463void readpng2_cleanup(mainprog_info *mainprog_ptr) 463void readpng2_cleanup(mainprog_info *mainprog_ptr)
464{ 464{
465 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 465 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
466 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 466 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
467 467
468 if (png_ptr && info_ptr) 468 if (png_ptr && info_ptr)
469 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 469 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
470 470
471 mainprog_ptr->png_ptr = NULL; 471 mainprog_ptr->png_ptr = NULL;
472 mainprog_ptr->info_ptr = NULL; 472 mainprog_ptr->info_ptr = NULL;
473} 473}
474 474
475 475
476 476
477 477
478 478
479static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg) 479static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg)
480{ 480{
481 mainprog_info *mainprog_ptr; 481 mainprog_info *mainprog_ptr;
482 482
483 /* This function, aside from the extra step of retrieving the "error 483 /* This function, aside from the extra step of retrieving the "error
484 * pointer" (below) and the fact that it exists within the application 484 * pointer" (below) and the fact that it exists within the application
485 * rather than within libpng, is essentially identical to libpng's 485 * rather than within libpng, is essentially identical to libpng's
486 * default error handler. The second point is critical: since both 486 * default error handler. The second point is critical: since both
487 * setjmp() and longjmp() are called from the same code, they are 487 * setjmp() and longjmp() are called from the same code, they are
488 * guaranteed to have compatible notions of how big a jmp_buf is, 488 * guaranteed to have compatible notions of how big a jmp_buf is,
489 * regardless of whether _BSD_SOURCE or anything else has (or has not) 489 * regardless of whether _BSD_SOURCE or anything else has (or has not)
490 * been defined. */ 490 * been defined. */
491 491
492 fprintf(stderr, "readpng2 libpng error: %s\n", msg); 492 fprintf(stderr, "readpng2 libpng error: %s\n", msg);
493 fflush(stderr); 493 fflush(stderr);
494 494
495 mainprog_ptr = png_get_error_ptr(png_ptr); 495 mainprog_ptr = png_get_error_ptr(png_ptr);
496 if (mainprog_ptr == NULL) { /* we are completely hosed now */ 496 if (mainprog_ptr == NULL) { /* we are completely hosed now */
497 fprintf(stderr, 497 fprintf(stderr,
498 "readpng2 severe error: jmpbuf not recoverable; terminating.\n"); 498 "readpng2 severe error: jmpbuf not recoverable; terminating.\n");
499 fflush(stderr); 499 fflush(stderr);
500 exit(99); 500 exit(99);
501 } 501 }
502 502
503 /* Now we have our data structure we can use the information in it 503 /* Now we have our data structure we can use the information in it
504 * to return control to our own higher level code (all the points 504 * to return control to our own higher level code (all the points
505 * where 'setjmp' is called in this file.) This will work with other 505 * where 'setjmp' is called in this file.) This will work with other
506 * error handling mechanisms as well - libpng always calls png_error 506 * error handling mechanisms as well - libpng always calls png_error
507 * when it can proceed no further, thus, so long as the error handler 507 * when it can proceed no further, thus, so long as the error handler
508 * is intercepted, application code can do its own error recovery. 508 * is intercepted, application code can do its own error recovery.
509 */ 509 */
510 longjmp(mainprog_ptr->jmpbuf, 1); 510 longjmp(mainprog_ptr->jmpbuf, 1);
511} 511}
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.h
index 7a59263..6b3660d 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.h
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readpng2.h
@@ -1,116 +1,116 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 rpng2 - progressive-model PNG display program readpng2.h 3 rpng2 - progressive-model PNG display program readpng2.h
4 4
5 --------------------------------------------------------------------------- 5 ---------------------------------------------------------------------------
6 6
7 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. 7 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved.
8 8
9 This software is provided "as is," without warranty of any kind, 9 This software is provided "as is," without warranty of any kind,
10 express or implied. In no event shall the author or contributors 10 express or implied. In no event shall the author or contributors
11 be held liable for any damages arising in any way from the use of 11 be held liable for any damages arising in any way from the use of
12 this software. 12 this software.
13 13
14 The contents of this file are DUAL-LICENSED. You may modify and/or 14 The contents of this file are DUAL-LICENSED. You may modify and/or
15 redistribute this software according to the terms of one of the 15 redistribute this software according to the terms of one of the
16 following two licenses (at your option): 16 following two licenses (at your option):
17 17
18 18
19 LICENSE 1 ("BSD-like with advertising clause"): 19 LICENSE 1 ("BSD-like with advertising clause"):
20 20
21 Permission is granted to anyone to use this software for any purpose, 21 Permission is granted to anyone to use this software for any purpose,
22 including commercial applications, and to alter it and redistribute 22 including commercial applications, and to alter it and redistribute
23 it freely, subject to the following restrictions: 23 it freely, subject to the following restrictions:
24 24
25 1. Redistributions of source code must retain the above copyright 25 1. Redistributions of source code must retain the above copyright
26 notice, disclaimer, and this list of conditions. 26 notice, disclaimer, and this list of conditions.
27 2. Redistributions in binary form must reproduce the above copyright 27 2. Redistributions in binary form must reproduce the above copyright
28 notice, disclaimer, and this list of conditions in the documenta- 28 notice, disclaimer, and this list of conditions in the documenta-
29 tion and/or other materials provided with the distribution. 29 tion and/or other materials provided with the distribution.
30 3. All advertising materials mentioning features or use of this 30 3. All advertising materials mentioning features or use of this
31 software must display the following acknowledgment: 31 software must display the following acknowledgment:
32 32
33 This product includes software developed by Greg Roelofs 33 This product includes software developed by Greg Roelofs
34 and contributors for the book, "PNG: The Definitive Guide," 34 and contributors for the book, "PNG: The Definitive Guide,"
35 published by O'Reilly and Associates. 35 published by O'Reilly and Associates.
36 36
37 37
38 LICENSE 2 (GNU GPL v2 or later): 38 LICENSE 2 (GNU GPL v2 or later):
39 39
40 This program is free software; you can redistribute it and/or modify 40 This program is free software; you can redistribute it and/or modify
41 it under the terms of the GNU General Public License as published by 41 it under the terms of the GNU General Public License as published by
42 the Free Software Foundation; either version 2 of the License, or 42 the Free Software Foundation; either version 2 of the License, or
43 (at your option) any later version. 43 (at your option) any later version.
44 44
45 This program is distributed in the hope that it will be useful, 45 This program is distributed in the hope that it will be useful,
46 but WITHOUT ANY WARRANTY; without even the implied warranty of 46 but WITHOUT ANY WARRANTY; without even the implied warranty of
47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 GNU General Public License for more details. 48 GNU General Public License for more details.
49 49
50 You should have received a copy of the GNU General Public License 50 You should have received a copy of the GNU General Public License
51 along with this program; if not, write to the Free Software Foundation, 51 along with this program; if not, write to the Free Software Foundation,
52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53 53
54 ---------------------------------------------------------------------------*/ 54 ---------------------------------------------------------------------------*/
55 55
56#ifndef TRUE 56#ifndef TRUE
57# define TRUE 1 57# define TRUE 1
58# define FALSE 0 58# define FALSE 0
59#endif 59#endif
60 60
61#ifndef MAX 61#ifndef MAX
62# define MAX(a,b) ((a) > (b)? (a) : (b)) 62# define MAX(a,b) ((a) > (b)? (a) : (b))
63# define MIN(a,b) ((a) < (b)? (a) : (b)) 63# define MIN(a,b) ((a) < (b)? (a) : (b))
64#endif 64#endif
65 65
66#ifdef DEBUG 66#ifdef DEBUG
67# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);} 67# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);}
68#else 68#else
69# define Trace(x) ; 69# define Trace(x) ;
70#endif 70#endif
71 71
72enum rpng2_states { 72enum rpng2_states {
73 kPreInit = 0, 73 kPreInit = 0,
74 kWindowInit, 74 kWindowInit,
75 kDone 75 kDone
76}; 76};
77 77
78typedef unsigned char uch; 78typedef unsigned char uch;
79typedef unsigned short ush; 79typedef unsigned short ush;
80typedef unsigned long ulg; 80typedef unsigned long ulg;
81 81
82typedef struct _mainprog_info { 82typedef struct _mainprog_info {
83 double display_exponent; 83 double display_exponent;
84 ulg width; 84 ulg width;
85 ulg height; 85 ulg height;
86 void *png_ptr; 86 void *png_ptr;
87 void *info_ptr; 87 void *info_ptr;
88 void (*mainprog_init)(void); 88 void (*mainprog_init)(void);
89 void (*mainprog_display_row)(ulg row_num); 89 void (*mainprog_display_row)(ulg row_num);
90 void (*mainprog_finish_display)(void); 90 void (*mainprog_finish_display)(void);
91 uch *image_data; 91 uch *image_data;
92 uch **row_pointers; 92 uch **row_pointers;
93 jmp_buf jmpbuf; 93 jmp_buf jmpbuf;
94 int passes; /* not used */ 94 int passes; /* not used */
95 int pass; 95 int pass;
96 int rowbytes; 96 int rowbytes;
97 int channels; 97 int channels;
98 int need_bgcolor; 98 int need_bgcolor;
99 int state; 99 int state;
100 uch bg_red; 100 uch bg_red;
101 uch bg_green; 101 uch bg_green;
102 uch bg_blue; 102 uch bg_blue;
103} mainprog_info; 103} mainprog_info;
104 104
105 105
106/* prototypes for public functions in readpng2.c */ 106/* prototypes for public functions in readpng2.c */
107 107
108void readpng2_version_info(void); 108void readpng2_version_info(void);
109 109
110int readpng2_check_sig(uch *sig, int num); 110int readpng2_check_sig(uch *sig, int num);
111 111
112int readpng2_init(mainprog_info *mainprog_ptr); 112int readpng2_init(mainprog_info *mainprog_ptr);
113 113
114int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length); 114int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length);
115 115
116void readpng2_cleanup(mainprog_info *mainprog_ptr); 116void readpng2_cleanup(mainprog_info *mainprog_ptr);
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readppm.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readppm.c
index 1ba2092..be9a56d 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readppm.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/readppm.c
@@ -1,179 +1,179 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 rpng - simple PNG display program readppm.c 3 rpng - simple PNG display program readppm.c
4 4
5 --------------------------------------------------------------------------- 5 ---------------------------------------------------------------------------
6 6
7 This is a special-purpose replacement for readpng.c that allows binary 7 This is a special-purpose replacement for readpng.c that allows binary
8 PPM files to be used in place of PNG images. 8 PPM files to be used in place of PNG images.
9 9
10 --------------------------------------------------------------------------- 10 ---------------------------------------------------------------------------
11 11
12 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. 12 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved.
13 13
14 This software is provided "as is," without warranty of any kind, 14 This software is provided "as is," without warranty of any kind,
15 express or implied. In no event shall the author or contributors 15 express or implied. In no event shall the author or contributors
16 be held liable for any damages arising in any way from the use of 16 be held liable for any damages arising in any way from the use of
17 this software. 17 this software.
18 18
19 The contents of this file are DUAL-LICENSED. You may modify and/or 19 The contents of this file are DUAL-LICENSED. You may modify and/or
20 redistribute this software according to the terms of one of the 20 redistribute this software according to the terms of one of the
21 following two licenses (at your option): 21 following two licenses (at your option):
22 22
23 23
24 LICENSE 1 ("BSD-like with advertising clause"): 24 LICENSE 1 ("BSD-like with advertising clause"):
25 25
26 Permission is granted to anyone to use this software for any purpose, 26 Permission is granted to anyone to use this software for any purpose,
27 including commercial applications, and to alter it and redistribute 27 including commercial applications, and to alter it and redistribute
28 it freely, subject to the following restrictions: 28 it freely, subject to the following restrictions:
29 29
30 1. Redistributions of source code must retain the above copyright 30 1. Redistributions of source code must retain the above copyright
31 notice, disclaimer, and this list of conditions. 31 notice, disclaimer, and this list of conditions.
32 2. Redistributions in binary form must reproduce the above copyright 32 2. Redistributions in binary form must reproduce the above copyright
33 notice, disclaimer, and this list of conditions in the documenta- 33 notice, disclaimer, and this list of conditions in the documenta-
34 tion and/or other materials provided with the distribution. 34 tion and/or other materials provided with the distribution.
35 3. All advertising materials mentioning features or use of this 35 3. All advertising materials mentioning features or use of this
36 software must display the following acknowledgment: 36 software must display the following acknowledgment:
37 37
38 This product includes software developed by Greg Roelofs 38 This product includes software developed by Greg Roelofs
39 and contributors for the book, "PNG: The Definitive Guide," 39 and contributors for the book, "PNG: The Definitive Guide,"
40 published by O'Reilly and Associates. 40 published by O'Reilly and Associates.
41 41
42 42
43 LICENSE 2 (GNU GPL v2 or later): 43 LICENSE 2 (GNU GPL v2 or later):
44 44
45 This program is free software; you can redistribute it and/or modify 45 This program is free software; you can redistribute it and/or modify
46 it under the terms of the GNU General Public License as published by 46 it under the terms of the GNU General Public License as published by
47 the Free Software Foundation; either version 2 of the License, or 47 the Free Software Foundation; either version 2 of the License, or
48 (at your option) any later version. 48 (at your option) any later version.
49 49
50 This program is distributed in the hope that it will be useful, 50 This program is distributed in the hope that it will be useful,
51 but WITHOUT ANY WARRANTY; without even the implied warranty of 51 but WITHOUT ANY WARRANTY; without even the implied warranty of
52 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 52 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53 GNU General Public License for more details. 53 GNU General Public License for more details.
54 54
55 You should have received a copy of the GNU General Public License 55 You should have received a copy of the GNU General Public License
56 along with this program; if not, write to the Free Software Foundation, 56 along with this program; if not, write to the Free Software Foundation,
57 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 57 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
58 58
59 ---------------------------------------------------------------------------*/ 59 ---------------------------------------------------------------------------*/
60 60
61#include <stdio.h> 61#include <stdio.h>
62#include <stdlib.h> 62#include <stdlib.h>
63 63
64#include "readpng.h" /* typedefs, common macros, public prototypes */ 64#include "readpng.h" /* typedefs, common macros, public prototypes */
65 65
66 66
67ulg width, height; 67ulg width, height;
68int bit_depth, color_type, channels; 68int bit_depth, color_type, channels;
69uch *image_data = NULL; 69uch *image_data = NULL;
70FILE *saved_infile; 70FILE *saved_infile;
71 71
72 72
73void readpng_version_info() 73void readpng_version_info()
74{ 74{
75 fprintf(stderr, " Compiled without libpng, zlib or PBMPLUS/NetPBM.\n"); 75 fprintf(stderr, " Compiled without libpng, zlib or PBMPLUS/NetPBM.\n");
76} 76}
77 77
78 78
79/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */ 79/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */
80 80
81int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight) 81int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)
82{ 82{
83 static uch ppmline[256]; 83 static uch ppmline[256];
84 int maxval; 84 int maxval;
85 85
86 86
87 saved_infile = infile; 87 saved_infile = infile;
88 88
89 fgets(ppmline, 256, infile); 89 fgets(ppmline, 256, infile);
90 if (ppmline[0] != 'P' || ppmline[1] != '6') { 90 if (ppmline[0] != 'P' || ppmline[1] != '6') {
91 fprintf(stderr, "ERROR: not a PPM file\n"); 91 fprintf(stderr, "ERROR: not a PPM file\n");
92 return 1; 92 return 1;
93 } 93 }
94 /* possible color types: P5 = grayscale (0), P6 = RGB (2), P8 = RGBA (6) */ 94 /* possible color types: P5 = grayscale (0), P6 = RGB (2), P8 = RGBA (6) */
95 if (ppmline[1] == '6') { 95 if (ppmline[1] == '6') {
96 color_type = 2; 96 color_type = 2;
97 channels = 3; 97 channels = 3;
98 } else if (ppmline[1] == '8') { 98 } else if (ppmline[1] == '8') {
99 color_type = 6; 99 color_type = 6;
100 channels = 4; 100 channels = 4;
101 } else /* if (ppmline[1] == '5') */ { 101 } else /* if (ppmline[1] == '5') */ {
102 color_type = 0; 102 color_type = 0;
103 channels = 1; 103 channels = 1;
104 } 104 }
105 105
106 do { 106 do {
107 fgets(ppmline, 256, infile); 107 fgets(ppmline, 256, infile);
108 } while (ppmline[0] == '#'); 108 } while (ppmline[0] == '#');
109 sscanf(ppmline, "%lu %lu", &width, &height); 109 sscanf(ppmline, "%lu %lu", &width, &height);
110 110
111 do { 111 do {
112 fgets(ppmline, 256, infile); 112 fgets(ppmline, 256, infile);
113 } while (ppmline[0] == '#'); 113 } while (ppmline[0] == '#');
114 sscanf(ppmline, "%d", &maxval); 114 sscanf(ppmline, "%d", &maxval);
115 if (maxval != 255) { 115 if (maxval != 255) {
116 fprintf(stderr, "ERROR: maxval = %d\n", maxval); 116 fprintf(stderr, "ERROR: maxval = %d\n", maxval);
117 return 2; 117 return 2;
118 } 118 }
119 bit_depth = 8; 119 bit_depth = 8;
120 120
121 *pWidth = width; 121 *pWidth = width;
122 *pHeight = height; 122 *pHeight = height;
123 123
124 return 0; 124 return 0;
125} 125}
126 126
127 127
128 128
129 129
130/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error; 130/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error;
131 * scales values to 8-bit if necessary */ 131 * scales values to 8-bit if necessary */
132 132
133int readpng_get_bgcolor(uch *red, uch *green, uch *blue) 133int readpng_get_bgcolor(uch *red, uch *green, uch *blue)
134{ 134{
135 return 1; 135 return 1;
136} 136}
137 137
138 138
139 139
140 140
141/* display_exponent == LUT_exponent * CRT_exponent */ 141/* display_exponent == LUT_exponent * CRT_exponent */
142 142
143uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes) 143uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
144{ 144{
145 ulg rowbytes; 145 ulg rowbytes;
146 146
147 147
148 /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits, 148 /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
149 * transparency chunks to full alpha channel; strip 16-bit-per-sample 149 * transparency chunks to full alpha channel; strip 16-bit-per-sample
150 * images to 8 bits per sample; and convert grayscale to RGB[A] */ 150 * images to 8 bits per sample; and convert grayscale to RGB[A] */
151 151
152 /* GRR WARNING: grayscale needs to be expanded and channels reset! */ 152 /* GRR WARNING: grayscale needs to be expanded and channels reset! */
153 153
154 *pRowbytes = rowbytes = channels*width; 154 *pRowbytes = rowbytes = channels*width;
155 *pChannels = channels; 155 *pChannels = channels;
156 156
157 if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { 157 if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
158 return NULL; 158 return NULL;
159 } 159 }
160 160
161 Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height)); 161 Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height));
162 162
163 163
164 /* now we can go ahead and just read the whole image */ 164 /* now we can go ahead and just read the whole image */
165 165
166 fread(image_data, 1L, rowbytes*height, saved_infile); 166 fread(image_data, 1L, rowbytes*height, saved_infile);
167 167
168 168
169 return image_data; 169 return image_data;
170} 170}
171 171
172 172
173void readpng_cleanup(int free_image_data) 173void readpng_cleanup(int free_image_data)
174{ 174{
175 if (free_image_data && image_data) { 175 if (free_image_data && image_data) {
176 free(image_data); 176 free(image_data);
177 image_data = NULL; 177 image_data = NULL;
178 } 178 }
179} 179}
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-win.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-win.c
index 1c22282..f53ddc8 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-win.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-win.c
@@ -1,728 +1,728 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 rpng - simple PNG display program rpng-win.c 3 rpng - simple PNG display program rpng-win.c
4 4
5 This program decodes and displays PNG images, with gamma correction and 5 This program decodes and displays PNG images, with gamma correction and
6 optionally with a user-specified background color (in case the image has 6 optionally with a user-specified background color (in case the image has
7 transparency). It is very nearly the most basic PNG viewer possible. 7 transparency). It is very nearly the most basic PNG viewer possible.
8 This version is for 32-bit Windows; it may compile under 16-bit Windows 8 This version is for 32-bit Windows; it may compile under 16-bit Windows
9 with a little tweaking (or maybe not). 9 with a little tweaking (or maybe not).
10 10
11 to do: 11 to do:
12 - handle quoted command-line args (especially filenames with spaces) 12 - handle quoted command-line args (especially filenames with spaces)
13 - have minimum window width: oh well 13 - have minimum window width: oh well
14 - use %.1023s to simplify truncation of title-bar string? 14 - use %.1023s to simplify truncation of title-bar string?
15 15
16 --------------------------------------------------------------------------- 16 ---------------------------------------------------------------------------
17 17
18 Changelog: 18 Changelog:
19 - 1.00: initial public release 19 - 1.00: initial public release
20 - 1.01: modified to allow abbreviated options; fixed long/ulong mis- 20 - 1.01: modified to allow abbreviated options; fixed long/ulong mis-
21 match; switched to png_jmpbuf() macro 21 match; switched to png_jmpbuf() macro
22 - 1.02: added extra set of parentheses to png_jmpbuf() macro; fixed 22 - 1.02: added extra set of parentheses to png_jmpbuf() macro; fixed
23 command-line parsing bug 23 command-line parsing bug
24 - 1.10: enabled "message window"/console (thanks to David Geldreich) 24 - 1.10: enabled "message window"/console (thanks to David Geldreich)
25 - 2.00: dual-licensed (added GNU GPL) 25 - 2.00: dual-licensed (added GNU GPL)
26 - 2.01: fixed improper display of usage screen on PNG error(s) 26 - 2.01: fixed improper display of usage screen on PNG error(s)
27 27
28 --------------------------------------------------------------------------- 28 ---------------------------------------------------------------------------
29 29
30 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. 30 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved.
31 31
32 This software is provided "as is," without warranty of any kind, 32 This software is provided "as is," without warranty of any kind,
33 express or implied. In no event shall the author or contributors 33 express or implied. In no event shall the author or contributors
34 be held liable for any damages arising in any way from the use of 34 be held liable for any damages arising in any way from the use of
35 this software. 35 this software.
36 36
37 The contents of this file are DUAL-LICENSED. You may modify and/or 37 The contents of this file are DUAL-LICENSED. You may modify and/or
38 redistribute this software according to the terms of one of the 38 redistribute this software according to the terms of one of the
39 following two licenses (at your option): 39 following two licenses (at your option):
40 40
41 41
42 LICENSE 1 ("BSD-like with advertising clause"): 42 LICENSE 1 ("BSD-like with advertising clause"):
43 43
44 Permission is granted to anyone to use this software for any purpose, 44 Permission is granted to anyone to use this software for any purpose,
45 including commercial applications, and to alter it and redistribute 45 including commercial applications, and to alter it and redistribute
46 it freely, subject to the following restrictions: 46 it freely, subject to the following restrictions:
47 47
48 1. Redistributions of source code must retain the above copyright 48 1. Redistributions of source code must retain the above copyright
49 notice, disclaimer, and this list of conditions. 49 notice, disclaimer, and this list of conditions.
50 2. Redistributions in binary form must reproduce the above copyright 50 2. Redistributions in binary form must reproduce the above copyright
51 notice, disclaimer, and this list of conditions in the documenta- 51 notice, disclaimer, and this list of conditions in the documenta-
52 tion and/or other materials provided with the distribution. 52 tion and/or other materials provided with the distribution.
53 3. All advertising materials mentioning features or use of this 53 3. All advertising materials mentioning features or use of this
54 software must display the following acknowledgment: 54 software must display the following acknowledgment:
55 55
56 This product includes software developed by Greg Roelofs 56 This product includes software developed by Greg Roelofs
57 and contributors for the book, "PNG: The Definitive Guide," 57 and contributors for the book, "PNG: The Definitive Guide,"
58 published by O'Reilly and Associates. 58 published by O'Reilly and Associates.
59 59
60 60
61 LICENSE 2 (GNU GPL v2 or later): 61 LICENSE 2 (GNU GPL v2 or later):
62 62
63 This program is free software; you can redistribute it and/or modify 63 This program is free software; you can redistribute it and/or modify
64 it under the terms of the GNU General Public License as published by 64 it under the terms of the GNU General Public License as published by
65 the Free Software Foundation; either version 2 of the License, or 65 the Free Software Foundation; either version 2 of the License, or
66 (at your option) any later version. 66 (at your option) any later version.
67 67
68 This program is distributed in the hope that it will be useful, 68 This program is distributed in the hope that it will be useful,
69 but WITHOUT ANY WARRANTY; without even the implied warranty of 69 but WITHOUT ANY WARRANTY; without even the implied warranty of
70 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 70 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
71 GNU General Public License for more details. 71 GNU General Public License for more details.
72 72
73 You should have received a copy of the GNU General Public License 73 You should have received a copy of the GNU General Public License
74 along with this program; if not, write to the Free Software Foundation, 74 along with this program; if not, write to the Free Software Foundation,
75 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 75 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
76 76
77 ---------------------------------------------------------------------------*/ 77 ---------------------------------------------------------------------------*/
78 78
79#define PROGNAME "rpng-win" 79#define PROGNAME "rpng-win"
80#define LONGNAME "Simple PNG Viewer for Windows" 80#define LONGNAME "Simple PNG Viewer for Windows"
81#define VERSION "2.01 of 16 March 2008" 81#define VERSION "2.01 of 16 March 2008"
82 82
83#include <stdio.h> 83#include <stdio.h>
84#include <stdlib.h> 84#include <stdlib.h>
85#include <string.h> 85#include <string.h>
86#include <time.h> 86#include <time.h>
87#include <windows.h> 87#include <windows.h>
88#ifdef __CYGWIN__ 88#ifdef __CYGWIN__
89/* getch replacement. Turns out, we don't really need this, 89/* getch replacement. Turns out, we don't really need this,
90 * but leave it here if we ever enable any of the uses of 90 * but leave it here if we ever enable any of the uses of
91 * _getch in the main code 91 * _getch in the main code
92 */ 92 */
93#include <unistd.h> 93#include <unistd.h>
94#include <termio.h> 94#include <termio.h>
95#include <sys/ioctl.h> 95#include <sys/ioctl.h>
96int repl_getch( void ) 96int repl_getch( void )
97{ 97{
98 char ch; 98 char ch;
99 int fd = fileno(stdin); 99 int fd = fileno(stdin);
100 struct termio old_tty, new_tty; 100 struct termio old_tty, new_tty;
101 101
102 ioctl(fd, TCGETA, &old_tty); 102 ioctl(fd, TCGETA, &old_tty);
103 new_tty = old_tty; 103 new_tty = old_tty;
104 new_tty.c_lflag &= ~(ICANON | ECHO | ISIG); 104 new_tty.c_lflag &= ~(ICANON | ECHO | ISIG);
105 ioctl(fd, TCSETA, &new_tty); 105 ioctl(fd, TCSETA, &new_tty);
106 fread(&ch, 1, sizeof(ch), stdin); 106 fread(&ch, 1, sizeof(ch), stdin);
107 ioctl(fd, TCSETA, &old_tty); 107 ioctl(fd, TCSETA, &old_tty);
108 108
109 return ch; 109 return ch;
110} 110}
111#define _getch repl_getch 111#define _getch repl_getch
112#else 112#else
113#include <conio.h> /* only for _getch() */ 113#include <conio.h> /* only for _getch() */
114#endif 114#endif
115 115
116/* #define DEBUG : this enables the Trace() macros */ 116/* #define DEBUG : this enables the Trace() macros */
117 117
118#include "readpng.h" /* typedefs, common macros, readpng prototypes */ 118#include "readpng.h" /* typedefs, common macros, readpng prototypes */
119 119
120 120
121/* could just include png.h, but this macro is the only thing we need 121/* could just include png.h, but this macro is the only thing we need
122 * (name and typedefs changed to local versions); note that side effects 122 * (name and typedefs changed to local versions); note that side effects
123 * only happen with alpha (which could easily be avoided with 123 * only happen with alpha (which could easily be avoided with
124 * "ush acopy = (alpha);") */ 124 * "ush acopy = (alpha);") */
125 125
126#define alpha_composite(composite, fg, alpha, bg) { \ 126#define alpha_composite(composite, fg, alpha, bg) { \
127 ush temp = ((ush)(fg)*(ush)(alpha) + \ 127 ush temp = ((ush)(fg)*(ush)(alpha) + \
128 (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ 128 (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
129 (composite) = (uch)((temp + (temp >> 8)) >> 8); \ 129 (composite) = (uch)((temp + (temp >> 8)) >> 8); \
130} 130}
131 131
132 132
133/* local prototypes */ 133/* local prototypes */
134static int rpng_win_create_window(HINSTANCE hInst, int showmode); 134static int rpng_win_create_window(HINSTANCE hInst, int showmode);
135static int rpng_win_display_image(void); 135static int rpng_win_display_image(void);
136static void rpng_win_cleanup(void); 136static void rpng_win_cleanup(void);
137LRESULT CALLBACK rpng_win_wndproc(HWND, UINT, WPARAM, LPARAM); 137LRESULT CALLBACK rpng_win_wndproc(HWND, UINT, WPARAM, LPARAM);
138 138
139 139
140static char titlebar[1024]; 140static char titlebar[1024];
141static char *progname = PROGNAME; 141static char *progname = PROGNAME;
142static char *appname = LONGNAME; 142static char *appname = LONGNAME;
143static char *filename; 143static char *filename;
144static FILE *infile; 144static FILE *infile;
145 145
146static char *bgstr; 146static char *bgstr;
147static uch bg_red=0, bg_green=0, bg_blue=0; 147static uch bg_red=0, bg_green=0, bg_blue=0;
148 148
149static double display_exponent; 149static double display_exponent;
150 150
151static ulg image_width, image_height, image_rowbytes; 151static ulg image_width, image_height, image_rowbytes;
152static int image_channels; 152static int image_channels;
153static uch *image_data; 153static uch *image_data;
154 154
155/* Windows-specific variables */ 155/* Windows-specific variables */
156static ulg wimage_rowbytes; 156static ulg wimage_rowbytes;
157static uch *dib; 157static uch *dib;
158static uch *wimage_data; 158static uch *wimage_data;
159static BITMAPINFOHEADER *bmih; 159static BITMAPINFOHEADER *bmih;
160 160
161static HWND global_hwnd; 161static HWND global_hwnd;
162 162
163 163
164 164
165 165
166int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode) 166int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
167{ 167{
168 char *args[1024]; /* arbitrary limit, but should suffice */ 168 char *args[1024]; /* arbitrary limit, but should suffice */
169 char *p, *q, **argv = args; 169 char *p, *q, **argv = args;
170 int argc = 0; 170 int argc = 0;
171 int rc, alen, flen; 171 int rc, alen, flen;
172 int error = 0; 172 int error = 0;
173 int have_bg = FALSE; 173 int have_bg = FALSE;
174 double LUT_exponent; /* just the lookup table */ 174 double LUT_exponent; /* just the lookup table */
175 double CRT_exponent = 2.2; /* just the monitor */ 175 double CRT_exponent = 2.2; /* just the monitor */
176 double default_display_exponent; /* whole display system */ 176 double default_display_exponent; /* whole display system */
177 MSG msg; 177 MSG msg;
178 178
179 179
180 filename = (char *)NULL; 180 filename = (char *)NULL;
181 181
182#ifndef __CYGWIN__ 182#ifndef __CYGWIN__
183 /* First reenable console output, which normally goes to the bit bucket 183 /* First reenable console output, which normally goes to the bit bucket
184 * for windowed apps. Closing the console window will terminate the 184 * for windowed apps. Closing the console window will terminate the
185 * app. Thanks to David.Geldreich@realviz.com for supplying the magical 185 * app. Thanks to David.Geldreich@realviz.com for supplying the magical
186 * incantation. */ 186 * incantation. */
187 187
188 AllocConsole(); 188 AllocConsole();
189 freopen("CONOUT$", "a", stderr); 189 freopen("CONOUT$", "a", stderr);
190 freopen("CONOUT$", "a", stdout); 190 freopen("CONOUT$", "a", stdout);
191#endif 191#endif
192 192
193 193
194 /* Next set the default value for our display-system exponent, i.e., 194 /* Next set the default value for our display-system exponent, i.e.,
195 * the product of the CRT exponent and the exponent corresponding to 195 * the product of the CRT exponent and the exponent corresponding to
196 * the frame-buffer's lookup table (LUT), if any. This is not an 196 * the frame-buffer's lookup table (LUT), if any. This is not an
197 * exhaustive list of LUT values (e.g., OpenStep has a lot of weird 197 * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
198 * ones), but it should cover 99% of the current possibilities. And 198 * ones), but it should cover 99% of the current possibilities. And
199 * yes, these ifdefs are completely wasted in a Windows program... */ 199 * yes, these ifdefs are completely wasted in a Windows program... */
200 200
201#if defined(NeXT) 201#if defined(NeXT)
202 LUT_exponent = 1.0 / 2.2; 202 LUT_exponent = 1.0 / 2.2;
203 /* 203 /*
204 if (some_next_function_that_returns_gamma(&next_gamma)) 204 if (some_next_function_that_returns_gamma(&next_gamma))
205 LUT_exponent = 1.0 / next_gamma; 205 LUT_exponent = 1.0 / next_gamma;
206 */ 206 */
207#elif defined(sgi) 207#elif defined(sgi)
208 LUT_exponent = 1.0 / 1.7; 208 LUT_exponent = 1.0 / 1.7;
209 /* there doesn't seem to be any documented function to get the 209 /* there doesn't seem to be any documented function to get the
210 * "gamma" value, so we do it the hard way */ 210 * "gamma" value, so we do it the hard way */
211 infile = fopen("/etc/config/system.glGammaVal", "r"); 211 infile = fopen("/etc/config/system.glGammaVal", "r");
212 if (infile) { 212 if (infile) {
213 double sgi_gamma; 213 double sgi_gamma;
214 214
215 fgets(tmpline, 80, infile); 215 fgets(tmpline, 80, infile);
216 fclose(infile); 216 fclose(infile);
217 sgi_gamma = atof(tmpline); 217 sgi_gamma = atof(tmpline);
218 if (sgi_gamma > 0.0) 218 if (sgi_gamma > 0.0)
219 LUT_exponent = 1.0 / sgi_gamma; 219 LUT_exponent = 1.0 / sgi_gamma;
220 } 220 }
221#elif defined(Macintosh) 221#elif defined(Macintosh)
222 LUT_exponent = 1.8 / 2.61; 222 LUT_exponent = 1.8 / 2.61;
223 /* 223 /*
224 if (some_mac_function_that_returns_gamma(&mac_gamma)) 224 if (some_mac_function_that_returns_gamma(&mac_gamma))
225 LUT_exponent = mac_gamma / 2.61; 225 LUT_exponent = mac_gamma / 2.61;
226 */ 226 */
227#else 227#else
228 LUT_exponent = 1.0; /* assume no LUT: most PCs */ 228 LUT_exponent = 1.0; /* assume no LUT: most PCs */
229#endif 229#endif
230 230
231 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ 231 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
232 default_display_exponent = LUT_exponent * CRT_exponent; 232 default_display_exponent = LUT_exponent * CRT_exponent;
233 233
234 234
235 /* If the user has set the SCREEN_GAMMA environment variable as suggested 235 /* If the user has set the SCREEN_GAMMA environment variable as suggested
236 * (somewhat imprecisely) in the libpng documentation, use that; otherwise 236 * (somewhat imprecisely) in the libpng documentation, use that; otherwise
237 * use the default value we just calculated. Either way, the user may 237 * use the default value we just calculated. Either way, the user may
238 * override this via a command-line option. */ 238 * override this via a command-line option. */
239 239
240 if ((p = getenv("SCREEN_GAMMA")) != NULL) 240 if ((p = getenv("SCREEN_GAMMA")) != NULL)
241 display_exponent = atof(p); 241 display_exponent = atof(p);
242 else 242 else
243 display_exponent = default_display_exponent; 243 display_exponent = default_display_exponent;
244 244
245 245
246 /* Windows really hates command lines, so we have to set up our own argv. 246 /* Windows really hates command lines, so we have to set up our own argv.
247 * Note that we do NOT bother with quoted arguments here, so don't use 247 * Note that we do NOT bother with quoted arguments here, so don't use
248 * filenames with spaces in 'em! */ 248 * filenames with spaces in 'em! */
249 249
250 argv[argc++] = PROGNAME; 250 argv[argc++] = PROGNAME;
251 p = cmd; 251 p = cmd;
252 for (;;) { 252 for (;;) {
253 if (*p == ' ') 253 if (*p == ' ')
254 while (*++p == ' ') 254 while (*++p == ' ')
255 ; 255 ;
256 /* now p points at the first non-space after some spaces */ 256 /* now p points at the first non-space after some spaces */
257 if (*p == '\0') 257 if (*p == '\0')
258 break; /* nothing after the spaces: done */ 258 break; /* nothing after the spaces: done */
259 argv[argc++] = q = p; 259 argv[argc++] = q = p;
260 while (*q && *q != ' ') 260 while (*q && *q != ' ')
261 ++q; 261 ++q;
262 /* now q points at a space or the end of the string */ 262 /* now q points at a space or the end of the string */
263 if (*q == '\0') 263 if (*q == '\0')
264 break; /* last argv already terminated; quit */ 264 break; /* last argv already terminated; quit */
265 *q = '\0'; /* change space to terminator */ 265 *q = '\0'; /* change space to terminator */
266 p = q + 1; 266 p = q + 1;
267 } 267 }
268 argv[argc] = NULL; /* terminate the argv array itself */ 268 argv[argc] = NULL; /* terminate the argv array itself */
269 269
270 270
271 /* Now parse the command line for options and the PNG filename. */ 271 /* Now parse the command line for options and the PNG filename. */
272 272
273 while (*++argv && !error) { 273 while (*++argv && !error) {
274 if (!strncmp(*argv, "-gamma", 2)) { 274 if (!strncmp(*argv, "-gamma", 2)) {
275 if (!*++argv) 275 if (!*++argv)
276 ++error; 276 ++error;
277 else { 277 else {
278 display_exponent = atof(*argv); 278 display_exponent = atof(*argv);
279 if (display_exponent <= 0.0) 279 if (display_exponent <= 0.0)
280 ++error; 280 ++error;
281 } 281 }
282 } else if (!strncmp(*argv, "-bgcolor", 2)) { 282 } else if (!strncmp(*argv, "-bgcolor", 2)) {
283 if (!*++argv) 283 if (!*++argv)
284 ++error; 284 ++error;
285 else { 285 else {
286 bgstr = *argv; 286 bgstr = *argv;
287 if (strlen(bgstr) != 7 || bgstr[0] != '#') 287 if (strlen(bgstr) != 7 || bgstr[0] != '#')
288 ++error; 288 ++error;
289 else 289 else
290 have_bg = TRUE; 290 have_bg = TRUE;
291 } 291 }
292 } else { 292 } else {
293 if (**argv != '-') { 293 if (**argv != '-') {
294 filename = *argv; 294 filename = *argv;
295 if (argv[1]) /* shouldn't be any more args after filename */ 295 if (argv[1]) /* shouldn't be any more args after filename */
296 ++error; 296 ++error;
297 } else 297 } else
298 ++error; /* not expecting any other options */ 298 ++error; /* not expecting any other options */
299 } 299 }
300 } 300 }
301 301
302 if (!filename) 302 if (!filename)
303 ++error; 303 ++error;
304 304
305 305
306 /* print usage screen if any errors up to this point */ 306 /* print usage screen if any errors up to this point */
307 307
308 if (error) { 308 if (error) {
309#ifndef __CYGWIN__ 309#ifndef __CYGWIN__
310 int ch; 310 int ch;
311#endif 311#endif
312 312
313 fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); 313 fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname);
314 readpng_version_info(); 314 readpng_version_info();
315 fprintf(stderr, "\n" 315 fprintf(stderr, "\n"
316 "Usage: %s [-gamma exp] [-bgcolor bg] file.png\n" 316 "Usage: %s [-gamma exp] [-bgcolor bg] file.png\n"
317 " exp \ttransfer-function exponent (``gamma'') of the display\n" 317 " exp \ttransfer-function exponent (``gamma'') of the display\n"
318 "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" 318 "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
319 "\t\t to the product of the lookup-table exponent (varies)\n" 319 "\t\t to the product of the lookup-table exponent (varies)\n"
320 "\t\t and the CRT exponent (usually 2.2); must be positive\n" 320 "\t\t and the CRT exponent (usually 2.2); must be positive\n"
321 " bg \tdesired background color in 7-character hex RGB format\n" 321 " bg \tdesired background color in 7-character hex RGB format\n"
322 "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" 322 "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
323 "\t\t used with transparent images\n" 323 "\t\t used with transparent images\n"
324 "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n" 324 "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
325#ifndef __CYGWIN__ 325#ifndef __CYGWIN__
326 "Press Q or Esc to quit this usage screen.\n" 326 "Press Q or Esc to quit this usage screen.\n"
327#endif 327#endif
328 "\n", PROGNAME, default_display_exponent); 328 "\n", PROGNAME, default_display_exponent);
329#ifndef __CYGWIN__ 329#ifndef __CYGWIN__
330 do 330 do
331 ch = _getch(); 331 ch = _getch();
332 while (ch != 'q' && ch != 'Q' && ch != 0x1B); 332 while (ch != 'q' && ch != 'Q' && ch != 0x1B);
333#endif 333#endif
334 exit(1); 334 exit(1);
335 } 335 }
336 336
337 337
338 if (!(infile = fopen(filename, "rb"))) { 338 if (!(infile = fopen(filename, "rb"))) {
339 fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); 339 fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
340 ++error; 340 ++error;
341 } else { 341 } else {
342 if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) { 342 if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
343 switch (rc) { 343 switch (rc) {
344 case 1: 344 case 1:
345 fprintf(stderr, PROGNAME 345 fprintf(stderr, PROGNAME
346 ": [%s] is not a PNG file: incorrect signature\n", 346 ": [%s] is not a PNG file: incorrect signature\n",
347 filename); 347 filename);
348 break; 348 break;
349 case 2: 349 case 2:
350 fprintf(stderr, PROGNAME 350 fprintf(stderr, PROGNAME
351 ": [%s] has bad IHDR (libpng longjmp)\n", filename); 351 ": [%s] has bad IHDR (libpng longjmp)\n", filename);
352 break; 352 break;
353 case 4: 353 case 4:
354 fprintf(stderr, PROGNAME ": insufficient memory\n"); 354 fprintf(stderr, PROGNAME ": insufficient memory\n");
355 break; 355 break;
356 default: 356 default:
357 fprintf(stderr, PROGNAME 357 fprintf(stderr, PROGNAME
358 ": unknown readpng_init() error\n"); 358 ": unknown readpng_init() error\n");
359 break; 359 break;
360 } 360 }
361 ++error; 361 ++error;
362 } 362 }
363 if (error) 363 if (error)
364 fclose(infile); 364 fclose(infile);
365 } 365 }
366 366
367 367
368 if (error) { 368 if (error) {
369#ifndef __CYGWIN__ 369#ifndef __CYGWIN__
370 int ch; 370 int ch;
371#endif 371#endif
372 372
373 fprintf(stderr, PROGNAME ": aborting.\n"); 373 fprintf(stderr, PROGNAME ": aborting.\n");
374#ifndef __CYGWIN__ 374#ifndef __CYGWIN__
375 do 375 do
376 ch = _getch(); 376 ch = _getch();
377 while (ch != 'q' && ch != 'Q' && ch != 0x1B); 377 while (ch != 'q' && ch != 'Q' && ch != 0x1B);
378#endif 378#endif
379 exit(2); 379 exit(2);
380 } else { 380 } else {
381 fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); 381 fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
382#ifndef __CYGWIN__ 382#ifndef __CYGWIN__
383 fprintf(stderr, 383 fprintf(stderr,
384 "\n [console window: closing this window will terminate %s]\n\n", 384 "\n [console window: closing this window will terminate %s]\n\n",
385 PROGNAME); 385 PROGNAME);
386#endif 386#endif
387 } 387 }
388 388
389 389
390 /* set the title-bar string, but make sure buffer doesn't overflow */ 390 /* set the title-bar string, but make sure buffer doesn't overflow */
391 391
392 alen = strlen(appname); 392 alen = strlen(appname);
393 flen = strlen(filename); 393 flen = strlen(filename);
394 if (alen + flen + 3 > 1023) 394 if (alen + flen + 3 > 1023)
395 sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); 395 sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
396 else 396 else
397 sprintf(titlebar, "%s: %s", appname, filename); 397 sprintf(titlebar, "%s: %s", appname, filename);
398 398
399 399
400 /* if the user didn't specify a background color on the command line, 400 /* if the user didn't specify a background color on the command line,
401 * check for one in the PNG file--if not, the initialized values of 0 401 * check for one in the PNG file--if not, the initialized values of 0
402 * (black) will be used */ 402 * (black) will be used */
403 403
404 if (have_bg) { 404 if (have_bg) {
405 unsigned r, g, b; /* this approach quiets compiler warnings */ 405 unsigned r, g, b; /* this approach quiets compiler warnings */
406 406
407 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); 407 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
408 bg_red = (uch)r; 408 bg_red = (uch)r;
409 bg_green = (uch)g; 409 bg_green = (uch)g;
410 bg_blue = (uch)b; 410 bg_blue = (uch)b;
411 } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) { 411 } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) {
412 readpng_cleanup(TRUE); 412 readpng_cleanup(TRUE);
413 fprintf(stderr, PROGNAME 413 fprintf(stderr, PROGNAME
414 ": libpng error while checking for background color\n"); 414 ": libpng error while checking for background color\n");
415 exit(2); 415 exit(2);
416 } 416 }
417 417
418 418
419 /* do the basic Windows initialization stuff, make the window and fill it 419 /* do the basic Windows initialization stuff, make the window and fill it
420 * with the background color */ 420 * with the background color */
421 421
422 if (rpng_win_create_window(hInst, showmode)) 422 if (rpng_win_create_window(hInst, showmode))
423 exit(2); 423 exit(2);
424 424
425 425
426 /* decode the image, all at once */ 426 /* decode the image, all at once */
427 427
428 Trace((stderr, "calling readpng_get_image()\n")) 428 Trace((stderr, "calling readpng_get_image()\n"))
429 image_data = readpng_get_image(display_exponent, &image_channels, 429 image_data = readpng_get_image(display_exponent, &image_channels,
430 &image_rowbytes); 430 &image_rowbytes);
431 Trace((stderr, "done with readpng_get_image()\n")) 431 Trace((stderr, "done with readpng_get_image()\n"))
432 432
433 433
434 /* done with PNG file, so clean up to minimize memory usage (but do NOT 434 /* done with PNG file, so clean up to minimize memory usage (but do NOT
435 * nuke image_data!) */ 435 * nuke image_data!) */
436 436
437 readpng_cleanup(FALSE); 437 readpng_cleanup(FALSE);
438 fclose(infile); 438 fclose(infile);
439 439
440 if (!image_data) { 440 if (!image_data) {
441 fprintf(stderr, PROGNAME ": unable to decode PNG image\n"); 441 fprintf(stderr, PROGNAME ": unable to decode PNG image\n");
442 exit(3); 442 exit(3);
443 } 443 }
444 444
445 445
446 /* display image (composite with background if requested) */ 446 /* display image (composite with background if requested) */
447 447
448 Trace((stderr, "calling rpng_win_display_image()\n")) 448 Trace((stderr, "calling rpng_win_display_image()\n"))
449 if (rpng_win_display_image()) { 449 if (rpng_win_display_image()) {
450 free(image_data); 450 free(image_data);
451 exit(4); 451 exit(4);
452 } 452 }
453 Trace((stderr, "done with rpng_win_display_image()\n")) 453 Trace((stderr, "done with rpng_win_display_image()\n"))
454 454
455 455
456 /* wait for the user to tell us when to quit */ 456 /* wait for the user to tell us when to quit */
457 457
458 printf( 458 printf(
459#ifndef __CYGWIN__ 459#ifndef __CYGWIN__
460 "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n" 460 "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"
461#else 461#else
462 "Done. Press mouse button 1 (within image window) to quit.\n" 462 "Done. Press mouse button 1 (within image window) to quit.\n"
463#endif 463#endif
464 ); 464 );
465 fflush(stdout); 465 fflush(stdout);
466 466
467 while (GetMessage(&msg, NULL, 0, 0)) { 467 while (GetMessage(&msg, NULL, 0, 0)) {
468 TranslateMessage(&msg); 468 TranslateMessage(&msg);
469 DispatchMessage(&msg); 469 DispatchMessage(&msg);
470 } 470 }
471 471
472 472
473 /* OK, we're done: clean up all image and Windows resources and go away */ 473 /* OK, we're done: clean up all image and Windows resources and go away */
474 474
475 rpng_win_cleanup(); 475 rpng_win_cleanup();
476 476
477 return msg.wParam; 477 return msg.wParam;
478} 478}
479 479
480 480
481 481
482 482
483 483
484static int rpng_win_create_window(HINSTANCE hInst, int showmode) 484static int rpng_win_create_window(HINSTANCE hInst, int showmode)
485{ 485{
486 uch *dest; 486 uch *dest;
487 int extra_width, extra_height; 487 int extra_width, extra_height;
488 ulg i, j; 488 ulg i, j;
489 WNDCLASSEX wndclass; 489 WNDCLASSEX wndclass;
490 490
491 491
492/*--------------------------------------------------------------------------- 492/*---------------------------------------------------------------------------
493 Allocate memory for the display-specific version of the image (round up 493 Allocate memory for the display-specific version of the image (round up
494 to multiple of 4 for Windows DIB). 494 to multiple of 4 for Windows DIB).
495 ---------------------------------------------------------------------------*/ 495 ---------------------------------------------------------------------------*/
496 496
497 wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2; 497 wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2;
498 498
499 if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) + 499 if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
500 wimage_rowbytes*image_height))) 500 wimage_rowbytes*image_height)))
501 { 501 {
502 return 4; /* fail */ 502 return 4; /* fail */
503 } 503 }
504 504
505/*--------------------------------------------------------------------------- 505/*---------------------------------------------------------------------------
506 Initialize the DIB. Negative height means to use top-down BMP ordering 506 Initialize the DIB. Negative height means to use top-down BMP ordering
507 (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8 507 (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8
508 implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values 508 implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values
509 directly => wimage_data begins immediately after BMP header. 509 directly => wimage_data begins immediately after BMP header.
510 ---------------------------------------------------------------------------*/ 510 ---------------------------------------------------------------------------*/
511 511
512 memset(dib, 0, sizeof(BITMAPINFOHEADER)); 512 memset(dib, 0, sizeof(BITMAPINFOHEADER));
513 bmih = (BITMAPINFOHEADER *)dib; 513 bmih = (BITMAPINFOHEADER *)dib;
514 bmih->biSize = sizeof(BITMAPINFOHEADER); 514 bmih->biSize = sizeof(BITMAPINFOHEADER);
515 bmih->biWidth = image_width; 515 bmih->biWidth = image_width;
516 bmih->biHeight = -((long)image_height); 516 bmih->biHeight = -((long)image_height);
517 bmih->biPlanes = 1; 517 bmih->biPlanes = 1;
518 bmih->biBitCount = 24; 518 bmih->biBitCount = 24;
519 bmih->biCompression = 0; 519 bmih->biCompression = 0;
520 wimage_data = dib + sizeof(BITMAPINFOHEADER); 520 wimage_data = dib + sizeof(BITMAPINFOHEADER);
521 521
522/*--------------------------------------------------------------------------- 522/*---------------------------------------------------------------------------
523 Fill in background color (black by default); data are in BGR order. 523 Fill in background color (black by default); data are in BGR order.
524 ---------------------------------------------------------------------------*/ 524 ---------------------------------------------------------------------------*/
525 525
526 for (j = 0; j < image_height; ++j) { 526 for (j = 0; j < image_height; ++j) {
527 dest = wimage_data + j*wimage_rowbytes; 527 dest = wimage_data + j*wimage_rowbytes;
528 for (i = image_width; i > 0; --i) { 528 for (i = image_width; i > 0; --i) {
529 *dest++ = bg_blue; 529 *dest++ = bg_blue;
530 *dest++ = bg_green; 530 *dest++ = bg_green;
531 *dest++ = bg_red; 531 *dest++ = bg_red;
532 } 532 }
533 } 533 }
534 534
535/*--------------------------------------------------------------------------- 535/*---------------------------------------------------------------------------
536 Set the window parameters. 536 Set the window parameters.
537 ---------------------------------------------------------------------------*/ 537 ---------------------------------------------------------------------------*/
538 538
539 memset(&wndclass, 0, sizeof(wndclass)); 539 memset(&wndclass, 0, sizeof(wndclass));
540 540
541 wndclass.cbSize = sizeof(wndclass); 541 wndclass.cbSize = sizeof(wndclass);
542 wndclass.style = CS_HREDRAW | CS_VREDRAW; 542 wndclass.style = CS_HREDRAW | CS_VREDRAW;
543 wndclass.lpfnWndProc = rpng_win_wndproc; 543 wndclass.lpfnWndProc = rpng_win_wndproc;
544 wndclass.hInstance = hInst; 544 wndclass.hInstance = hInst;
545 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 545 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
546 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 546 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
547 wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); 547 wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
548 wndclass.lpszMenuName = NULL; 548 wndclass.lpszMenuName = NULL;
549 wndclass.lpszClassName = progname; 549 wndclass.lpszClassName = progname;
550 wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 550 wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
551 551
552 RegisterClassEx(&wndclass); 552 RegisterClassEx(&wndclass);
553 553
554/*--------------------------------------------------------------------------- 554/*---------------------------------------------------------------------------
555 Finally, create the window. 555 Finally, create the window.
556 ---------------------------------------------------------------------------*/ 556 ---------------------------------------------------------------------------*/
557 557
558 extra_width = 2*(GetSystemMetrics(SM_CXBORDER) + 558 extra_width = 2*(GetSystemMetrics(SM_CXBORDER) +
559 GetSystemMetrics(SM_CXDLGFRAME)); 559 GetSystemMetrics(SM_CXDLGFRAME));
560 extra_height = 2*(GetSystemMetrics(SM_CYBORDER) + 560 extra_height = 2*(GetSystemMetrics(SM_CYBORDER) +
561 GetSystemMetrics(SM_CYDLGFRAME)) + 561 GetSystemMetrics(SM_CYDLGFRAME)) +
562 GetSystemMetrics(SM_CYCAPTION); 562 GetSystemMetrics(SM_CYCAPTION);
563 563
564 global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW, 564 global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW,
565 CW_USEDEFAULT, CW_USEDEFAULT, image_width+extra_width, 565 CW_USEDEFAULT, CW_USEDEFAULT, image_width+extra_width,
566 image_height+extra_height, NULL, NULL, hInst, NULL); 566 image_height+extra_height, NULL, NULL, hInst, NULL);
567 567
568 ShowWindow(global_hwnd, showmode); 568 ShowWindow(global_hwnd, showmode);
569 UpdateWindow(global_hwnd); 569 UpdateWindow(global_hwnd);
570 570
571 return 0; 571 return 0;
572 572
573} /* end function rpng_win_create_window() */ 573} /* end function rpng_win_create_window() */
574 574
575 575
576 576
577 577
578 578
579static int rpng_win_display_image() 579static int rpng_win_display_image()
580{ 580{
581 uch *src, *dest; 581 uch *src, *dest;
582 uch r, g, b, a; 582 uch r, g, b, a;
583 ulg i, row, lastrow; 583 ulg i, row, lastrow;
584 RECT rect; 584 RECT rect;
585 585
586 586
587 Trace((stderr, "beginning display loop (image_channels == %d)\n", 587 Trace((stderr, "beginning display loop (image_channels == %d)\n",
588 image_channels)) 588 image_channels))
589 Trace((stderr, "(width = %ld, rowbytes = %ld, wimage_rowbytes = %d)\n", 589 Trace((stderr, "(width = %ld, rowbytes = %ld, wimage_rowbytes = %d)\n",
590 image_width, image_rowbytes, wimage_rowbytes)) 590 image_width, image_rowbytes, wimage_rowbytes))
591 591
592 592
593/*--------------------------------------------------------------------------- 593/*---------------------------------------------------------------------------
594 Blast image data to buffer. This whole routine takes place before the 594 Blast image data to buffer. This whole routine takes place before the
595 message loop begins, so there's no real point in any pseudo-progressive 595 message loop begins, so there's no real point in any pseudo-progressive
596 display... 596 display...
597 ---------------------------------------------------------------------------*/ 597 ---------------------------------------------------------------------------*/
598 598
599 for (lastrow = row = 0; row < image_height; ++row) { 599 for (lastrow = row = 0; row < image_height; ++row) {
600 src = image_data + row*image_rowbytes; 600 src = image_data + row*image_rowbytes;
601 dest = wimage_data + row*wimage_rowbytes; 601 dest = wimage_data + row*wimage_rowbytes;
602 if (image_channels == 3) { 602 if (image_channels == 3) {
603 for (i = image_width; i > 0; --i) { 603 for (i = image_width; i > 0; --i) {
604 r = *src++; 604 r = *src++;
605 g = *src++; 605 g = *src++;
606 b = *src++; 606 b = *src++;
607 *dest++ = b; 607 *dest++ = b;
608 *dest++ = g; /* note reverse order */ 608 *dest++ = g; /* note reverse order */
609 *dest++ = r; 609 *dest++ = r;
610 } 610 }
611 } else /* if (image_channels == 4) */ { 611 } else /* if (image_channels == 4) */ {
612 for (i = image_width; i > 0; --i) { 612 for (i = image_width; i > 0; --i) {
613 r = *src++; 613 r = *src++;
614 g = *src++; 614 g = *src++;
615 b = *src++; 615 b = *src++;
616 a = *src++; 616 a = *src++;
617 if (a == 255) { 617 if (a == 255) {
618 *dest++ = b; 618 *dest++ = b;
619 *dest++ = g; 619 *dest++ = g;
620 *dest++ = r; 620 *dest++ = r;
621 } else if (a == 0) { 621 } else if (a == 0) {
622 *dest++ = bg_blue; 622 *dest++ = bg_blue;
623 *dest++ = bg_green; 623 *dest++ = bg_green;
624 *dest++ = bg_red; 624 *dest++ = bg_red;
625 } else { 625 } else {
626 /* this macro (copied from png.h) composites the 626 /* this macro (copied from png.h) composites the
627 * foreground and background values and puts the 627 * foreground and background values and puts the
628 * result into the first argument; there are no 628 * result into the first argument; there are no
629 * side effects with the first argument */ 629 * side effects with the first argument */
630 alpha_composite(*dest++, b, a, bg_blue); 630 alpha_composite(*dest++, b, a, bg_blue);
631 alpha_composite(*dest++, g, a, bg_green); 631 alpha_composite(*dest++, g, a, bg_green);
632 alpha_composite(*dest++, r, a, bg_red); 632 alpha_composite(*dest++, r, a, bg_red);
633 } 633 }
634 } 634 }
635 } 635 }
636 /* display after every 16 lines */ 636 /* display after every 16 lines */
637 if (((row+1) & 0xf) == 0) { 637 if (((row+1) & 0xf) == 0) {
638 rect.left = 0L; 638 rect.left = 0L;
639 rect.top = (LONG)lastrow; 639 rect.top = (LONG)lastrow;
640 rect.right = (LONG)image_width; /* possibly off by one? */ 640 rect.right = (LONG)image_width; /* possibly off by one? */
641 rect.bottom = (LONG)lastrow + 16L; /* possibly off by one? */ 641 rect.bottom = (LONG)lastrow + 16L; /* possibly off by one? */
642 InvalidateRect(global_hwnd, &rect, FALSE); 642 InvalidateRect(global_hwnd, &rect, FALSE);
643 UpdateWindow(global_hwnd); /* similar to XFlush() */ 643 UpdateWindow(global_hwnd); /* similar to XFlush() */
644 lastrow = row + 1; 644 lastrow = row + 1;
645 } 645 }
646 } 646 }
647 647
648 Trace((stderr, "calling final image-flush routine\n")) 648 Trace((stderr, "calling final image-flush routine\n"))
649 if (lastrow < image_height) { 649 if (lastrow < image_height) {
650 rect.left = 0L; 650 rect.left = 0L;
651 rect.top = (LONG)lastrow; 651 rect.top = (LONG)lastrow;
652 rect.right = (LONG)image_width; /* possibly off by one? */ 652 rect.right = (LONG)image_width; /* possibly off by one? */
653 rect.bottom = (LONG)image_height; /* possibly off by one? */ 653 rect.bottom = (LONG)image_height; /* possibly off by one? */
654 InvalidateRect(global_hwnd, &rect, FALSE); 654 InvalidateRect(global_hwnd, &rect, FALSE);
655 UpdateWindow(global_hwnd); /* similar to XFlush() */ 655 UpdateWindow(global_hwnd); /* similar to XFlush() */
656 } 656 }
657 657
658/* 658/*
659 last param determines whether or not background is wiped before paint 659 last param determines whether or not background is wiped before paint
660 InvalidateRect(global_hwnd, NULL, TRUE); 660 InvalidateRect(global_hwnd, NULL, TRUE);
661 UpdateWindow(global_hwnd); 661 UpdateWindow(global_hwnd);
662 */ 662 */
663 663
664 return 0; 664 return 0;
665} 665}
666 666
667 667
668 668
669 669
670 670
671static void rpng_win_cleanup() 671static void rpng_win_cleanup()
672{ 672{
673 if (image_data) { 673 if (image_data) {
674 free(image_data); 674 free(image_data);
675 image_data = NULL; 675 image_data = NULL;
676 } 676 }
677 677
678 if (dib) { 678 if (dib) {
679 free(dib); 679 free(dib);
680 dib = NULL; 680 dib = NULL;
681 } 681 }
682} 682}
683 683
684 684
685 685
686 686
687 687
688LRESULT CALLBACK rpng_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP) 688LRESULT CALLBACK rpng_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)
689{ 689{
690 HDC hdc; 690 HDC hdc;
691 PAINTSTRUCT ps; 691 PAINTSTRUCT ps;
692 int rc; 692 int rc;
693 693
694 switch (iMsg) { 694 switch (iMsg) {
695 case WM_CREATE: 695 case WM_CREATE:
696 /* one-time processing here, if any */ 696 /* one-time processing here, if any */
697 return 0; 697 return 0;
698 698
699 case WM_PAINT: 699 case WM_PAINT:
700 hdc = BeginPaint(hwnd, &ps); 700 hdc = BeginPaint(hwnd, &ps);
701 /* dest */ 701 /* dest */
702 rc = StretchDIBits(hdc, 0, 0, image_width, image_height, 702 rc = StretchDIBits(hdc, 0, 0, image_width, image_height,
703 /* source */ 703 /* source */
704 0, 0, image_width, image_height, 704 0, 0, image_width, image_height,
705 wimage_data, (BITMAPINFO *)bmih, 705 wimage_data, (BITMAPINFO *)bmih,
706 /* iUsage: no clue */ 706 /* iUsage: no clue */
707 0, SRCCOPY); 707 0, SRCCOPY);
708 EndPaint(hwnd, &ps); 708 EndPaint(hwnd, &ps);
709 return 0; 709 return 0;
710 710
711 /* wait for the user to tell us when to quit */ 711 /* wait for the user to tell us when to quit */
712 case WM_CHAR: 712 case WM_CHAR:
713 switch (wP) { /* only need one, so ignore repeat count */ 713 switch (wP) { /* only need one, so ignore repeat count */
714 case 'q': 714 case 'q':
715 case 'Q': 715 case 'Q':
716 case 0x1B: /* Esc key */ 716 case 0x1B: /* Esc key */
717 PostQuitMessage(0); 717 PostQuitMessage(0);
718 } 718 }
719 return 0; 719 return 0;
720 720
721 case WM_LBUTTONDOWN: /* another way of quitting */ 721 case WM_LBUTTONDOWN: /* another way of quitting */
722 case WM_DESTROY: 722 case WM_DESTROY:
723 PostQuitMessage(0); 723 PostQuitMessage(0);
724 return 0; 724 return 0;
725 } 725 }
726 726
727 return DefWindowProc(hwnd, iMsg, wP, lP); 727 return DefWindowProc(hwnd, iMsg, wP, lP);
728} 728}
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-x.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-x.c
index fc8be88..6d10e1b 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-x.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng-x.c
@@ -1,904 +1,904 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 rpng - simple PNG display program rpng-x.c 3 rpng - simple PNG display program rpng-x.c
4 4
5 This program decodes and displays PNG images, with gamma correction and 5 This program decodes and displays PNG images, with gamma correction and
6 optionally with a user-specified background color (in case the image has 6 optionally with a user-specified background color (in case the image has
7 transparency). It is very nearly the most basic PNG viewer possible. 7 transparency). It is very nearly the most basic PNG viewer possible.
8 This version is for the X Window System (tested by author under Unix and 8 This version is for the X Window System (tested by author under Unix and
9 by Martin Zinser under OpenVMS; may work under OS/2 with some tweaking). 9 by Martin Zinser under OpenVMS; may work under OS/2 with some tweaking).
10 10
11 to do: 11 to do:
12 - 8-bit (colormapped) X support 12 - 8-bit (colormapped) X support
13 - use %.1023s to simplify truncation of title-bar string? 13 - use %.1023s to simplify truncation of title-bar string?
14 14
15 --------------------------------------------------------------------------- 15 ---------------------------------------------------------------------------
16 16
17 Changelog: 17 Changelog:
18 - 1.01: initial public release 18 - 1.01: initial public release
19 - 1.02: modified to allow abbreviated options; fixed long/ulong mis- 19 - 1.02: modified to allow abbreviated options; fixed long/ulong mis-
20 match; switched to png_jmpbuf() macro 20 match; switched to png_jmpbuf() macro
21 - 1.10: added support for non-default visuals; fixed X pixel-conversion 21 - 1.10: added support for non-default visuals; fixed X pixel-conversion
22 - 1.11: added extra set of parentheses to png_jmpbuf() macro; fixed 22 - 1.11: added extra set of parentheses to png_jmpbuf() macro; fixed
23 command-line parsing bug 23 command-line parsing bug
24 - 1.12: fixed some small X memory leaks (thanks to François Petitjean) 24 - 1.12: fixed some small X memory leaks (thanks to François Petitjean)
25 - 1.13: fixed XFreeGC() crash bug (thanks to Patrick Welche) 25 - 1.13: fixed XFreeGC() crash bug (thanks to Patrick Welche)
26 - 1.14: added support for X resources (thanks to Gerhard Niklasch) 26 - 1.14: added support for X resources (thanks to Gerhard Niklasch)
27 - 2.00: dual-licensed (added GNU GPL) 27 - 2.00: dual-licensed (added GNU GPL)
28 - 2.01: fixed improper display of usage screen on PNG error(s) 28 - 2.01: fixed improper display of usage screen on PNG error(s)
29 29
30 --------------------------------------------------------------------------- 30 ---------------------------------------------------------------------------
31 31
32 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. 32 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved.
33 33
34 This software is provided "as is," without warranty of any kind, 34 This software is provided "as is," without warranty of any kind,
35 express or implied. In no event shall the author or contributors 35 express or implied. In no event shall the author or contributors
36 be held liable for any damages arising in any way from the use of 36 be held liable for any damages arising in any way from the use of
37 this software. 37 this software.
38 38
39 The contents of this file are DUAL-LICENSED. You may modify and/or 39 The contents of this file are DUAL-LICENSED. You may modify and/or
40 redistribute this software according to the terms of one of the 40 redistribute this software according to the terms of one of the
41 following two licenses (at your option): 41 following two licenses (at your option):
42 42
43 43
44 LICENSE 1 ("BSD-like with advertising clause"): 44 LICENSE 1 ("BSD-like with advertising clause"):
45 45
46 Permission is granted to anyone to use this software for any purpose, 46 Permission is granted to anyone to use this software for any purpose,
47 including commercial applications, and to alter it and redistribute 47 including commercial applications, and to alter it and redistribute
48 it freely, subject to the following restrictions: 48 it freely, subject to the following restrictions:
49 49
50 1. Redistributions of source code must retain the above copyright 50 1. Redistributions of source code must retain the above copyright
51 notice, disclaimer, and this list of conditions. 51 notice, disclaimer, and this list of conditions.
52 2. Redistributions in binary form must reproduce the above copyright 52 2. Redistributions in binary form must reproduce the above copyright
53 notice, disclaimer, and this list of conditions in the documenta- 53 notice, disclaimer, and this list of conditions in the documenta-
54 tion and/or other materials provided with the distribution. 54 tion and/or other materials provided with the distribution.
55 3. All advertising materials mentioning features or use of this 55 3. All advertising materials mentioning features or use of this
56 software must display the following acknowledgment: 56 software must display the following acknowledgment:
57 57
58 This product includes software developed by Greg Roelofs 58 This product includes software developed by Greg Roelofs
59 and contributors for the book, "PNG: The Definitive Guide," 59 and contributors for the book, "PNG: The Definitive Guide,"
60 published by O'Reilly and Associates. 60 published by O'Reilly and Associates.
61 61
62 62
63 LICENSE 2 (GNU GPL v2 or later): 63 LICENSE 2 (GNU GPL v2 or later):
64 64
65 This program is free software; you can redistribute it and/or modify 65 This program is free software; you can redistribute it and/or modify
66 it under the terms of the GNU General Public License as published by 66 it under the terms of the GNU General Public License as published by
67 the Free Software Foundation; either version 2 of the License, or 67 the Free Software Foundation; either version 2 of the License, or
68 (at your option) any later version. 68 (at your option) any later version.
69 69
70 This program is distributed in the hope that it will be useful, 70 This program is distributed in the hope that it will be useful,
71 but WITHOUT ANY WARRANTY; without even the implied warranty of 71 but WITHOUT ANY WARRANTY; without even the implied warranty of
72 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 72 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
73 GNU General Public License for more details. 73 GNU General Public License for more details.
74 74
75 You should have received a copy of the GNU General Public License 75 You should have received a copy of the GNU General Public License
76 along with this program; if not, write to the Free Software Foundation, 76 along with this program; if not, write to the Free Software Foundation,
77 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 77 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
78 78
79 ---------------------------------------------------------------------------*/ 79 ---------------------------------------------------------------------------*/
80 80
81#define PROGNAME "rpng-x" 81#define PROGNAME "rpng-x"
82#define LONGNAME "Simple PNG Viewer for X" 82#define LONGNAME "Simple PNG Viewer for X"
83#define VERSION "2.01 of 16 March 2008" 83#define VERSION "2.01 of 16 March 2008"
84#define RESNAME "rpng" /* our X resource application name */ 84#define RESNAME "rpng" /* our X resource application name */
85#define RESCLASS "Rpng" /* our X resource class name */ 85#define RESCLASS "Rpng" /* our X resource class name */
86 86
87#include <stdio.h> 87#include <stdio.h>
88#include <stdlib.h> 88#include <stdlib.h>
89#include <string.h> 89#include <string.h>
90#include <time.h> 90#include <time.h>
91#include <X11/Xlib.h> 91#include <X11/Xlib.h>
92#include <X11/Xutil.h> 92#include <X11/Xutil.h>
93#include <X11/Xos.h> 93#include <X11/Xos.h>
94#include <X11/keysym.h> 94#include <X11/keysym.h>
95 95
96/* #define DEBUG : this enables the Trace() macros */ 96/* #define DEBUG : this enables the Trace() macros */
97 97
98#include "readpng.h" /* typedefs, common macros, readpng prototypes */ 98#include "readpng.h" /* typedefs, common macros, readpng prototypes */
99 99
100 100
101/* could just include png.h, but this macro is the only thing we need 101/* could just include png.h, but this macro is the only thing we need
102 * (name and typedefs changed to local versions); note that side effects 102 * (name and typedefs changed to local versions); note that side effects
103 * only happen with alpha (which could easily be avoided with 103 * only happen with alpha (which could easily be avoided with
104 * "ush acopy = (alpha);") */ 104 * "ush acopy = (alpha);") */
105 105
106#define alpha_composite(composite, fg, alpha, bg) { \ 106#define alpha_composite(composite, fg, alpha, bg) { \
107 ush temp = ((ush)(fg)*(ush)(alpha) + \ 107 ush temp = ((ush)(fg)*(ush)(alpha) + \
108 (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ 108 (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
109 (composite) = (uch)((temp + (temp >> 8)) >> 8); \ 109 (composite) = (uch)((temp + (temp >> 8)) >> 8); \
110} 110}
111 111
112 112
113/* local prototypes */ 113/* local prototypes */
114static int rpng_x_create_window(void); 114static int rpng_x_create_window(void);
115static int rpng_x_display_image(void); 115static int rpng_x_display_image(void);
116static void rpng_x_cleanup(void); 116static void rpng_x_cleanup(void);
117static int rpng_x_msb(ulg u32val); 117static int rpng_x_msb(ulg u32val);
118 118
119 119
120static char titlebar[1024], *window_name = titlebar; 120static char titlebar[1024], *window_name = titlebar;
121static char *appname = LONGNAME; 121static char *appname = LONGNAME;
122static char *icon_name = PROGNAME; 122static char *icon_name = PROGNAME;
123static char *res_name = RESNAME; 123static char *res_name = RESNAME;
124static char *res_class = RESCLASS; 124static char *res_class = RESCLASS;
125static char *filename; 125static char *filename;
126static FILE *infile; 126static FILE *infile;
127 127
128static char *bgstr; 128static char *bgstr;
129static uch bg_red=0, bg_green=0, bg_blue=0; 129static uch bg_red=0, bg_green=0, bg_blue=0;
130 130
131static double display_exponent; 131static double display_exponent;
132 132
133static ulg image_width, image_height, image_rowbytes; 133static ulg image_width, image_height, image_rowbytes;
134static int image_channels; 134static int image_channels;
135static uch *image_data; 135static uch *image_data;
136 136
137/* X-specific variables */ 137/* X-specific variables */
138static char *displayname; 138static char *displayname;
139static XImage *ximage; 139static XImage *ximage;
140static Display *display; 140static Display *display;
141static int depth; 141static int depth;
142static Visual *visual; 142static Visual *visual;
143static XVisualInfo *visual_list; 143static XVisualInfo *visual_list;
144static int RShift, GShift, BShift; 144static int RShift, GShift, BShift;
145static ulg RMask, GMask, BMask; 145static ulg RMask, GMask, BMask;
146static Window window; 146static Window window;
147static GC gc; 147static GC gc;
148static Colormap colormap; 148static Colormap colormap;
149 149
150static int have_nondefault_visual = FALSE; 150static int have_nondefault_visual = FALSE;
151static int have_colormap = FALSE; 151static int have_colormap = FALSE;
152static int have_window = FALSE; 152static int have_window = FALSE;
153static int have_gc = FALSE; 153static int have_gc = FALSE;
154/* 154/*
155ulg numcolors=0, pixels[256]; 155ulg numcolors=0, pixels[256];
156ush reds[256], greens[256], blues[256]; 156ush reds[256], greens[256], blues[256];
157 */ 157 */
158 158
159 159
160 160
161 161
162int main(int argc, char **argv) 162int main(int argc, char **argv)
163{ 163{
164#ifdef sgi 164#ifdef sgi
165 char tmpline[80]; 165 char tmpline[80];
166#endif 166#endif
167 char *p; 167 char *p;
168 int rc, alen, flen; 168 int rc, alen, flen;
169 int error = 0; 169 int error = 0;
170 int have_bg = FALSE; 170 int have_bg = FALSE;
171 double LUT_exponent; /* just the lookup table */ 171 double LUT_exponent; /* just the lookup table */
172 double CRT_exponent = 2.2; /* just the monitor */ 172 double CRT_exponent = 2.2; /* just the monitor */
173 double default_display_exponent; /* whole display system */ 173 double default_display_exponent; /* whole display system */
174 XEvent e; 174 XEvent e;
175 KeySym k; 175 KeySym k;
176 176
177 177
178 displayname = (char *)NULL; 178 displayname = (char *)NULL;
179 filename = (char *)NULL; 179 filename = (char *)NULL;
180 180
181 181
182 /* First set the default value for our display-system exponent, i.e., 182 /* First set the default value for our display-system exponent, i.e.,
183 * the product of the CRT exponent and the exponent corresponding to 183 * the product of the CRT exponent and the exponent corresponding to
184 * the frame-buffer's lookup table (LUT), if any. This is not an 184 * the frame-buffer's lookup table (LUT), if any. This is not an
185 * exhaustive list of LUT values (e.g., OpenStep has a lot of weird 185 * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
186 * ones), but it should cover 99% of the current possibilities. */ 186 * ones), but it should cover 99% of the current possibilities. */
187 187
188#if defined(NeXT) 188#if defined(NeXT)
189 LUT_exponent = 1.0 / 2.2; 189 LUT_exponent = 1.0 / 2.2;
190 /* 190 /*
191 if (some_next_function_that_returns_gamma(&next_gamma)) 191 if (some_next_function_that_returns_gamma(&next_gamma))
192 LUT_exponent = 1.0 / next_gamma; 192 LUT_exponent = 1.0 / next_gamma;
193 */ 193 */
194#elif defined(sgi) 194#elif defined(sgi)
195 LUT_exponent = 1.0 / 1.7; 195 LUT_exponent = 1.0 / 1.7;
196 /* there doesn't seem to be any documented function to get the 196 /* there doesn't seem to be any documented function to get the
197 * "gamma" value, so we do it the hard way */ 197 * "gamma" value, so we do it the hard way */
198 infile = fopen("/etc/config/system.glGammaVal", "r"); 198 infile = fopen("/etc/config/system.glGammaVal", "r");
199 if (infile) { 199 if (infile) {
200 double sgi_gamma; 200 double sgi_gamma;
201 201
202 fgets(tmpline, 80, infile); 202 fgets(tmpline, 80, infile);
203 fclose(infile); 203 fclose(infile);
204 sgi_gamma = atof(tmpline); 204 sgi_gamma = atof(tmpline);
205 if (sgi_gamma > 0.0) 205 if (sgi_gamma > 0.0)
206 LUT_exponent = 1.0 / sgi_gamma; 206 LUT_exponent = 1.0 / sgi_gamma;
207 } 207 }
208#elif defined(Macintosh) 208#elif defined(Macintosh)
209 LUT_exponent = 1.8 / 2.61; 209 LUT_exponent = 1.8 / 2.61;
210 /* 210 /*
211 if (some_mac_function_that_returns_gamma(&mac_gamma)) 211 if (some_mac_function_that_returns_gamma(&mac_gamma))
212 LUT_exponent = mac_gamma / 2.61; 212 LUT_exponent = mac_gamma / 2.61;
213 */ 213 */
214#else 214#else
215 LUT_exponent = 1.0; /* assume no LUT: most PCs */ 215 LUT_exponent = 1.0; /* assume no LUT: most PCs */
216#endif 216#endif
217 217
218 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ 218 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
219 default_display_exponent = LUT_exponent * CRT_exponent; 219 default_display_exponent = LUT_exponent * CRT_exponent;
220 220
221 221
222 /* If the user has set the SCREEN_GAMMA environment variable as suggested 222 /* If the user has set the SCREEN_GAMMA environment variable as suggested
223 * (somewhat imprecisely) in the libpng documentation, use that; otherwise 223 * (somewhat imprecisely) in the libpng documentation, use that; otherwise
224 * use the default value we just calculated. Either way, the user may 224 * use the default value we just calculated. Either way, the user may
225 * override this via a command-line option. */ 225 * override this via a command-line option. */
226 226
227 if ((p = getenv("SCREEN_GAMMA")) != NULL) 227 if ((p = getenv("SCREEN_GAMMA")) != NULL)
228 display_exponent = atof(p); 228 display_exponent = atof(p);
229 else 229 else
230 display_exponent = default_display_exponent; 230 display_exponent = default_display_exponent;
231 231
232 232
233 /* Now parse the command line for options and the PNG filename. */ 233 /* Now parse the command line for options and the PNG filename. */
234 234
235 while (*++argv && !error) { 235 while (*++argv && !error) {
236 if (!strncmp(*argv, "-display", 2)) { 236 if (!strncmp(*argv, "-display", 2)) {
237 if (!*++argv) 237 if (!*++argv)
238 ++error; 238 ++error;
239 else 239 else
240 displayname = *argv; 240 displayname = *argv;
241 } else if (!strncmp(*argv, "-gamma", 2)) { 241 } else if (!strncmp(*argv, "-gamma", 2)) {
242 if (!*++argv) 242 if (!*++argv)
243 ++error; 243 ++error;
244 else { 244 else {
245 display_exponent = atof(*argv); 245 display_exponent = atof(*argv);
246 if (display_exponent <= 0.0) 246 if (display_exponent <= 0.0)
247 ++error; 247 ++error;
248 } 248 }
249 } else if (!strncmp(*argv, "-bgcolor", 2)) { 249 } else if (!strncmp(*argv, "-bgcolor", 2)) {
250 if (!*++argv) 250 if (!*++argv)
251 ++error; 251 ++error;
252 else { 252 else {
253 bgstr = *argv; 253 bgstr = *argv;
254 if (strlen(bgstr) != 7 || bgstr[0] != '#') 254 if (strlen(bgstr) != 7 || bgstr[0] != '#')
255 ++error; 255 ++error;
256 else 256 else
257 have_bg = TRUE; 257 have_bg = TRUE;
258 } 258 }
259 } else { 259 } else {
260 if (**argv != '-') { 260 if (**argv != '-') {
261 filename = *argv; 261 filename = *argv;
262 if (argv[1]) /* shouldn't be any more args after filename */ 262 if (argv[1]) /* shouldn't be any more args after filename */
263 ++error; 263 ++error;
264 } else 264 } else
265 ++error; /* not expecting any other options */ 265 ++error; /* not expecting any other options */
266 } 266 }
267 } 267 }
268 268
269 if (!filename) 269 if (!filename)
270 ++error; 270 ++error;
271 271
272 272
273 /* print usage screen if any errors up to this point */ 273 /* print usage screen if any errors up to this point */
274 274
275 if (error) { 275 if (error) {
276 fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); 276 fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
277 readpng_version_info(); 277 readpng_version_info();
278 fprintf(stderr, "\n" 278 fprintf(stderr, "\n"
279 "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n" 279 "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n"
280 " xdpy\tname of the target X display (e.g., ``hostname:0'')\n" 280 " xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
281 " exp \ttransfer-function exponent (``gamma'') of the display\n" 281 " exp \ttransfer-function exponent (``gamma'') of the display\n"
282 "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" 282 "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
283 "\t\t to the product of the lookup-table exponent (varies)\n" 283 "\t\t to the product of the lookup-table exponent (varies)\n"
284 "\t\t and the CRT exponent (usually 2.2); must be positive\n" 284 "\t\t and the CRT exponent (usually 2.2); must be positive\n"
285 " bg \tdesired background color in 7-character hex RGB format\n" 285 " bg \tdesired background color in 7-character hex RGB format\n"
286 "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" 286 "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
287 "\t\t used with transparent images\n" 287 "\t\t used with transparent images\n"
288 "\nPress Q, Esc or mouse button 1 (within image window, after image\n" 288 "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
289 "is displayed) to quit.\n" 289 "is displayed) to quit.\n"
290 "\n", PROGNAME, default_display_exponent); 290 "\n", PROGNAME, default_display_exponent);
291 exit(1); 291 exit(1);
292 } 292 }
293 293
294 294
295 if (!(infile = fopen(filename, "rb"))) { 295 if (!(infile = fopen(filename, "rb"))) {
296 fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); 296 fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
297 ++error; 297 ++error;
298 } else { 298 } else {
299 if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) { 299 if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
300 switch (rc) { 300 switch (rc) {
301 case 1: 301 case 1:
302 fprintf(stderr, PROGNAME 302 fprintf(stderr, PROGNAME
303 ": [%s] is not a PNG file: incorrect signature\n", 303 ": [%s] is not a PNG file: incorrect signature\n",
304 filename); 304 filename);
305 break; 305 break;
306 case 2: 306 case 2:
307 fprintf(stderr, PROGNAME 307 fprintf(stderr, PROGNAME
308 ": [%s] has bad IHDR (libpng longjmp)\n", filename); 308 ": [%s] has bad IHDR (libpng longjmp)\n", filename);
309 break; 309 break;
310 case 4: 310 case 4:
311 fprintf(stderr, PROGNAME ": insufficient memory\n"); 311 fprintf(stderr, PROGNAME ": insufficient memory\n");
312 break; 312 break;
313 default: 313 default:
314 fprintf(stderr, PROGNAME 314 fprintf(stderr, PROGNAME
315 ": unknown readpng_init() error\n"); 315 ": unknown readpng_init() error\n");
316 break; 316 break;
317 } 317 }
318 ++error; 318 ++error;
319 } else { 319 } else {
320 display = XOpenDisplay(displayname); 320 display = XOpenDisplay(displayname);
321 if (!display) { 321 if (!display) {
322 readpng_cleanup(TRUE); 322 readpng_cleanup(TRUE);
323 fprintf(stderr, PROGNAME ": can't open X display [%s]\n", 323 fprintf(stderr, PROGNAME ": can't open X display [%s]\n",
324 displayname? displayname : "default"); 324 displayname? displayname : "default");
325 ++error; 325 ++error;
326 } 326 }
327 } 327 }
328 if (error) 328 if (error)
329 fclose(infile); 329 fclose(infile);
330 } 330 }
331 331
332 332
333 if (error) { 333 if (error) {
334 fprintf(stderr, PROGNAME ": aborting.\n"); 334 fprintf(stderr, PROGNAME ": aborting.\n");
335 exit(2); 335 exit(2);
336 } 336 }
337 337
338 338
339 /* set the title-bar string, but make sure buffer doesn't overflow */ 339 /* set the title-bar string, but make sure buffer doesn't overflow */
340 340
341 alen = strlen(appname); 341 alen = strlen(appname);
342 flen = strlen(filename); 342 flen = strlen(filename);
343 if (alen + flen + 3 > 1023) 343 if (alen + flen + 3 > 1023)
344 sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); 344 sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
345 else 345 else
346 sprintf(titlebar, "%s: %s", appname, filename); 346 sprintf(titlebar, "%s: %s", appname, filename);
347 347
348 348
349 /* if the user didn't specify a background color on the command line, 349 /* if the user didn't specify a background color on the command line,
350 * check for one in the PNG file--if not, the initialized values of 0 350 * check for one in the PNG file--if not, the initialized values of 0
351 * (black) will be used */ 351 * (black) will be used */
352 352
353 if (have_bg) { 353 if (have_bg) {
354 unsigned r, g, b; /* this approach quiets compiler warnings */ 354 unsigned r, g, b; /* this approach quiets compiler warnings */
355 355
356 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); 356 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
357 bg_red = (uch)r; 357 bg_red = (uch)r;
358 bg_green = (uch)g; 358 bg_green = (uch)g;
359 bg_blue = (uch)b; 359 bg_blue = (uch)b;
360 } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) { 360 } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) {
361 readpng_cleanup(TRUE); 361 readpng_cleanup(TRUE);
362 fprintf(stderr, PROGNAME 362 fprintf(stderr, PROGNAME
363 ": libpng error while checking for background color\n"); 363 ": libpng error while checking for background color\n");
364 exit(2); 364 exit(2);
365 } 365 }
366 366
367 367
368 /* do the basic X initialization stuff, make the window and fill it 368 /* do the basic X initialization stuff, make the window and fill it
369 * with the background color */ 369 * with the background color */
370 370
371 if (rpng_x_create_window()) 371 if (rpng_x_create_window())
372 exit(2); 372 exit(2);
373 373
374 374
375 /* decode the image, all at once */ 375 /* decode the image, all at once */
376 376
377 Trace((stderr, "calling readpng_get_image()\n")) 377 Trace((stderr, "calling readpng_get_image()\n"))
378 image_data = readpng_get_image(display_exponent, &image_channels, 378 image_data = readpng_get_image(display_exponent, &image_channels,
379 &image_rowbytes); 379 &image_rowbytes);
380 Trace((stderr, "done with readpng_get_image()\n")) 380 Trace((stderr, "done with readpng_get_image()\n"))
381 381
382 382
383 /* done with PNG file, so clean up to minimize memory usage (but do NOT 383 /* done with PNG file, so clean up to minimize memory usage (but do NOT
384 * nuke image_data!) */ 384 * nuke image_data!) */
385 385
386 readpng_cleanup(FALSE); 386 readpng_cleanup(FALSE);
387 fclose(infile); 387 fclose(infile);
388 388
389 if (!image_data) { 389 if (!image_data) {
390 fprintf(stderr, PROGNAME ": unable to decode PNG image\n"); 390 fprintf(stderr, PROGNAME ": unable to decode PNG image\n");
391 exit(3); 391 exit(3);
392 } 392 }
393 393
394 394
395 /* display image (composite with background if requested) */ 395 /* display image (composite with background if requested) */
396 396
397 Trace((stderr, "calling rpng_x_display_image()\n")) 397 Trace((stderr, "calling rpng_x_display_image()\n"))
398 if (rpng_x_display_image()) { 398 if (rpng_x_display_image()) {
399 free(image_data); 399 free(image_data);
400 exit(4); 400 exit(4);
401 } 401 }
402 Trace((stderr, "done with rpng_x_display_image()\n")) 402 Trace((stderr, "done with rpng_x_display_image()\n"))
403 403
404 404
405 /* wait for the user to tell us when to quit */ 405 /* wait for the user to tell us when to quit */
406 406
407 printf( 407 printf(
408 "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); 408 "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n");
409 fflush(stdout); 409 fflush(stdout);
410 410
411 do 411 do
412 XNextEvent(display, &e); 412 XNextEvent(display, &e);
413 while (!(e.type == ButtonPress && e.xbutton.button == Button1) && 413 while (!(e.type == ButtonPress && e.xbutton.button == Button1) &&
414 !(e.type == KeyPress && /* v--- or 1 for shifted keys */ 414 !(e.type == KeyPress && /* v--- or 1 for shifted keys */
415 ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) )); 415 ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) ));
416 416
417 417
418 /* OK, we're done: clean up all image and X resources and go away */ 418 /* OK, we're done: clean up all image and X resources and go away */
419 419
420 rpng_x_cleanup(); 420 rpng_x_cleanup();
421 421
422 return 0; 422 return 0;
423} 423}
424 424
425 425
426 426
427 427
428 428
429static int rpng_x_create_window(void) 429static int rpng_x_create_window(void)
430{ 430{
431 uch *xdata; 431 uch *xdata;
432 int need_colormap = FALSE; 432 int need_colormap = FALSE;
433 int screen, pad; 433 int screen, pad;
434 ulg bg_pixel = 0L; 434 ulg bg_pixel = 0L;
435 ulg attrmask; 435 ulg attrmask;
436 Window root; 436 Window root;
437 XEvent e; 437 XEvent e;
438 XGCValues gcvalues; 438 XGCValues gcvalues;
439 XSetWindowAttributes attr; 439 XSetWindowAttributes attr;
440 XTextProperty windowName, *pWindowName = &windowName; 440 XTextProperty windowName, *pWindowName = &windowName;
441 XTextProperty iconName, *pIconName = &iconName; 441 XTextProperty iconName, *pIconName = &iconName;
442 XVisualInfo visual_info; 442 XVisualInfo visual_info;
443 XSizeHints *size_hints; 443 XSizeHints *size_hints;
444 XWMHints *wm_hints; 444 XWMHints *wm_hints;
445 XClassHint *class_hints; 445 XClassHint *class_hints;
446 446
447 447
448 screen = DefaultScreen(display); 448 screen = DefaultScreen(display);
449 depth = DisplayPlanes(display, screen); 449 depth = DisplayPlanes(display, screen);
450 root = RootWindow(display, screen); 450 root = RootWindow(display, screen);
451 451
452#ifdef DEBUG 452#ifdef DEBUG
453 XSynchronize(display, True); 453 XSynchronize(display, True);
454#endif 454#endif
455 455
456#if 0 456#if 0
457/* GRR: add 8-bit support */ 457/* GRR: add 8-bit support */
458 if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) { 458 if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) {
459 fprintf(stderr, 459 fprintf(stderr,
460 "screen depth %d not supported (only 16-, 24- or 32-bit TrueColor)\n", 460 "screen depth %d not supported (only 16-, 24- or 32-bit TrueColor)\n",
461 depth); 461 depth);
462 return 2; 462 return 2;
463 } 463 }
464 464
465 XMatchVisualInfo(display, screen, depth, 465 XMatchVisualInfo(display, screen, depth,
466 (depth == 8)? PseudoColor : TrueColor, &visual_info); 466 (depth == 8)? PseudoColor : TrueColor, &visual_info);
467 visual = visual_info.visual; 467 visual = visual_info.visual;
468#else 468#else
469 if (depth != 16 && depth != 24 && depth != 32) { 469 if (depth != 16 && depth != 24 && depth != 32) {
470 int visuals_matched = 0; 470 int visuals_matched = 0;
471 471
472 Trace((stderr, "default depth is %d: checking other visuals\n", 472 Trace((stderr, "default depth is %d: checking other visuals\n",
473 depth)) 473 depth))
474 474
475 /* 24-bit first */ 475 /* 24-bit first */
476 visual_info.screen = screen; 476 visual_info.screen = screen;
477 visual_info.depth = 24; 477 visual_info.depth = 24;
478 visual_list = XGetVisualInfo(display, 478 visual_list = XGetVisualInfo(display,
479 VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched); 479 VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
480 if (visuals_matched == 0) { 480 if (visuals_matched == 0) {
481/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */ 481/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
482 fprintf(stderr, "default screen depth %d not supported, and no" 482 fprintf(stderr, "default screen depth %d not supported, and no"
483 " 24-bit visuals found\n", depth); 483 " 24-bit visuals found\n", depth);
484 return 2; 484 return 2;
485 } 485 }
486 Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n", 486 Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
487 visuals_matched)) 487 visuals_matched))
488 visual = visual_list[0].visual; 488 visual = visual_list[0].visual;
489 depth = visual_list[0].depth; 489 depth = visual_list[0].depth;
490/* 490/*
491 colormap_size = visual_list[0].colormap_size; 491 colormap_size = visual_list[0].colormap_size;
492 visual_class = visual->class; 492 visual_class = visual->class;
493 visualID = XVisualIDFromVisual(visual); 493 visualID = XVisualIDFromVisual(visual);
494 */ 494 */
495 have_nondefault_visual = TRUE; 495 have_nondefault_visual = TRUE;
496 need_colormap = TRUE; 496 need_colormap = TRUE;
497 } else { 497 } else {
498 XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info); 498 XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
499 visual = visual_info.visual; 499 visual = visual_info.visual;
500 } 500 }
501#endif 501#endif
502 502
503 RMask = visual->red_mask; 503 RMask = visual->red_mask;
504 GMask = visual->green_mask; 504 GMask = visual->green_mask;
505 BMask = visual->blue_mask; 505 BMask = visual->blue_mask;
506 506
507/* GRR: add/check 8-bit support */ 507/* GRR: add/check 8-bit support */
508 if (depth == 8 || need_colormap) { 508 if (depth == 8 || need_colormap) {
509 colormap = XCreateColormap(display, root, visual, AllocNone); 509 colormap = XCreateColormap(display, root, visual, AllocNone);
510 if (!colormap) { 510 if (!colormap) {
511 fprintf(stderr, "XCreateColormap() failed\n"); 511 fprintf(stderr, "XCreateColormap() failed\n");
512 return 2; 512 return 2;
513 } 513 }
514 have_colormap = TRUE; 514 have_colormap = TRUE;
515 } 515 }
516 if (depth == 15 || depth == 16) { 516 if (depth == 15 || depth == 16) {
517 RShift = 15 - rpng_x_msb(RMask); /* these are right-shifts */ 517 RShift = 15 - rpng_x_msb(RMask); /* these are right-shifts */
518 GShift = 15 - rpng_x_msb(GMask); 518 GShift = 15 - rpng_x_msb(GMask);
519 BShift = 15 - rpng_x_msb(BMask); 519 BShift = 15 - rpng_x_msb(BMask);
520 } else if (depth > 16) { 520 } else if (depth > 16) {
521#define NO_24BIT_MASKS 521#define NO_24BIT_MASKS
522#ifdef NO_24BIT_MASKS 522#ifdef NO_24BIT_MASKS
523 RShift = rpng_x_msb(RMask) - 7; /* these are left-shifts */ 523 RShift = rpng_x_msb(RMask) - 7; /* these are left-shifts */
524 GShift = rpng_x_msb(GMask) - 7; 524 GShift = rpng_x_msb(GMask) - 7;
525 BShift = rpng_x_msb(BMask) - 7; 525 BShift = rpng_x_msb(BMask) - 7;
526#else 526#else
527 RShift = 7 - rpng_x_msb(RMask); /* these are right-shifts, too */ 527 RShift = 7 - rpng_x_msb(RMask); /* these are right-shifts, too */
528 GShift = 7 - rpng_x_msb(GMask); 528 GShift = 7 - rpng_x_msb(GMask);
529 BShift = 7 - rpng_x_msb(BMask); 529 BShift = 7 - rpng_x_msb(BMask);
530#endif 530#endif
531 } 531 }
532 if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) { 532 if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
533 fprintf(stderr, "rpng internal logic error: negative X shift(s)!\n"); 533 fprintf(stderr, "rpng internal logic error: negative X shift(s)!\n");
534 return 2; 534 return 2;
535 } 535 }
536 536
537/*--------------------------------------------------------------------------- 537/*---------------------------------------------------------------------------
538 Finally, create the window. 538 Finally, create the window.
539 ---------------------------------------------------------------------------*/ 539 ---------------------------------------------------------------------------*/
540 540
541 attr.backing_store = Always; 541 attr.backing_store = Always;
542 attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask; 542 attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
543 attrmask = CWBackingStore | CWEventMask; 543 attrmask = CWBackingStore | CWEventMask;
544 if (have_nondefault_visual) { 544 if (have_nondefault_visual) {
545 attr.colormap = colormap; 545 attr.colormap = colormap;
546 attr.background_pixel = 0; 546 attr.background_pixel = 0;
547 attr.border_pixel = 1; 547 attr.border_pixel = 1;
548 attrmask |= CWColormap | CWBackPixel | CWBorderPixel; 548 attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
549 } 549 }
550 550
551 window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0, 551 window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0,
552 depth, InputOutput, visual, attrmask, &attr); 552 depth, InputOutput, visual, attrmask, &attr);
553 553
554 if (window == None) { 554 if (window == None) {
555 fprintf(stderr, "XCreateWindow() failed\n"); 555 fprintf(stderr, "XCreateWindow() failed\n");
556 return 2; 556 return 2;
557 } else 557 } else
558 have_window = TRUE; 558 have_window = TRUE;
559 559
560 if (depth == 8) 560 if (depth == 8)
561 XSetWindowColormap(display, window, colormap); 561 XSetWindowColormap(display, window, colormap);
562 562
563 if (!XStringListToTextProperty(&window_name, 1, pWindowName)) 563 if (!XStringListToTextProperty(&window_name, 1, pWindowName))
564 pWindowName = NULL; 564 pWindowName = NULL;
565 if (!XStringListToTextProperty(&icon_name, 1, pIconName)) 565 if (!XStringListToTextProperty(&icon_name, 1, pIconName))
566 pIconName = NULL; 566 pIconName = NULL;
567 567
568 /* OK if any hints allocation fails; XSetWMProperties() allows NULLs */ 568 /* OK if any hints allocation fails; XSetWMProperties() allows NULLs */
569 569
570 if ((size_hints = XAllocSizeHints()) != NULL) { 570 if ((size_hints = XAllocSizeHints()) != NULL) {
571 /* window will not be resizable */ 571 /* window will not be resizable */
572 size_hints->flags = PMinSize | PMaxSize; 572 size_hints->flags = PMinSize | PMaxSize;
573 size_hints->min_width = size_hints->max_width = (int)image_width; 573 size_hints->min_width = size_hints->max_width = (int)image_width;
574 size_hints->min_height = size_hints->max_height = (int)image_height; 574 size_hints->min_height = size_hints->max_height = (int)image_height;
575 } 575 }
576 576
577 if ((wm_hints = XAllocWMHints()) != NULL) { 577 if ((wm_hints = XAllocWMHints()) != NULL) {
578 wm_hints->initial_state = NormalState; 578 wm_hints->initial_state = NormalState;
579 wm_hints->input = True; 579 wm_hints->input = True;
580 /* wm_hints->icon_pixmap = icon_pixmap; */ 580 /* wm_hints->icon_pixmap = icon_pixmap; */
581 wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ; 581 wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ;
582 } 582 }
583 583
584 if ((class_hints = XAllocClassHint()) != NULL) { 584 if ((class_hints = XAllocClassHint()) != NULL) {
585 class_hints->res_name = res_name; 585 class_hints->res_name = res_name;
586 class_hints->res_class = res_class; 586 class_hints->res_class = res_class;
587 } 587 }
588 588
589 XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0, 589 XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,
590 size_hints, wm_hints, class_hints); 590 size_hints, wm_hints, class_hints);
591 591
592 /* various properties and hints no longer needed; free memory */ 592 /* various properties and hints no longer needed; free memory */
593 if (pWindowName) 593 if (pWindowName)
594 XFree(pWindowName->value); 594 XFree(pWindowName->value);
595 if (pIconName) 595 if (pIconName)
596 XFree(pIconName->value); 596 XFree(pIconName->value);
597 if (size_hints) 597 if (size_hints)
598 XFree(size_hints); 598 XFree(size_hints);
599 if (wm_hints) 599 if (wm_hints)
600 XFree(wm_hints); 600 XFree(wm_hints);
601 if (class_hints) 601 if (class_hints)
602 XFree(class_hints); 602 XFree(class_hints);
603 603
604 XMapWindow(display, window); 604 XMapWindow(display, window);
605 605
606 gc = XCreateGC(display, window, 0, &gcvalues); 606 gc = XCreateGC(display, window, 0, &gcvalues);
607 have_gc = TRUE; 607 have_gc = TRUE;
608 608
609/*--------------------------------------------------------------------------- 609/*---------------------------------------------------------------------------
610 Fill window with the specified background color. 610 Fill window with the specified background color.
611 ---------------------------------------------------------------------------*/ 611 ---------------------------------------------------------------------------*/
612 612
613 if (depth == 24 || depth == 32) { 613 if (depth == 24 || depth == 32) {
614 bg_pixel = ((ulg)bg_red << RShift) | 614 bg_pixel = ((ulg)bg_red << RShift) |
615 ((ulg)bg_green << GShift) | 615 ((ulg)bg_green << GShift) |
616 ((ulg)bg_blue << BShift); 616 ((ulg)bg_blue << BShift);
617 } else if (depth == 16) { 617 } else if (depth == 16) {
618 bg_pixel = ((((ulg)bg_red << 8) >> RShift) & RMask) | 618 bg_pixel = ((((ulg)bg_red << 8) >> RShift) & RMask) |
619 ((((ulg)bg_green << 8) >> GShift) & GMask) | 619 ((((ulg)bg_green << 8) >> GShift) & GMask) |
620 ((((ulg)bg_blue << 8) >> BShift) & BMask); 620 ((((ulg)bg_blue << 8) >> BShift) & BMask);
621 } else /* depth == 8 */ { 621 } else /* depth == 8 */ {
622 622
623 /* GRR: add 8-bit support */ 623 /* GRR: add 8-bit support */
624 624
625 } 625 }
626 626
627 XSetForeground(display, gc, bg_pixel); 627 XSetForeground(display, gc, bg_pixel);
628 XFillRectangle(display, window, gc, 0, 0, image_width, image_height); 628 XFillRectangle(display, window, gc, 0, 0, image_width, image_height);
629 629
630/*--------------------------------------------------------------------------- 630/*---------------------------------------------------------------------------
631 Wait for first Expose event to do any drawing, then flush. 631 Wait for first Expose event to do any drawing, then flush.
632 ---------------------------------------------------------------------------*/ 632 ---------------------------------------------------------------------------*/
633 633
634 do 634 do
635 XNextEvent(display, &e); 635 XNextEvent(display, &e);
636 while (e.type != Expose || e.xexpose.count); 636 while (e.type != Expose || e.xexpose.count);
637 637
638 XFlush(display); 638 XFlush(display);
639 639
640/*--------------------------------------------------------------------------- 640/*---------------------------------------------------------------------------
641 Allocate memory for the X- and display-specific version of the image. 641 Allocate memory for the X- and display-specific version of the image.
642 ---------------------------------------------------------------------------*/ 642 ---------------------------------------------------------------------------*/
643 643
644 if (depth == 24 || depth == 32) { 644 if (depth == 24 || depth == 32) {
645 xdata = (uch *)malloc(4*image_width*image_height); 645 xdata = (uch *)malloc(4*image_width*image_height);
646 pad = 32; 646 pad = 32;
647 } else if (depth == 16) { 647 } else if (depth == 16) {
648 xdata = (uch *)malloc(2*image_width*image_height); 648 xdata = (uch *)malloc(2*image_width*image_height);
649 pad = 16; 649 pad = 16;
650 } else /* depth == 8 */ { 650 } else /* depth == 8 */ {
651 xdata = (uch *)malloc(image_width*image_height); 651 xdata = (uch *)malloc(image_width*image_height);
652 pad = 8; 652 pad = 8;
653 } 653 }
654 654
655 if (!xdata) { 655 if (!xdata) {
656 fprintf(stderr, PROGNAME ": unable to allocate image memory\n"); 656 fprintf(stderr, PROGNAME ": unable to allocate image memory\n");
657 return 4; 657 return 4;
658 } 658 }
659 659
660 ximage = XCreateImage(display, visual, depth, ZPixmap, 0, 660 ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
661 (char *)xdata, image_width, image_height, pad, 0); 661 (char *)xdata, image_width, image_height, pad, 0);
662 662
663 if (!ximage) { 663 if (!ximage) {
664 fprintf(stderr, PROGNAME ": XCreateImage() failed\n"); 664 fprintf(stderr, PROGNAME ": XCreateImage() failed\n");
665 free(xdata); 665 free(xdata);
666 return 3; 666 return 3;
667 } 667 }
668 668
669 /* to avoid testing the byte order every pixel (or doubling the size of 669 /* to avoid testing the byte order every pixel (or doubling the size of
670 * the drawing routine with a giant if-test), we arbitrarily set the byte 670 * the drawing routine with a giant if-test), we arbitrarily set the byte
671 * order to MSBFirst and let Xlib worry about inverting things on little- 671 * order to MSBFirst and let Xlib worry about inverting things on little-
672 * endian machines (like Linux/x86, old VAXen, etc.)--this is not the most 672 * endian machines (like Linux/x86, old VAXen, etc.)--this is not the most
673 * efficient approach (the giant if-test would be better), but in the 673 * efficient approach (the giant if-test would be better), but in the
674 * interest of clarity, we take the easy way out... */ 674 * interest of clarity, we take the easy way out... */
675 675
676 ximage->byte_order = MSBFirst; 676 ximage->byte_order = MSBFirst;
677 677
678 return 0; 678 return 0;
679 679
680} /* end function rpng_x_create_window() */ 680} /* end function rpng_x_create_window() */
681 681
682 682
683 683
684 684
685 685
686static int rpng_x_display_image(void) 686static int rpng_x_display_image(void)
687{ 687{
688 uch *src; 688 uch *src;
689 char *dest; 689 char *dest;
690 uch r, g, b, a; 690 uch r, g, b, a;
691 ulg i, row, lastrow = 0; 691 ulg i, row, lastrow = 0;
692 ulg pixel; 692 ulg pixel;
693 int ximage_rowbytes = ximage->bytes_per_line; 693 int ximage_rowbytes = ximage->bytes_per_line;
694/* int bpp = ximage->bits_per_pixel; */ 694/* int bpp = ximage->bits_per_pixel; */
695 695
696 696
697 Trace((stderr, "beginning display loop (image_channels == %d)\n", 697 Trace((stderr, "beginning display loop (image_channels == %d)\n",
698 image_channels)) 698 image_channels))
699 Trace((stderr, " (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n", 699 Trace((stderr, " (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n",
700 image_width, image_rowbytes, ximage_rowbytes)) 700 image_width, image_rowbytes, ximage_rowbytes))
701 Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel)) 701 Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel))
702 Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst? 702 Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst?
703 "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown"))) 703 "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown")))
704 704
705 if (depth == 24 || depth == 32) { 705 if (depth == 24 || depth == 32) {
706 ulg red, green, blue; 706 ulg red, green, blue;
707 707
708 for (lastrow = row = 0; row < image_height; ++row) { 708 for (lastrow = row = 0; row < image_height; ++row) {
709 src = image_data + row*image_rowbytes; 709 src = image_data + row*image_rowbytes;
710 dest = ximage->data + row*ximage_rowbytes; 710 dest = ximage->data + row*ximage_rowbytes;
711 if (image_channels == 3) { 711 if (image_channels == 3) {
712 for (i = image_width; i > 0; --i) { 712 for (i = image_width; i > 0; --i) {
713 red = *src++; 713 red = *src++;
714 green = *src++; 714 green = *src++;
715 blue = *src++; 715 blue = *src++;
716#ifdef NO_24BIT_MASKS 716#ifdef NO_24BIT_MASKS
717 pixel = (red << RShift) | 717 pixel = (red << RShift) |
718 (green << GShift) | 718 (green << GShift) |
719 (blue << BShift); 719 (blue << BShift);
720 /* recall that we set ximage->byte_order = MSBFirst above */ 720 /* recall that we set ximage->byte_order = MSBFirst above */
721 /* GRR BUG: this assumes bpp == 32, but may be 24: */ 721 /* GRR BUG: this assumes bpp == 32, but may be 24: */
722 *dest++ = (char)((pixel >> 24) & 0xff); 722 *dest++ = (char)((pixel >> 24) & 0xff);
723 *dest++ = (char)((pixel >> 16) & 0xff); 723 *dest++ = (char)((pixel >> 16) & 0xff);
724 *dest++ = (char)((pixel >> 8) & 0xff); 724 *dest++ = (char)((pixel >> 8) & 0xff);
725 *dest++ = (char)( pixel & 0xff); 725 *dest++ = (char)( pixel & 0xff);
726#else 726#else
727 red = (RShift < 0)? red << (-RShift) : red >> RShift; 727 red = (RShift < 0)? red << (-RShift) : red >> RShift;
728 green = (GShift < 0)? green << (-GShift) : green >> GShift; 728 green = (GShift < 0)? green << (-GShift) : green >> GShift;
729 blue = (BShift < 0)? blue << (-BShift) : blue >> BShift; 729 blue = (BShift < 0)? blue << (-BShift) : blue >> BShift;
730 pixel = (red & RMask) | (green & GMask) | (blue & BMask); 730 pixel = (red & RMask) | (green & GMask) | (blue & BMask);
731 /* recall that we set ximage->byte_order = MSBFirst above */ 731 /* recall that we set ximage->byte_order = MSBFirst above */
732 *dest++ = (char)((pixel >> 24) & 0xff); 732 *dest++ = (char)((pixel >> 24) & 0xff);
733 *dest++ = (char)((pixel >> 16) & 0xff); 733 *dest++ = (char)((pixel >> 16) & 0xff);
734 *dest++ = (char)((pixel >> 8) & 0xff); 734 *dest++ = (char)((pixel >> 8) & 0xff);
735 *dest++ = (char)( pixel & 0xff); 735 *dest++ = (char)( pixel & 0xff);
736#endif 736#endif
737 } 737 }
738 } else /* if (image_channels == 4) */ { 738 } else /* if (image_channels == 4) */ {
739 for (i = image_width; i > 0; --i) { 739 for (i = image_width; i > 0; --i) {
740 r = *src++; 740 r = *src++;
741 g = *src++; 741 g = *src++;
742 b = *src++; 742 b = *src++;
743 a = *src++; 743 a = *src++;
744 if (a == 255) { 744 if (a == 255) {
745 red = r; 745 red = r;
746 green = g; 746 green = g;
747 blue = b; 747 blue = b;
748 } else if (a == 0) { 748 } else if (a == 0) {
749 red = bg_red; 749 red = bg_red;
750 green = bg_green; 750 green = bg_green;
751 blue = bg_blue; 751 blue = bg_blue;
752 } else { 752 } else {
753 /* this macro (from png.h) composites the foreground 753 /* this macro (from png.h) composites the foreground
754 * and background values and puts the result into the 754 * and background values and puts the result into the
755 * first argument */ 755 * first argument */
756 alpha_composite(red, r, a, bg_red); 756 alpha_composite(red, r, a, bg_red);
757 alpha_composite(green, g, a, bg_green); 757 alpha_composite(green, g, a, bg_green);
758 alpha_composite(blue, b, a, bg_blue); 758 alpha_composite(blue, b, a, bg_blue);
759 } 759 }
760 pixel = (red << RShift) | 760 pixel = (red << RShift) |
761 (green << GShift) | 761 (green << GShift) |
762 (blue << BShift); 762 (blue << BShift);
763 /* recall that we set ximage->byte_order = MSBFirst above */ 763 /* recall that we set ximage->byte_order = MSBFirst above */
764 *dest++ = (char)((pixel >> 24) & 0xff); 764 *dest++ = (char)((pixel >> 24) & 0xff);
765 *dest++ = (char)((pixel >> 16) & 0xff); 765 *dest++ = (char)((pixel >> 16) & 0xff);
766 *dest++ = (char)((pixel >> 8) & 0xff); 766 *dest++ = (char)((pixel >> 8) & 0xff);
767 *dest++ = (char)( pixel & 0xff); 767 *dest++ = (char)( pixel & 0xff);
768 } 768 }
769 } 769 }
770 /* display after every 16 lines */ 770 /* display after every 16 lines */
771 if (((row+1) & 0xf) == 0) { 771 if (((row+1) & 0xf) == 0) {
772 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, 772 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
773 (int)lastrow, image_width, 16); 773 (int)lastrow, image_width, 16);
774 XFlush(display); 774 XFlush(display);
775 lastrow = row + 1; 775 lastrow = row + 1;
776 } 776 }
777 } 777 }
778 778
779 } else if (depth == 16) { 779 } else if (depth == 16) {
780 ush red, green, blue; 780 ush red, green, blue;
781 781
782 for (lastrow = row = 0; row < image_height; ++row) { 782 for (lastrow = row = 0; row < image_height; ++row) {
783 src = image_data + row*image_rowbytes; 783 src = image_data + row*image_rowbytes;
784 dest = ximage->data + row*ximage_rowbytes; 784 dest = ximage->data + row*ximage_rowbytes;
785 if (image_channels == 3) { 785 if (image_channels == 3) {
786 for (i = image_width; i > 0; --i) { 786 for (i = image_width; i > 0; --i) {
787 red = ((ush)(*src) << 8); 787 red = ((ush)(*src) << 8);
788 ++src; 788 ++src;
789 green = ((ush)(*src) << 8); 789 green = ((ush)(*src) << 8);
790 ++src; 790 ++src;
791 blue = ((ush)(*src) << 8); 791 blue = ((ush)(*src) << 8);
792 ++src; 792 ++src;
793 pixel = ((red >> RShift) & RMask) | 793 pixel = ((red >> RShift) & RMask) |
794 ((green >> GShift) & GMask) | 794 ((green >> GShift) & GMask) |
795 ((blue >> BShift) & BMask); 795 ((blue >> BShift) & BMask);
796 /* recall that we set ximage->byte_order = MSBFirst above */ 796 /* recall that we set ximage->byte_order = MSBFirst above */
797 *dest++ = (char)((pixel >> 8) & 0xff); 797 *dest++ = (char)((pixel >> 8) & 0xff);
798 *dest++ = (char)( pixel & 0xff); 798 *dest++ = (char)( pixel & 0xff);
799 } 799 }
800 } else /* if (image_channels == 4) */ { 800 } else /* if (image_channels == 4) */ {
801 for (i = image_width; i > 0; --i) { 801 for (i = image_width; i > 0; --i) {
802 r = *src++; 802 r = *src++;
803 g = *src++; 803 g = *src++;
804 b = *src++; 804 b = *src++;
805 a = *src++; 805 a = *src++;
806 if (a == 255) { 806 if (a == 255) {
807 red = ((ush)r << 8); 807 red = ((ush)r << 8);
808 green = ((ush)g << 8); 808 green = ((ush)g << 8);
809 blue = ((ush)b << 8); 809 blue = ((ush)b << 8);
810 } else if (a == 0) { 810 } else if (a == 0) {
811 red = ((ush)bg_red << 8); 811 red = ((ush)bg_red << 8);
812 green = ((ush)bg_green << 8); 812 green = ((ush)bg_green << 8);
813 blue = ((ush)bg_blue << 8); 813 blue = ((ush)bg_blue << 8);
814 } else { 814 } else {
815 /* this macro (from png.h) composites the foreground 815 /* this macro (from png.h) composites the foreground
816 * and background values and puts the result back into 816 * and background values and puts the result back into
817 * the first argument (== fg byte here: safe) */ 817 * the first argument (== fg byte here: safe) */
818 alpha_composite(r, r, a, bg_red); 818 alpha_composite(r, r, a, bg_red);
819 alpha_composite(g, g, a, bg_green); 819 alpha_composite(g, g, a, bg_green);
820 alpha_composite(b, b, a, bg_blue); 820 alpha_composite(b, b, a, bg_blue);
821 red = ((ush)r << 8); 821 red = ((ush)r << 8);
822 green = ((ush)g << 8); 822 green = ((ush)g << 8);
823 blue = ((ush)b << 8); 823 blue = ((ush)b << 8);
824 } 824 }
825 pixel = ((red >> RShift) & RMask) | 825 pixel = ((red >> RShift) & RMask) |
826 ((green >> GShift) & GMask) | 826 ((green >> GShift) & GMask) |
827 ((blue >> BShift) & BMask); 827 ((blue >> BShift) & BMask);
828 /* recall that we set ximage->byte_order = MSBFirst above */ 828 /* recall that we set ximage->byte_order = MSBFirst above */
829 *dest++ = (char)((pixel >> 8) & 0xff); 829 *dest++ = (char)((pixel >> 8) & 0xff);
830 *dest++ = (char)( pixel & 0xff); 830 *dest++ = (char)( pixel & 0xff);
831 } 831 }
832 } 832 }
833 /* display after every 16 lines */ 833 /* display after every 16 lines */
834 if (((row+1) & 0xf) == 0) { 834 if (((row+1) & 0xf) == 0) {
835 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, 835 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
836 (int)lastrow, image_width, 16); 836 (int)lastrow, image_width, 16);
837 XFlush(display); 837 XFlush(display);
838 lastrow = row + 1; 838 lastrow = row + 1;
839 } 839 }
840 } 840 }
841 841
842 } else /* depth == 8 */ { 842 } else /* depth == 8 */ {
843 843
844 /* GRR: add 8-bit support */ 844 /* GRR: add 8-bit support */
845 845
846 } 846 }
847 847
848 Trace((stderr, "calling final XPutImage()\n")) 848 Trace((stderr, "calling final XPutImage()\n"))
849 if (lastrow < image_height) { 849 if (lastrow < image_height) {
850 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, 850 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
851 (int)lastrow, image_width, image_height-lastrow); 851 (int)lastrow, image_width, image_height-lastrow);
852 XFlush(display); 852 XFlush(display);
853 } 853 }
854 854
855 return 0; 855 return 0;
856} 856}
857 857
858 858
859 859
860 860
861static void rpng_x_cleanup(void) 861static void rpng_x_cleanup(void)
862{ 862{
863 if (image_data) { 863 if (image_data) {
864 free(image_data); 864 free(image_data);
865 image_data = NULL; 865 image_data = NULL;
866 } 866 }
867 867
868 if (ximage) { 868 if (ximage) {
869 if (ximage->data) { 869 if (ximage->data) {
870 free(ximage->data); /* we allocated it, so we free it */ 870 free(ximage->data); /* we allocated it, so we free it */
871 ximage->data = (char *)NULL; /* instead of XDestroyImage() */ 871 ximage->data = (char *)NULL; /* instead of XDestroyImage() */
872 } 872 }
873 XDestroyImage(ximage); 873 XDestroyImage(ximage);
874 ximage = NULL; 874 ximage = NULL;
875 } 875 }
876 876
877 if (have_gc) 877 if (have_gc)
878 XFreeGC(display, gc); 878 XFreeGC(display, gc);
879 879
880 if (have_window) 880 if (have_window)
881 XDestroyWindow(display, window); 881 XDestroyWindow(display, window);
882 882
883 if (have_colormap) 883 if (have_colormap)
884 XFreeColormap(display, colormap); 884 XFreeColormap(display, colormap);
885 885
886 if (have_nondefault_visual) 886 if (have_nondefault_visual)
887 XFree(visual_list); 887 XFree(visual_list);
888} 888}
889 889
890 890
891 891
892 892
893 893
894static int rpng_x_msb(ulg u32val) 894static int rpng_x_msb(ulg u32val)
895{ 895{
896 int i; 896 int i;
897 897
898 for (i = 31; i >= 0; --i) { 898 for (i = 31; i >= 0; --i) {
899 if (u32val & 0x80000000L) 899 if (u32val & 0x80000000L)
900 break; 900 break;
901 u32val <<= 1; 901 u32val <<= 1;
902 } 902 }
903 return i; 903 return i;
904} 904}
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-win.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-win.c
index 2303b58..223e737 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-win.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-win.c
@@ -1,1253 +1,1253 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 rpng2 - progressive-model PNG display program rpng2-win.c 3 rpng2 - progressive-model PNG display program rpng2-win.c
4 4
5 This program decodes and displays PNG files progressively, as if it were 5 This program decodes and displays PNG files progressively, as if it were
6 a web browser (though the front end is only set up to read from files). 6 a web browser (though the front end is only set up to read from files).
7 It supports gamma correction, user-specified background colors, and user- 7 It supports gamma correction, user-specified background colors, and user-
8 specified background patterns (for transparent images). This version is 8 specified background patterns (for transparent images). This version is
9 for 32-bit Windows; it may compile under 16-bit Windows with a little 9 for 32-bit Windows; it may compile under 16-bit Windows with a little
10 tweaking (or maybe not). Thanks to Adam Costello and Pieter S. van der 10 tweaking (or maybe not). Thanks to Adam Costello and Pieter S. van der
11 Meulen for the "diamond" and "radial waves" patterns, respectively. 11 Meulen for the "diamond" and "radial waves" patterns, respectively.
12 12
13 to do (someday, maybe): 13 to do (someday, maybe):
14 - handle quoted command-line args (especially filenames with spaces) 14 - handle quoted command-line args (especially filenames with spaces)
15 - finish resizable checkerboard-gradient (sizes 4-128?) 15 - finish resizable checkerboard-gradient (sizes 4-128?)
16 - use %.1023s to simplify truncation of title-bar string? 16 - use %.1023s to simplify truncation of title-bar string?
17 - have minimum window width: oh well 17 - have minimum window width: oh well
18 18
19 --------------------------------------------------------------------------- 19 ---------------------------------------------------------------------------
20 20
21 Changelog: 21 Changelog:
22 - 1.01: initial public release 22 - 1.01: initial public release
23 - 1.02: fixed cut-and-paste error in usage screen (oops...) 23 - 1.02: fixed cut-and-paste error in usage screen (oops...)
24 - 1.03: modified to allow abbreviated options 24 - 1.03: modified to allow abbreviated options
25 - 1.04: removed bogus extra argument from usage fprintf() [Glenn R-P?]; 25 - 1.04: removed bogus extra argument from usage fprintf() [Glenn R-P?];
26 fixed command-line parsing bug 26 fixed command-line parsing bug
27 - 1.10: enabled "message window"/console (thanks to David Geldreich) 27 - 1.10: enabled "message window"/console (thanks to David Geldreich)
28 - 1.20: added runtime MMX-enabling/disabling and new -mmx* options 28 - 1.20: added runtime MMX-enabling/disabling and new -mmx* options
29 - 1.21: made minor tweak to usage screen to fit within 25-line console 29 - 1.21: made minor tweak to usage screen to fit within 25-line console
30 - 1.22: added AMD64/EM64T support (__x86_64__) 30 - 1.22: added AMD64/EM64T support (__x86_64__)
31 - 2.00: dual-licensed (added GNU GPL) 31 - 2.00: dual-licensed (added GNU GPL)
32 - 2.01: fixed 64-bit typo in readpng2.c 32 - 2.01: fixed 64-bit typo in readpng2.c
33 - 2.02: fixed improper display of usage screen on PNG error(s); fixed 33 - 2.02: fixed improper display of usage screen on PNG error(s); fixed
34 unexpected-EOF and file-read-error cases 34 unexpected-EOF and file-read-error cases
35 - 2.03: removed runtime MMX-enabling/disabling and obsolete -mmx* options 35 - 2.03: removed runtime MMX-enabling/disabling and obsolete -mmx* options
36 36
37 --------------------------------------------------------------------------- 37 ---------------------------------------------------------------------------
38 38
39 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. 39 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved.
40 40
41 This software is provided "as is," without warranty of any kind, 41 This software is provided "as is," without warranty of any kind,
42 express or implied. In no event shall the author or contributors 42 express or implied. In no event shall the author or contributors
43 be held liable for any damages arising in any way from the use of 43 be held liable for any damages arising in any way from the use of
44 this software. 44 this software.
45 45
46 The contents of this file are DUAL-LICENSED. You may modify and/or 46 The contents of this file are DUAL-LICENSED. You may modify and/or
47 redistribute this software according to the terms of one of the 47 redistribute this software according to the terms of one of the
48 following two licenses (at your option): 48 following two licenses (at your option):
49 49
50 50
51 LICENSE 1 ("BSD-like with advertising clause"): 51 LICENSE 1 ("BSD-like with advertising clause"):
52 52
53 Permission is granted to anyone to use this software for any purpose, 53 Permission is granted to anyone to use this software for any purpose,
54 including commercial applications, and to alter it and redistribute 54 including commercial applications, and to alter it and redistribute
55 it freely, subject to the following restrictions: 55 it freely, subject to the following restrictions:
56 56
57 1. Redistributions of source code must retain the above copyright 57 1. Redistributions of source code must retain the above copyright
58 notice, disclaimer, and this list of conditions. 58 notice, disclaimer, and this list of conditions.
59 2. Redistributions in binary form must reproduce the above copyright 59 2. Redistributions in binary form must reproduce the above copyright
60 notice, disclaimer, and this list of conditions in the documenta- 60 notice, disclaimer, and this list of conditions in the documenta-
61 tion and/or other materials provided with the distribution. 61 tion and/or other materials provided with the distribution.
62 3. All advertising materials mentioning features or use of this 62 3. All advertising materials mentioning features or use of this
63 software must display the following acknowledgment: 63 software must display the following acknowledgment:
64 64
65 This product includes software developed by Greg Roelofs 65 This product includes software developed by Greg Roelofs
66 and contributors for the book, "PNG: The Definitive Guide," 66 and contributors for the book, "PNG: The Definitive Guide,"
67 published by O'Reilly and Associates. 67 published by O'Reilly and Associates.
68 68
69 69
70 LICENSE 2 (GNU GPL v2 or later): 70 LICENSE 2 (GNU GPL v2 or later):
71 71
72 This program is free software; you can redistribute it and/or modify 72 This program is free software; you can redistribute it and/or modify
73 it under the terms of the GNU General Public License as published by 73 it under the terms of the GNU General Public License as published by
74 the Free Software Foundation; either version 2 of the License, or 74 the Free Software Foundation; either version 2 of the License, or
75 (at your option) any later version. 75 (at your option) any later version.
76 76
77 This program is distributed in the hope that it will be useful, 77 This program is distributed in the hope that it will be useful,
78 but WITHOUT ANY WARRANTY; without even the implied warranty of 78 but WITHOUT ANY WARRANTY; without even the implied warranty of
79 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 79 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
80 GNU General Public License for more details. 80 GNU General Public License for more details.
81 81
82 You should have received a copy of the GNU General Public License 82 You should have received a copy of the GNU General Public License
83 along with this program; if not, write to the Free Software Foundation, 83 along with this program; if not, write to the Free Software Foundation,
84 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 84 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
85 85
86 ---------------------------------------------------------------------------*/ 86 ---------------------------------------------------------------------------*/
87 87
88#define PROGNAME "rpng2-win" 88#define PROGNAME "rpng2-win"
89#define LONGNAME "Progressive PNG Viewer for Windows" 89#define LONGNAME "Progressive PNG Viewer for Windows"
90#define VERSION "2.02 of 16 March 2008" 90#define VERSION "2.02 of 16 March 2008"
91 91
92#include <stdio.h> 92#include <stdio.h>
93#include <stdlib.h> 93#include <stdlib.h>
94#include <string.h> 94#include <string.h>
95#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */ 95#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */
96#include <time.h> 96#include <time.h>
97#include <math.h> /* only for PvdM background code */ 97#include <math.h> /* only for PvdM background code */
98#include <windows.h> 98#include <windows.h>
99#ifdef __CYGWIN__ 99#ifdef __CYGWIN__
100/* getch replacement. Turns out, we don't really need this, 100/* getch replacement. Turns out, we don't really need this,
101 * but leave it here if we ever enable any of the uses of 101 * but leave it here if we ever enable any of the uses of
102 * _getch in the main code 102 * _getch in the main code
103 */ 103 */
104#include <unistd.h> 104#include <unistd.h>
105#include <termio.h> 105#include <termio.h>
106#include <sys/ioctl.h> 106#include <sys/ioctl.h>
107int repl_getch( void ) 107int repl_getch( void )
108{ 108{
109 char ch; 109 char ch;
110 int fd = fileno(stdin); 110 int fd = fileno(stdin);
111 struct termio old_tty, new_tty; 111 struct termio old_tty, new_tty;
112 112
113 ioctl(fd, TCGETA, &old_tty); 113 ioctl(fd, TCGETA, &old_tty);
114 new_tty = old_tty; 114 new_tty = old_tty;
115 new_tty.c_lflag &= ~(ICANON | ECHO | ISIG); 115 new_tty.c_lflag &= ~(ICANON | ECHO | ISIG);
116 ioctl(fd, TCSETA, &new_tty); 116 ioctl(fd, TCSETA, &new_tty);
117 fread(&ch, 1, sizeof(ch), stdin); 117 fread(&ch, 1, sizeof(ch), stdin);
118 ioctl(fd, TCSETA, &old_tty); 118 ioctl(fd, TCSETA, &old_tty);
119 119
120 return ch; 120 return ch;
121} 121}
122#define _getch repl_getch 122#define _getch repl_getch
123#else 123#else
124#include <conio.h> /* only for _getch() */ 124#include <conio.h> /* only for _getch() */
125#endif 125#endif
126 126
127/* all for PvdM background code: */ 127/* all for PvdM background code: */
128#ifndef PI 128#ifndef PI
129# define PI 3.141592653589793238 129# define PI 3.141592653589793238
130#endif 130#endif
131#define PI_2 (PI*0.5) 131#define PI_2 (PI*0.5)
132#define INV_PI_360 (360.0 / PI) 132#define INV_PI_360 (360.0 / PI)
133#define MAX(a,b) (a>b?a:b) 133#define MAX(a,b) (a>b?a:b)
134#define MIN(a,b) (a<b?a:b) 134#define MIN(a,b) (a<b?a:b)
135#define CLIP(a,min,max) MAX(min,MIN((a),max)) 135#define CLIP(a,min,max) MAX(min,MIN((a),max))
136#define ABS(a) ((a)<0?-(a):(a)) 136#define ABS(a) ((a)<0?-(a):(a))
137#define CLIP8P(c) MAX(0,(MIN((c),255))) /* 8-bit pos. integer (uch) */ 137#define CLIP8P(c) MAX(0,(MIN((c),255))) /* 8-bit pos. integer (uch) */
138#define ROUNDF(f) ((int)(f + 0.5)) 138#define ROUNDF(f) ((int)(f + 0.5))
139 139
140#define rgb1_max bg_freq 140#define rgb1_max bg_freq
141#define rgb1_min bg_gray 141#define rgb1_min bg_gray
142#define rgb2_max bg_bsat 142#define rgb2_max bg_bsat
143#define rgb2_min bg_brot 143#define rgb2_min bg_brot
144 144
145/* #define DEBUG */ /* this enables the Trace() macros */ 145/* #define DEBUG */ /* this enables the Trace() macros */
146 146
147#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */ 147#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */
148 148
149 149
150/* could just include png.h, but this macro is the only thing we need 150/* could just include png.h, but this macro is the only thing we need
151 * (name and typedefs changed to local versions); note that side effects 151 * (name and typedefs changed to local versions); note that side effects
152 * only happen with alpha (which could easily be avoided with 152 * only happen with alpha (which could easily be avoided with
153 * "ush acopy = (alpha);") */ 153 * "ush acopy = (alpha);") */
154 154
155#define alpha_composite(composite, fg, alpha, bg) { \ 155#define alpha_composite(composite, fg, alpha, bg) { \
156 ush temp = ((ush)(fg)*(ush)(alpha) + \ 156 ush temp = ((ush)(fg)*(ush)(alpha) + \
157 (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ 157 (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
158 (composite) = (uch)((temp + (temp >> 8)) >> 8); \ 158 (composite) = (uch)((temp + (temp >> 8)) >> 8); \
159} 159}
160 160
161 161
162#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this 162#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
163 * block size corresponds roughly to a download 163 * block size corresponds roughly to a download
164 * speed 10% faster than theoretical 33.6K maximum 164 * speed 10% faster than theoretical 33.6K maximum
165 * (assuming 8 data bits, 1 stop bit and no other 165 * (assuming 8 data bits, 1 stop bit and no other
166 * overhead) */ 166 * overhead) */
167 167
168/* local prototypes */ 168/* local prototypes */
169static void rpng2_win_init(void); 169static void rpng2_win_init(void);
170static int rpng2_win_create_window(void); 170static int rpng2_win_create_window(void);
171static int rpng2_win_load_bg_image(void); 171static int rpng2_win_load_bg_image(void);
172static void rpng2_win_display_row(ulg row); 172static void rpng2_win_display_row(ulg row);
173static void rpng2_win_finish_display(void); 173static void rpng2_win_finish_display(void);
174static void rpng2_win_cleanup(void); 174static void rpng2_win_cleanup(void);
175LRESULT CALLBACK rpng2_win_wndproc(HWND, UINT, WPARAM, LPARAM); 175LRESULT CALLBACK rpng2_win_wndproc(HWND, UINT, WPARAM, LPARAM);
176 176
177 177
178static char titlebar[1024]; 178static char titlebar[1024];
179static char *progname = PROGNAME; 179static char *progname = PROGNAME;
180static char *appname = LONGNAME; 180static char *appname = LONGNAME;
181static char *filename; 181static char *filename;
182static FILE *infile; 182static FILE *infile;
183 183
184static mainprog_info rpng2_info; 184static mainprog_info rpng2_info;
185 185
186static uch inbuf[INBUFSIZE]; 186static uch inbuf[INBUFSIZE];
187static int incount; 187static int incount;
188 188
189static int pat = 6; /* must be less than num_bgpat */ 189static int pat = 6; /* must be less than num_bgpat */
190static int bg_image = 0; 190static int bg_image = 0;
191static int bgscale = 16; 191static int bgscale = 16;
192static ulg bg_rowbytes; 192static ulg bg_rowbytes;
193static uch *bg_data; 193static uch *bg_data;
194 194
195static struct rgb_color { 195static struct rgb_color {
196 uch r, g, b; 196 uch r, g, b;
197} rgb[] = { 197} rgb[] = {
198 { 0, 0, 0}, /* 0: black */ 198 { 0, 0, 0}, /* 0: black */
199 {255, 255, 255}, /* 1: white */ 199 {255, 255, 255}, /* 1: white */
200 {173, 132, 57}, /* 2: tan */ 200 {173, 132, 57}, /* 2: tan */
201 { 64, 132, 0}, /* 3: medium green */ 201 { 64, 132, 0}, /* 3: medium green */
202 {189, 117, 1}, /* 4: gold */ 202 {189, 117, 1}, /* 4: gold */
203 {253, 249, 1}, /* 5: yellow */ 203 {253, 249, 1}, /* 5: yellow */
204 { 0, 0, 255}, /* 6: blue */ 204 { 0, 0, 255}, /* 6: blue */
205 { 0, 0, 120}, /* 7: medium blue */ 205 { 0, 0, 120}, /* 7: medium blue */
206 {255, 0, 255}, /* 8: magenta */ 206 {255, 0, 255}, /* 8: magenta */
207 { 64, 0, 64}, /* 9: dark magenta */ 207 { 64, 0, 64}, /* 9: dark magenta */
208 {255, 0, 0}, /* 10: red */ 208 {255, 0, 0}, /* 10: red */
209 { 64, 0, 0}, /* 11: dark red */ 209 { 64, 0, 0}, /* 11: dark red */
210 {255, 127, 0}, /* 12: orange */ 210 {255, 127, 0}, /* 12: orange */
211 {192, 96, 0}, /* 13: darker orange */ 211 {192, 96, 0}, /* 13: darker orange */
212 { 24, 60, 0}, /* 14: dark green-yellow */ 212 { 24, 60, 0}, /* 14: dark green-yellow */
213 { 85, 125, 200} /* 15: ice blue */ 213 { 85, 125, 200} /* 15: ice blue */
214}; 214};
215/* not used for now, but should be for error-checking: 215/* not used for now, but should be for error-checking:
216static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color); 216static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);
217 */ 217 */
218 218
219/* 219/*
220 This whole struct is a fairly cheesy way to keep the number of 220 This whole struct is a fairly cheesy way to keep the number of
221 command-line options to a minimum. The radial-waves background 221 command-line options to a minimum. The radial-waves background
222 type is a particularly poor fit to the integer elements of the 222 type is a particularly poor fit to the integer elements of the
223 struct...but a few macros and a little fixed-point math will do 223 struct...but a few macros and a little fixed-point math will do
224 wonders for ya. 224 wonders for ya.
225 225
226 type bits: 226 type bits:
227 F E D C B A 9 8 7 6 5 4 3 2 1 0 227 F E D C B A 9 8 7 6 5 4 3 2 1 0
228 | | | | | 228 | | | | |
229 | | +-+-+-- 0 = sharp-edged checkerboard 229 | | +-+-+-- 0 = sharp-edged checkerboard
230 | | 1 = soft diamonds 230 | | 1 = soft diamonds
231 | | 2 = radial waves 231 | | 2 = radial waves
232 | | 3-7 = undefined 232 | | 3-7 = undefined
233 | +-- gradient #2 inverted? 233 | +-- gradient #2 inverted?
234 +-- alternating columns inverted? 234 +-- alternating columns inverted?
235 */ 235 */
236static struct background_pattern { 236static struct background_pattern {
237 ush type; 237 ush type;
238 int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */ 238 int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */
239 int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/ 239 int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/
240} bg[] = { 240} bg[] = {
241 {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */ 241 {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */
242 {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */ 242 {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */
243 {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */ 243 {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */
244 {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */ 244 {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */
245 {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */ 245 {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */
246 {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */ 246 {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */
247 {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */ 247 {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */
248 {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */ 248 {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */
249 {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */ 249 {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */
250 {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */ 250 {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */
251 {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */ 251 {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */
252 {1, 3,0, 0,0}, /* diamonds: medium green vs. black */ 252 {1, 3,0, 0,0}, /* diamonds: medium green vs. black */
253 {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */ 253 {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */
254 {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */ 254 {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */
255 {2, 16, 256, 100, 250}, /* radial: very tight spiral */ 255 {2, 16, 256, 100, 250}, /* radial: very tight spiral */
256 {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */ 256 {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */
257}; 257};
258static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern); 258static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);
259 259
260 260
261/* Windows-specific global variables (could go in struct, but messy...) */ 261/* Windows-specific global variables (could go in struct, but messy...) */
262static ulg wimage_rowbytes; 262static ulg wimage_rowbytes;
263static uch *dib; 263static uch *dib;
264static uch *wimage_data; 264static uch *wimage_data;
265static BITMAPINFOHEADER *bmih; 265static BITMAPINFOHEADER *bmih;
266 266
267static HWND global_hwnd; 267static HWND global_hwnd;
268static HINSTANCE global_hInst; 268static HINSTANCE global_hInst;
269static int global_showmode; 269static int global_showmode;
270 270
271 271
272 272
273 273
274int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode) 274int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
275{ 275{
276 char *args[1024]; /* arbitrary limit, but should suffice */ 276 char *args[1024]; /* arbitrary limit, but should suffice */
277 char **argv = args; 277 char **argv = args;
278 char *p, *q, *bgstr = NULL; 278 char *p, *q, *bgstr = NULL;
279 int argc = 0; 279 int argc = 0;
280 int rc, alen, flen; 280 int rc, alen, flen;
281 int error = 0; 281 int error = 0;
282 int timing = FALSE; 282 int timing = FALSE;
283 int have_bg = FALSE; 283 int have_bg = FALSE;
284 double LUT_exponent; /* just the lookup table */ 284 double LUT_exponent; /* just the lookup table */
285 double CRT_exponent = 2.2; /* just the monitor */ 285 double CRT_exponent = 2.2; /* just the monitor */
286 double default_display_exponent; /* whole display system */ 286 double default_display_exponent; /* whole display system */
287 MSG msg; 287 MSG msg;
288 288
289 289
290 /* First initialize a few things, just to be sure--memset takes care of 290 /* First initialize a few things, just to be sure--memset takes care of
291 * default background color (black), booleans (FALSE), pointers (NULL), 291 * default background color (black), booleans (FALSE), pointers (NULL),
292 * etc. */ 292 * etc. */
293 293
294 global_hInst = hInst; 294 global_hInst = hInst;
295 global_showmode = showmode; 295 global_showmode = showmode;
296 filename = (char *)NULL; 296 filename = (char *)NULL;
297 memset(&rpng2_info, 0, sizeof(mainprog_info)); 297 memset(&rpng2_info, 0, sizeof(mainprog_info));
298 298
299#ifndef __CYGWIN__ 299#ifndef __CYGWIN__
300 /* Next reenable console output, which normally goes to the bit bucket 300 /* Next reenable console output, which normally goes to the bit bucket
301 * for windowed apps. Closing the console window will terminate the 301 * for windowed apps. Closing the console window will terminate the
302 * app. Thanks to David.Geldreich@realviz.com for supplying the magical 302 * app. Thanks to David.Geldreich@realviz.com for supplying the magical
303 * incantation. */ 303 * incantation. */
304 304
305 AllocConsole(); 305 AllocConsole();
306 freopen("CONOUT$", "a", stderr); 306 freopen("CONOUT$", "a", stderr);
307 freopen("CONOUT$", "a", stdout); 307 freopen("CONOUT$", "a", stdout);
308#endif 308#endif
309 309
310 /* Set the default value for our display-system exponent, i.e., the 310 /* Set the default value for our display-system exponent, i.e., the
311 * product of the CRT exponent and the exponent corresponding to 311 * product of the CRT exponent and the exponent corresponding to
312 * the frame-buffer's lookup table (LUT), if any. This is not an 312 * the frame-buffer's lookup table (LUT), if any. This is not an
313 * exhaustive list of LUT values (e.g., OpenStep has a lot of weird 313 * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
314 * ones), but it should cover 99% of the current possibilities. And 314 * ones), but it should cover 99% of the current possibilities. And
315 * yes, these ifdefs are completely wasted in a Windows program... */ 315 * yes, these ifdefs are completely wasted in a Windows program... */
316 316
317#if defined(NeXT) 317#if defined(NeXT)
318 /* third-party utilities can modify the default LUT exponent */ 318 /* third-party utilities can modify the default LUT exponent */
319 LUT_exponent = 1.0 / 2.2; 319 LUT_exponent = 1.0 / 2.2;
320 /* 320 /*
321 if (some_next_function_that_returns_gamma(&next_gamma)) 321 if (some_next_function_that_returns_gamma(&next_gamma))
322 LUT_exponent = 1.0 / next_gamma; 322 LUT_exponent = 1.0 / next_gamma;
323 */ 323 */
324#elif defined(sgi) 324#elif defined(sgi)
325 LUT_exponent = 1.0 / 1.7; 325 LUT_exponent = 1.0 / 1.7;
326 /* there doesn't seem to be any documented function to 326 /* there doesn't seem to be any documented function to
327 * get the "gamma" value, so we do it the hard way */ 327 * get the "gamma" value, so we do it the hard way */
328 infile = fopen("/etc/config/system.glGammaVal", "r"); 328 infile = fopen("/etc/config/system.glGammaVal", "r");
329 if (infile) { 329 if (infile) {
330 double sgi_gamma; 330 double sgi_gamma;
331 331
332 fgets(tmpline, 80, infile); 332 fgets(tmpline, 80, infile);
333 fclose(infile); 333 fclose(infile);
334 sgi_gamma = atof(tmpline); 334 sgi_gamma = atof(tmpline);
335 if (sgi_gamma > 0.0) 335 if (sgi_gamma > 0.0)
336 LUT_exponent = 1.0 / sgi_gamma; 336 LUT_exponent = 1.0 / sgi_gamma;
337 } 337 }
338#elif defined(Macintosh) 338#elif defined(Macintosh)
339 LUT_exponent = 1.8 / 2.61; 339 LUT_exponent = 1.8 / 2.61;
340 /* 340 /*
341 if (some_mac_function_that_returns_gamma(&mac_gamma)) 341 if (some_mac_function_that_returns_gamma(&mac_gamma))
342 LUT_exponent = mac_gamma / 2.61; 342 LUT_exponent = mac_gamma / 2.61;
343 */ 343 */
344#else 344#else
345 LUT_exponent = 1.0; /* assume no LUT: most PCs */ 345 LUT_exponent = 1.0; /* assume no LUT: most PCs */
346#endif 346#endif
347 347
348 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ 348 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
349 default_display_exponent = LUT_exponent * CRT_exponent; 349 default_display_exponent = LUT_exponent * CRT_exponent;
350 350
351 351
352 /* If the user has set the SCREEN_GAMMA environment variable as suggested 352 /* If the user has set the SCREEN_GAMMA environment variable as suggested
353 * (somewhat imprecisely) in the libpng documentation, use that; otherwise 353 * (somewhat imprecisely) in the libpng documentation, use that; otherwise
354 * use the default value we just calculated. Either way, the user may 354 * use the default value we just calculated. Either way, the user may
355 * override this via a command-line option. */ 355 * override this via a command-line option. */
356 356
357 if ((p = getenv("SCREEN_GAMMA")) != NULL) 357 if ((p = getenv("SCREEN_GAMMA")) != NULL)
358 rpng2_info.display_exponent = atof(p); 358 rpng2_info.display_exponent = atof(p);
359 else 359 else
360 rpng2_info.display_exponent = default_display_exponent; 360 rpng2_info.display_exponent = default_display_exponent;
361 361
362 362
363 /* Windows really hates command lines, so we have to set up our own argv. 363 /* Windows really hates command lines, so we have to set up our own argv.
364 * Note that we do NOT bother with quoted arguments here, so don't use 364 * Note that we do NOT bother with quoted arguments here, so don't use
365 * filenames with spaces in 'em! */ 365 * filenames with spaces in 'em! */
366 366
367 argv[argc++] = PROGNAME; 367 argv[argc++] = PROGNAME;
368 p = cmd; 368 p = cmd;
369 for (;;) { 369 for (;;) {
370 if (*p == ' ') 370 if (*p == ' ')
371 while (*++p == ' ') 371 while (*++p == ' ')
372 ; 372 ;
373 /* now p points at the first non-space after some spaces */ 373 /* now p points at the first non-space after some spaces */
374 if (*p == '\0') 374 if (*p == '\0')
375 break; /* nothing after the spaces: done */ 375 break; /* nothing after the spaces: done */
376 argv[argc++] = q = p; 376 argv[argc++] = q = p;
377 while (*q && *q != ' ') 377 while (*q && *q != ' ')
378 ++q; 378 ++q;
379 /* now q points at a space or the end of the string */ 379 /* now q points at a space or the end of the string */
380 if (*q == '\0') 380 if (*q == '\0')
381 break; /* last argv already terminated; quit */ 381 break; /* last argv already terminated; quit */
382 *q = '\0'; /* change space to terminator */ 382 *q = '\0'; /* change space to terminator */
383 p = q + 1; 383 p = q + 1;
384 } 384 }
385 argv[argc] = NULL; /* terminate the argv array itself */ 385 argv[argc] = NULL; /* terminate the argv array itself */
386 386
387 387
388 /* Now parse the command line for options and the PNG filename. */ 388 /* Now parse the command line for options and the PNG filename. */
389 389
390 while (*++argv && !error) { 390 while (*++argv && !error) {
391 if (!strncmp(*argv, "-gamma", 2)) { 391 if (!strncmp(*argv, "-gamma", 2)) {
392 if (!*++argv) 392 if (!*++argv)
393 ++error; 393 ++error;
394 else { 394 else {
395 rpng2_info.display_exponent = atof(*argv); 395 rpng2_info.display_exponent = atof(*argv);
396 if (rpng2_info.display_exponent <= 0.0) 396 if (rpng2_info.display_exponent <= 0.0)
397 ++error; 397 ++error;
398 } 398 }
399 } else if (!strncmp(*argv, "-bgcolor", 4)) { 399 } else if (!strncmp(*argv, "-bgcolor", 4)) {
400 if (!*++argv) 400 if (!*++argv)
401 ++error; 401 ++error;
402 else { 402 else {
403 bgstr = *argv; 403 bgstr = *argv;
404 if (strlen(bgstr) != 7 || bgstr[0] != '#') 404 if (strlen(bgstr) != 7 || bgstr[0] != '#')
405 ++error; 405 ++error;
406 else { 406 else {
407 have_bg = TRUE; 407 have_bg = TRUE;
408 bg_image = FALSE; 408 bg_image = FALSE;
409 } 409 }
410 } 410 }
411 } else if (!strncmp(*argv, "-bgpat", 4)) { 411 } else if (!strncmp(*argv, "-bgpat", 4)) {
412 if (!*++argv) 412 if (!*++argv)
413 ++error; 413 ++error;
414 else { 414 else {
415 pat = atoi(*argv) - 1; 415 pat = atoi(*argv) - 1;
416 if (pat < 0 || pat >= num_bgpat) 416 if (pat < 0 || pat >= num_bgpat)
417 ++error; 417 ++error;
418 else { 418 else {
419 bg_image = TRUE; 419 bg_image = TRUE;
420 have_bg = FALSE; 420 have_bg = FALSE;
421 } 421 }
422 } 422 }
423 } else if (!strncmp(*argv, "-timing", 2)) { 423 } else if (!strncmp(*argv, "-timing", 2)) {
424 timing = TRUE; 424 timing = TRUE;
425 } else { 425 } else {
426 if (**argv != '-') { 426 if (**argv != '-') {
427 filename = *argv; 427 filename = *argv;
428 if (argv[1]) /* shouldn't be any more args after filename */ 428 if (argv[1]) /* shouldn't be any more args after filename */
429 ++error; 429 ++error;
430 } else 430 } else
431 ++error; /* not expecting any other options */ 431 ++error; /* not expecting any other options */
432 } 432 }
433 } 433 }
434 434
435 if (!filename) 435 if (!filename)
436 ++error; 436 ++error;
437 437
438 438
439 /* print usage screen if any errors up to this point */ 439 /* print usage screen if any errors up to this point */
440 440
441 if (error) { 441 if (error) {
442#ifndef __CYGWIN__ 442#ifndef __CYGWIN__
443 int ch; 443 int ch;
444#endif 444#endif
445 445
446 fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); 446 fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname);
447 readpng2_version_info(); 447 readpng2_version_info();
448 fprintf(stderr, "\n" 448 fprintf(stderr, "\n"
449 "Usage: %s [-gamma exp] [-bgcolor bg | -bgpat pat] [-timing]\n" 449 "Usage: %s [-gamma exp] [-bgcolor bg | -bgpat pat] [-timing]\n"
450 " %*s file.png\n\n" 450 " %*s file.png\n\n"
451 " exp \ttransfer-function exponent (``gamma'') of the display\n" 451 " exp \ttransfer-function exponent (``gamma'') of the display\n"
452 "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" 452 "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
453 "\t\t to the product of the lookup-table exponent (varies)\n" 453 "\t\t to the product of the lookup-table exponent (varies)\n"
454 "\t\t and the CRT exponent (usually 2.2); must be positive\n" 454 "\t\t and the CRT exponent (usually 2.2); must be positive\n"
455 " bg \tdesired background color in 7-character hex RGB format\n" 455 " bg \tdesired background color in 7-character hex RGB format\n"
456 "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" 456 "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
457 "\t\t used with transparent images; overrides -bgpat option\n" 457 "\t\t used with transparent images; overrides -bgpat option\n"
458 " pat \tdesired background pattern number (1-%d); used with\n" 458 " pat \tdesired background pattern number (1-%d); used with\n"
459 "\t\t transparent images; overrides -bgcolor option\n" 459 "\t\t transparent images; overrides -bgcolor option\n"
460 " -timing\tenables delay for every block read, to simulate modem\n" 460 " -timing\tenables delay for every block read, to simulate modem\n"
461 "\t\t download of image (~36 Kbps)\n" 461 "\t\t download of image (~36 Kbps)\n"
462 "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n" 462 "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
463#ifndef __CYGWIN__ 463#ifndef __CYGWIN__
464 "Press Q or Esc to quit this usage screen. ", 464 "Press Q or Esc to quit this usage screen. ",
465#else 465#else
466 , 466 ,
467#endif 467#endif
468 PROGNAME, 468 PROGNAME,
469#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__)) && \ 469#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__)) && \
470 !(defined(__CYGWIN__) || defined(__MINGW32__)) 470 !(defined(__CYGWIN__) || defined(__MINGW32__))
471 (int)strlen(PROGNAME), " ", 471 (int)strlen(PROGNAME), " ",
472#endif 472#endif
473 (int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat); 473 (int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat);
474 fflush(stderr); 474 fflush(stderr);
475#ifndef __CYGWIN__ 475#ifndef __CYGWIN__
476 do 476 do
477 ch = _getch(); 477 ch = _getch();
478 while (ch != 'q' && ch != 'Q' && ch != 0x1B); 478 while (ch != 'q' && ch != 'Q' && ch != 0x1B);
479#endif 479#endif
480 exit(1); 480 exit(1);
481 } 481 }
482 482
483 483
484 if (!(infile = fopen(filename, "rb"))) { 484 if (!(infile = fopen(filename, "rb"))) {
485 fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); 485 fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
486 ++error; 486 ++error;
487 } else { 487 } else {
488 incount = fread(inbuf, 1, INBUFSIZE, infile); 488 incount = fread(inbuf, 1, INBUFSIZE, infile);
489 if (incount < 8 || !readpng2_check_sig(inbuf, 8)) { 489 if (incount < 8 || !readpng2_check_sig(inbuf, 8)) {
490 fprintf(stderr, PROGNAME 490 fprintf(stderr, PROGNAME
491 ": [%s] is not a PNG file: incorrect signature\n", 491 ": [%s] is not a PNG file: incorrect signature\n",
492 filename); 492 filename);
493 ++error; 493 ++error;
494 } else if ((rc = readpng2_init(&rpng2_info)) != 0) { 494 } else if ((rc = readpng2_init(&rpng2_info)) != 0) {
495 switch (rc) { 495 switch (rc) {
496 case 2: 496 case 2:
497 fprintf(stderr, PROGNAME 497 fprintf(stderr, PROGNAME
498 ": [%s] has bad IHDR (libpng longjmp)\n", filename); 498 ": [%s] has bad IHDR (libpng longjmp)\n", filename);
499 break; 499 break;
500 case 4: 500 case 4:
501 fprintf(stderr, PROGNAME ": insufficient memory\n"); 501 fprintf(stderr, PROGNAME ": insufficient memory\n");
502 break; 502 break;
503 default: 503 default:
504 fprintf(stderr, PROGNAME 504 fprintf(stderr, PROGNAME
505 ": unknown readpng2_init() error\n"); 505 ": unknown readpng2_init() error\n");
506 break; 506 break;
507 } 507 }
508 ++error; 508 ++error;
509 } 509 }
510 if (error) 510 if (error)
511 fclose(infile); 511 fclose(infile);
512 } 512 }
513 513
514 514
515 if (error) { 515 if (error) {
516#ifndef __CYGWIN__ 516#ifndef __CYGWIN__
517 int ch; 517 int ch;
518#endif 518#endif
519 519
520 fprintf(stderr, PROGNAME ": aborting.\n"); 520 fprintf(stderr, PROGNAME ": aborting.\n");
521#ifndef __CYGWIN__ 521#ifndef __CYGWIN__
522 do 522 do
523 ch = _getch(); 523 ch = _getch();
524 while (ch != 'q' && ch != 'Q' && ch != 0x1B); 524 while (ch != 'q' && ch != 'Q' && ch != 0x1B);
525#endif 525#endif
526 exit(2); 526 exit(2);
527 } else { 527 } else {
528 fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); 528 fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
529#ifndef __CYGWIN__ 529#ifndef __CYGWIN__
530 fprintf(stderr, 530 fprintf(stderr,
531 "\n [console window: closing this window will terminate %s]\n\n", 531 "\n [console window: closing this window will terminate %s]\n\n",
532 PROGNAME); 532 PROGNAME);
533#endif 533#endif
534 fflush(stderr); 534 fflush(stderr);
535 } 535 }
536 536
537 537
538 /* set the title-bar string, but make sure buffer doesn't overflow */ 538 /* set the title-bar string, but make sure buffer doesn't overflow */
539 539
540 alen = strlen(appname); 540 alen = strlen(appname);
541 flen = strlen(filename); 541 flen = strlen(filename);
542 if (alen + flen + 3 > 1023) 542 if (alen + flen + 3 > 1023)
543 sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); 543 sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
544 else 544 else
545 sprintf(titlebar, "%s: %s", appname, filename); 545 sprintf(titlebar, "%s: %s", appname, filename);
546 546
547 547
548 /* set some final rpng2_info variables before entering main data loop */ 548 /* set some final rpng2_info variables before entering main data loop */
549 549
550 if (have_bg) { 550 if (have_bg) {
551 unsigned r, g, b; /* this approach quiets compiler warnings */ 551 unsigned r, g, b; /* this approach quiets compiler warnings */
552 552
553 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); 553 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
554 rpng2_info.bg_red = (uch)r; 554 rpng2_info.bg_red = (uch)r;
555 rpng2_info.bg_green = (uch)g; 555 rpng2_info.bg_green = (uch)g;
556 rpng2_info.bg_blue = (uch)b; 556 rpng2_info.bg_blue = (uch)b;
557 } else 557 } else
558 rpng2_info.need_bgcolor = TRUE; 558 rpng2_info.need_bgcolor = TRUE;
559 559
560 rpng2_info.state = kPreInit; 560 rpng2_info.state = kPreInit;
561 rpng2_info.mainprog_init = rpng2_win_init; 561 rpng2_info.mainprog_init = rpng2_win_init;
562 rpng2_info.mainprog_display_row = rpng2_win_display_row; 562 rpng2_info.mainprog_display_row = rpng2_win_display_row;
563 rpng2_info.mainprog_finish_display = rpng2_win_finish_display; 563 rpng2_info.mainprog_finish_display = rpng2_win_finish_display;
564 564
565 565
566 /* OK, this is the fun part: call readpng2_decode_data() at the start of 566 /* OK, this is the fun part: call readpng2_decode_data() at the start of
567 * the loop to deal with our first buffer of data (read in above to verify 567 * the loop to deal with our first buffer of data (read in above to verify
568 * that the file is a PNG image), then loop through the file and continue 568 * that the file is a PNG image), then loop through the file and continue
569 * calling the same routine to handle each chunk of data. It in turn 569 * calling the same routine to handle each chunk of data. It in turn
570 * passes the data to libpng, which will invoke one or more of our call- 570 * passes the data to libpng, which will invoke one or more of our call-
571 * backs as decoded data become available. We optionally call Sleep() for 571 * backs as decoded data become available. We optionally call Sleep() for
572 * one second per iteration to simulate downloading the image via an analog 572 * one second per iteration to simulate downloading the image via an analog
573 * modem. */ 573 * modem. */
574 574
575 for (;;) { 575 for (;;) {
576 Trace((stderr, "about to call readpng2_decode_data()\n")) 576 Trace((stderr, "about to call readpng2_decode_data()\n"))
577 if (readpng2_decode_data(&rpng2_info, inbuf, incount)) 577 if (readpng2_decode_data(&rpng2_info, inbuf, incount))
578 ++error; 578 ++error;
579 Trace((stderr, "done with readpng2_decode_data()\n")) 579 Trace((stderr, "done with readpng2_decode_data()\n"))
580 580
581 if (error || incount != INBUFSIZE || rpng2_info.state == kDone) { 581 if (error || incount != INBUFSIZE || rpng2_info.state == kDone) {
582 if (rpng2_info.state == kDone) { 582 if (rpng2_info.state == kDone) {
583 Trace((stderr, "done decoding PNG image\n")) 583 Trace((stderr, "done decoding PNG image\n"))
584 } else if (ferror(infile)) { 584 } else if (ferror(infile)) {
585 fprintf(stderr, PROGNAME 585 fprintf(stderr, PROGNAME
586 ": error while reading PNG image file\n"); 586 ": error while reading PNG image file\n");
587 exit(3); 587 exit(3);
588 } else if (feof(infile)) { 588 } else if (feof(infile)) {
589 fprintf(stderr, PROGNAME ": end of file reached " 589 fprintf(stderr, PROGNAME ": end of file reached "
590 "(unexpectedly) while reading PNG image file\n"); 590 "(unexpectedly) while reading PNG image file\n");
591 exit(3); 591 exit(3);
592 } else /* if (error) */ { 592 } else /* if (error) */ {
593 /* will print error message below */ 593 /* will print error message below */
594 } 594 }
595 break; 595 break;
596 } 596 }
597 597
598 if (timing) 598 if (timing)
599 Sleep(1000L); 599 Sleep(1000L);
600 600
601 incount = fread(inbuf, 1, INBUFSIZE, infile); 601 incount = fread(inbuf, 1, INBUFSIZE, infile);
602 } 602 }
603 603
604 604
605 /* clean up PNG stuff and report any decoding errors */ 605 /* clean up PNG stuff and report any decoding errors */
606 606
607 fclose(infile); 607 fclose(infile);
608 Trace((stderr, "about to call readpng2_cleanup()\n")) 608 Trace((stderr, "about to call readpng2_cleanup()\n"))
609 readpng2_cleanup(&rpng2_info); 609 readpng2_cleanup(&rpng2_info);
610 610
611 if (error) { 611 if (error) {
612 fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n"); 612 fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n");
613 exit(3); 613 exit(3);
614 } 614 }
615 615
616 616
617 /* wait for the user to tell us when to quit */ 617 /* wait for the user to tell us when to quit */
618 618
619 while (GetMessage(&msg, NULL, 0, 0)) { 619 while (GetMessage(&msg, NULL, 0, 0)) {
620 TranslateMessage(&msg); 620 TranslateMessage(&msg);
621 DispatchMessage(&msg); 621 DispatchMessage(&msg);
622 } 622 }
623 623
624 624
625 /* we're done: clean up all image and Windows resources and go away */ 625 /* we're done: clean up all image and Windows resources and go away */
626 626
627 Trace((stderr, "about to call rpng2_win_cleanup()\n")) 627 Trace((stderr, "about to call rpng2_win_cleanup()\n"))
628 rpng2_win_cleanup(); 628 rpng2_win_cleanup();
629 629
630 return msg.wParam; 630 return msg.wParam;
631} 631}
632 632
633 633
634 634
635 635
636 636
637/* this function is called by readpng2_info_callback() in readpng2.c, which 637/* this function is called by readpng2_info_callback() in readpng2.c, which
638 * in turn is called by libpng after all of the pre-IDAT chunks have been 638 * in turn is called by libpng after all of the pre-IDAT chunks have been
639 * read and processed--i.e., we now have enough info to finish initializing */ 639 * read and processed--i.e., we now have enough info to finish initializing */
640 640
641static void rpng2_win_init() 641static void rpng2_win_init()
642{ 642{
643 ulg i; 643 ulg i;
644 ulg rowbytes = rpng2_info.rowbytes; 644 ulg rowbytes = rpng2_info.rowbytes;
645 645
646 Trace((stderr, "beginning rpng2_win_init()\n")) 646 Trace((stderr, "beginning rpng2_win_init()\n"))
647 Trace((stderr, " rowbytes = %d\n", rpng2_info.rowbytes)) 647 Trace((stderr, " rowbytes = %d\n", rpng2_info.rowbytes))
648 Trace((stderr, " width = %ld\n", rpng2_info.width)) 648 Trace((stderr, " width = %ld\n", rpng2_info.width))
649 Trace((stderr, " height = %ld\n", rpng2_info.height)) 649 Trace((stderr, " height = %ld\n", rpng2_info.height))
650 650
651 rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height); 651 rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
652 if (!rpng2_info.image_data) { 652 if (!rpng2_info.image_data) {
653 readpng2_cleanup(&rpng2_info); 653 readpng2_cleanup(&rpng2_info);
654 return; 654 return;
655 } 655 }
656 656
657 rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *)); 657 rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *));
658 if (!rpng2_info.row_pointers) { 658 if (!rpng2_info.row_pointers) {
659 free(rpng2_info.image_data); 659 free(rpng2_info.image_data);
660 rpng2_info.image_data = NULL; 660 rpng2_info.image_data = NULL;
661 readpng2_cleanup(&rpng2_info); 661 readpng2_cleanup(&rpng2_info);
662 return; 662 return;
663 } 663 }
664 664
665 for (i = 0; i < rpng2_info.height; ++i) 665 for (i = 0; i < rpng2_info.height; ++i)
666 rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes; 666 rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes;
667 667
668/*--------------------------------------------------------------------------- 668/*---------------------------------------------------------------------------
669 Do the basic Windows initialization stuff, make the window, and fill it 669 Do the basic Windows initialization stuff, make the window, and fill it
670 with the user-specified, file-specified or default background color. 670 with the user-specified, file-specified or default background color.
671 ---------------------------------------------------------------------------*/ 671 ---------------------------------------------------------------------------*/
672 672
673 if (rpng2_win_create_window()) { 673 if (rpng2_win_create_window()) {
674 readpng2_cleanup(&rpng2_info); 674 readpng2_cleanup(&rpng2_info);
675 return; 675 return;
676 } 676 }
677 677
678 rpng2_info.state = kWindowInit; 678 rpng2_info.state = kWindowInit;
679} 679}
680 680
681 681
682 682
683 683
684 684
685static int rpng2_win_create_window() 685static int rpng2_win_create_window()
686{ 686{
687 uch bg_red = rpng2_info.bg_red; 687 uch bg_red = rpng2_info.bg_red;
688 uch bg_green = rpng2_info.bg_green; 688 uch bg_green = rpng2_info.bg_green;
689 uch bg_blue = rpng2_info.bg_blue; 689 uch bg_blue = rpng2_info.bg_blue;
690 uch *dest; 690 uch *dest;
691 int extra_width, extra_height; 691 int extra_width, extra_height;
692 ulg i, j; 692 ulg i, j;
693 WNDCLASSEX wndclass; 693 WNDCLASSEX wndclass;
694 RECT rect; 694 RECT rect;
695 695
696 696
697/*--------------------------------------------------------------------------- 697/*---------------------------------------------------------------------------
698 Allocate memory for the display-specific version of the image (round up 698 Allocate memory for the display-specific version of the image (round up
699 to multiple of 4 for Windows DIB). 699 to multiple of 4 for Windows DIB).
700 ---------------------------------------------------------------------------*/ 700 ---------------------------------------------------------------------------*/
701 701
702 wimage_rowbytes = ((3*rpng2_info.width + 3L) >> 2) << 2; 702 wimage_rowbytes = ((3*rpng2_info.width + 3L) >> 2) << 2;
703 703
704 if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) + 704 if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
705 wimage_rowbytes*rpng2_info.height))) 705 wimage_rowbytes*rpng2_info.height)))
706 { 706 {
707 return 4; /* fail */ 707 return 4; /* fail */
708 } 708 }
709 709
710/*--------------------------------------------------------------------------- 710/*---------------------------------------------------------------------------
711 Initialize the DIB. Negative height means to use top-down BMP ordering 711 Initialize the DIB. Negative height means to use top-down BMP ordering
712 (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8 712 (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8
713 implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values 713 implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values
714 directly => wimage_data begins immediately after BMP header. 714 directly => wimage_data begins immediately after BMP header.
715 ---------------------------------------------------------------------------*/ 715 ---------------------------------------------------------------------------*/
716 716
717 memset(dib, 0, sizeof(BITMAPINFOHEADER)); 717 memset(dib, 0, sizeof(BITMAPINFOHEADER));
718 bmih = (BITMAPINFOHEADER *)dib; 718 bmih = (BITMAPINFOHEADER *)dib;
719 bmih->biSize = sizeof(BITMAPINFOHEADER); 719 bmih->biSize = sizeof(BITMAPINFOHEADER);
720 bmih->biWidth = rpng2_info.width; 720 bmih->biWidth = rpng2_info.width;
721 bmih->biHeight = -((long)rpng2_info.height); 721 bmih->biHeight = -((long)rpng2_info.height);
722 bmih->biPlanes = 1; 722 bmih->biPlanes = 1;
723 bmih->biBitCount = 24; 723 bmih->biBitCount = 24;
724 bmih->biCompression = 0; 724 bmih->biCompression = 0;
725 wimage_data = dib + sizeof(BITMAPINFOHEADER); 725 wimage_data = dib + sizeof(BITMAPINFOHEADER);
726 726
727/*--------------------------------------------------------------------------- 727/*---------------------------------------------------------------------------
728 Fill window with the specified background color (default is black), but 728 Fill window with the specified background color (default is black), but
729 defer loading faked "background image" until window is displayed (may be 729 defer loading faked "background image" until window is displayed (may be
730 slow to compute). Data are in BGR order. 730 slow to compute). Data are in BGR order.
731 ---------------------------------------------------------------------------*/ 731 ---------------------------------------------------------------------------*/
732 732
733 if (bg_image) { /* just fill with black for now */ 733 if (bg_image) { /* just fill with black for now */
734 memset(wimage_data, 0, wimage_rowbytes*rpng2_info.height); 734 memset(wimage_data, 0, wimage_rowbytes*rpng2_info.height);
735 } else { 735 } else {
736 for (j = 0; j < rpng2_info.height; ++j) { 736 for (j = 0; j < rpng2_info.height; ++j) {
737 dest = wimage_data + j*wimage_rowbytes; 737 dest = wimage_data + j*wimage_rowbytes;
738 for (i = rpng2_info.width; i > 0; --i) { 738 for (i = rpng2_info.width; i > 0; --i) {
739 *dest++ = bg_blue; 739 *dest++ = bg_blue;
740 *dest++ = bg_green; 740 *dest++ = bg_green;
741 *dest++ = bg_red; 741 *dest++ = bg_red;
742 } 742 }
743 } 743 }
744 } 744 }
745 745
746/*--------------------------------------------------------------------------- 746/*---------------------------------------------------------------------------
747 Set the window parameters. 747 Set the window parameters.
748 ---------------------------------------------------------------------------*/ 748 ---------------------------------------------------------------------------*/
749 749
750 memset(&wndclass, 0, sizeof(wndclass)); 750 memset(&wndclass, 0, sizeof(wndclass));
751 751
752 wndclass.cbSize = sizeof(wndclass); 752 wndclass.cbSize = sizeof(wndclass);
753 wndclass.style = CS_HREDRAW | CS_VREDRAW; 753 wndclass.style = CS_HREDRAW | CS_VREDRAW;
754 wndclass.lpfnWndProc = rpng2_win_wndproc; 754 wndclass.lpfnWndProc = rpng2_win_wndproc;
755 wndclass.hInstance = global_hInst; 755 wndclass.hInstance = global_hInst;
756 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 756 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
757 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 757 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
758 wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); 758 wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
759 wndclass.lpszMenuName = NULL; 759 wndclass.lpszMenuName = NULL;
760 wndclass.lpszClassName = progname; 760 wndclass.lpszClassName = progname;
761 wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 761 wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
762 762
763 RegisterClassEx(&wndclass); 763 RegisterClassEx(&wndclass);
764 764
765/*--------------------------------------------------------------------------- 765/*---------------------------------------------------------------------------
766 Finally, create the window. 766 Finally, create the window.
767 ---------------------------------------------------------------------------*/ 767 ---------------------------------------------------------------------------*/
768 768
769 extra_width = 2*(GetSystemMetrics(SM_CXBORDER) + 769 extra_width = 2*(GetSystemMetrics(SM_CXBORDER) +
770 GetSystemMetrics(SM_CXDLGFRAME)); 770 GetSystemMetrics(SM_CXDLGFRAME));
771 extra_height = 2*(GetSystemMetrics(SM_CYBORDER) + 771 extra_height = 2*(GetSystemMetrics(SM_CYBORDER) +
772 GetSystemMetrics(SM_CYDLGFRAME)) + 772 GetSystemMetrics(SM_CYDLGFRAME)) +
773 GetSystemMetrics(SM_CYCAPTION); 773 GetSystemMetrics(SM_CYCAPTION);
774 774
775 global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW, 775 global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW,
776 CW_USEDEFAULT, CW_USEDEFAULT, rpng2_info.width+extra_width, 776 CW_USEDEFAULT, CW_USEDEFAULT, rpng2_info.width+extra_width,
777 rpng2_info.height+extra_height, NULL, NULL, global_hInst, NULL); 777 rpng2_info.height+extra_height, NULL, NULL, global_hInst, NULL);
778 778
779 ShowWindow(global_hwnd, global_showmode); 779 ShowWindow(global_hwnd, global_showmode);
780 UpdateWindow(global_hwnd); 780 UpdateWindow(global_hwnd);
781 781
782/*--------------------------------------------------------------------------- 782/*---------------------------------------------------------------------------
783 Now compute the background image and display it. If it fails (memory 783 Now compute the background image and display it. If it fails (memory
784 allocation), revert to a plain background color. 784 allocation), revert to a plain background color.
785 ---------------------------------------------------------------------------*/ 785 ---------------------------------------------------------------------------*/
786 786
787 if (bg_image) { 787 if (bg_image) {
788 static const char *msg = "Computing background image..."; 788 static const char *msg = "Computing background image...";
789 int x, y, len = strlen(msg); 789 int x, y, len = strlen(msg);
790 HDC hdc = GetDC(global_hwnd); 790 HDC hdc = GetDC(global_hwnd);
791 TEXTMETRIC tm; 791 TEXTMETRIC tm;
792 792
793 GetTextMetrics(hdc, &tm); 793 GetTextMetrics(hdc, &tm);
794 x = (rpng2_info.width - len*tm.tmAveCharWidth)/2; 794 x = (rpng2_info.width - len*tm.tmAveCharWidth)/2;
795 y = (rpng2_info.height - tm.tmHeight)/2; 795 y = (rpng2_info.height - tm.tmHeight)/2;
796 SetBkMode(hdc, TRANSPARENT); 796 SetBkMode(hdc, TRANSPARENT);
797 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); 797 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
798 /* this can still begin out of bounds even if x is positive (???): */ 798 /* this can still begin out of bounds even if x is positive (???): */
799 TextOut(hdc, ((x < 0)? 0 : x), ((y < 0)? 0 : y), msg, len); 799 TextOut(hdc, ((x < 0)? 0 : x), ((y < 0)? 0 : y), msg, len);
800 ReleaseDC(global_hwnd, hdc); 800 ReleaseDC(global_hwnd, hdc);
801 801
802 rpng2_win_load_bg_image(); /* resets bg_image if fails */ 802 rpng2_win_load_bg_image(); /* resets bg_image if fails */
803 } 803 }
804 804
805 if (!bg_image) { 805 if (!bg_image) {
806 for (j = 0; j < rpng2_info.height; ++j) { 806 for (j = 0; j < rpng2_info.height; ++j) {
807 dest = wimage_data + j*wimage_rowbytes; 807 dest = wimage_data + j*wimage_rowbytes;
808 for (i = rpng2_info.width; i > 0; --i) { 808 for (i = rpng2_info.width; i > 0; --i) {
809 *dest++ = bg_blue; 809 *dest++ = bg_blue;
810 *dest++ = bg_green; 810 *dest++ = bg_green;
811 *dest++ = bg_red; 811 *dest++ = bg_red;
812 } 812 }
813 } 813 }
814 } 814 }
815 815
816 rect.left = 0L; 816 rect.left = 0L;
817 rect.top = 0L; 817 rect.top = 0L;
818 rect.right = (LONG)rpng2_info.width; /* possibly off by one? */ 818 rect.right = (LONG)rpng2_info.width; /* possibly off by one? */
819 rect.bottom = (LONG)rpng2_info.height; /* possibly off by one? */ 819 rect.bottom = (LONG)rpng2_info.height; /* possibly off by one? */
820 InvalidateRect(global_hwnd, &rect, FALSE); 820 InvalidateRect(global_hwnd, &rect, FALSE);
821 UpdateWindow(global_hwnd); /* similar to XFlush() */ 821 UpdateWindow(global_hwnd); /* similar to XFlush() */
822 822
823 return 0; 823 return 0;
824 824
825} /* end function rpng2_win_create_window() */ 825} /* end function rpng2_win_create_window() */
826 826
827 827
828 828
829 829
830 830
831static int rpng2_win_load_bg_image() 831static int rpng2_win_load_bg_image()
832{ 832{
833 uch *src, *dest; 833 uch *src, *dest;
834 uch r1, r2, g1, g2, b1, b2; 834 uch r1, r2, g1, g2, b1, b2;
835 uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv; 835 uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;
836 int k, hmax, max; 836 int k, hmax, max;
837 int xidx, yidx, yidx_max = (bgscale-1); 837 int xidx, yidx, yidx_max = (bgscale-1);
838 int even_odd_vert, even_odd_horiz, even_odd; 838 int even_odd_vert, even_odd_horiz, even_odd;
839 int invert_gradient2 = (bg[pat].type & 0x08); 839 int invert_gradient2 = (bg[pat].type & 0x08);
840 int invert_column; 840 int invert_column;
841 ulg i, row; 841 ulg i, row;
842 842
843/*--------------------------------------------------------------------------- 843/*---------------------------------------------------------------------------
844 Allocate buffer for fake background image to be used with transparent 844 Allocate buffer for fake background image to be used with transparent
845 images; if this fails, revert to plain background color. 845 images; if this fails, revert to plain background color.
846 ---------------------------------------------------------------------------*/ 846 ---------------------------------------------------------------------------*/
847 847
848 bg_rowbytes = 3 * rpng2_info.width; 848 bg_rowbytes = 3 * rpng2_info.width;
849 bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height); 849 bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height);
850 if (!bg_data) { 850 if (!bg_data) {
851 fprintf(stderr, PROGNAME 851 fprintf(stderr, PROGNAME
852 ": unable to allocate memory for background image\n"); 852 ": unable to allocate memory for background image\n");
853 bg_image = 0; 853 bg_image = 0;
854 return 1; 854 return 1;
855 } 855 }
856 856
857/*--------------------------------------------------------------------------- 857/*---------------------------------------------------------------------------
858 Vertical gradients (ramps) in NxN squares, alternating direction and 858 Vertical gradients (ramps) in NxN squares, alternating direction and
859 colors (N == bgscale). 859 colors (N == bgscale).
860 ---------------------------------------------------------------------------*/ 860 ---------------------------------------------------------------------------*/
861 861
862 if ((bg[pat].type & 0x07) == 0) { 862 if ((bg[pat].type & 0x07) == 0) {
863 uch r1_min = rgb[bg[pat].rgb1_min].r; 863 uch r1_min = rgb[bg[pat].rgb1_min].r;
864 uch g1_min = rgb[bg[pat].rgb1_min].g; 864 uch g1_min = rgb[bg[pat].rgb1_min].g;
865 uch b1_min = rgb[bg[pat].rgb1_min].b; 865 uch b1_min = rgb[bg[pat].rgb1_min].b;
866 uch r2_min = rgb[bg[pat].rgb2_min].r; 866 uch r2_min = rgb[bg[pat].rgb2_min].r;
867 uch g2_min = rgb[bg[pat].rgb2_min].g; 867 uch g2_min = rgb[bg[pat].rgb2_min].g;
868 uch b2_min = rgb[bg[pat].rgb2_min].b; 868 uch b2_min = rgb[bg[pat].rgb2_min].b;
869 int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min; 869 int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;
870 int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min; 870 int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;
871 int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min; 871 int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;
872 int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min; 872 int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;
873 int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min; 873 int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;
874 int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min; 874 int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
875 875
876 for (row = 0; row < rpng2_info.height; ++row) { 876 for (row = 0; row < rpng2_info.height; ++row) {
877 yidx = row % bgscale; 877 yidx = row % bgscale;
878 even_odd_vert = (row / bgscale) & 1; 878 even_odd_vert = (row / bgscale) & 1;
879 879
880 r1 = r1_min + (r1_diff * yidx) / yidx_max; 880 r1 = r1_min + (r1_diff * yidx) / yidx_max;
881 g1 = g1_min + (g1_diff * yidx) / yidx_max; 881 g1 = g1_min + (g1_diff * yidx) / yidx_max;
882 b1 = b1_min + (b1_diff * yidx) / yidx_max; 882 b1 = b1_min + (b1_diff * yidx) / yidx_max;
883 r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max; 883 r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;
884 g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max; 884 g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;
885 b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max; 885 b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;
886 886
887 r2 = r2_min + (r2_diff * yidx) / yidx_max; 887 r2 = r2_min + (r2_diff * yidx) / yidx_max;
888 g2 = g2_min + (g2_diff * yidx) / yidx_max; 888 g2 = g2_min + (g2_diff * yidx) / yidx_max;
889 b2 = b2_min + (b2_diff * yidx) / yidx_max; 889 b2 = b2_min + (b2_diff * yidx) / yidx_max;
890 r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max; 890 r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;
891 g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max; 891 g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
892 b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max; 892 b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
893 893
894 dest = bg_data + row*bg_rowbytes; 894 dest = bg_data + row*bg_rowbytes;
895 for (i = 0; i < rpng2_info.width; ++i) { 895 for (i = 0; i < rpng2_info.width; ++i) {
896 even_odd_horiz = (i / bgscale) & 1; 896 even_odd_horiz = (i / bgscale) & 1;
897 even_odd = even_odd_vert ^ even_odd_horiz; 897 even_odd = even_odd_vert ^ even_odd_horiz;
898 invert_column = 898 invert_column =
899 (even_odd_horiz && (bg[pat].type & 0x10)); 899 (even_odd_horiz && (bg[pat].type & 0x10));
900 if (even_odd == 0) { /* gradient #1 */ 900 if (even_odd == 0) { /* gradient #1 */
901 if (invert_column) { 901 if (invert_column) {
902 *dest++ = r1_inv; 902 *dest++ = r1_inv;
903 *dest++ = g1_inv; 903 *dest++ = g1_inv;
904 *dest++ = b1_inv; 904 *dest++ = b1_inv;
905 } else { 905 } else {
906 *dest++ = r1; 906 *dest++ = r1;
907 *dest++ = g1; 907 *dest++ = g1;
908 *dest++ = b1; 908 *dest++ = b1;
909 } 909 }
910 } else { /* gradient #2 */ 910 } else { /* gradient #2 */
911 if ((invert_column && invert_gradient2) || 911 if ((invert_column && invert_gradient2) ||
912 (!invert_column && !invert_gradient2)) 912 (!invert_column && !invert_gradient2))
913 { 913 {
914 *dest++ = r2; /* not inverted or */ 914 *dest++ = r2; /* not inverted or */
915 *dest++ = g2; /* doubly inverted */ 915 *dest++ = g2; /* doubly inverted */
916 *dest++ = b2; 916 *dest++ = b2;
917 } else { 917 } else {
918 *dest++ = r2_inv; 918 *dest++ = r2_inv;
919 *dest++ = g2_inv; /* singly inverted */ 919 *dest++ = g2_inv; /* singly inverted */
920 *dest++ = b2_inv; 920 *dest++ = b2_inv;
921 } 921 }
922 } 922 }
923 } 923 }
924 } 924 }
925 925
926/*--------------------------------------------------------------------------- 926/*---------------------------------------------------------------------------
927 Soft gradient-diamonds with scale = bgscale. Code contributed by Adam 927 Soft gradient-diamonds with scale = bgscale. Code contributed by Adam
928 M. Costello. 928 M. Costello.
929 ---------------------------------------------------------------------------*/ 929 ---------------------------------------------------------------------------*/
930 930
931 } else if ((bg[pat].type & 0x07) == 1) { 931 } else if ((bg[pat].type & 0x07) == 1) {
932 932
933 hmax = (bgscale-1)/2; /* half the max weight of a color */ 933 hmax = (bgscale-1)/2; /* half the max weight of a color */
934 max = 2*hmax; /* the max weight of a color */ 934 max = 2*hmax; /* the max weight of a color */
935 935
936 r1 = rgb[bg[pat].rgb1_max].r; 936 r1 = rgb[bg[pat].rgb1_max].r;
937 g1 = rgb[bg[pat].rgb1_max].g; 937 g1 = rgb[bg[pat].rgb1_max].g;
938 b1 = rgb[bg[pat].rgb1_max].b; 938 b1 = rgb[bg[pat].rgb1_max].b;
939 r2 = rgb[bg[pat].rgb2_max].r; 939 r2 = rgb[bg[pat].rgb2_max].r;
940 g2 = rgb[bg[pat].rgb2_max].g; 940 g2 = rgb[bg[pat].rgb2_max].g;
941 b2 = rgb[bg[pat].rgb2_max].b; 941 b2 = rgb[bg[pat].rgb2_max].b;
942 942
943 for (row = 0; row < rpng2_info.height; ++row) { 943 for (row = 0; row < rpng2_info.height; ++row) {
944 yidx = row % bgscale; 944 yidx = row % bgscale;
945 if (yidx > hmax) 945 if (yidx > hmax)
946 yidx = bgscale-1 - yidx; 946 yidx = bgscale-1 - yidx;
947 dest = bg_data + row*bg_rowbytes; 947 dest = bg_data + row*bg_rowbytes;
948 for (i = 0; i < rpng2_info.width; ++i) { 948 for (i = 0; i < rpng2_info.width; ++i) {
949 xidx = i % bgscale; 949 xidx = i % bgscale;
950 if (xidx > hmax) 950 if (xidx > hmax)
951 xidx = bgscale-1 - xidx; 951 xidx = bgscale-1 - xidx;
952 k = xidx + yidx; 952 k = xidx + yidx;
953 *dest++ = (k*r1 + (max-k)*r2) / max; 953 *dest++ = (k*r1 + (max-k)*r2) / max;
954 *dest++ = (k*g1 + (max-k)*g2) / max; 954 *dest++ = (k*g1 + (max-k)*g2) / max;
955 *dest++ = (k*b1 + (max-k)*b2) / max; 955 *dest++ = (k*b1 + (max-k)*b2) / max;
956 } 956 }
957 } 957 }
958 958
959/*--------------------------------------------------------------------------- 959/*---------------------------------------------------------------------------
960 Radial "starburst" with azimuthal sinusoids; [eventually number of sinu- 960 Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
961 soids will equal bgscale?]. This one is slow but very cool. Code con- 961 soids will equal bgscale?]. This one is slow but very cool. Code con-
962 tributed by Pieter S. van der Meulen (originally in Smalltalk). 962 tributed by Pieter S. van der Meulen (originally in Smalltalk).
963 ---------------------------------------------------------------------------*/ 963 ---------------------------------------------------------------------------*/
964 964
965 } else if ((bg[pat].type & 0x07) == 2) { 965 } else if ((bg[pat].type & 0x07) == 2) {
966 uch ch; 966 uch ch;
967 int ii, x, y, hw, hh, grayspot; 967 int ii, x, y, hw, hh, grayspot;
968 double freq, rotate, saturate, gray, intensity; 968 double freq, rotate, saturate, gray, intensity;
969 double angle=0.0, aoffset=0.0, maxDist, dist; 969 double angle=0.0, aoffset=0.0, maxDist, dist;
970 double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t; 970 double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;
971 971
972 fprintf(stderr, "%s: computing radial background...", 972 fprintf(stderr, "%s: computing radial background...",
973 PROGNAME); 973 PROGNAME);
974 fflush(stderr); 974 fflush(stderr);
975 975
976 hh = rpng2_info.height / 2; 976 hh = rpng2_info.height / 2;
977 hw = rpng2_info.width / 2; 977 hw = rpng2_info.width / 2;
978 978
979 /* variables for radial waves: 979 /* variables for radial waves:
980 * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED] 980 * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED]
981 * freq: number of color beams originating from the center 981 * freq: number of color beams originating from the center
982 * grayspot: size of the graying center area (anti-alias) 982 * grayspot: size of the graying center area (anti-alias)
983 * rotate: rotation of the beams as a function of radius 983 * rotate: rotation of the beams as a function of radius
984 * saturate: saturation of beams' shape azimuthally 984 * saturate: saturation of beams' shape azimuthally
985 */ 985 */
986 angle = CLIP(angle, 0.0, 360.0); 986 angle = CLIP(angle, 0.0, 360.0);
987 grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw)); 987 grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
988 freq = MAX((double)bg[pat].bg_freq, 0.0); 988 freq = MAX((double)bg[pat].bg_freq, 0.0);
989 saturate = (double)bg[pat].bg_bsat * 0.1; 989 saturate = (double)bg[pat].bg_bsat * 0.1;
990 rotate = (double)bg[pat].bg_brot * 0.1; 990 rotate = (double)bg[pat].bg_brot * 0.1;
991 gray = 0.0; 991 gray = 0.0;
992 intensity = 0.0; 992 intensity = 0.0;
993 maxDist = (double)((hw*hw) + (hh*hh)); 993 maxDist = (double)((hw*hw) + (hh*hh));
994 994
995 for (row = 0; row < rpng2_info.height; ++row) { 995 for (row = 0; row < rpng2_info.height; ++row) {
996 y = row - hh; 996 y = row - hh;
997 dest = bg_data + row*bg_rowbytes; 997 dest = bg_data + row*bg_rowbytes;
998 for (i = 0; i < rpng2_info.width; ++i) { 998 for (i = 0; i < rpng2_info.width; ++i) {
999 x = i - hw; 999 x = i - hw;
1000 angle = (x == 0)? PI_2 : atan((double)y / (double)x); 1000 angle = (x == 0)? PI_2 : atan((double)y / (double)x);
1001 gray = (double)MAX(ABS(y), ABS(x)) / grayspot; 1001 gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
1002 gray = MIN(1.0, gray); 1002 gray = MIN(1.0, gray);
1003 dist = (double)((x*x) + (y*y)) / maxDist; 1003 dist = (double)((x*x) + (y*y)) / maxDist;
1004 intensity = cos((angle+(rotate*dist*PI)) * freq) * 1004 intensity = cos((angle+(rotate*dist*PI)) * freq) *
1005 gray * saturate; 1005 gray * saturate;
1006 intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5; 1006 intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
1007 hue = (angle + PI) * INV_PI_360 + aoffset; 1007 hue = (angle + PI) * INV_PI_360 + aoffset;
1008 s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh)); 1008 s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
1009 s = MIN(MAX(s,0.0), 1.0); 1009 s = MIN(MAX(s,0.0), 1.0);
1010 v = MIN(MAX(intensity,0.0), 1.0); 1010 v = MIN(MAX(intensity,0.0), 1.0);
1011 1011
1012 if (s == 0.0) { 1012 if (s == 0.0) {
1013 ch = (uch)(v * 255.0); 1013 ch = (uch)(v * 255.0);
1014 *dest++ = ch; 1014 *dest++ = ch;
1015 *dest++ = ch; 1015 *dest++ = ch;
1016 *dest++ = ch; 1016 *dest++ = ch;
1017 } else { 1017 } else {
1018 if ((hue < 0.0) || (hue >= 360.0)) 1018 if ((hue < 0.0) || (hue >= 360.0))
1019 hue -= (((int)(hue / 360.0)) * 360.0); 1019 hue -= (((int)(hue / 360.0)) * 360.0);
1020 hue /= 60.0; 1020 hue /= 60.0;
1021 ii = (int)hue; 1021 ii = (int)hue;
1022 f = hue - (double)ii; 1022 f = hue - (double)ii;
1023 p = (1.0 - s) * v; 1023 p = (1.0 - s) * v;
1024 q = (1.0 - (s * f)) * v; 1024 q = (1.0 - (s * f)) * v;
1025 t = (1.0 - (s * (1.0 - f))) * v; 1025 t = (1.0 - (s * (1.0 - f))) * v;
1026 if (ii == 0) { red = v; green = t; blue = p; } 1026 if (ii == 0) { red = v; green = t; blue = p; }
1027 else if (ii == 1) { red = q; green = v; blue = p; } 1027 else if (ii == 1) { red = q; green = v; blue = p; }
1028 else if (ii == 2) { red = p; green = v; blue = t; } 1028 else if (ii == 2) { red = p; green = v; blue = t; }
1029 else if (ii == 3) { red = p; green = q; blue = v; } 1029 else if (ii == 3) { red = p; green = q; blue = v; }
1030 else if (ii == 4) { red = t; green = p; blue = v; } 1030 else if (ii == 4) { red = t; green = p; blue = v; }
1031 else if (ii == 5) { red = v; green = p; blue = q; } 1031 else if (ii == 5) { red = v; green = p; blue = q; }
1032 *dest++ = (uch)(red * 255.0); 1032 *dest++ = (uch)(red * 255.0);
1033 *dest++ = (uch)(green * 255.0); 1033 *dest++ = (uch)(green * 255.0);
1034 *dest++ = (uch)(blue * 255.0); 1034 *dest++ = (uch)(blue * 255.0);
1035 } 1035 }
1036 } 1036 }
1037 } 1037 }
1038 fprintf(stderr, "done.\n"); 1038 fprintf(stderr, "done.\n");
1039 fflush(stderr); 1039 fflush(stderr);
1040 } 1040 }
1041 1041
1042/*--------------------------------------------------------------------------- 1042/*---------------------------------------------------------------------------
1043 Blast background image to display buffer before beginning PNG decode; 1043 Blast background image to display buffer before beginning PNG decode;
1044 calling function will handle invalidation and UpdateWindow() call. 1044 calling function will handle invalidation and UpdateWindow() call.
1045 ---------------------------------------------------------------------------*/ 1045 ---------------------------------------------------------------------------*/
1046 1046
1047 for (row = 0; row < rpng2_info.height; ++row) { 1047 for (row = 0; row < rpng2_info.height; ++row) {
1048 src = bg_data + row*bg_rowbytes; 1048 src = bg_data + row*bg_rowbytes;
1049 dest = wimage_data + row*wimage_rowbytes; 1049 dest = wimage_data + row*wimage_rowbytes;
1050 for (i = rpng2_info.width; i > 0; --i) { 1050 for (i = rpng2_info.width; i > 0; --i) {
1051 r1 = *src++; 1051 r1 = *src++;
1052 g1 = *src++; 1052 g1 = *src++;
1053 b1 = *src++; 1053 b1 = *src++;
1054 *dest++ = b1; 1054 *dest++ = b1;
1055 *dest++ = g1; /* note reverse order */ 1055 *dest++ = g1; /* note reverse order */
1056 *dest++ = r1; 1056 *dest++ = r1;
1057 } 1057 }
1058 } 1058 }
1059 1059
1060 return 0; 1060 return 0;
1061 1061
1062} /* end function rpng2_win_load_bg_image() */ 1062} /* end function rpng2_win_load_bg_image() */
1063 1063
1064 1064
1065 1065
1066 1066
1067 1067
1068static void rpng2_win_display_row(ulg row) 1068static void rpng2_win_display_row(ulg row)
1069{ 1069{
1070 uch bg_red = rpng2_info.bg_red; 1070 uch bg_red = rpng2_info.bg_red;
1071 uch bg_green = rpng2_info.bg_green; 1071 uch bg_green = rpng2_info.bg_green;
1072 uch bg_blue = rpng2_info.bg_blue; 1072 uch bg_blue = rpng2_info.bg_blue;
1073 uch *src, *src2=NULL, *dest; 1073 uch *src, *src2=NULL, *dest;
1074 uch r, g, b, a; 1074 uch r, g, b, a;
1075 ulg i; 1075 ulg i;
1076 static int rows=0; 1076 static int rows=0;
1077 static ulg firstrow; 1077 static ulg firstrow;
1078 1078
1079/*--------------------------------------------------------------------------- 1079/*---------------------------------------------------------------------------
1080 rows and firstrow simply track how many rows (and which ones) have not 1080 rows and firstrow simply track how many rows (and which ones) have not
1081 yet been displayed; alternatively, we could call InvalidateRect() for 1081 yet been displayed; alternatively, we could call InvalidateRect() for
1082 every row and not bother with the records-keeping. 1082 every row and not bother with the records-keeping.
1083 ---------------------------------------------------------------------------*/ 1083 ---------------------------------------------------------------------------*/
1084 1084
1085 Trace((stderr, "beginning rpng2_win_display_row()\n")) 1085 Trace((stderr, "beginning rpng2_win_display_row()\n"))
1086 1086
1087 if (rows == 0) 1087 if (rows == 0)
1088 firstrow = row; /* first row not yet displayed */ 1088 firstrow = row; /* first row not yet displayed */
1089 1089
1090 ++rows; /* count of rows received but not yet displayed */ 1090 ++rows; /* count of rows received but not yet displayed */
1091 1091
1092/*--------------------------------------------------------------------------- 1092/*---------------------------------------------------------------------------
1093 Aside from the use of the rpng2_info struct and the lack of an outer 1093 Aside from the use of the rpng2_info struct and the lack of an outer
1094 loop (over rows), this routine is identical to rpng_win_display_image() 1094 loop (over rows), this routine is identical to rpng_win_display_image()
1095 in the non-progressive version of the program. 1095 in the non-progressive version of the program.
1096 ---------------------------------------------------------------------------*/ 1096 ---------------------------------------------------------------------------*/
1097 1097
1098 src = rpng2_info.image_data + row*rpng2_info.rowbytes; 1098 src = rpng2_info.image_data + row*rpng2_info.rowbytes;
1099 if (bg_image) 1099 if (bg_image)
1100 src2 = bg_data + row*bg_rowbytes; 1100 src2 = bg_data + row*bg_rowbytes;
1101 dest = wimage_data + row*wimage_rowbytes; 1101 dest = wimage_data + row*wimage_rowbytes;
1102 1102
1103 if (rpng2_info.channels == 3) { 1103 if (rpng2_info.channels == 3) {
1104 for (i = rpng2_info.width; i > 0; --i) { 1104 for (i = rpng2_info.width; i > 0; --i) {
1105 r = *src++; 1105 r = *src++;
1106 g = *src++; 1106 g = *src++;
1107 b = *src++; 1107 b = *src++;
1108 *dest++ = b; 1108 *dest++ = b;
1109 *dest++ = g; /* note reverse order */ 1109 *dest++ = g; /* note reverse order */
1110 *dest++ = r; 1110 *dest++ = r;
1111 } 1111 }
1112 } else /* if (rpng2_info.channels == 4) */ { 1112 } else /* if (rpng2_info.channels == 4) */ {
1113 for (i = rpng2_info.width; i > 0; --i) { 1113 for (i = rpng2_info.width; i > 0; --i) {
1114 r = *src++; 1114 r = *src++;
1115 g = *src++; 1115 g = *src++;
1116 b = *src++; 1116 b = *src++;
1117 a = *src++; 1117 a = *src++;
1118 if (bg_image) { 1118 if (bg_image) {
1119 bg_red = *src2++; 1119 bg_red = *src2++;
1120 bg_green = *src2++; 1120 bg_green = *src2++;
1121 bg_blue = *src2++; 1121 bg_blue = *src2++;
1122 } 1122 }
1123 if (a == 255) { 1123 if (a == 255) {
1124 *dest++ = b; 1124 *dest++ = b;
1125 *dest++ = g; 1125 *dest++ = g;
1126 *dest++ = r; 1126 *dest++ = r;
1127 } else if (a == 0) { 1127 } else if (a == 0) {
1128 *dest++ = bg_blue; 1128 *dest++ = bg_blue;
1129 *dest++ = bg_green; 1129 *dest++ = bg_green;
1130 *dest++ = bg_red; 1130 *dest++ = bg_red;
1131 } else { 1131 } else {
1132 /* this macro (copied from png.h) composites the 1132 /* this macro (copied from png.h) composites the
1133 * foreground and background values and puts the 1133 * foreground and background values and puts the
1134 * result into the first argument; there are no 1134 * result into the first argument; there are no
1135 * side effects with the first argument */ 1135 * side effects with the first argument */
1136 alpha_composite(*dest++, b, a, bg_blue); 1136 alpha_composite(*dest++, b, a, bg_blue);
1137 alpha_composite(*dest++, g, a, bg_green); 1137 alpha_composite(*dest++, g, a, bg_green);
1138 alpha_composite(*dest++, r, a, bg_red); 1138 alpha_composite(*dest++, r, a, bg_red);
1139 } 1139 }
1140 } 1140 }
1141 } 1141 }
1142 1142
1143/*--------------------------------------------------------------------------- 1143/*---------------------------------------------------------------------------
1144 Display after every 16 rows or when on last row. (Region may include 1144 Display after every 16 rows or when on last row. (Region may include
1145 previously displayed lines due to interlacing--i.e., not contiguous.) 1145 previously displayed lines due to interlacing--i.e., not contiguous.)
1146 ---------------------------------------------------------------------------*/ 1146 ---------------------------------------------------------------------------*/
1147 1147
1148 if ((rows & 0xf) == 0 || row == rpng2_info.height-1) { 1148 if ((rows & 0xf) == 0 || row == rpng2_info.height-1) {
1149 RECT rect; 1149 RECT rect;
1150 1150
1151 rect.left = 0L; 1151 rect.left = 0L;
1152 rect.top = (LONG)firstrow; 1152 rect.top = (LONG)firstrow;
1153 rect.right = (LONG)rpng2_info.width; /* possibly off by one? */ 1153 rect.right = (LONG)rpng2_info.width; /* possibly off by one? */
1154 rect.bottom = (LONG)row + 1L; /* possibly off by one? */ 1154 rect.bottom = (LONG)row + 1L; /* possibly off by one? */
1155 InvalidateRect(global_hwnd, &rect, FALSE); 1155 InvalidateRect(global_hwnd, &rect, FALSE);
1156 UpdateWindow(global_hwnd); /* similar to XFlush() */ 1156 UpdateWindow(global_hwnd); /* similar to XFlush() */
1157 rows = 0; 1157 rows = 0;
1158 } 1158 }
1159 1159
1160} /* end function rpng2_win_display_row() */ 1160} /* end function rpng2_win_display_row() */
1161 1161
1162 1162
1163 1163
1164 1164
1165 1165
1166static void rpng2_win_finish_display() 1166static void rpng2_win_finish_display()
1167{ 1167{
1168 Trace((stderr, "beginning rpng2_win_finish_display()\n")) 1168 Trace((stderr, "beginning rpng2_win_finish_display()\n"))
1169 1169
1170 /* last row has already been displayed by rpng2_win_display_row(), so 1170 /* last row has already been displayed by rpng2_win_display_row(), so
1171 * we have nothing to do here except set a flag and let the user know 1171 * we have nothing to do here except set a flag and let the user know
1172 * that the image is done */ 1172 * that the image is done */
1173 1173
1174 rpng2_info.state = kDone; 1174 rpng2_info.state = kDone;
1175 printf( 1175 printf(
1176#ifndef __CYGWIN__ 1176#ifndef __CYGWIN__
1177 "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n" 1177 "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"
1178#else 1178#else
1179 "Done. Press mouse button 1 (within image window) to quit.\n" 1179 "Done. Press mouse button 1 (within image window) to quit.\n"
1180#endif 1180#endif
1181 ); 1181 );
1182 fflush(stdout); 1182 fflush(stdout);
1183} 1183}
1184 1184
1185 1185
1186 1186
1187 1187
1188 1188
1189static void rpng2_win_cleanup() 1189static void rpng2_win_cleanup()
1190{ 1190{
1191 if (bg_image && bg_data) { 1191 if (bg_image && bg_data) {
1192 free(bg_data); 1192 free(bg_data);
1193 bg_data = NULL; 1193 bg_data = NULL;
1194 } 1194 }
1195 1195
1196 if (rpng2_info.image_data) { 1196 if (rpng2_info.image_data) {
1197 free(rpng2_info.image_data); 1197 free(rpng2_info.image_data);
1198 rpng2_info.image_data = NULL; 1198 rpng2_info.image_data = NULL;
1199 } 1199 }
1200 1200
1201 if (rpng2_info.row_pointers) { 1201 if (rpng2_info.row_pointers) {
1202 free(rpng2_info.row_pointers); 1202 free(rpng2_info.row_pointers);
1203 rpng2_info.row_pointers = NULL; 1203 rpng2_info.row_pointers = NULL;
1204 } 1204 }
1205 1205
1206 if (dib) { 1206 if (dib) {
1207 free(dib); 1207 free(dib);
1208 dib = NULL; 1208 dib = NULL;
1209 } 1209 }
1210} 1210}
1211 1211
1212 1212
1213 1213
1214 1214
1215 1215
1216LRESULT CALLBACK rpng2_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP) 1216LRESULT CALLBACK rpng2_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)
1217{ 1217{
1218 HDC hdc; 1218 HDC hdc;
1219 PAINTSTRUCT ps; 1219 PAINTSTRUCT ps;
1220 int rc; 1220 int rc;
1221 1221
1222 switch (iMsg) { 1222 switch (iMsg) {
1223 case WM_CREATE: 1223 case WM_CREATE:
1224 /* one-time processing here, if any */ 1224 /* one-time processing here, if any */
1225 return 0; 1225 return 0;
1226 1226
1227 case WM_PAINT: 1227 case WM_PAINT:
1228 hdc = BeginPaint(hwnd, &ps); 1228 hdc = BeginPaint(hwnd, &ps);
1229 rc = StretchDIBits(hdc, 0, 0, rpng2_info.width, rpng2_info.height, 1229 rc = StretchDIBits(hdc, 0, 0, rpng2_info.width, rpng2_info.height,
1230 0, 0, rpng2_info.width, rpng2_info.height, 1230 0, 0, rpng2_info.width, rpng2_info.height,
1231 wimage_data, (BITMAPINFO *)bmih, 1231 wimage_data, (BITMAPINFO *)bmih,
1232 0, SRCCOPY); 1232 0, SRCCOPY);
1233 EndPaint(hwnd, &ps); 1233 EndPaint(hwnd, &ps);
1234 return 0; 1234 return 0;
1235 1235
1236 /* wait for the user to tell us when to quit */ 1236 /* wait for the user to tell us when to quit */
1237 case WM_CHAR: 1237 case WM_CHAR:
1238 switch (wP) { /* only need one, so ignore repeat count */ 1238 switch (wP) { /* only need one, so ignore repeat count */
1239 case 'q': 1239 case 'q':
1240 case 'Q': 1240 case 'Q':
1241 case 0x1B: /* Esc key */ 1241 case 0x1B: /* Esc key */
1242 PostQuitMessage(0); 1242 PostQuitMessage(0);
1243 } 1243 }
1244 return 0; 1244 return 0;
1245 1245
1246 case WM_LBUTTONDOWN: /* another way of quitting */ 1246 case WM_LBUTTONDOWN: /* another way of quitting */
1247 case WM_DESTROY: 1247 case WM_DESTROY:
1248 PostQuitMessage(0); 1248 PostQuitMessage(0);
1249 return 0; 1249 return 0;
1250 } 1250 }
1251 1251
1252 return DefWindowProc(hwnd, iMsg, wP, lP); 1252 return DefWindowProc(hwnd, iMsg, wP, lP);
1253} 1253}
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-x.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-x.c
index 6c687db..7f24b63 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-x.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/rpng2-x.c
@@ -1,2107 +1,2107 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 rpng2 - progressive-model PNG display program rpng2-x.c 3 rpng2 - progressive-model PNG display program rpng2-x.c
4 4
5 This program decodes and displays PNG files progressively, as if it were 5 This program decodes and displays PNG files progressively, as if it were
6 a web browser (though the front end is only set up to read from files). 6 a web browser (though the front end is only set up to read from files).
7 It supports gamma correction, user-specified background colors, and user- 7 It supports gamma correction, user-specified background colors, and user-
8 specified background patterns (for transparent images). This version is 8 specified background patterns (for transparent images). This version is
9 for the X Window System (tested by the author under Unix and by Martin 9 for the X Window System (tested by the author under Unix and by Martin
10 Zinser under OpenVMS; may work under OS/2 with a little tweaking). 10 Zinser under OpenVMS; may work under OS/2 with a little tweaking).
11 11
12 Thanks to Adam Costello and Pieter S. van der Meulen for the "diamond" 12 Thanks to Adam Costello and Pieter S. van der Meulen for the "diamond"
13 and "radial waves" patterns, respectively. 13 and "radial waves" patterns, respectively.
14 14
15 to do (someday, maybe): 15 to do (someday, maybe):
16 - fix expose/redraw code: don't draw entire row if only part exposed 16 - fix expose/redraw code: don't draw entire row if only part exposed
17 - 8-bit (colormapped) X support 17 - 8-bit (colormapped) X support
18 - finish resizable checkerboard-gradient (sizes 4-128?) 18 - finish resizable checkerboard-gradient (sizes 4-128?)
19 - use %.1023s to simplify truncation of title-bar string? 19 - use %.1023s to simplify truncation of title-bar string?
20 20
21 --------------------------------------------------------------------------- 21 ---------------------------------------------------------------------------
22 22
23 Changelog: 23 Changelog:
24 - 1.01: initial public release 24 - 1.01: initial public release
25 - 1.02: modified to allow abbreviated options; fixed char/uchar mismatch 25 - 1.02: modified to allow abbreviated options; fixed char/uchar mismatch
26 - 1.10: added support for non-default visuals; fixed X pixel-conversion 26 - 1.10: added support for non-default visuals; fixed X pixel-conversion
27 - 1.11: added -usleep option for demos; fixed command-line parsing bug 27 - 1.11: added -usleep option for demos; fixed command-line parsing bug
28 - 1.12: added -pause option for demos and testing 28 - 1.12: added -pause option for demos and testing
29 - 1.20: added runtime MMX-enabling/disabling and new -mmx* options 29 - 1.20: added runtime MMX-enabling/disabling and new -mmx* options
30 - 1.21: fixed some small X memory leaks (thanks to François Petitjean) 30 - 1.21: fixed some small X memory leaks (thanks to François Petitjean)
31 - 1.22: fixed XFreeGC() crash bug (thanks to Patrick Welche) 31 - 1.22: fixed XFreeGC() crash bug (thanks to Patrick Welche)
32 - 1.23: added -bgpat 0 mode (std white/gray checkerboard, 8x8 squares) 32 - 1.23: added -bgpat 0 mode (std white/gray checkerboard, 8x8 squares)
33 - 1.30: added -loop option for -bgpat (ifdef FEATURE_LOOP); fixed bpp = 33 - 1.30: added -loop option for -bgpat (ifdef FEATURE_LOOP); fixed bpp =
34 24; added support for X resources (thanks to Gerhard Niklasch) 34 24; added support for X resources (thanks to Gerhard Niklasch)
35 - 1.31: added code to skip unused chunks (thanks to Glenn Randers-Pehrson) 35 - 1.31: added code to skip unused chunks (thanks to Glenn Randers-Pehrson)
36 - 1.32: added AMD64/EM64T support (__x86_64__); added basic expose/redraw 36 - 1.32: added AMD64/EM64T support (__x86_64__); added basic expose/redraw
37 handling 37 handling
38 - 2.00: dual-licensed (added GNU GPL) 38 - 2.00: dual-licensed (added GNU GPL)
39 - 2.01: fixed 64-bit typo in readpng2.c; fixed -pause usage description 39 - 2.01: fixed 64-bit typo in readpng2.c; fixed -pause usage description
40 - 2.02: fixed improper display of usage screen on PNG error(s); fixed 40 - 2.02: fixed improper display of usage screen on PNG error(s); fixed
41 unexpected-EOF and file-read-error cases; fixed Trace() cut-and- 41 unexpected-EOF and file-read-error cases; fixed Trace() cut-and-
42 paste bugs 42 paste bugs
43 - 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options 43 - 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options
44 44
45 --------------------------------------------------------------------------- 45 ---------------------------------------------------------------------------
46 46
47 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. 47 Copyright (c) 1998-2008 Greg Roelofs. All rights reserved.
48 48
49 This software is provided "as is," without warranty of any kind, 49 This software is provided "as is," without warranty of any kind,
50 express or implied. In no event shall the author or contributors 50 express or implied. In no event shall the author or contributors
51 be held liable for any damages arising in any way from the use of 51 be held liable for any damages arising in any way from the use of
52 this software. 52 this software.
53 53
54 The contents of this file are DUAL-LICENSED. You may modify and/or 54 The contents of this file are DUAL-LICENSED. You may modify and/or
55 redistribute this software according to the terms of one of the 55 redistribute this software according to the terms of one of the
56 following two licenses (at your option): 56 following two licenses (at your option):
57 57
58 58
59 LICENSE 1 ("BSD-like with advertising clause"): 59 LICENSE 1 ("BSD-like with advertising clause"):
60 60
61 Permission is granted to anyone to use this software for any purpose, 61 Permission is granted to anyone to use this software for any purpose,
62 including commercial applications, and to alter it and redistribute 62 including commercial applications, and to alter it and redistribute
63 it freely, subject to the following restrictions: 63 it freely, subject to the following restrictions:
64 64
65 1. Redistributions of source code must retain the above copyright 65 1. Redistributions of source code must retain the above copyright
66 notice, disclaimer, and this list of conditions. 66 notice, disclaimer, and this list of conditions.
67 2. Redistributions in binary form must reproduce the above copyright 67 2. Redistributions in binary form must reproduce the above copyright
68 notice, disclaimer, and this list of conditions in the documenta- 68 notice, disclaimer, and this list of conditions in the documenta-
69 tion and/or other materials provided with the distribution. 69 tion and/or other materials provided with the distribution.
70 3. All advertising materials mentioning features or use of this 70 3. All advertising materials mentioning features or use of this
71 software must display the following acknowledgment: 71 software must display the following acknowledgment:
72 72
73 This product includes software developed by Greg Roelofs 73 This product includes software developed by Greg Roelofs
74 and contributors for the book, "PNG: The Definitive Guide," 74 and contributors for the book, "PNG: The Definitive Guide,"
75 published by O'Reilly and Associates. 75 published by O'Reilly and Associates.
76 76
77 77
78 LICENSE 2 (GNU GPL v2 or later): 78 LICENSE 2 (GNU GPL v2 or later):
79 79
80 This program is free software; you can redistribute it and/or modify 80 This program is free software; you can redistribute it and/or modify
81 it under the terms of the GNU General Public License as published by 81 it under the terms of the GNU General Public License as published by
82 the Free Software Foundation; either version 2 of the License, or 82 the Free Software Foundation; either version 2 of the License, or
83 (at your option) any later version. 83 (at your option) any later version.
84 84
85 This program is distributed in the hope that it will be useful, 85 This program is distributed in the hope that it will be useful,
86 but WITHOUT ANY WARRANTY; without even the implied warranty of 86 but WITHOUT ANY WARRANTY; without even the implied warranty of
87 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 87 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
88 GNU General Public License for more details. 88 GNU General Public License for more details.
89 89
90 You should have received a copy of the GNU General Public License 90 You should have received a copy of the GNU General Public License
91 along with this program; if not, write to the Free Software Foundation, 91 along with this program; if not, write to the Free Software Foundation,
92 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 92 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
93 93
94 ---------------------------------------------------------------------------*/ 94 ---------------------------------------------------------------------------*/
95 95
96#define PROGNAME "rpng2-x" 96#define PROGNAME "rpng2-x"
97#define LONGNAME "Progressive PNG Viewer for X" 97#define LONGNAME "Progressive PNG Viewer for X"
98#define VERSION "2.03 of 25 February 2010" 98#define VERSION "2.03 of 25 February 2010"
99#define RESNAME "rpng2" /* our X resource application name */ 99#define RESNAME "rpng2" /* our X resource application name */
100#define RESCLASS "Rpng" /* our X resource class name */ 100#define RESCLASS "Rpng" /* our X resource class name */
101 101
102#include <stdio.h> 102#include <stdio.h>
103#include <stdlib.h> 103#include <stdlib.h>
104#include <ctype.h> 104#include <ctype.h>
105#include <string.h> 105#include <string.h>
106#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */ 106#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */
107#include <time.h> 107#include <time.h>
108#include <math.h> /* only for PvdM background code */ 108#include <math.h> /* only for PvdM background code */
109#include <X11/Xlib.h> 109#include <X11/Xlib.h>
110#include <X11/Xutil.h> 110#include <X11/Xutil.h>
111#include <X11/Xos.h> 111#include <X11/Xos.h>
112#include <X11/keysym.h> /* defines XK_* macros */ 112#include <X11/keysym.h> /* defines XK_* macros */
113 113
114#ifdef VMS 114#ifdef VMS
115# include <unistd.h> 115# include <unistd.h>
116#endif 116#endif
117 117
118/* all for PvdM background code: */ 118/* all for PvdM background code: */
119#ifndef PI 119#ifndef PI
120# define PI 3.141592653589793238 120# define PI 3.141592653589793238
121#endif 121#endif
122#define PI_2 (PI*0.5) 122#define PI_2 (PI*0.5)
123#define INV_PI_360 (360.0 / PI) 123#define INV_PI_360 (360.0 / PI)
124#define MAX(a,b) (a>b?a:b) 124#define MAX(a,b) (a>b?a:b)
125#define MIN(a,b) (a<b?a:b) 125#define MIN(a,b) (a<b?a:b)
126#define CLIP(a,min,max) MAX(min,MIN((a),max)) 126#define CLIP(a,min,max) MAX(min,MIN((a),max))
127#define ABS(a) ((a)<0?-(a):(a)) 127#define ABS(a) ((a)<0?-(a):(a))
128#define CLIP8P(c) MAX(0,(MIN((c),255))) /* 8-bit pos. integer (uch) */ 128#define CLIP8P(c) MAX(0,(MIN((c),255))) /* 8-bit pos. integer (uch) */
129#define ROUNDF(f) ((int)(f + 0.5)) 129#define ROUNDF(f) ((int)(f + 0.5))
130 130
131#define QUIT(e,k) ((e.type == ButtonPress && e.xbutton.button == Button1) || \ 131#define QUIT(e,k) ((e.type == ButtonPress && e.xbutton.button == Button1) || \
132 (e.type == KeyPress && /* v--- or 1 for shifted keys */ \ 132 (e.type == KeyPress && /* v--- or 1 for shifted keys */ \
133 ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape))) 133 ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape)))
134 134
135#define NO_24BIT_MASKS /* undef case not fully written--only for redisplay() */ 135#define NO_24BIT_MASKS /* undef case not fully written--only for redisplay() */
136 136
137#define rgb1_max bg_freq 137#define rgb1_max bg_freq
138#define rgb1_min bg_gray 138#define rgb1_min bg_gray
139#define rgb2_max bg_bsat 139#define rgb2_max bg_bsat
140#define rgb2_min bg_brot 140#define rgb2_min bg_brot
141 141
142/* #define DEBUG */ /* this enables the Trace() macros */ 142/* #define DEBUG */ /* this enables the Trace() macros */
143 143
144#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */ 144#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */
145 145
146 146
147/* could just include png.h, but this macro is the only thing we need 147/* could just include png.h, but this macro is the only thing we need
148 * (name and typedefs changed to local versions); note that side effects 148 * (name and typedefs changed to local versions); note that side effects
149 * only happen with alpha (which could easily be avoided with 149 * only happen with alpha (which could easily be avoided with
150 * "ush acopy = (alpha);") */ 150 * "ush acopy = (alpha);") */
151 151
152#define alpha_composite(composite, fg, alpha, bg) { \ 152#define alpha_composite(composite, fg, alpha, bg) { \
153 ush temp = ((ush)(fg)*(ush)(alpha) + \ 153 ush temp = ((ush)(fg)*(ush)(alpha) + \
154 (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ 154 (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
155 (composite) = (uch)((temp + (temp >> 8)) >> 8); \ 155 (composite) = (uch)((temp + (temp >> 8)) >> 8); \
156} 156}
157 157
158 158
159#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this 159#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
160 * block size corresponds roughly to a download 160 * block size corresponds roughly to a download
161 * speed 10% faster than theoretical 33.6K maximum 161 * speed 10% faster than theoretical 33.6K maximum
162 * (assuming 8 data bits, 1 stop bit and no other 162 * (assuming 8 data bits, 1 stop bit and no other
163 * overhead) */ 163 * overhead) */
164 164
165/* local prototypes */ 165/* local prototypes */
166static void rpng2_x_init (void); 166static void rpng2_x_init (void);
167static int rpng2_x_create_window (void); 167static int rpng2_x_create_window (void);
168static int rpng2_x_load_bg_image (void); 168static int rpng2_x_load_bg_image (void);
169static void rpng2_x_display_row (ulg row); 169static void rpng2_x_display_row (ulg row);
170static void rpng2_x_finish_display (void); 170static void rpng2_x_finish_display (void);
171static void rpng2_x_redisplay_image (ulg startcol, ulg startrow, 171static void rpng2_x_redisplay_image (ulg startcol, ulg startrow,
172 ulg width, ulg height); 172 ulg width, ulg height);
173#ifdef FEATURE_LOOP 173#ifdef FEATURE_LOOP
174static void rpng2_x_reload_bg_image (void); 174static void rpng2_x_reload_bg_image (void);
175static int is_number (char *p); 175static int is_number (char *p);
176#endif 176#endif
177static void rpng2_x_cleanup (void); 177static void rpng2_x_cleanup (void);
178static int rpng2_x_msb (ulg u32val); 178static int rpng2_x_msb (ulg u32val);
179 179
180 180
181static char titlebar[1024], *window_name = titlebar; 181static char titlebar[1024], *window_name = titlebar;
182static char *appname = LONGNAME; 182static char *appname = LONGNAME;
183static char *icon_name = PROGNAME; 183static char *icon_name = PROGNAME;
184static char *res_name = RESNAME; 184static char *res_name = RESNAME;
185static char *res_class = RESCLASS; 185static char *res_class = RESCLASS;
186static char *filename; 186static char *filename;
187static FILE *infile; 187static FILE *infile;
188 188
189static mainprog_info rpng2_info; 189static mainprog_info rpng2_info;
190 190
191static uch inbuf[INBUFSIZE]; 191static uch inbuf[INBUFSIZE];
192static int incount; 192static int incount;
193 193
194static int pat = 6; /* must be less than num_bgpat */ 194static int pat = 6; /* must be less than num_bgpat */
195static int bg_image = 0; 195static int bg_image = 0;
196static int bgscale, bgscale_default = 16; 196static int bgscale, bgscale_default = 16;
197static ulg bg_rowbytes; 197static ulg bg_rowbytes;
198static uch *bg_data; 198static uch *bg_data;
199 199
200int pause_after_pass = FALSE; 200int pause_after_pass = FALSE;
201int demo_timing = FALSE; 201int demo_timing = FALSE;
202ulg usleep_duration = 0L; 202ulg usleep_duration = 0L;
203 203
204static struct rgb_color { 204static struct rgb_color {
205 uch r, g, b; 205 uch r, g, b;
206} rgb[] = { 206} rgb[] = {
207 { 0, 0, 0}, /* 0: black */ 207 { 0, 0, 0}, /* 0: black */
208 {255, 255, 255}, /* 1: white */ 208 {255, 255, 255}, /* 1: white */
209 {173, 132, 57}, /* 2: tan */ 209 {173, 132, 57}, /* 2: tan */
210 { 64, 132, 0}, /* 3: medium green */ 210 { 64, 132, 0}, /* 3: medium green */
211 {189, 117, 1}, /* 4: gold */ 211 {189, 117, 1}, /* 4: gold */
212 {253, 249, 1}, /* 5: yellow */ 212 {253, 249, 1}, /* 5: yellow */
213 { 0, 0, 255}, /* 6: blue */ 213 { 0, 0, 255}, /* 6: blue */
214 { 0, 0, 120}, /* 7: medium blue */ 214 { 0, 0, 120}, /* 7: medium blue */
215 {255, 0, 255}, /* 8: magenta */ 215 {255, 0, 255}, /* 8: magenta */
216 { 64, 0, 64}, /* 9: dark magenta */ 216 { 64, 0, 64}, /* 9: dark magenta */
217 {255, 0, 0}, /* 10: red */ 217 {255, 0, 0}, /* 10: red */
218 { 64, 0, 0}, /* 11: dark red */ 218 { 64, 0, 0}, /* 11: dark red */
219 {255, 127, 0}, /* 12: orange */ 219 {255, 127, 0}, /* 12: orange */
220 {192, 96, 0}, /* 13: darker orange */ 220 {192, 96, 0}, /* 13: darker orange */
221 { 24, 60, 0}, /* 14: dark green-yellow */ 221 { 24, 60, 0}, /* 14: dark green-yellow */
222 { 85, 125, 200}, /* 15: ice blue */ 222 { 85, 125, 200}, /* 15: ice blue */
223 {192, 192, 192} /* 16: Netscape/Mosaic gray */ 223 {192, 192, 192} /* 16: Netscape/Mosaic gray */
224}; 224};
225/* not used for now, but should be for error-checking: 225/* not used for now, but should be for error-checking:
226static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color); 226static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);
227 */ 227 */
228 228
229/* 229/*
230 This whole struct is a fairly cheesy way to keep the number of 230 This whole struct is a fairly cheesy way to keep the number of
231 command-line options to a minimum. The radial-waves background 231 command-line options to a minimum. The radial-waves background
232 type is a particularly poor fit to the integer elements of the 232 type is a particularly poor fit to the integer elements of the
233 struct...but a few macros and a little fixed-point math will do 233 struct...but a few macros and a little fixed-point math will do
234 wonders for ya. 234 wonders for ya.
235 235
236 type bits: 236 type bits:
237 F E D C B A 9 8 7 6 5 4 3 2 1 0 237 F E D C B A 9 8 7 6 5 4 3 2 1 0
238 | | | | | 238 | | | | |
239 | | +-+-+-- 0 = sharp-edged checkerboard 239 | | +-+-+-- 0 = sharp-edged checkerboard
240 | | 1 = soft diamonds 240 | | 1 = soft diamonds
241 | | 2 = radial waves 241 | | 2 = radial waves
242 | | 3-7 = undefined 242 | | 3-7 = undefined
243 | +-- gradient #2 inverted? 243 | +-- gradient #2 inverted?
244 +-- alternating columns inverted? 244 +-- alternating columns inverted?
245 */ 245 */
246static struct background_pattern { 246static struct background_pattern {
247 ush type; 247 ush type;
248 int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */ 248 int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */
249 int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/ 249 int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/
250} bg[] = { 250} bg[] = {
251 {0, 1,1, 16,16}, /* checkered: white vs. light gray (basic) */ 251 {0, 1,1, 16,16}, /* checkered: white vs. light gray (basic) */
252 {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */ 252 {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */
253 {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */ 253 {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */
254 {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */ 254 {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */
255 {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */ 255 {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */
256 {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */ 256 {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */
257 {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */ 257 {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */
258 {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */ 258 {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */
259 {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */ 259 {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */
260 {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */ 260 {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */
261 {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */ 261 {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */
262 {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */ 262 {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */
263 {1, 3,0, 0,0}, /* diamonds: medium green vs. black */ 263 {1, 3,0, 0,0}, /* diamonds: medium green vs. black */
264 {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */ 264 {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */
265 {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */ 265 {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */
266 {2, 16, 256, 100, 250}, /* radial: very tight spiral */ 266 {2, 16, 256, 100, 250}, /* radial: very tight spiral */
267 {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */ 267 {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */
268}; 268};
269static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern); 269static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);
270 270
271 271
272/* X-specific variables */ 272/* X-specific variables */
273static char *displayname; 273static char *displayname;
274static XImage *ximage; 274static XImage *ximage;
275static Display *display; 275static Display *display;
276static int depth; 276static int depth;
277static Visual *visual; 277static Visual *visual;
278static XVisualInfo *visual_list; 278static XVisualInfo *visual_list;
279static int RShift, GShift, BShift; 279static int RShift, GShift, BShift;
280static ulg RMask, GMask, BMask; 280static ulg RMask, GMask, BMask;
281static Window window; 281static Window window;
282static GC gc; 282static GC gc;
283static Colormap colormap; 283static Colormap colormap;
284 284
285static int have_nondefault_visual = FALSE; 285static int have_nondefault_visual = FALSE;
286static int have_colormap = FALSE; 286static int have_colormap = FALSE;
287static int have_window = FALSE; 287static int have_window = FALSE;
288static int have_gc = FALSE; 288static int have_gc = FALSE;
289 289
290 290
291 291
292 292
293int main(int argc, char **argv) 293int main(int argc, char **argv)
294{ 294{
295#ifdef sgi 295#ifdef sgi
296 char tmpline[80]; 296 char tmpline[80];
297#endif 297#endif
298 char *p, *bgstr = NULL; 298 char *p, *bgstr = NULL;
299 int rc, alen, flen; 299 int rc, alen, flen;
300 int error = 0; 300 int error = 0;
301 int timing = FALSE; 301 int timing = FALSE;
302 int have_bg = FALSE; 302 int have_bg = FALSE;
303#ifdef FEATURE_LOOP 303#ifdef FEATURE_LOOP
304 int loop = FALSE; 304 int loop = FALSE;
305 long loop_interval = -1; /* seconds (100,000 max) */ 305 long loop_interval = -1; /* seconds (100,000 max) */
306#endif 306#endif
307 double LUT_exponent; /* just the lookup table */ 307 double LUT_exponent; /* just the lookup table */
308 double CRT_exponent = 2.2; /* just the monitor */ 308 double CRT_exponent = 2.2; /* just the monitor */
309 double default_display_exponent; /* whole display system */ 309 double default_display_exponent; /* whole display system */
310 XEvent e; 310 XEvent e;
311 KeySym k; 311 KeySym k;
312 312
313 313
314 /* First initialize a few things, just to be sure--memset takes care of 314 /* First initialize a few things, just to be sure--memset takes care of
315 * default background color (black), booleans (FALSE), pointers (NULL), 315 * default background color (black), booleans (FALSE), pointers (NULL),
316 * etc. */ 316 * etc. */
317 317
318 displayname = (char *)NULL; 318 displayname = (char *)NULL;
319 filename = (char *)NULL; 319 filename = (char *)NULL;
320 memset(&rpng2_info, 0, sizeof(mainprog_info)); 320 memset(&rpng2_info, 0, sizeof(mainprog_info));
321 321
322 322
323 /* Set the default value for our display-system exponent, i.e., the 323 /* Set the default value for our display-system exponent, i.e., the
324 * product of the CRT exponent and the exponent corresponding to 324 * product of the CRT exponent and the exponent corresponding to
325 * the frame-buffer's lookup table (LUT), if any. This is not an 325 * the frame-buffer's lookup table (LUT), if any. This is not an
326 * exhaustive list of LUT values (e.g., OpenStep has a lot of weird 326 * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
327 * ones), but it should cover 99% of the current possibilities. */ 327 * ones), but it should cover 99% of the current possibilities. */
328 328
329#if defined(NeXT) 329#if defined(NeXT)
330 /* third-party utilities can modify the default LUT exponent */ 330 /* third-party utilities can modify the default LUT exponent */
331 LUT_exponent = 1.0 / 2.2; 331 LUT_exponent = 1.0 / 2.2;
332 /* 332 /*
333 if (some_next_function_that_returns_gamma(&next_gamma)) 333 if (some_next_function_that_returns_gamma(&next_gamma))
334 LUT_exponent = 1.0 / next_gamma; 334 LUT_exponent = 1.0 / next_gamma;
335 */ 335 */
336#elif defined(sgi) 336#elif defined(sgi)
337 LUT_exponent = 1.0 / 1.7; 337 LUT_exponent = 1.0 / 1.7;
338 /* there doesn't seem to be any documented function to 338 /* there doesn't seem to be any documented function to
339 * get the "gamma" value, so we do it the hard way */ 339 * get the "gamma" value, so we do it the hard way */
340 infile = fopen("/etc/config/system.glGammaVal", "r"); 340 infile = fopen("/etc/config/system.glGammaVal", "r");
341 if (infile) { 341 if (infile) {
342 double sgi_gamma; 342 double sgi_gamma;
343 343
344 fgets(tmpline, 80, infile); 344 fgets(tmpline, 80, infile);
345 fclose(infile); 345 fclose(infile);
346 sgi_gamma = atof(tmpline); 346 sgi_gamma = atof(tmpline);
347 if (sgi_gamma > 0.0) 347 if (sgi_gamma > 0.0)
348 LUT_exponent = 1.0 / sgi_gamma; 348 LUT_exponent = 1.0 / sgi_gamma;
349 } 349 }
350#elif defined(Macintosh) 350#elif defined(Macintosh)
351 LUT_exponent = 1.8 / 2.61; 351 LUT_exponent = 1.8 / 2.61;
352 /* 352 /*
353 if (some_mac_function_that_returns_gamma(&mac_gamma)) 353 if (some_mac_function_that_returns_gamma(&mac_gamma))
354 LUT_exponent = mac_gamma / 2.61; 354 LUT_exponent = mac_gamma / 2.61;
355 */ 355 */
356#else 356#else
357 LUT_exponent = 1.0; /* assume no LUT: most PCs */ 357 LUT_exponent = 1.0; /* assume no LUT: most PCs */
358#endif 358#endif
359 359
360 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ 360 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
361 default_display_exponent = LUT_exponent * CRT_exponent; 361 default_display_exponent = LUT_exponent * CRT_exponent;
362 362
363 363
364 /* If the user has set the SCREEN_GAMMA environment variable as suggested 364 /* If the user has set the SCREEN_GAMMA environment variable as suggested
365 * (somewhat imprecisely) in the libpng documentation, use that; otherwise 365 * (somewhat imprecisely) in the libpng documentation, use that; otherwise
366 * use the default value we just calculated. Either way, the user may 366 * use the default value we just calculated. Either way, the user may
367 * override this via a command-line option. */ 367 * override this via a command-line option. */
368 368
369 if ((p = getenv("SCREEN_GAMMA")) != NULL) 369 if ((p = getenv("SCREEN_GAMMA")) != NULL)
370 rpng2_info.display_exponent = atof(p); 370 rpng2_info.display_exponent = atof(p);
371 else 371 else
372 rpng2_info.display_exponent = default_display_exponent; 372 rpng2_info.display_exponent = default_display_exponent;
373 373
374 374
375 /* Now parse the command line for options and the PNG filename. */ 375 /* Now parse the command line for options and the PNG filename. */
376 376
377 while (*++argv && !error) { 377 while (*++argv && !error) {
378 if (!strncmp(*argv, "-display", 2)) { 378 if (!strncmp(*argv, "-display", 2)) {
379 if (!*++argv) 379 if (!*++argv)
380 ++error; 380 ++error;
381 else 381 else
382 displayname = *argv; 382 displayname = *argv;
383 } else if (!strncmp(*argv, "-gamma", 2)) { 383 } else if (!strncmp(*argv, "-gamma", 2)) {
384 if (!*++argv) 384 if (!*++argv)
385 ++error; 385 ++error;
386 else { 386 else {
387 rpng2_info.display_exponent = atof(*argv); 387 rpng2_info.display_exponent = atof(*argv);
388 if (rpng2_info.display_exponent <= 0.0) 388 if (rpng2_info.display_exponent <= 0.0)
389 ++error; 389 ++error;
390 } 390 }
391 } else if (!strncmp(*argv, "-bgcolor", 4)) { 391 } else if (!strncmp(*argv, "-bgcolor", 4)) {
392 if (!*++argv) 392 if (!*++argv)
393 ++error; 393 ++error;
394 else { 394 else {
395 bgstr = *argv; 395 bgstr = *argv;
396 if (strlen(bgstr) != 7 || bgstr[0] != '#') 396 if (strlen(bgstr) != 7 || bgstr[0] != '#')
397 ++error; 397 ++error;
398 else { 398 else {
399 have_bg = TRUE; 399 have_bg = TRUE;
400 bg_image = FALSE; 400 bg_image = FALSE;
401 } 401 }
402 } 402 }
403 } else if (!strncmp(*argv, "-bgpat", 4)) { 403 } else if (!strncmp(*argv, "-bgpat", 4)) {
404 if (!*++argv) 404 if (!*++argv)
405 ++error; 405 ++error;
406 else { 406 else {
407 pat = atoi(*argv); 407 pat = atoi(*argv);
408 if (pat >= 0 && pat < num_bgpat) { 408 if (pat >= 0 && pat < num_bgpat) {
409 bg_image = TRUE; 409 bg_image = TRUE;
410 have_bg = FALSE; 410 have_bg = FALSE;
411 } else 411 } else
412 ++error; 412 ++error;
413 } 413 }
414 } else if (!strncmp(*argv, "-usleep", 2)) { 414 } else if (!strncmp(*argv, "-usleep", 2)) {
415 if (!*++argv) 415 if (!*++argv)
416 ++error; 416 ++error;
417 else { 417 else {
418 usleep_duration = (ulg)atol(*argv); 418 usleep_duration = (ulg)atol(*argv);
419 demo_timing = TRUE; 419 demo_timing = TRUE;
420 } 420 }
421 } else if (!strncmp(*argv, "-pause", 2)) { 421 } else if (!strncmp(*argv, "-pause", 2)) {
422 pause_after_pass = TRUE; 422 pause_after_pass = TRUE;
423 } else if (!strncmp(*argv, "-timing", 2)) { 423 } else if (!strncmp(*argv, "-timing", 2)) {
424 timing = TRUE; 424 timing = TRUE;
425#ifdef FEATURE_LOOP 425#ifdef FEATURE_LOOP
426 } else if (!strncmp(*argv, "-loop", 2)) { 426 } else if (!strncmp(*argv, "-loop", 2)) {
427 loop = TRUE; 427 loop = TRUE;
428 if (!argv[1] || !is_number(argv[1])) 428 if (!argv[1] || !is_number(argv[1]))
429 loop_interval = 2; 429 loop_interval = 2;
430 else { 430 else {
431 ++argv; 431 ++argv;
432 loop_interval = atol(*argv); 432 loop_interval = atol(*argv);
433 if (loop_interval < 0) 433 if (loop_interval < 0)
434 loop_interval = 2; 434 loop_interval = 2;
435 else if (loop_interval > 100000) /* bit more than one day */ 435 else if (loop_interval > 100000) /* bit more than one day */
436 loop_interval = 100000; 436 loop_interval = 100000;
437 } 437 }
438#endif 438#endif
439 } else { 439 } else {
440 if (**argv != '-') { 440 if (**argv != '-') {
441 filename = *argv; 441 filename = *argv;
442 if (argv[1]) /* shouldn't be any more args after filename */ 442 if (argv[1]) /* shouldn't be any more args after filename */
443 ++error; 443 ++error;
444 } else 444 } else
445 ++error; /* not expecting any other options */ 445 ++error; /* not expecting any other options */
446 } 446 }
447 } 447 }
448 448
449 if (!filename) 449 if (!filename)
450 ++error; 450 ++error;
451 451
452 452
453 /* print usage screen if any errors up to this point */ 453 /* print usage screen if any errors up to this point */
454 454
455 if (error) { 455 if (error) {
456 fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); 456 fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname);
457 readpng2_version_info(); 457 readpng2_version_info();
458 fprintf(stderr, "\n" 458 fprintf(stderr, "\n"
459 "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n" 459 "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n"
460#ifdef FEATURE_LOOP 460#ifdef FEATURE_LOOP
461 " %*s [-usleep dur | -timing] [-pause] [-loop [sec]] file.png\n\n" 461 " %*s [-usleep dur | -timing] [-pause] [-loop [sec]] file.png\n\n"
462#else 462#else
463 " %*s [-usleep dur | -timing] [-pause] file.png\n\n" 463 " %*s [-usleep dur | -timing] [-pause] file.png\n\n"
464#endif 464#endif
465 " xdpy\tname of the target X display (e.g., ``hostname:0'')\n" 465 " xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
466 " exp \ttransfer-function exponent (``gamma'') of the display\n" 466 " exp \ttransfer-function exponent (``gamma'') of the display\n"
467 "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" 467 "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
468 "\t\t to the product of the lookup-table exponent (varies)\n" 468 "\t\t to the product of the lookup-table exponent (varies)\n"
469 "\t\t and the CRT exponent (usually 2.2); must be positive\n" 469 "\t\t and the CRT exponent (usually 2.2); must be positive\n"
470 " bg \tdesired background color in 7-character hex RGB format\n" 470 " bg \tdesired background color in 7-character hex RGB format\n"
471 "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" 471 "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
472 "\t\t used with transparent images; overrides -bgpat\n" 472 "\t\t used with transparent images; overrides -bgpat\n"
473 " pat \tdesired background pattern number (0-%d); used with\n" 473 " pat \tdesired background pattern number (0-%d); used with\n"
474 "\t\t transparent images; overrides -bgcolor\n" 474 "\t\t transparent images; overrides -bgcolor\n"
475#ifdef FEATURE_LOOP 475#ifdef FEATURE_LOOP
476 " -loop\tloops through background images after initial display\n" 476 " -loop\tloops through background images after initial display\n"
477 "\t\t is complete (depends on -bgpat)\n" 477 "\t\t is complete (depends on -bgpat)\n"
478 " sec \tseconds to display each background image (default = 2)\n" 478 " sec \tseconds to display each background image (default = 2)\n"
479#endif 479#endif
480 " dur \tduration in microseconds to wait after displaying each\n" 480 " dur \tduration in microseconds to wait after displaying each\n"
481 "\t\t row (for demo purposes)\n" 481 "\t\t row (for demo purposes)\n"
482 " -timing\tenables delay for every block read, to simulate modem\n" 482 " -timing\tenables delay for every block read, to simulate modem\n"
483 "\t\t download of image (~36 Kbps)\n" 483 "\t\t download of image (~36 Kbps)\n"
484 " -pause\tpauses after displaying each pass until mouse clicked\n" 484 " -pause\tpauses after displaying each pass until mouse clicked\n"
485 "\nPress Q, Esc or mouse button 1 (within image window, after image\n" 485 "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
486 "is displayed) to quit.\n" 486 "is displayed) to quit.\n"
487 "\n", PROGNAME, 487 "\n", PROGNAME,
488 (int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat-1); 488 (int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat-1);
489 exit(1); 489 exit(1);
490 } 490 }
491 491
492 492
493 if (!(infile = fopen(filename, "rb"))) { 493 if (!(infile = fopen(filename, "rb"))) {
494 fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); 494 fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
495 ++error; 495 ++error;
496 } else { 496 } else {
497 incount = fread(inbuf, 1, INBUFSIZE, infile); 497 incount = fread(inbuf, 1, INBUFSIZE, infile);
498 if (incount < 8 || !readpng2_check_sig(inbuf, 8)) { 498 if (incount < 8 || !readpng2_check_sig(inbuf, 8)) {
499 fprintf(stderr, PROGNAME 499 fprintf(stderr, PROGNAME
500 ": [%s] is not a PNG file: incorrect signature\n", 500 ": [%s] is not a PNG file: incorrect signature\n",
501 filename); 501 filename);
502 ++error; 502 ++error;
503 } else if ((rc = readpng2_init(&rpng2_info)) != 0) { 503 } else if ((rc = readpng2_init(&rpng2_info)) != 0) {
504 switch (rc) { 504 switch (rc) {
505 case 2: 505 case 2:
506 fprintf(stderr, PROGNAME 506 fprintf(stderr, PROGNAME
507 ": [%s] has bad IHDR (libpng longjmp)\n", filename); 507 ": [%s] has bad IHDR (libpng longjmp)\n", filename);
508 break; 508 break;
509 case 4: 509 case 4:
510 fprintf(stderr, PROGNAME ": insufficient memory\n"); 510 fprintf(stderr, PROGNAME ": insufficient memory\n");
511 break; 511 break;
512 default: 512 default:
513 fprintf(stderr, PROGNAME 513 fprintf(stderr, PROGNAME
514 ": unknown readpng2_init() error\n"); 514 ": unknown readpng2_init() error\n");
515 break; 515 break;
516 } 516 }
517 ++error; 517 ++error;
518 } else { 518 } else {
519 Trace((stderr, "about to call XOpenDisplay()\n")) 519 Trace((stderr, "about to call XOpenDisplay()\n"))
520 display = XOpenDisplay(displayname); 520 display = XOpenDisplay(displayname);
521 if (!display) { 521 if (!display) {
522 readpng2_cleanup(&rpng2_info); 522 readpng2_cleanup(&rpng2_info);
523 fprintf(stderr, PROGNAME ": can't open X display [%s]\n", 523 fprintf(stderr, PROGNAME ": can't open X display [%s]\n",
524 displayname? displayname : "default"); 524 displayname? displayname : "default");
525 ++error; 525 ++error;
526 } 526 }
527 } 527 }
528 if (error) 528 if (error)
529 fclose(infile); 529 fclose(infile);
530 } 530 }
531 531
532 532
533 if (error) { 533 if (error) {
534 fprintf(stderr, PROGNAME ": aborting.\n"); 534 fprintf(stderr, PROGNAME ": aborting.\n");
535 exit(2); 535 exit(2);
536 } 536 }
537 537
538 538
539 /* set the title-bar string, but make sure buffer doesn't overflow */ 539 /* set the title-bar string, but make sure buffer doesn't overflow */
540 540
541 alen = strlen(appname); 541 alen = strlen(appname);
542 flen = strlen(filename); 542 flen = strlen(filename);
543 if (alen + flen + 3 > 1023) 543 if (alen + flen + 3 > 1023)
544 sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); 544 sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
545 else 545 else
546 sprintf(titlebar, "%s: %s", appname, filename); 546 sprintf(titlebar, "%s: %s", appname, filename);
547 547
548 548
549 /* set some final rpng2_info variables before entering main data loop */ 549 /* set some final rpng2_info variables before entering main data loop */
550 550
551 if (have_bg) { 551 if (have_bg) {
552 unsigned r, g, b; /* this approach quiets compiler warnings */ 552 unsigned r, g, b; /* this approach quiets compiler warnings */
553 553
554 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); 554 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
555 rpng2_info.bg_red = (uch)r; 555 rpng2_info.bg_red = (uch)r;
556 rpng2_info.bg_green = (uch)g; 556 rpng2_info.bg_green = (uch)g;
557 rpng2_info.bg_blue = (uch)b; 557 rpng2_info.bg_blue = (uch)b;
558 } else 558 } else
559 rpng2_info.need_bgcolor = TRUE; 559 rpng2_info.need_bgcolor = TRUE;
560 560
561 rpng2_info.state = kPreInit; 561 rpng2_info.state = kPreInit;
562 rpng2_info.mainprog_init = rpng2_x_init; 562 rpng2_info.mainprog_init = rpng2_x_init;
563 rpng2_info.mainprog_display_row = rpng2_x_display_row; 563 rpng2_info.mainprog_display_row = rpng2_x_display_row;
564 rpng2_info.mainprog_finish_display = rpng2_x_finish_display; 564 rpng2_info.mainprog_finish_display = rpng2_x_finish_display;
565 565
566 566
567 /* OK, this is the fun part: call readpng2_decode_data() at the start of 567 /* OK, this is the fun part: call readpng2_decode_data() at the start of
568 * the loop to deal with our first buffer of data (read in above to verify 568 * the loop to deal with our first buffer of data (read in above to verify
569 * that the file is a PNG image), then loop through the file and continue 569 * that the file is a PNG image), then loop through the file and continue
570 * calling the same routine to handle each chunk of data. It in turn 570 * calling the same routine to handle each chunk of data. It in turn
571 * passes the data to libpng, which will invoke one or more of our call- 571 * passes the data to libpng, which will invoke one or more of our call-
572 * backs as decoded data become available. We optionally call sleep() for 572 * backs as decoded data become available. We optionally call sleep() for
573 * one second per iteration to simulate downloading the image via an analog 573 * one second per iteration to simulate downloading the image via an analog
574 * modem. */ 574 * modem. */
575 575
576 for (;;) { 576 for (;;) {
577 Trace((stderr, "about to call readpng2_decode_data()\n")) 577 Trace((stderr, "about to call readpng2_decode_data()\n"))
578 if (readpng2_decode_data(&rpng2_info, inbuf, incount)) 578 if (readpng2_decode_data(&rpng2_info, inbuf, incount))
579 ++error; 579 ++error;
580 Trace((stderr, "done with readpng2_decode_data()\n")) 580 Trace((stderr, "done with readpng2_decode_data()\n"))
581 581
582 if (error || incount != INBUFSIZE || rpng2_info.state == kDone) { 582 if (error || incount != INBUFSIZE || rpng2_info.state == kDone) {
583 if (rpng2_info.state == kDone) { 583 if (rpng2_info.state == kDone) {
584 Trace((stderr, "done decoding PNG image\n")) 584 Trace((stderr, "done decoding PNG image\n"))
585 } else if (ferror(infile)) { 585 } else if (ferror(infile)) {
586 fprintf(stderr, PROGNAME 586 fprintf(stderr, PROGNAME
587 ": error while reading PNG image file\n"); 587 ": error while reading PNG image file\n");
588 exit(3); 588 exit(3);
589 } else if (feof(infile)) { 589 } else if (feof(infile)) {
590 fprintf(stderr, PROGNAME ": end of file reached " 590 fprintf(stderr, PROGNAME ": end of file reached "
591 "(unexpectedly) while reading PNG image file\n"); 591 "(unexpectedly) while reading PNG image file\n");
592 exit(3); 592 exit(3);
593 } else /* if (error) */ { 593 } else /* if (error) */ {
594 /* will print error message below */ 594 /* will print error message below */
595 } 595 }
596 break; 596 break;
597 } 597 }
598 598
599 if (timing) 599 if (timing)
600 sleep(1); 600 sleep(1);
601 601
602 incount = fread(inbuf, 1, INBUFSIZE, infile); 602 incount = fread(inbuf, 1, INBUFSIZE, infile);
603 } 603 }
604 604
605 605
606 /* clean up PNG stuff and report any decoding errors */ 606 /* clean up PNG stuff and report any decoding errors */
607 607
608 fclose(infile); 608 fclose(infile);
609 Trace((stderr, "about to call readpng2_cleanup()\n")) 609 Trace((stderr, "about to call readpng2_cleanup()\n"))
610 readpng2_cleanup(&rpng2_info); 610 readpng2_cleanup(&rpng2_info);
611 611
612 if (error) { 612 if (error) {
613 fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n"); 613 fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n");
614 exit(3); 614 exit(3);
615 } 615 }
616 616
617 617
618#ifdef FEATURE_LOOP 618#ifdef FEATURE_LOOP
619 619
620 if (loop && bg_image) { 620 if (loop && bg_image) {
621 Trace((stderr, "entering -loop loop (FEATURE_LOOP)\n")) 621 Trace((stderr, "entering -loop loop (FEATURE_LOOP)\n"))
622 for (;;) { 622 for (;;) {
623 int i, use_sleep; 623 int i, use_sleep;
624 struct timeval now, then; 624 struct timeval now, then;
625 625
626 /* get current time and add loop_interval to get target time */ 626 /* get current time and add loop_interval to get target time */
627 if (gettimeofday(&then, NULL) == 0) { 627 if (gettimeofday(&then, NULL) == 0) {
628 then.tv_sec += loop_interval; 628 then.tv_sec += loop_interval;
629 use_sleep = FALSE; 629 use_sleep = FALSE;
630 } else 630 } else
631 use_sleep = TRUE; 631 use_sleep = TRUE;
632 632
633 /* do quick check for a quit event but don't wait for it */ 633 /* do quick check for a quit event but don't wait for it */
634 /* GRR BUG: should also check for Expose events and redraw... */ 634 /* GRR BUG: should also check for Expose events and redraw... */
635 if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, &e)) 635 if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, &e))
636 if (QUIT(e,k)) 636 if (QUIT(e,k))
637 break; 637 break;
638 638
639 /* generate next background image */ 639 /* generate next background image */
640 if (++pat >= num_bgpat) 640 if (++pat >= num_bgpat)
641 pat = 0; 641 pat = 0;
642 rpng2_x_reload_bg_image(); 642 rpng2_x_reload_bg_image();
643 643
644 /* wait for timeout, using whatever means are available */ 644 /* wait for timeout, using whatever means are available */
645 if (use_sleep || gettimeofday(&now, NULL) != 0) { 645 if (use_sleep || gettimeofday(&now, NULL) != 0) {
646 for (i = loop_interval; i > 0; --i) { 646 for (i = loop_interval; i > 0; --i) {
647 sleep(1); 647 sleep(1);
648 /* GRR BUG: also need to check for Expose (and redraw!) */ 648 /* GRR BUG: also need to check for Expose (and redraw!) */
649 if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, 649 if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask,
650 &e) && QUIT(e,k)) 650 &e) && QUIT(e,k))
651 break; 651 break;
652 } 652 }
653 } else { 653 } else {
654 /* Y2038 BUG! */ 654 /* Y2038 BUG! */
655 if (now.tv_sec < then.tv_sec || 655 if (now.tv_sec < then.tv_sec ||
656 (now.tv_sec == then.tv_sec && now.tv_usec < then.tv_usec)) 656 (now.tv_sec == then.tv_sec && now.tv_usec < then.tv_usec))
657 { 657 {
658 int quit = FALSE; 658 int quit = FALSE;
659 long seconds_to_go = then.tv_sec - now.tv_sec; 659 long seconds_to_go = then.tv_sec - now.tv_sec;
660 long usleep_usec; 660 long usleep_usec;
661 661
662 /* basically chew up most of remaining loop-interval with 662 /* basically chew up most of remaining loop-interval with
663 * calls to sleep(1) interleaved with checks for quit 663 * calls to sleep(1) interleaved with checks for quit
664 * events, but also recalc time-to-go periodically; when 664 * events, but also recalc time-to-go periodically; when
665 * done, clean up any remaining time with usleep() call 665 * done, clean up any remaining time with usleep() call
666 * (could also use SIGALRM, but signals are a pain...) */ 666 * (could also use SIGALRM, but signals are a pain...) */
667 while (seconds_to_go-- > 1) { 667 while (seconds_to_go-- > 1) {
668 int seconds_done = 0; 668 int seconds_done = 0;
669 669
670 for (i = seconds_to_go; i > 0 && !quit; --i) { 670 for (i = seconds_to_go; i > 0 && !quit; --i) {
671 sleep(1); 671 sleep(1);
672 /* GRR BUG: need to check for Expose and redraw */ 672 /* GRR BUG: need to check for Expose and redraw */
673 if (XCheckMaskEvent(display, KeyPressMask | 673 if (XCheckMaskEvent(display, KeyPressMask |
674 ButtonPressMask, &e) && QUIT(e,k)) 674 ButtonPressMask, &e) && QUIT(e,k))
675 quit = TRUE; 675 quit = TRUE;
676 if (++seconds_done > 1000) 676 if (++seconds_done > 1000)
677 break; /* time to redo seconds_to_go meas. */ 677 break; /* time to redo seconds_to_go meas. */
678 } 678 }
679 if (quit) 679 if (quit)
680 break; 680 break;
681 681
682 /* OK, more than 1000 seconds since last check: 682 /* OK, more than 1000 seconds since last check:
683 * correct the time-to-go measurement for drift */ 683 * correct the time-to-go measurement for drift */
684 if (gettimeofday(&now, NULL) == 0) { 684 if (gettimeofday(&now, NULL) == 0) {
685 if (now.tv_sec >= then.tv_sec) 685 if (now.tv_sec >= then.tv_sec)
686 break; 686 break;
687 seconds_to_go = then.tv_sec - now.tv_sec; 687 seconds_to_go = then.tv_sec - now.tv_sec;
688 } else 688 } else
689 ++seconds_to_go; /* restore what we subtracted */ 689 ++seconds_to_go; /* restore what we subtracted */
690 } 690 }
691 if (quit) 691 if (quit)
692 break; /* breaks outer do-loop, skips redisplay */ 692 break; /* breaks outer do-loop, skips redisplay */
693 693
694 /* since difference between "now" and "then" is already 694 /* since difference between "now" and "then" is already
695 * eaten up to within a couple of seconds, don't need to 695 * eaten up to within a couple of seconds, don't need to
696 * worry about overflow--but might have overshot (neg.) */ 696 * worry about overflow--but might have overshot (neg.) */
697 if (gettimeofday(&now, NULL) == 0) { 697 if (gettimeofday(&now, NULL) == 0) {
698 usleep_usec = 1000000L*(then.tv_sec - now.tv_sec) + 698 usleep_usec = 1000000L*(then.tv_sec - now.tv_sec) +
699 then.tv_usec - now.tv_usec; 699 then.tv_usec - now.tv_usec;
700 if (usleep_usec > 0) 700 if (usleep_usec > 0)
701 usleep((ulg)usleep_usec); 701 usleep((ulg)usleep_usec);
702 } 702 }
703 } 703 }
704 } 704 }
705 705
706 /* composite image against new background and display (note that 706 /* composite image against new background and display (note that
707 * we do not take into account the time spent doing this...) */ 707 * we do not take into account the time spent doing this...) */
708 rpng2_x_redisplay_image (0, 0, rpng2_info.width, rpng2_info.height); 708 rpng2_x_redisplay_image (0, 0, rpng2_info.width, rpng2_info.height);
709 } 709 }
710 710
711 } else /* FALL THROUGH and do the normal thing */ 711 } else /* FALL THROUGH and do the normal thing */
712 712
713#endif /* FEATURE_LOOP */ 713#endif /* FEATURE_LOOP */
714 714
715 /* wait for the user to tell us when to quit */ 715 /* wait for the user to tell us when to quit */
716 716
717 if (rpng2_info.state >= kWindowInit) { 717 if (rpng2_info.state >= kWindowInit) {
718 Trace((stderr, "entering final wait-for-quit-event loop\n")) 718 Trace((stderr, "entering final wait-for-quit-event loop\n"))
719 do { 719 do {
720 XNextEvent(display, &e); 720 XNextEvent(display, &e);
721 if (e.type == Expose) { 721 if (e.type == Expose) {
722 XExposeEvent *ex = (XExposeEvent *)&e; 722 XExposeEvent *ex = (XExposeEvent *)&e;
723 rpng2_x_redisplay_image (ex->x, ex->y, ex->width, ex->height); 723 rpng2_x_redisplay_image (ex->x, ex->y, ex->width, ex->height);
724 } 724 }
725 } while (!QUIT(e,k)); 725 } while (!QUIT(e,k));
726 } else { 726 } else {
727 fprintf(stderr, PROGNAME ": init callback never called: probable " 727 fprintf(stderr, PROGNAME ": init callback never called: probable "
728 "libpng error while decoding PNG metadata\n"); 728 "libpng error while decoding PNG metadata\n");
729 exit(4); 729 exit(4);
730 } 730 }
731 731
732 732
733 /* we're done: clean up all image and X resources and go away */ 733 /* we're done: clean up all image and X resources and go away */
734 734
735 Trace((stderr, "about to call rpng2_x_cleanup()\n")) 735 Trace((stderr, "about to call rpng2_x_cleanup()\n"))
736 rpng2_x_cleanup(); 736 rpng2_x_cleanup();
737 737
738 return 0; 738 return 0;
739} 739}
740 740
741 741
742 742
743 743
744 744
745/* this function is called by readpng2_info_callback() in readpng2.c, which 745/* this function is called by readpng2_info_callback() in readpng2.c, which
746 * in turn is called by libpng after all of the pre-IDAT chunks have been 746 * in turn is called by libpng after all of the pre-IDAT chunks have been
747 * read and processed--i.e., we now have enough info to finish initializing */ 747 * read and processed--i.e., we now have enough info to finish initializing */
748 748
749static void rpng2_x_init(void) 749static void rpng2_x_init(void)
750{ 750{
751 ulg i; 751 ulg i;
752 ulg rowbytes = rpng2_info.rowbytes; 752 ulg rowbytes = rpng2_info.rowbytes;
753 753
754 Trace((stderr, "beginning rpng2_x_init()\n")) 754 Trace((stderr, "beginning rpng2_x_init()\n"))
755 Trace((stderr, " rowbytes = %d\n", rpng2_info.rowbytes)) 755 Trace((stderr, " rowbytes = %d\n", rpng2_info.rowbytes))
756 Trace((stderr, " width = %ld\n", rpng2_info.width)) 756 Trace((stderr, " width = %ld\n", rpng2_info.width))
757 Trace((stderr, " height = %ld\n", rpng2_info.height)) 757 Trace((stderr, " height = %ld\n", rpng2_info.height))
758 758
759 rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height); 759 rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
760 if (!rpng2_info.image_data) { 760 if (!rpng2_info.image_data) {
761 readpng2_cleanup(&rpng2_info); 761 readpng2_cleanup(&rpng2_info);
762 return; 762 return;
763 } 763 }
764 764
765 rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *)); 765 rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *));
766 if (!rpng2_info.row_pointers) { 766 if (!rpng2_info.row_pointers) {
767 free(rpng2_info.image_data); 767 free(rpng2_info.image_data);
768 rpng2_info.image_data = NULL; 768 rpng2_info.image_data = NULL;
769 readpng2_cleanup(&rpng2_info); 769 readpng2_cleanup(&rpng2_info);
770 return; 770 return;
771 } 771 }
772 772
773 for (i = 0; i < rpng2_info.height; ++i) 773 for (i = 0; i < rpng2_info.height; ++i)
774 rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes; 774 rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes;
775 775
776 776
777 /* do the basic X initialization stuff, make the window, and fill it with 777 /* do the basic X initialization stuff, make the window, and fill it with
778 * the user-specified, file-specified or default background color or 778 * the user-specified, file-specified or default background color or
779 * pattern */ 779 * pattern */
780 780
781 if (rpng2_x_create_window()) { 781 if (rpng2_x_create_window()) {
782 782
783 /* GRR TEMPORARY HACK: this is fundamentally no different from cases 783 /* GRR TEMPORARY HACK: this is fundamentally no different from cases
784 * above; libpng should call our error handler to longjmp() back to us 784 * above; libpng should call our error handler to longjmp() back to us
785 * when png_ptr goes away. If we/it segfault instead, seems like a 785 * when png_ptr goes away. If we/it segfault instead, seems like a
786 * libpng bug... */ 786 * libpng bug... */
787 787
788 /* we're here via libpng callback, so if window fails, clean and bail */ 788 /* we're here via libpng callback, so if window fails, clean and bail */
789 readpng2_cleanup(&rpng2_info); 789 readpng2_cleanup(&rpng2_info);
790 rpng2_x_cleanup(); 790 rpng2_x_cleanup();
791 exit(2); 791 exit(2);
792 } 792 }
793 793
794 rpng2_info.state = kWindowInit; 794 rpng2_info.state = kWindowInit;
795} 795}
796 796
797 797
798 798
799 799
800 800
801static int rpng2_x_create_window(void) 801static int rpng2_x_create_window(void)
802{ 802{
803 ulg bg_red = rpng2_info.bg_red; 803 ulg bg_red = rpng2_info.bg_red;
804 ulg bg_green = rpng2_info.bg_green; 804 ulg bg_green = rpng2_info.bg_green;
805 ulg bg_blue = rpng2_info.bg_blue; 805 ulg bg_blue = rpng2_info.bg_blue;
806 ulg bg_pixel = 0L; 806 ulg bg_pixel = 0L;
807 ulg attrmask; 807 ulg attrmask;
808 int need_colormap = FALSE; 808 int need_colormap = FALSE;
809 int screen, pad; 809 int screen, pad;
810 uch *xdata; 810 uch *xdata;
811 Window root; 811 Window root;
812 XEvent e; 812 XEvent e;
813 XGCValues gcvalues; 813 XGCValues gcvalues;
814 XSetWindowAttributes attr; 814 XSetWindowAttributes attr;
815 XTextProperty windowName, *pWindowName = &windowName; 815 XTextProperty windowName, *pWindowName = &windowName;
816 XTextProperty iconName, *pIconName = &iconName; 816 XTextProperty iconName, *pIconName = &iconName;
817 XVisualInfo visual_info; 817 XVisualInfo visual_info;
818 XSizeHints *size_hints; 818 XSizeHints *size_hints;
819 XWMHints *wm_hints; 819 XWMHints *wm_hints;
820 XClassHint *class_hints; 820 XClassHint *class_hints;
821 821
822 822
823 Trace((stderr, "beginning rpng2_x_create_window()\n")) 823 Trace((stderr, "beginning rpng2_x_create_window()\n"))
824 824
825 screen = DefaultScreen(display); 825 screen = DefaultScreen(display);
826 depth = DisplayPlanes(display, screen); 826 depth = DisplayPlanes(display, screen);
827 root = RootWindow(display, screen); 827 root = RootWindow(display, screen);
828 828
829#ifdef DEBUG 829#ifdef DEBUG
830 XSynchronize(display, True); 830 XSynchronize(display, True);
831#endif 831#endif
832 832
833 if (depth != 16 && depth != 24 && depth != 32) { 833 if (depth != 16 && depth != 24 && depth != 32) {
834 int visuals_matched = 0; 834 int visuals_matched = 0;
835 835
836 Trace((stderr, "default depth is %d: checking other visuals\n", 836 Trace((stderr, "default depth is %d: checking other visuals\n",
837 depth)) 837 depth))
838 838
839 /* 24-bit first */ 839 /* 24-bit first */
840 visual_info.screen = screen; 840 visual_info.screen = screen;
841 visual_info.depth = 24; 841 visual_info.depth = 24;
842 visual_list = XGetVisualInfo(display, 842 visual_list = XGetVisualInfo(display,
843 VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched); 843 VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
844 if (visuals_matched == 0) { 844 if (visuals_matched == 0) {
845/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */ 845/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
846 fprintf(stderr, "default screen depth %d not supported, and no" 846 fprintf(stderr, "default screen depth %d not supported, and no"
847 " 24-bit visuals found\n", depth); 847 " 24-bit visuals found\n", depth);
848 return 2; 848 return 2;
849 } 849 }
850 Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n", 850 Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
851 visuals_matched)) 851 visuals_matched))
852 visual = visual_list[0].visual; 852 visual = visual_list[0].visual;
853 depth = visual_list[0].depth; 853 depth = visual_list[0].depth;
854/* 854/*
855 colormap_size = visual_list[0].colormap_size; 855 colormap_size = visual_list[0].colormap_size;
856 visual_class = visual->class; 856 visual_class = visual->class;
857 visualID = XVisualIDFromVisual(visual); 857 visualID = XVisualIDFromVisual(visual);
858 */ 858 */
859 have_nondefault_visual = TRUE; 859 have_nondefault_visual = TRUE;
860 need_colormap = TRUE; 860 need_colormap = TRUE;
861 } else { 861 } else {
862 XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info); 862 XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
863 visual = visual_info.visual; 863 visual = visual_info.visual;
864 } 864 }
865 865
866 RMask = visual->red_mask; 866 RMask = visual->red_mask;
867 GMask = visual->green_mask; 867 GMask = visual->green_mask;
868 BMask = visual->blue_mask; 868 BMask = visual->blue_mask;
869 869
870/* GRR: add/check 8-bit support */ 870/* GRR: add/check 8-bit support */
871 if (depth == 8 || need_colormap) { 871 if (depth == 8 || need_colormap) {
872 colormap = XCreateColormap(display, root, visual, AllocNone); 872 colormap = XCreateColormap(display, root, visual, AllocNone);
873 if (!colormap) { 873 if (!colormap) {
874 fprintf(stderr, "XCreateColormap() failed\n"); 874 fprintf(stderr, "XCreateColormap() failed\n");
875 return 2; 875 return 2;
876 } 876 }
877 have_colormap = TRUE; 877 have_colormap = TRUE;
878 if (depth == 8) 878 if (depth == 8)
879 bg_image = FALSE; /* gradient just wastes palette entries */ 879 bg_image = FALSE; /* gradient just wastes palette entries */
880 } 880 }
881 if (depth == 15 || depth == 16) { 881 if (depth == 15 || depth == 16) {
882 RShift = 15 - rpng2_x_msb(RMask); /* these are right-shifts */ 882 RShift = 15 - rpng2_x_msb(RMask); /* these are right-shifts */
883 GShift = 15 - rpng2_x_msb(GMask); 883 GShift = 15 - rpng2_x_msb(GMask);
884 BShift = 15 - rpng2_x_msb(BMask); 884 BShift = 15 - rpng2_x_msb(BMask);
885 } else if (depth > 16) { 885 } else if (depth > 16) {
886 RShift = rpng2_x_msb(RMask) - 7; /* these are left-shifts */ 886 RShift = rpng2_x_msb(RMask) - 7; /* these are left-shifts */
887 GShift = rpng2_x_msb(GMask) - 7; 887 GShift = rpng2_x_msb(GMask) - 7;
888 BShift = rpng2_x_msb(BMask) - 7; 888 BShift = rpng2_x_msb(BMask) - 7;
889 } 889 }
890 if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) { 890 if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
891 fprintf(stderr, "rpng2 internal logic error: negative X shift(s)!\n"); 891 fprintf(stderr, "rpng2 internal logic error: negative X shift(s)!\n");
892 return 2; 892 return 2;
893 } 893 }
894 894
895/*--------------------------------------------------------------------------- 895/*---------------------------------------------------------------------------
896 Finally, create the window. 896 Finally, create the window.
897 ---------------------------------------------------------------------------*/ 897 ---------------------------------------------------------------------------*/
898 898
899 attr.backing_store = Always; 899 attr.backing_store = Always;
900 attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask; 900 attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
901 attrmask = CWBackingStore | CWEventMask; 901 attrmask = CWBackingStore | CWEventMask;
902 if (have_nondefault_visual) { 902 if (have_nondefault_visual) {
903 attr.colormap = colormap; 903 attr.colormap = colormap;
904 attr.background_pixel = 0; 904 attr.background_pixel = 0;
905 attr.border_pixel = 1; 905 attr.border_pixel = 1;
906 attrmask |= CWColormap | CWBackPixel | CWBorderPixel; 906 attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
907 } 907 }
908 908
909 window = XCreateWindow(display, root, 0, 0, rpng2_info.width, 909 window = XCreateWindow(display, root, 0, 0, rpng2_info.width,
910 rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr); 910 rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr);
911 911
912 if (window == None) { 912 if (window == None) {
913 fprintf(stderr, "XCreateWindow() failed\n"); 913 fprintf(stderr, "XCreateWindow() failed\n");
914 return 2; 914 return 2;
915 } else 915 } else
916 have_window = TRUE; 916 have_window = TRUE;
917 917
918 if (depth == 8) 918 if (depth == 8)
919 XSetWindowColormap(display, window, colormap); 919 XSetWindowColormap(display, window, colormap);
920 920
921 if (!XStringListToTextProperty(&window_name, 1, pWindowName)) 921 if (!XStringListToTextProperty(&window_name, 1, pWindowName))
922 pWindowName = NULL; 922 pWindowName = NULL;
923 if (!XStringListToTextProperty(&icon_name, 1, pIconName)) 923 if (!XStringListToTextProperty(&icon_name, 1, pIconName))
924 pIconName = NULL; 924 pIconName = NULL;
925 925
926 /* OK if either hints allocation fails; XSetWMProperties() allows NULLs */ 926 /* OK if either hints allocation fails; XSetWMProperties() allows NULLs */
927 927
928 if ((size_hints = XAllocSizeHints()) != NULL) { 928 if ((size_hints = XAllocSizeHints()) != NULL) {
929 /* window will not be resizable */ 929 /* window will not be resizable */
930 size_hints->flags = PMinSize | PMaxSize; 930 size_hints->flags = PMinSize | PMaxSize;
931 size_hints->min_width = size_hints->max_width = (int)rpng2_info.width; 931 size_hints->min_width = size_hints->max_width = (int)rpng2_info.width;
932 size_hints->min_height = size_hints->max_height = 932 size_hints->min_height = size_hints->max_height =
933 (int)rpng2_info.height; 933 (int)rpng2_info.height;
934 } 934 }
935 935
936 if ((wm_hints = XAllocWMHints()) != NULL) { 936 if ((wm_hints = XAllocWMHints()) != NULL) {
937 wm_hints->initial_state = NormalState; 937 wm_hints->initial_state = NormalState;
938 wm_hints->input = True; 938 wm_hints->input = True;
939 /* wm_hints->icon_pixmap = icon_pixmap; */ 939 /* wm_hints->icon_pixmap = icon_pixmap; */
940 wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ; 940 wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ;
941 } 941 }
942 942
943 if ((class_hints = XAllocClassHint()) != NULL) { 943 if ((class_hints = XAllocClassHint()) != NULL) {
944 class_hints->res_name = res_name; 944 class_hints->res_name = res_name;
945 class_hints->res_class = res_class; 945 class_hints->res_class = res_class;
946 } 946 }
947 947
948 XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0, 948 XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,
949 size_hints, wm_hints, class_hints); 949 size_hints, wm_hints, class_hints);
950 950
951 /* various properties and hints no longer needed; free memory */ 951 /* various properties and hints no longer needed; free memory */
952 if (pWindowName) 952 if (pWindowName)
953 XFree(pWindowName->value); 953 XFree(pWindowName->value);
954 if (pIconName) 954 if (pIconName)
955 XFree(pIconName->value); 955 XFree(pIconName->value);
956 if (size_hints) 956 if (size_hints)
957 XFree(size_hints); 957 XFree(size_hints);
958 if (wm_hints) 958 if (wm_hints)
959 XFree(wm_hints); 959 XFree(wm_hints);
960 if (class_hints) 960 if (class_hints)
961 XFree(class_hints); 961 XFree(class_hints);
962 962
963 XMapWindow(display, window); 963 XMapWindow(display, window);
964 964
965 gc = XCreateGC(display, window, 0, &gcvalues); 965 gc = XCreateGC(display, window, 0, &gcvalues);
966 have_gc = TRUE; 966 have_gc = TRUE;
967 967
968/*--------------------------------------------------------------------------- 968/*---------------------------------------------------------------------------
969 Allocate memory for the X- and display-specific version of the image. 969 Allocate memory for the X- and display-specific version of the image.
970 ---------------------------------------------------------------------------*/ 970 ---------------------------------------------------------------------------*/
971 971
972 if (depth == 24 || depth == 32) { 972 if (depth == 24 || depth == 32) {
973 xdata = (uch *)malloc(4*rpng2_info.width*rpng2_info.height); 973 xdata = (uch *)malloc(4*rpng2_info.width*rpng2_info.height);
974 pad = 32; 974 pad = 32;
975 } else if (depth == 16) { 975 } else if (depth == 16) {
976 xdata = (uch *)malloc(2*rpng2_info.width*rpng2_info.height); 976 xdata = (uch *)malloc(2*rpng2_info.width*rpng2_info.height);
977 pad = 16; 977 pad = 16;
978 } else /* depth == 8 */ { 978 } else /* depth == 8 */ {
979 xdata = (uch *)malloc(rpng2_info.width*rpng2_info.height); 979 xdata = (uch *)malloc(rpng2_info.width*rpng2_info.height);
980 pad = 8; 980 pad = 8;
981 } 981 }
982 982
983 if (!xdata) { 983 if (!xdata) {
984 fprintf(stderr, PROGNAME ": unable to allocate image memory\n"); 984 fprintf(stderr, PROGNAME ": unable to allocate image memory\n");
985 return 4; 985 return 4;
986 } 986 }
987 987
988 ximage = XCreateImage(display, visual, depth, ZPixmap, 0, 988 ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
989 (char *)xdata, rpng2_info.width, rpng2_info.height, pad, 0); 989 (char *)xdata, rpng2_info.width, rpng2_info.height, pad, 0);
990 990
991 if (!ximage) { 991 if (!ximage) {
992 fprintf(stderr, PROGNAME ": XCreateImage() failed\n"); 992 fprintf(stderr, PROGNAME ": XCreateImage() failed\n");
993 free(xdata); 993 free(xdata);
994 return 3; 994 return 3;
995 } 995 }
996 996
997 /* to avoid testing the byte order every pixel (or doubling the size of 997 /* to avoid testing the byte order every pixel (or doubling the size of
998 * the drawing routine with a giant if-test), we arbitrarily set the byte 998 * the drawing routine with a giant if-test), we arbitrarily set the byte
999 * order to MSBFirst and let Xlib worry about inverting things on little- 999 * order to MSBFirst and let Xlib worry about inverting things on little-
1000 * endian machines (e.g., Linux/x86, old VAXen, etc.)--this is not the 1000 * endian machines (e.g., Linux/x86, old VAXen, etc.)--this is not the
1001 * most efficient approach (the giant if-test would be better), but in 1001 * most efficient approach (the giant if-test would be better), but in
1002 * the interest of clarity, we'll take the easy way out... */ 1002 * the interest of clarity, we'll take the easy way out... */
1003 1003
1004 ximage->byte_order = MSBFirst; 1004 ximage->byte_order = MSBFirst;
1005 1005
1006/*--------------------------------------------------------------------------- 1006/*---------------------------------------------------------------------------
1007 Fill window with the specified background color (default is black) or 1007 Fill window with the specified background color (default is black) or
1008 faked "background image" (but latter is disabled if 8-bit; gradients 1008 faked "background image" (but latter is disabled if 8-bit; gradients
1009 just waste palette entries). 1009 just waste palette entries).
1010 ---------------------------------------------------------------------------*/ 1010 ---------------------------------------------------------------------------*/
1011 1011
1012 if (bg_image) 1012 if (bg_image)
1013 rpng2_x_load_bg_image(); /* resets bg_image if fails */ 1013 rpng2_x_load_bg_image(); /* resets bg_image if fails */
1014 1014
1015 if (!bg_image) { 1015 if (!bg_image) {
1016 if (depth == 24 || depth == 32) { 1016 if (depth == 24 || depth == 32) {
1017 bg_pixel = (bg_red << RShift) | 1017 bg_pixel = (bg_red << RShift) |
1018 (bg_green << GShift) | 1018 (bg_green << GShift) |
1019 (bg_blue << BShift); 1019 (bg_blue << BShift);
1020 } else if (depth == 16) { 1020 } else if (depth == 16) {
1021 bg_pixel = (((bg_red << 8) >> RShift) & RMask) | 1021 bg_pixel = (((bg_red << 8) >> RShift) & RMask) |
1022 (((bg_green << 8) >> GShift) & GMask) | 1022 (((bg_green << 8) >> GShift) & GMask) |
1023 (((bg_blue << 8) >> BShift) & BMask); 1023 (((bg_blue << 8) >> BShift) & BMask);
1024 } else /* depth == 8 */ { 1024 } else /* depth == 8 */ {
1025 1025
1026 /* GRR: add 8-bit support */ 1026 /* GRR: add 8-bit support */
1027 1027
1028 } 1028 }
1029 XSetForeground(display, gc, bg_pixel); 1029 XSetForeground(display, gc, bg_pixel);
1030 XFillRectangle(display, window, gc, 0, 0, rpng2_info.width, 1030 XFillRectangle(display, window, gc, 0, 0, rpng2_info.width,
1031 rpng2_info.height); 1031 rpng2_info.height);
1032 } 1032 }
1033 1033
1034/*--------------------------------------------------------------------------- 1034/*---------------------------------------------------------------------------
1035 Wait for first Expose event to do any drawing, then flush and return. 1035 Wait for first Expose event to do any drawing, then flush and return.
1036 ---------------------------------------------------------------------------*/ 1036 ---------------------------------------------------------------------------*/
1037 1037
1038 do 1038 do
1039 XNextEvent(display, &e); 1039 XNextEvent(display, &e);
1040 while (e.type != Expose || e.xexpose.count); 1040 while (e.type != Expose || e.xexpose.count);
1041 1041
1042 XFlush(display); 1042 XFlush(display);
1043 1043
1044 return 0; 1044 return 0;
1045 1045
1046} /* end function rpng2_x_create_window() */ 1046} /* end function rpng2_x_create_window() */
1047 1047
1048 1048
1049 1049
1050 1050
1051 1051
1052static int rpng2_x_load_bg_image(void) 1052static int rpng2_x_load_bg_image(void)
1053{ 1053{
1054 uch *src; 1054 uch *src;
1055 char *dest; 1055 char *dest;
1056 uch r1, r2, g1, g2, b1, b2; 1056 uch r1, r2, g1, g2, b1, b2;
1057 uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv; 1057 uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;
1058 int k, hmax, max; 1058 int k, hmax, max;
1059 int xidx, yidx, yidx_max; 1059 int xidx, yidx, yidx_max;
1060 int even_odd_vert, even_odd_horiz, even_odd; 1060 int even_odd_vert, even_odd_horiz, even_odd;
1061 int invert_gradient2 = (bg[pat].type & 0x08); 1061 int invert_gradient2 = (bg[pat].type & 0x08);
1062 int invert_column; 1062 int invert_column;
1063 int ximage_rowbytes = ximage->bytes_per_line; 1063 int ximage_rowbytes = ximage->bytes_per_line;
1064 ulg i, row; 1064 ulg i, row;
1065 ulg pixel; 1065 ulg pixel;
1066 1066
1067/*--------------------------------------------------------------------------- 1067/*---------------------------------------------------------------------------
1068 Allocate buffer for fake background image to be used with transparent 1068 Allocate buffer for fake background image to be used with transparent
1069 images; if this fails, revert to plain background color. 1069 images; if this fails, revert to plain background color.
1070 ---------------------------------------------------------------------------*/ 1070 ---------------------------------------------------------------------------*/
1071 1071
1072 bg_rowbytes = 3 * rpng2_info.width; 1072 bg_rowbytes = 3 * rpng2_info.width;
1073 bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height); 1073 bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height);
1074 if (!bg_data) { 1074 if (!bg_data) {
1075 fprintf(stderr, PROGNAME 1075 fprintf(stderr, PROGNAME
1076 ": unable to allocate memory for background image\n"); 1076 ": unable to allocate memory for background image\n");
1077 bg_image = 0; 1077 bg_image = 0;
1078 return 1; 1078 return 1;
1079 } 1079 }
1080 1080
1081 bgscale = (pat == 0)? 8 : bgscale_default; 1081 bgscale = (pat == 0)? 8 : bgscale_default;
1082 yidx_max = bgscale - 1; 1082 yidx_max = bgscale - 1;
1083 1083
1084/*--------------------------------------------------------------------------- 1084/*---------------------------------------------------------------------------
1085 Vertical gradients (ramps) in NxN squares, alternating direction and 1085 Vertical gradients (ramps) in NxN squares, alternating direction and
1086 colors (N == bgscale). 1086 colors (N == bgscale).
1087 ---------------------------------------------------------------------------*/ 1087 ---------------------------------------------------------------------------*/
1088 1088
1089 if ((bg[pat].type & 0x07) == 0) { 1089 if ((bg[pat].type & 0x07) == 0) {
1090 uch r1_min = rgb[bg[pat].rgb1_min].r; 1090 uch r1_min = rgb[bg[pat].rgb1_min].r;
1091 uch g1_min = rgb[bg[pat].rgb1_min].g; 1091 uch g1_min = rgb[bg[pat].rgb1_min].g;
1092 uch b1_min = rgb[bg[pat].rgb1_min].b; 1092 uch b1_min = rgb[bg[pat].rgb1_min].b;
1093 uch r2_min = rgb[bg[pat].rgb2_min].r; 1093 uch r2_min = rgb[bg[pat].rgb2_min].r;
1094 uch g2_min = rgb[bg[pat].rgb2_min].g; 1094 uch g2_min = rgb[bg[pat].rgb2_min].g;
1095 uch b2_min = rgb[bg[pat].rgb2_min].b; 1095 uch b2_min = rgb[bg[pat].rgb2_min].b;
1096 int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min; 1096 int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;
1097 int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min; 1097 int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;
1098 int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min; 1098 int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;
1099 int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min; 1099 int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;
1100 int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min; 1100 int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;
1101 int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min; 1101 int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
1102 1102
1103 for (row = 0; row < rpng2_info.height; ++row) { 1103 for (row = 0; row < rpng2_info.height; ++row) {
1104 yidx = (int)(row % bgscale); 1104 yidx = (int)(row % bgscale);
1105 even_odd_vert = (int)((row / bgscale) & 1); 1105 even_odd_vert = (int)((row / bgscale) & 1);
1106 1106
1107 r1 = r1_min + (r1_diff * yidx) / yidx_max; 1107 r1 = r1_min + (r1_diff * yidx) / yidx_max;
1108 g1 = g1_min + (g1_diff * yidx) / yidx_max; 1108 g1 = g1_min + (g1_diff * yidx) / yidx_max;
1109 b1 = b1_min + (b1_diff * yidx) / yidx_max; 1109 b1 = b1_min + (b1_diff * yidx) / yidx_max;
1110 r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max; 1110 r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;
1111 g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max; 1111 g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;
1112 b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max; 1112 b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;
1113 1113
1114 r2 = r2_min + (r2_diff * yidx) / yidx_max; 1114 r2 = r2_min + (r2_diff * yidx) / yidx_max;
1115 g2 = g2_min + (g2_diff * yidx) / yidx_max; 1115 g2 = g2_min + (g2_diff * yidx) / yidx_max;
1116 b2 = b2_min + (b2_diff * yidx) / yidx_max; 1116 b2 = b2_min + (b2_diff * yidx) / yidx_max;
1117 r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max; 1117 r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;
1118 g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max; 1118 g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
1119 b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max; 1119 b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
1120 1120
1121 dest = (char *)bg_data + row*bg_rowbytes; 1121 dest = (char *)bg_data + row*bg_rowbytes;
1122 for (i = 0; i < rpng2_info.width; ++i) { 1122 for (i = 0; i < rpng2_info.width; ++i) {
1123 even_odd_horiz = (int)((i / bgscale) & 1); 1123 even_odd_horiz = (int)((i / bgscale) & 1);
1124 even_odd = even_odd_vert ^ even_odd_horiz; 1124 even_odd = even_odd_vert ^ even_odd_horiz;
1125 invert_column = 1125 invert_column =
1126 (even_odd_horiz && (bg[pat].type & 0x10)); 1126 (even_odd_horiz && (bg[pat].type & 0x10));
1127 if (even_odd == 0) { /* gradient #1 */ 1127 if (even_odd == 0) { /* gradient #1 */
1128 if (invert_column) { 1128 if (invert_column) {
1129 *dest++ = r1_inv; 1129 *dest++ = r1_inv;
1130 *dest++ = g1_inv; 1130 *dest++ = g1_inv;
1131 *dest++ = b1_inv; 1131 *dest++ = b1_inv;
1132 } else { 1132 } else {
1133 *dest++ = r1; 1133 *dest++ = r1;
1134 *dest++ = g1; 1134 *dest++ = g1;
1135 *dest++ = b1; 1135 *dest++ = b1;
1136 } 1136 }
1137 } else { /* gradient #2 */ 1137 } else { /* gradient #2 */
1138 if ((invert_column && invert_gradient2) || 1138 if ((invert_column && invert_gradient2) ||
1139 (!invert_column && !invert_gradient2)) 1139 (!invert_column && !invert_gradient2))
1140 { 1140 {
1141 *dest++ = r2; /* not inverted or */ 1141 *dest++ = r2; /* not inverted or */
1142 *dest++ = g2; /* doubly inverted */ 1142 *dest++ = g2; /* doubly inverted */
1143 *dest++ = b2; 1143 *dest++ = b2;
1144 } else { 1144 } else {
1145 *dest++ = r2_inv; 1145 *dest++ = r2_inv;
1146 *dest++ = g2_inv; /* singly inverted */ 1146 *dest++ = g2_inv; /* singly inverted */
1147 *dest++ = b2_inv; 1147 *dest++ = b2_inv;
1148 } 1148 }
1149 } 1149 }
1150 } 1150 }
1151 } 1151 }
1152 1152
1153/*--------------------------------------------------------------------------- 1153/*---------------------------------------------------------------------------
1154 Soft gradient-diamonds with scale = bgscale. Code contributed by Adam 1154 Soft gradient-diamonds with scale = bgscale. Code contributed by Adam
1155 M. Costello. 1155 M. Costello.
1156 ---------------------------------------------------------------------------*/ 1156 ---------------------------------------------------------------------------*/
1157 1157
1158 } else if ((bg[pat].type & 0x07) == 1) { 1158 } else if ((bg[pat].type & 0x07) == 1) {
1159 1159
1160 hmax = (bgscale-1)/2; /* half the max weight of a color */ 1160 hmax = (bgscale-1)/2; /* half the max weight of a color */
1161 max = 2*hmax; /* the max weight of a color */ 1161 max = 2*hmax; /* the max weight of a color */
1162 1162
1163 r1 = rgb[bg[pat].rgb1_max].r; 1163 r1 = rgb[bg[pat].rgb1_max].r;
1164 g1 = rgb[bg[pat].rgb1_max].g; 1164 g1 = rgb[bg[pat].rgb1_max].g;
1165 b1 = rgb[bg[pat].rgb1_max].b; 1165 b1 = rgb[bg[pat].rgb1_max].b;
1166 r2 = rgb[bg[pat].rgb2_max].r; 1166 r2 = rgb[bg[pat].rgb2_max].r;
1167 g2 = rgb[bg[pat].rgb2_max].g; 1167 g2 = rgb[bg[pat].rgb2_max].g;
1168 b2 = rgb[bg[pat].rgb2_max].b; 1168 b2 = rgb[bg[pat].rgb2_max].b;
1169 1169
1170 for (row = 0; row < rpng2_info.height; ++row) { 1170 for (row = 0; row < rpng2_info.height; ++row) {
1171 yidx = (int)(row % bgscale); 1171 yidx = (int)(row % bgscale);
1172 if (yidx > hmax) 1172 if (yidx > hmax)
1173 yidx = bgscale-1 - yidx; 1173 yidx = bgscale-1 - yidx;
1174 dest = (char *)bg_data + row*bg_rowbytes; 1174 dest = (char *)bg_data + row*bg_rowbytes;
1175 for (i = 0; i < rpng2_info.width; ++i) { 1175 for (i = 0; i < rpng2_info.width; ++i) {
1176 xidx = (int)(i % bgscale); 1176 xidx = (int)(i % bgscale);
1177 if (xidx > hmax) 1177 if (xidx > hmax)
1178 xidx = bgscale-1 - xidx; 1178 xidx = bgscale-1 - xidx;
1179 k = xidx + yidx; 1179 k = xidx + yidx;
1180 *dest++ = (k*r1 + (max-k)*r2) / max; 1180 *dest++ = (k*r1 + (max-k)*r2) / max;
1181 *dest++ = (k*g1 + (max-k)*g2) / max; 1181 *dest++ = (k*g1 + (max-k)*g2) / max;
1182 *dest++ = (k*b1 + (max-k)*b2) / max; 1182 *dest++ = (k*b1 + (max-k)*b2) / max;
1183 } 1183 }
1184 } 1184 }
1185 1185
1186/*--------------------------------------------------------------------------- 1186/*---------------------------------------------------------------------------
1187 Radial "starburst" with azimuthal sinusoids; [eventually number of sinu- 1187 Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
1188 soids will equal bgscale?]. This one is slow but very cool. Code con- 1188 soids will equal bgscale?]. This one is slow but very cool. Code con-
1189 tributed by Pieter S. van der Meulen (originally in Smalltalk). 1189 tributed by Pieter S. van der Meulen (originally in Smalltalk).
1190 ---------------------------------------------------------------------------*/ 1190 ---------------------------------------------------------------------------*/
1191 1191
1192 } else if ((bg[pat].type & 0x07) == 2) { 1192 } else if ((bg[pat].type & 0x07) == 2) {
1193 uch ch; 1193 uch ch;
1194 int ii, x, y, hw, hh, grayspot; 1194 int ii, x, y, hw, hh, grayspot;
1195 double freq, rotate, saturate, gray, intensity; 1195 double freq, rotate, saturate, gray, intensity;
1196 double angle=0.0, aoffset=0.0, maxDist, dist; 1196 double angle=0.0, aoffset=0.0, maxDist, dist;
1197 double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t; 1197 double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;
1198 1198
1199 fprintf(stderr, "%s: computing radial background...", 1199 fprintf(stderr, "%s: computing radial background...",
1200 PROGNAME); 1200 PROGNAME);
1201 fflush(stderr); 1201 fflush(stderr);
1202 1202
1203 hh = (int)(rpng2_info.height / 2); 1203 hh = (int)(rpng2_info.height / 2);
1204 hw = (int)(rpng2_info.width / 2); 1204 hw = (int)(rpng2_info.width / 2);
1205 1205
1206 /* variables for radial waves: 1206 /* variables for radial waves:
1207 * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED] 1207 * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED]
1208 * freq: number of color beams originating from the center 1208 * freq: number of color beams originating from the center
1209 * grayspot: size of the graying center area (anti-alias) 1209 * grayspot: size of the graying center area (anti-alias)
1210 * rotate: rotation of the beams as a function of radius 1210 * rotate: rotation of the beams as a function of radius
1211 * saturate: saturation of beams' shape azimuthally 1211 * saturate: saturation of beams' shape azimuthally
1212 */ 1212 */
1213 angle = CLIP(angle, 0.0, 360.0); 1213 angle = CLIP(angle, 0.0, 360.0);
1214 grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw)); 1214 grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
1215 freq = MAX((double)bg[pat].bg_freq, 0.0); 1215 freq = MAX((double)bg[pat].bg_freq, 0.0);
1216 saturate = (double)bg[pat].bg_bsat * 0.1; 1216 saturate = (double)bg[pat].bg_bsat * 0.1;
1217 rotate = (double)bg[pat].bg_brot * 0.1; 1217 rotate = (double)bg[pat].bg_brot * 0.1;
1218 gray = 0.0; 1218 gray = 0.0;
1219 intensity = 0.0; 1219 intensity = 0.0;
1220 maxDist = (double)((hw*hw) + (hh*hh)); 1220 maxDist = (double)((hw*hw) + (hh*hh));
1221 1221
1222 for (row = 0; row < rpng2_info.height; ++row) { 1222 for (row = 0; row < rpng2_info.height; ++row) {
1223 y = (int)(row - hh); 1223 y = (int)(row - hh);
1224 dest = (char *)bg_data + row*bg_rowbytes; 1224 dest = (char *)bg_data + row*bg_rowbytes;
1225 for (i = 0; i < rpng2_info.width; ++i) { 1225 for (i = 0; i < rpng2_info.width; ++i) {
1226 x = (int)(i - hw); 1226 x = (int)(i - hw);
1227 angle = (x == 0)? PI_2 : atan((double)y / (double)x); 1227 angle = (x == 0)? PI_2 : atan((double)y / (double)x);
1228 gray = (double)MAX(ABS(y), ABS(x)) / grayspot; 1228 gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
1229 gray = MIN(1.0, gray); 1229 gray = MIN(1.0, gray);
1230 dist = (double)((x*x) + (y*y)) / maxDist; 1230 dist = (double)((x*x) + (y*y)) / maxDist;
1231 intensity = cos((angle+(rotate*dist*PI)) * freq) * 1231 intensity = cos((angle+(rotate*dist*PI)) * freq) *
1232 gray * saturate; 1232 gray * saturate;
1233 intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5; 1233 intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
1234 hue = (angle + PI) * INV_PI_360 + aoffset; 1234 hue = (angle + PI) * INV_PI_360 + aoffset;
1235 s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh)); 1235 s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
1236 s = MIN(MAX(s,0.0), 1.0); 1236 s = MIN(MAX(s,0.0), 1.0);
1237 v = MIN(MAX(intensity,0.0), 1.0); 1237 v = MIN(MAX(intensity,0.0), 1.0);
1238 1238
1239 if (s == 0.0) { 1239 if (s == 0.0) {
1240 ch = (uch)(v * 255.0); 1240 ch = (uch)(v * 255.0);
1241 *dest++ = ch; 1241 *dest++ = ch;
1242 *dest++ = ch; 1242 *dest++ = ch;
1243 *dest++ = ch; 1243 *dest++ = ch;
1244 } else { 1244 } else {
1245 if ((hue < 0.0) || (hue >= 360.0)) 1245 if ((hue < 0.0) || (hue >= 360.0))
1246 hue -= (((int)(hue / 360.0)) * 360.0); 1246 hue -= (((int)(hue / 360.0)) * 360.0);
1247 hue /= 60.0; 1247 hue /= 60.0;
1248 ii = (int)hue; 1248 ii = (int)hue;
1249 f = hue - (double)ii; 1249 f = hue - (double)ii;
1250 p = (1.0 - s) * v; 1250 p = (1.0 - s) * v;
1251 q = (1.0 - (s * f)) * v; 1251 q = (1.0 - (s * f)) * v;
1252 t = (1.0 - (s * (1.0 - f))) * v; 1252 t = (1.0 - (s * (1.0 - f))) * v;
1253 if (ii == 0) { red = v; green = t; blue = p; } 1253 if (ii == 0) { red = v; green = t; blue = p; }
1254 else if (ii == 1) { red = q; green = v; blue = p; } 1254 else if (ii == 1) { red = q; green = v; blue = p; }
1255 else if (ii == 2) { red = p; green = v; blue = t; } 1255 else if (ii == 2) { red = p; green = v; blue = t; }
1256 else if (ii == 3) { red = p; green = q; blue = v; } 1256 else if (ii == 3) { red = p; green = q; blue = v; }
1257 else if (ii == 4) { red = t; green = p; blue = v; } 1257 else if (ii == 4) { red = t; green = p; blue = v; }
1258 else if (ii == 5) { red = v; green = p; blue = q; } 1258 else if (ii == 5) { red = v; green = p; blue = q; }
1259 *dest++ = (uch)(red * 255.0); 1259 *dest++ = (uch)(red * 255.0);
1260 *dest++ = (uch)(green * 255.0); 1260 *dest++ = (uch)(green * 255.0);
1261 *dest++ = (uch)(blue * 255.0); 1261 *dest++ = (uch)(blue * 255.0);
1262 } 1262 }
1263 } 1263 }
1264 } 1264 }
1265 fprintf(stderr, "done.\n"); 1265 fprintf(stderr, "done.\n");
1266 fflush(stderr); 1266 fflush(stderr);
1267 } 1267 }
1268 1268
1269/*--------------------------------------------------------------------------- 1269/*---------------------------------------------------------------------------
1270 Blast background image to display buffer before beginning PNG decode. 1270 Blast background image to display buffer before beginning PNG decode.
1271 ---------------------------------------------------------------------------*/ 1271 ---------------------------------------------------------------------------*/
1272 1272
1273 if (depth == 24 || depth == 32) { 1273 if (depth == 24 || depth == 32) {
1274 ulg red, green, blue; 1274 ulg red, green, blue;
1275 int bpp = ximage->bits_per_pixel; 1275 int bpp = ximage->bits_per_pixel;
1276 1276
1277 for (row = 0; row < rpng2_info.height; ++row) { 1277 for (row = 0; row < rpng2_info.height; ++row) {
1278 src = bg_data + row*bg_rowbytes; 1278 src = bg_data + row*bg_rowbytes;
1279 dest = ximage->data + row*ximage_rowbytes; 1279 dest = ximage->data + row*ximage_rowbytes;
1280 if (bpp == 32) { /* slightly optimized version */ 1280 if (bpp == 32) { /* slightly optimized version */
1281 for (i = rpng2_info.width; i > 0; --i) { 1281 for (i = rpng2_info.width; i > 0; --i) {
1282 red = *src++; 1282 red = *src++;
1283 green = *src++; 1283 green = *src++;
1284 blue = *src++; 1284 blue = *src++;
1285 pixel = (red << RShift) | 1285 pixel = (red << RShift) |
1286 (green << GShift) | 1286 (green << GShift) |
1287 (blue << BShift); 1287 (blue << BShift);
1288 /* recall that we set ximage->byte_order = MSBFirst above */ 1288 /* recall that we set ximage->byte_order = MSBFirst above */
1289 *dest++ = (char)((pixel >> 24) & 0xff); 1289 *dest++ = (char)((pixel >> 24) & 0xff);
1290 *dest++ = (char)((pixel >> 16) & 0xff); 1290 *dest++ = (char)((pixel >> 16) & 0xff);
1291 *dest++ = (char)((pixel >> 8) & 0xff); 1291 *dest++ = (char)((pixel >> 8) & 0xff);
1292 *dest++ = (char)( pixel & 0xff); 1292 *dest++ = (char)( pixel & 0xff);
1293 } 1293 }
1294 } else { 1294 } else {
1295 for (i = rpng2_info.width; i > 0; --i) { 1295 for (i = rpng2_info.width; i > 0; --i) {
1296 red = *src++; 1296 red = *src++;
1297 green = *src++; 1297 green = *src++;
1298 blue = *src++; 1298 blue = *src++;
1299 pixel = (red << RShift) | 1299 pixel = (red << RShift) |
1300 (green << GShift) | 1300 (green << GShift) |
1301 (blue << BShift); 1301 (blue << BShift);
1302 /* recall that we set ximage->byte_order = MSBFirst above */ 1302 /* recall that we set ximage->byte_order = MSBFirst above */
1303 /* GRR BUG? this assumes bpp == 24 & bits are packed low */ 1303 /* GRR BUG? this assumes bpp == 24 & bits are packed low */
1304 /* (probably need to use RShift, RMask, etc.) */ 1304 /* (probably need to use RShift, RMask, etc.) */
1305 *dest++ = (char)((pixel >> 16) & 0xff); 1305 *dest++ = (char)((pixel >> 16) & 0xff);
1306 *dest++ = (char)((pixel >> 8) & 0xff); 1306 *dest++ = (char)((pixel >> 8) & 0xff);
1307 *dest++ = (char)( pixel & 0xff); 1307 *dest++ = (char)( pixel & 0xff);
1308 } 1308 }
1309 } 1309 }
1310 } 1310 }
1311 1311
1312 } else if (depth == 16) { 1312 } else if (depth == 16) {
1313 ush red, green, blue; 1313 ush red, green, blue;
1314 1314
1315 for (row = 0; row < rpng2_info.height; ++row) { 1315 for (row = 0; row < rpng2_info.height; ++row) {
1316 src = bg_data + row*bg_rowbytes; 1316 src = bg_data + row*bg_rowbytes;
1317 dest = ximage->data + row*ximage_rowbytes; 1317 dest = ximage->data + row*ximage_rowbytes;
1318 for (i = rpng2_info.width; i > 0; --i) { 1318 for (i = rpng2_info.width; i > 0; --i) {
1319 red = ((ush)(*src) << 8); ++src; 1319 red = ((ush)(*src) << 8); ++src;
1320 green = ((ush)(*src) << 8); ++src; 1320 green = ((ush)(*src) << 8); ++src;
1321 blue = ((ush)(*src) << 8); ++src; 1321 blue = ((ush)(*src) << 8); ++src;
1322 pixel = ((red >> RShift) & RMask) | 1322 pixel = ((red >> RShift) & RMask) |
1323 ((green >> GShift) & GMask) | 1323 ((green >> GShift) & GMask) |
1324 ((blue >> BShift) & BMask); 1324 ((blue >> BShift) & BMask);
1325 /* recall that we set ximage->byte_order = MSBFirst above */ 1325 /* recall that we set ximage->byte_order = MSBFirst above */
1326 *dest++ = (char)((pixel >> 8) & 0xff); 1326 *dest++ = (char)((pixel >> 8) & 0xff);
1327 *dest++ = (char)( pixel & 0xff); 1327 *dest++ = (char)( pixel & 0xff);
1328 } 1328 }
1329 } 1329 }
1330 1330
1331 } else /* depth == 8 */ { 1331 } else /* depth == 8 */ {
1332 1332
1333 /* GRR: add 8-bit support */ 1333 /* GRR: add 8-bit support */
1334 1334
1335 } 1335 }
1336 1336
1337 XPutImage(display, window, gc, ximage, 0, 0, 0, 0, rpng2_info.width, 1337 XPutImage(display, window, gc, ximage, 0, 0, 0, 0, rpng2_info.width,
1338 rpng2_info.height); 1338 rpng2_info.height);
1339 1339
1340 return 0; 1340 return 0;
1341 1341
1342} /* end function rpng2_x_load_bg_image() */ 1342} /* end function rpng2_x_load_bg_image() */
1343 1343
1344 1344
1345 1345
1346 1346
1347 1347
1348static void rpng2_x_display_row(ulg row) 1348static void rpng2_x_display_row(ulg row)
1349{ 1349{
1350 uch bg_red = rpng2_info.bg_red; 1350 uch bg_red = rpng2_info.bg_red;
1351 uch bg_green = rpng2_info.bg_green; 1351 uch bg_green = rpng2_info.bg_green;
1352 uch bg_blue = rpng2_info.bg_blue; 1352 uch bg_blue = rpng2_info.bg_blue;
1353 uch *src, *src2=NULL; 1353 uch *src, *src2=NULL;
1354 char *dest; 1354 char *dest;
1355 uch r, g, b, a; 1355 uch r, g, b, a;
1356 int ximage_rowbytes = ximage->bytes_per_line; 1356 int ximage_rowbytes = ximage->bytes_per_line;
1357 ulg i, pixel; 1357 ulg i, pixel;
1358 static int rows=0, prevpass=(-1); 1358 static int rows=0, prevpass=(-1);
1359 static ulg firstrow; 1359 static ulg firstrow;
1360 1360
1361/*--------------------------------------------------------------------------- 1361/*---------------------------------------------------------------------------
1362 rows and firstrow simply track how many rows (and which ones) have not 1362 rows and firstrow simply track how many rows (and which ones) have not
1363 yet been displayed; alternatively, we could call XPutImage() for every 1363 yet been displayed; alternatively, we could call XPutImage() for every
1364 row and not bother with the records-keeping. 1364 row and not bother with the records-keeping.
1365 ---------------------------------------------------------------------------*/ 1365 ---------------------------------------------------------------------------*/
1366 1366
1367 Trace((stderr, "beginning rpng2_x_display_row()\n")) 1367 Trace((stderr, "beginning rpng2_x_display_row()\n"))
1368 1368
1369 if (rpng2_info.pass != prevpass) { 1369 if (rpng2_info.pass != prevpass) {
1370 if (pause_after_pass && rpng2_info.pass > 0) { 1370 if (pause_after_pass && rpng2_info.pass > 0) {
1371 XEvent e; 1371 XEvent e;
1372 KeySym k; 1372 KeySym k;
1373 1373
1374 fprintf(stderr, 1374 fprintf(stderr,
1375 "%s: end of pass %d of 7; click in image window to continue\n", 1375 "%s: end of pass %d of 7; click in image window to continue\n",
1376 PROGNAME, prevpass + 1); 1376 PROGNAME, prevpass + 1);
1377 do 1377 do
1378 XNextEvent(display, &e); 1378 XNextEvent(display, &e);
1379 while (!QUIT(e,k)); 1379 while (!QUIT(e,k));
1380 } 1380 }
1381 fprintf(stderr, "%s: pass %d of 7\r", PROGNAME, rpng2_info.pass + 1); 1381 fprintf(stderr, "%s: pass %d of 7\r", PROGNAME, rpng2_info.pass + 1);
1382 fflush(stderr); 1382 fflush(stderr);
1383 prevpass = rpng2_info.pass; 1383 prevpass = rpng2_info.pass;
1384 } 1384 }
1385 1385
1386 if (rows == 0) 1386 if (rows == 0)
1387 firstrow = row; /* first row that is not yet displayed */ 1387 firstrow = row; /* first row that is not yet displayed */
1388 1388
1389 ++rows; /* count of rows received but not yet displayed */ 1389 ++rows; /* count of rows received but not yet displayed */
1390 1390
1391/*--------------------------------------------------------------------------- 1391/*---------------------------------------------------------------------------
1392 Aside from the use of the rpng2_info struct, the lack of an outer loop 1392 Aside from the use of the rpng2_info struct, the lack of an outer loop
1393 (over rows) and moving the XPutImage() call outside the "if (depth)" 1393 (over rows) and moving the XPutImage() call outside the "if (depth)"
1394 tests, this routine is identical to rpng_x_display_image() in the non- 1394 tests, this routine is identical to rpng_x_display_image() in the non-
1395 progressive version of the program. 1395 progressive version of the program.
1396 ---------------------------------------------------------------------------*/ 1396 ---------------------------------------------------------------------------*/
1397 1397
1398 if (depth == 24 || depth == 32) { 1398 if (depth == 24 || depth == 32) {
1399 ulg red, green, blue; 1399 ulg red, green, blue;
1400 int bpp = ximage->bits_per_pixel; 1400 int bpp = ximage->bits_per_pixel;
1401 1401
1402 src = rpng2_info.image_data + row*rpng2_info.rowbytes; 1402 src = rpng2_info.image_data + row*rpng2_info.rowbytes;
1403 if (bg_image) 1403 if (bg_image)
1404 src2 = bg_data + row*bg_rowbytes; 1404 src2 = bg_data + row*bg_rowbytes;
1405 dest = ximage->data + row*ximage_rowbytes; 1405 dest = ximage->data + row*ximage_rowbytes;
1406 if (rpng2_info.channels == 3) { 1406 if (rpng2_info.channels == 3) {
1407 for (i = rpng2_info.width; i > 0; --i) { 1407 for (i = rpng2_info.width; i > 0; --i) {
1408 red = *src++; 1408 red = *src++;
1409 green = *src++; 1409 green = *src++;
1410 blue = *src++; 1410 blue = *src++;
1411 pixel = (red << RShift) | 1411 pixel = (red << RShift) |
1412 (green << GShift) | 1412 (green << GShift) |
1413 (blue << BShift); 1413 (blue << BShift);
1414 /* recall that we set ximage->byte_order = MSBFirst above */ 1414 /* recall that we set ximage->byte_order = MSBFirst above */
1415 if (bpp == 32) { 1415 if (bpp == 32) {
1416 *dest++ = (char)((pixel >> 24) & 0xff); 1416 *dest++ = (char)((pixel >> 24) & 0xff);
1417 *dest++ = (char)((pixel >> 16) & 0xff); 1417 *dest++ = (char)((pixel >> 16) & 0xff);
1418 *dest++ = (char)((pixel >> 8) & 0xff); 1418 *dest++ = (char)((pixel >> 8) & 0xff);
1419 *dest++ = (char)( pixel & 0xff); 1419 *dest++ = (char)( pixel & 0xff);
1420 } else { 1420 } else {
1421 /* GRR BUG? this assumes bpp == 24 & bits are packed low */ 1421 /* GRR BUG? this assumes bpp == 24 & bits are packed low */
1422 /* (probably need to use RShift, RMask, etc.) */ 1422 /* (probably need to use RShift, RMask, etc.) */
1423 *dest++ = (char)((pixel >> 16) & 0xff); 1423 *dest++ = (char)((pixel >> 16) & 0xff);
1424 *dest++ = (char)((pixel >> 8) & 0xff); 1424 *dest++ = (char)((pixel >> 8) & 0xff);
1425 *dest++ = (char)( pixel & 0xff); 1425 *dest++ = (char)( pixel & 0xff);
1426 } 1426 }
1427 } 1427 }
1428 } else /* if (rpng2_info.channels == 4) */ { 1428 } else /* if (rpng2_info.channels == 4) */ {
1429 for (i = rpng2_info.width; i > 0; --i) { 1429 for (i = rpng2_info.width; i > 0; --i) {
1430 r = *src++; 1430 r = *src++;
1431 g = *src++; 1431 g = *src++;
1432 b = *src++; 1432 b = *src++;
1433 a = *src++; 1433 a = *src++;
1434 if (bg_image) { 1434 if (bg_image) {
1435 bg_red = *src2++; 1435 bg_red = *src2++;
1436 bg_green = *src2++; 1436 bg_green = *src2++;
1437 bg_blue = *src2++; 1437 bg_blue = *src2++;
1438 } 1438 }
1439 if (a == 255) { 1439 if (a == 255) {
1440 red = r; 1440 red = r;
1441 green = g; 1441 green = g;
1442 blue = b; 1442 blue = b;
1443 } else if (a == 0) { 1443 } else if (a == 0) {
1444 red = bg_red; 1444 red = bg_red;
1445 green = bg_green; 1445 green = bg_green;
1446 blue = bg_blue; 1446 blue = bg_blue;
1447 } else { 1447 } else {
1448 /* this macro (from png.h) composites the foreground 1448 /* this macro (from png.h) composites the foreground
1449 * and background values and puts the result into the 1449 * and background values and puts the result into the
1450 * first argument */ 1450 * first argument */
1451 alpha_composite(red, r, a, bg_red); 1451 alpha_composite(red, r, a, bg_red);
1452 alpha_composite(green, g, a, bg_green); 1452 alpha_composite(green, g, a, bg_green);
1453 alpha_composite(blue, b, a, bg_blue); 1453 alpha_composite(blue, b, a, bg_blue);
1454 } 1454 }
1455 pixel = (red << RShift) | 1455 pixel = (red << RShift) |
1456 (green << GShift) | 1456 (green << GShift) |
1457 (blue << BShift); 1457 (blue << BShift);
1458 /* recall that we set ximage->byte_order = MSBFirst above */ 1458 /* recall that we set ximage->byte_order = MSBFirst above */
1459 if (bpp == 32) { 1459 if (bpp == 32) {
1460 *dest++ = (char)((pixel >> 24) & 0xff); 1460 *dest++ = (char)((pixel >> 24) & 0xff);
1461 *dest++ = (char)((pixel >> 16) & 0xff); 1461 *dest++ = (char)((pixel >> 16) & 0xff);
1462 *dest++ = (char)((pixel >> 8) & 0xff); 1462 *dest++ = (char)((pixel >> 8) & 0xff);
1463 *dest++ = (char)( pixel & 0xff); 1463 *dest++ = (char)( pixel & 0xff);
1464 } else { 1464 } else {
1465 /* GRR BUG? this assumes bpp == 24 & bits are packed low */ 1465 /* GRR BUG? this assumes bpp == 24 & bits are packed low */
1466 /* (probably need to use RShift, RMask, etc.) */ 1466 /* (probably need to use RShift, RMask, etc.) */
1467 *dest++ = (char)((pixel >> 16) & 0xff); 1467 *dest++ = (char)((pixel >> 16) & 0xff);
1468 *dest++ = (char)((pixel >> 8) & 0xff); 1468 *dest++ = (char)((pixel >> 8) & 0xff);
1469 *dest++ = (char)( pixel & 0xff); 1469 *dest++ = (char)( pixel & 0xff);
1470 } 1470 }
1471 } 1471 }
1472 } 1472 }
1473 1473
1474 } else if (depth == 16) { 1474 } else if (depth == 16) {
1475 ush red, green, blue; 1475 ush red, green, blue;
1476 1476
1477 src = rpng2_info.row_pointers[row]; 1477 src = rpng2_info.row_pointers[row];
1478 if (bg_image) 1478 if (bg_image)
1479 src2 = bg_data + row*bg_rowbytes; 1479 src2 = bg_data + row*bg_rowbytes;
1480 dest = ximage->data + row*ximage_rowbytes; 1480 dest = ximage->data + row*ximage_rowbytes;
1481 if (rpng2_info.channels == 3) { 1481 if (rpng2_info.channels == 3) {
1482 for (i = rpng2_info.width; i > 0; --i) { 1482 for (i = rpng2_info.width; i > 0; --i) {
1483 red = ((ush)(*src) << 8); 1483 red = ((ush)(*src) << 8);
1484 ++src; 1484 ++src;
1485 green = ((ush)(*src) << 8); 1485 green = ((ush)(*src) << 8);
1486 ++src; 1486 ++src;
1487 blue = ((ush)(*src) << 8); 1487 blue = ((ush)(*src) << 8);
1488 ++src; 1488 ++src;
1489 pixel = ((red >> RShift) & RMask) | 1489 pixel = ((red >> RShift) & RMask) |
1490 ((green >> GShift) & GMask) | 1490 ((green >> GShift) & GMask) |
1491 ((blue >> BShift) & BMask); 1491 ((blue >> BShift) & BMask);
1492 /* recall that we set ximage->byte_order = MSBFirst above */ 1492 /* recall that we set ximage->byte_order = MSBFirst above */
1493 *dest++ = (char)((pixel >> 8) & 0xff); 1493 *dest++ = (char)((pixel >> 8) & 0xff);
1494 *dest++ = (char)( pixel & 0xff); 1494 *dest++ = (char)( pixel & 0xff);
1495 } 1495 }
1496 } else /* if (rpng2_info.channels == 4) */ { 1496 } else /* if (rpng2_info.channels == 4) */ {
1497 for (i = rpng2_info.width; i > 0; --i) { 1497 for (i = rpng2_info.width; i > 0; --i) {
1498 r = *src++; 1498 r = *src++;
1499 g = *src++; 1499 g = *src++;
1500 b = *src++; 1500 b = *src++;
1501 a = *src++; 1501 a = *src++;
1502 if (bg_image) { 1502 if (bg_image) {
1503 bg_red = *src2++; 1503 bg_red = *src2++;
1504 bg_green = *src2++; 1504 bg_green = *src2++;
1505 bg_blue = *src2++; 1505 bg_blue = *src2++;
1506 } 1506 }
1507 if (a == 255) { 1507 if (a == 255) {
1508 red = ((ush)r << 8); 1508 red = ((ush)r << 8);
1509 green = ((ush)g << 8); 1509 green = ((ush)g << 8);
1510 blue = ((ush)b << 8); 1510 blue = ((ush)b << 8);
1511 } else if (a == 0) { 1511 } else if (a == 0) {
1512 red = ((ush)bg_red << 8); 1512 red = ((ush)bg_red << 8);
1513 green = ((ush)bg_green << 8); 1513 green = ((ush)bg_green << 8);
1514 blue = ((ush)bg_blue << 8); 1514 blue = ((ush)bg_blue << 8);
1515 } else { 1515 } else {
1516 /* this macro (from png.h) composites the foreground 1516 /* this macro (from png.h) composites the foreground
1517 * and background values and puts the result back into 1517 * and background values and puts the result back into
1518 * the first argument (== fg byte here: safe) */ 1518 * the first argument (== fg byte here: safe) */
1519 alpha_composite(r, r, a, bg_red); 1519 alpha_composite(r, r, a, bg_red);
1520 alpha_composite(g, g, a, bg_green); 1520 alpha_composite(g, g, a, bg_green);
1521 alpha_composite(b, b, a, bg_blue); 1521 alpha_composite(b, b, a, bg_blue);
1522 red = ((ush)r << 8); 1522 red = ((ush)r << 8);
1523 green = ((ush)g << 8); 1523 green = ((ush)g << 8);
1524 blue = ((ush)b << 8); 1524 blue = ((ush)b << 8);
1525 } 1525 }
1526 pixel = ((red >> RShift) & RMask) | 1526 pixel = ((red >> RShift) & RMask) |
1527 ((green >> GShift) & GMask) | 1527 ((green >> GShift) & GMask) |
1528 ((blue >> BShift) & BMask); 1528 ((blue >> BShift) & BMask);
1529 /* recall that we set ximage->byte_order = MSBFirst above */ 1529 /* recall that we set ximage->byte_order = MSBFirst above */
1530 *dest++ = (char)((pixel >> 8) & 0xff); 1530 *dest++ = (char)((pixel >> 8) & 0xff);
1531 *dest++ = (char)( pixel & 0xff); 1531 *dest++ = (char)( pixel & 0xff);
1532 } 1532 }
1533 } 1533 }
1534 1534
1535 } else /* depth == 8 */ { 1535 } else /* depth == 8 */ {
1536 1536
1537 /* GRR: add 8-bit support */ 1537 /* GRR: add 8-bit support */
1538 1538
1539 } 1539 }
1540 1540
1541 1541
1542/*--------------------------------------------------------------------------- 1542/*---------------------------------------------------------------------------
1543 Display after every 16 rows or when on one of last two rows. (Region 1543 Display after every 16 rows or when on one of last two rows. (Region
1544 may include previously displayed lines due to interlacing--i.e., not 1544 may include previously displayed lines due to interlacing--i.e., not
1545 contiguous. Also, second-to-last row is final one in interlaced images 1545 contiguous. Also, second-to-last row is final one in interlaced images
1546 with odd number of rows.) For demos, flush (and delay) after every 16th 1546 with odd number of rows.) For demos, flush (and delay) after every 16th
1547 row so "sparse" passes don't go twice as fast. 1547 row so "sparse" passes don't go twice as fast.
1548 ---------------------------------------------------------------------------*/ 1548 ---------------------------------------------------------------------------*/
1549 1549
1550 if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) { 1550 if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) {
1551 XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0, 1551 XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
1552 (int)firstrow, rpng2_info.width, row - firstrow + 1); 1552 (int)firstrow, rpng2_info.width, row - firstrow + 1);
1553 XFlush(display); 1553 XFlush(display);
1554 rows = 0; 1554 rows = 0;
1555 usleep(usleep_duration); 1555 usleep(usleep_duration);
1556 } else 1556 } else
1557 if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) { 1557 if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) {
1558 XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0, 1558 XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
1559 (int)firstrow, rpng2_info.width, row - firstrow + 1); 1559 (int)firstrow, rpng2_info.width, row - firstrow + 1);
1560 XFlush(display); 1560 XFlush(display);
1561 rows = 0; 1561 rows = 0;
1562 } 1562 }
1563 1563
1564} 1564}
1565 1565
1566 1566
1567 1567
1568 1568
1569 1569
1570static void rpng2_x_finish_display(void) 1570static void rpng2_x_finish_display(void)
1571{ 1571{
1572 Trace((stderr, "beginning rpng2_x_finish_display()\n")) 1572 Trace((stderr, "beginning rpng2_x_finish_display()\n"))
1573 1573
1574 /* last row has already been displayed by rpng2_x_display_row(), so we 1574 /* last row has already been displayed by rpng2_x_display_row(), so we
1575 * have nothing to do here except set a flag and let the user know that 1575 * have nothing to do here except set a flag and let the user know that
1576 * the image is done */ 1576 * the image is done */
1577 1577
1578 rpng2_info.state = kDone; 1578 rpng2_info.state = kDone;
1579 printf( 1579 printf(
1580 "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); 1580 "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n");
1581 fflush(stdout); 1581 fflush(stdout);
1582} 1582}
1583 1583
1584 1584
1585 1585
1586 1586
1587 1587
1588static void rpng2_x_redisplay_image(ulg startcol, ulg startrow, 1588static void rpng2_x_redisplay_image(ulg startcol, ulg startrow,
1589 ulg width, ulg height) 1589 ulg width, ulg height)
1590{ 1590{
1591 uch bg_red = rpng2_info.bg_red; 1591 uch bg_red = rpng2_info.bg_red;
1592 uch bg_green = rpng2_info.bg_green; 1592 uch bg_green = rpng2_info.bg_green;
1593 uch bg_blue = rpng2_info.bg_blue; 1593 uch bg_blue = rpng2_info.bg_blue;
1594 uch *src, *src2=NULL; 1594 uch *src, *src2=NULL;
1595 char *dest; 1595 char *dest;
1596 uch r, g, b, a; 1596 uch r, g, b, a;
1597 ulg i, row, lastrow = 0; 1597 ulg i, row, lastrow = 0;
1598 ulg pixel; 1598 ulg pixel;
1599 int ximage_rowbytes = ximage->bytes_per_line; 1599 int ximage_rowbytes = ximage->bytes_per_line;
1600 1600
1601 1601
1602 Trace((stderr, "beginning display loop (image_channels == %d)\n", 1602 Trace((stderr, "beginning display loop (image_channels == %d)\n",
1603 rpng2_info.channels)) 1603 rpng2_info.channels))
1604 Trace((stderr, " (width = %ld, rowbytes = %d, ximage_rowbytes = %d)\n", 1604 Trace((stderr, " (width = %ld, rowbytes = %d, ximage_rowbytes = %d)\n",
1605 rpng2_info.width, rpng2_info.rowbytes, ximage_rowbytes)) 1605 rpng2_info.width, rpng2_info.rowbytes, ximage_rowbytes))
1606 Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel)) 1606 Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel))
1607 Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst? 1607 Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst?
1608 "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown"))) 1608 "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown")))
1609 1609
1610/*--------------------------------------------------------------------------- 1610/*---------------------------------------------------------------------------
1611 Aside from the use of the rpng2_info struct and of src2 (for background 1611 Aside from the use of the rpng2_info struct and of src2 (for background
1612 image), this routine is identical to rpng_x_display_image() in the non- 1612 image), this routine is identical to rpng_x_display_image() in the non-
1613 progressive version of the program--for the simple reason that redisplay 1613 progressive version of the program--for the simple reason that redisplay
1614 of the image against a new background happens after the image is fully 1614 of the image against a new background happens after the image is fully
1615 decoded and therefore is, by definition, non-progressive. 1615 decoded and therefore is, by definition, non-progressive.
1616 ---------------------------------------------------------------------------*/ 1616 ---------------------------------------------------------------------------*/
1617 1617
1618 if (depth == 24 || depth == 32) { 1618 if (depth == 24 || depth == 32) {
1619 ulg red, green, blue; 1619 ulg red, green, blue;
1620 int bpp = ximage->bits_per_pixel; 1620 int bpp = ximage->bits_per_pixel;
1621 1621
1622 for (lastrow = row = startrow; row < startrow+height; ++row) { 1622 for (lastrow = row = startrow; row < startrow+height; ++row) {
1623 src = rpng2_info.image_data + row*rpng2_info.rowbytes; 1623 src = rpng2_info.image_data + row*rpng2_info.rowbytes;
1624 if (bg_image) 1624 if (bg_image)
1625 src2 = bg_data + row*bg_rowbytes; 1625 src2 = bg_data + row*bg_rowbytes;
1626 dest = ximage->data + row*ximage_rowbytes; 1626 dest = ximage->data + row*ximage_rowbytes;
1627 if (rpng2_info.channels == 3) { 1627 if (rpng2_info.channels == 3) {
1628 for (i = rpng2_info.width; i > 0; --i) { 1628 for (i = rpng2_info.width; i > 0; --i) {
1629 red = *src++; 1629 red = *src++;
1630 green = *src++; 1630 green = *src++;
1631 blue = *src++; 1631 blue = *src++;
1632#ifdef NO_24BIT_MASKS 1632#ifdef NO_24BIT_MASKS
1633 pixel = (red << RShift) | 1633 pixel = (red << RShift) |
1634 (green << GShift) | 1634 (green << GShift) |
1635 (blue << BShift); 1635 (blue << BShift);
1636 /* recall that we set ximage->byte_order = MSBFirst above */ 1636 /* recall that we set ximage->byte_order = MSBFirst above */
1637 if (bpp == 32) { 1637 if (bpp == 32) {
1638 *dest++ = (char)((pixel >> 24) & 0xff); 1638 *dest++ = (char)((pixel >> 24) & 0xff);
1639 *dest++ = (char)((pixel >> 16) & 0xff); 1639 *dest++ = (char)((pixel >> 16) & 0xff);
1640 *dest++ = (char)((pixel >> 8) & 0xff); 1640 *dest++ = (char)((pixel >> 8) & 0xff);
1641 *dest++ = (char)( pixel & 0xff); 1641 *dest++ = (char)( pixel & 0xff);
1642 } else { 1642 } else {
1643 /* this assumes bpp == 24 & bits are packed low */ 1643 /* this assumes bpp == 24 & bits are packed low */
1644 /* (probably need to use RShift, RMask, etc.) */ 1644 /* (probably need to use RShift, RMask, etc.) */
1645 *dest++ = (char)((pixel >> 16) & 0xff); 1645 *dest++ = (char)((pixel >> 16) & 0xff);
1646 *dest++ = (char)((pixel >> 8) & 0xff); 1646 *dest++ = (char)((pixel >> 8) & 0xff);
1647 *dest++ = (char)( pixel & 0xff); 1647 *dest++ = (char)( pixel & 0xff);
1648 } 1648 }
1649#else 1649#else
1650 red = (RShift < 0)? red << (-RShift) : red >> RShift; 1650 red = (RShift < 0)? red << (-RShift) : red >> RShift;
1651 green = (GShift < 0)? green << (-GShift) : green >> GShift; 1651 green = (GShift < 0)? green << (-GShift) : green >> GShift;
1652 blue = (BShift < 0)? blue << (-BShift) : blue >> BShift; 1652 blue = (BShift < 0)? blue << (-BShift) : blue >> BShift;
1653 pixel = (red & RMask) | (green & GMask) | (blue & BMask); 1653 pixel = (red & RMask) | (green & GMask) | (blue & BMask);
1654 /* recall that we set ximage->byte_order = MSBFirst above */ 1654 /* recall that we set ximage->byte_order = MSBFirst above */
1655 if (bpp == 32) { 1655 if (bpp == 32) {
1656 *dest++ = (char)((pixel >> 24) & 0xff); 1656 *dest++ = (char)((pixel >> 24) & 0xff);
1657 *dest++ = (char)((pixel >> 16) & 0xff); 1657 *dest++ = (char)((pixel >> 16) & 0xff);
1658 *dest++ = (char)((pixel >> 8) & 0xff); 1658 *dest++ = (char)((pixel >> 8) & 0xff);
1659 *dest++ = (char)( pixel & 0xff); 1659 *dest++ = (char)( pixel & 0xff);
1660 } else { 1660 } else {
1661 /* GRR BUG */ 1661 /* GRR BUG */
1662 /* this assumes bpp == 24 & bits are packed low */ 1662 /* this assumes bpp == 24 & bits are packed low */
1663 /* (probably need to use RShift/RMask/etc. here, too) */ 1663 /* (probably need to use RShift/RMask/etc. here, too) */
1664 *dest++ = (char)((pixel >> 16) & 0xff); 1664 *dest++ = (char)((pixel >> 16) & 0xff);
1665 *dest++ = (char)((pixel >> 8) & 0xff); 1665 *dest++ = (char)((pixel >> 8) & 0xff);
1666 *dest++ = (char)( pixel & 0xff); 1666 *dest++ = (char)( pixel & 0xff);
1667 } 1667 }
1668#endif 1668#endif
1669 } 1669 }
1670 1670
1671 } else /* if (rpng2_info.channels == 4) */ { 1671 } else /* if (rpng2_info.channels == 4) */ {
1672 for (i = rpng2_info.width; i > 0; --i) { 1672 for (i = rpng2_info.width; i > 0; --i) {
1673 r = *src++; 1673 r = *src++;
1674 g = *src++; 1674 g = *src++;
1675 b = *src++; 1675 b = *src++;
1676 a = *src++; 1676 a = *src++;
1677 if (bg_image) { 1677 if (bg_image) {
1678 bg_red = *src2++; 1678 bg_red = *src2++;
1679 bg_green = *src2++; 1679 bg_green = *src2++;
1680 bg_blue = *src2++; 1680 bg_blue = *src2++;
1681 } 1681 }
1682 if (a == 255) { 1682 if (a == 255) {
1683 red = r; 1683 red = r;
1684 green = g; 1684 green = g;
1685 blue = b; 1685 blue = b;
1686 } else if (a == 0) { 1686 } else if (a == 0) {
1687 red = bg_red; 1687 red = bg_red;
1688 green = bg_green; 1688 green = bg_green;
1689 blue = bg_blue; 1689 blue = bg_blue;
1690 } else { 1690 } else {
1691 /* this macro (from png.h) composites the foreground 1691 /* this macro (from png.h) composites the foreground
1692 * and background values and puts the result into the 1692 * and background values and puts the result into the
1693 * first argument */ 1693 * first argument */
1694 alpha_composite(red, r, a, bg_red); 1694 alpha_composite(red, r, a, bg_red);
1695 alpha_composite(green, g, a, bg_green); 1695 alpha_composite(green, g, a, bg_green);
1696 alpha_composite(blue, b, a, bg_blue); 1696 alpha_composite(blue, b, a, bg_blue);
1697 } 1697 }
1698#ifdef NO_24BIT_MASKS 1698#ifdef NO_24BIT_MASKS
1699 pixel = (red << RShift) | 1699 pixel = (red << RShift) |
1700 (green << GShift) | 1700 (green << GShift) |
1701 (blue << BShift); 1701 (blue << BShift);
1702 /* recall that we set ximage->byte_order = MSBFirst above */ 1702 /* recall that we set ximage->byte_order = MSBFirst above */
1703 if (bpp == 32) { 1703 if (bpp == 32) {
1704 *dest++ = (char)((pixel >> 24) & 0xff); 1704 *dest++ = (char)((pixel >> 24) & 0xff);
1705 *dest++ = (char)((pixel >> 16) & 0xff); 1705 *dest++ = (char)((pixel >> 16) & 0xff);
1706 *dest++ = (char)((pixel >> 8) & 0xff); 1706 *dest++ = (char)((pixel >> 8) & 0xff);
1707 *dest++ = (char)( pixel & 0xff); 1707 *dest++ = (char)( pixel & 0xff);
1708 } else { 1708 } else {
1709 /* this assumes bpp == 24 & bits are packed low */ 1709 /* this assumes bpp == 24 & bits are packed low */
1710 /* (probably need to use RShift, RMask, etc.) */ 1710 /* (probably need to use RShift, RMask, etc.) */
1711 *dest++ = (char)((pixel >> 16) & 0xff); 1711 *dest++ = (char)((pixel >> 16) & 0xff);
1712 *dest++ = (char)((pixel >> 8) & 0xff); 1712 *dest++ = (char)((pixel >> 8) & 0xff);
1713 *dest++ = (char)( pixel & 0xff); 1713 *dest++ = (char)( pixel & 0xff);
1714 } 1714 }
1715#else 1715#else
1716 red = (RShift < 0)? red << (-RShift) : red >> RShift; 1716 red = (RShift < 0)? red << (-RShift) : red >> RShift;
1717 green = (GShift < 0)? green << (-GShift) : green >> GShift; 1717 green = (GShift < 0)? green << (-GShift) : green >> GShift;
1718 blue = (BShift < 0)? blue << (-BShift) : blue >> BShift; 1718 blue = (BShift < 0)? blue << (-BShift) : blue >> BShift;
1719 pixel = (red & RMask) | (green & GMask) | (blue & BMask); 1719 pixel = (red & RMask) | (green & GMask) | (blue & BMask);
1720 /* recall that we set ximage->byte_order = MSBFirst above */ 1720 /* recall that we set ximage->byte_order = MSBFirst above */
1721 if (bpp == 32) { 1721 if (bpp == 32) {
1722 *dest++ = (char)((pixel >> 24) & 0xff); 1722 *dest++ = (char)((pixel >> 24) & 0xff);
1723 *dest++ = (char)((pixel >> 16) & 0xff); 1723 *dest++ = (char)((pixel >> 16) & 0xff);
1724 *dest++ = (char)((pixel >> 8) & 0xff); 1724 *dest++ = (char)((pixel >> 8) & 0xff);
1725 *dest++ = (char)( pixel & 0xff); 1725 *dest++ = (char)( pixel & 0xff);
1726 } else { 1726 } else {
1727 /* GRR BUG */ 1727 /* GRR BUG */
1728 /* this assumes bpp == 24 & bits are packed low */ 1728 /* this assumes bpp == 24 & bits are packed low */
1729 /* (probably need to use RShift/RMask/etc. here, too) */ 1729 /* (probably need to use RShift/RMask/etc. here, too) */
1730 *dest++ = (char)((pixel >> 16) & 0xff); 1730 *dest++ = (char)((pixel >> 16) & 0xff);
1731 *dest++ = (char)((pixel >> 8) & 0xff); 1731 *dest++ = (char)((pixel >> 8) & 0xff);
1732 *dest++ = (char)( pixel & 0xff); 1732 *dest++ = (char)( pixel & 0xff);
1733 } 1733 }
1734#endif 1734#endif
1735 } 1735 }
1736 } 1736 }
1737 /* display after every 16 lines */ 1737 /* display after every 16 lines */
1738 if (((row+1) & 0xf) == 0) { 1738 if (((row+1) & 0xf) == 0) {
1739 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, 1739 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
1740 (int)lastrow, rpng2_info.width, 16); 1740 (int)lastrow, rpng2_info.width, 16);
1741 XFlush(display); 1741 XFlush(display);
1742 lastrow = row + 1; 1742 lastrow = row + 1;
1743 } 1743 }
1744 } 1744 }
1745 1745
1746 } else if (depth == 16) { 1746 } else if (depth == 16) {
1747 ush red, green, blue; 1747 ush red, green, blue;
1748 1748
1749 for (lastrow = row = startrow; row < startrow+height; ++row) { 1749 for (lastrow = row = startrow; row < startrow+height; ++row) {
1750 src = rpng2_info.row_pointers[row]; 1750 src = rpng2_info.row_pointers[row];
1751 if (bg_image) 1751 if (bg_image)
1752 src2 = bg_data + row*bg_rowbytes; 1752 src2 = bg_data + row*bg_rowbytes;
1753 dest = ximage->data + row*ximage_rowbytes; 1753 dest = ximage->data + row*ximage_rowbytes;
1754 if (rpng2_info.channels == 3) { 1754 if (rpng2_info.channels == 3) {
1755 for (i = rpng2_info.width; i > 0; --i) { 1755 for (i = rpng2_info.width; i > 0; --i) {
1756 red = ((ush)(*src) << 8); 1756 red = ((ush)(*src) << 8);
1757 ++src; 1757 ++src;
1758 green = ((ush)(*src) << 8); 1758 green = ((ush)(*src) << 8);
1759 ++src; 1759 ++src;
1760 blue = ((ush)(*src) << 8); 1760 blue = ((ush)(*src) << 8);
1761 ++src; 1761 ++src;
1762 pixel = ((red >> RShift) & RMask) | 1762 pixel = ((red >> RShift) & RMask) |
1763 ((green >> GShift) & GMask) | 1763 ((green >> GShift) & GMask) |
1764 ((blue >> BShift) & BMask); 1764 ((blue >> BShift) & BMask);
1765 /* recall that we set ximage->byte_order = MSBFirst above */ 1765 /* recall that we set ximage->byte_order = MSBFirst above */
1766 *dest++ = (char)((pixel >> 8) & 0xff); 1766 *dest++ = (char)((pixel >> 8) & 0xff);
1767 *dest++ = (char)( pixel & 0xff); 1767 *dest++ = (char)( pixel & 0xff);
1768 } 1768 }
1769 } else /* if (rpng2_info.channels == 4) */ { 1769 } else /* if (rpng2_info.channels == 4) */ {
1770 for (i = rpng2_info.width; i > 0; --i) { 1770 for (i = rpng2_info.width; i > 0; --i) {
1771 r = *src++; 1771 r = *src++;
1772 g = *src++; 1772 g = *src++;
1773 b = *src++; 1773 b = *src++;
1774 a = *src++; 1774 a = *src++;
1775 if (bg_image) { 1775 if (bg_image) {
1776 bg_red = *src2++; 1776 bg_red = *src2++;
1777 bg_green = *src2++; 1777 bg_green = *src2++;
1778 bg_blue = *src2++; 1778 bg_blue = *src2++;
1779 } 1779 }
1780 if (a == 255) { 1780 if (a == 255) {
1781 red = ((ush)r << 8); 1781 red = ((ush)r << 8);
1782 green = ((ush)g << 8); 1782 green = ((ush)g << 8);
1783 blue = ((ush)b << 8); 1783 blue = ((ush)b << 8);
1784 } else if (a == 0) { 1784 } else if (a == 0) {
1785 red = ((ush)bg_red << 8); 1785 red = ((ush)bg_red << 8);
1786 green = ((ush)bg_green << 8); 1786 green = ((ush)bg_green << 8);
1787 blue = ((ush)bg_blue << 8); 1787 blue = ((ush)bg_blue << 8);
1788 } else { 1788 } else {
1789 /* this macro (from png.h) composites the foreground 1789 /* this macro (from png.h) composites the foreground
1790 * and background values and puts the result back into 1790 * and background values and puts the result back into
1791 * the first argument (== fg byte here: safe) */ 1791 * the first argument (== fg byte here: safe) */
1792 alpha_composite(r, r, a, bg_red); 1792 alpha_composite(r, r, a, bg_red);
1793 alpha_composite(g, g, a, bg_green); 1793 alpha_composite(g, g, a, bg_green);
1794 alpha_composite(b, b, a, bg_blue); 1794 alpha_composite(b, b, a, bg_blue);
1795 red = ((ush)r << 8); 1795 red = ((ush)r << 8);
1796 green = ((ush)g << 8); 1796 green = ((ush)g << 8);
1797 blue = ((ush)b << 8); 1797 blue = ((ush)b << 8);
1798 } 1798 }
1799 pixel = ((red >> RShift) & RMask) | 1799 pixel = ((red >> RShift) & RMask) |
1800 ((green >> GShift) & GMask) | 1800 ((green >> GShift) & GMask) |
1801 ((blue >> BShift) & BMask); 1801 ((blue >> BShift) & BMask);
1802 /* recall that we set ximage->byte_order = MSBFirst above */ 1802 /* recall that we set ximage->byte_order = MSBFirst above */
1803 *dest++ = (char)((pixel >> 8) & 0xff); 1803 *dest++ = (char)((pixel >> 8) & 0xff);
1804 *dest++ = (char)( pixel & 0xff); 1804 *dest++ = (char)( pixel & 0xff);
1805 } 1805 }
1806 } 1806 }
1807 /* display after every 16 lines */ 1807 /* display after every 16 lines */
1808 if (((row+1) & 0xf) == 0) { 1808 if (((row+1) & 0xf) == 0) {
1809 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, 1809 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
1810 (int)lastrow, rpng2_info.width, 16); 1810 (int)lastrow, rpng2_info.width, 16);
1811 XFlush(display); 1811 XFlush(display);
1812 lastrow = row + 1; 1812 lastrow = row + 1;
1813 } 1813 }
1814 } 1814 }
1815 1815
1816 } else /* depth == 8 */ { 1816 } else /* depth == 8 */ {
1817 1817
1818 /* GRR: add 8-bit support */ 1818 /* GRR: add 8-bit support */
1819 1819
1820 } 1820 }
1821 1821
1822 Trace((stderr, "calling final XPutImage()\n")) 1822 Trace((stderr, "calling final XPutImage()\n"))
1823 if (lastrow < startrow+height) { 1823 if (lastrow < startrow+height) {
1824 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, 1824 XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
1825 (int)lastrow, rpng2_info.width, rpng2_info.height-lastrow); 1825 (int)lastrow, rpng2_info.width, rpng2_info.height-lastrow);
1826 XFlush(display); 1826 XFlush(display);
1827 } 1827 }
1828 1828
1829} /* end function rpng2_x_redisplay_image() */ 1829} /* end function rpng2_x_redisplay_image() */
1830 1830
1831 1831
1832 1832
1833 1833
1834 1834
1835#ifdef FEATURE_LOOP 1835#ifdef FEATURE_LOOP
1836 1836
1837static void rpng2_x_reload_bg_image(void) 1837static void rpng2_x_reload_bg_image(void)
1838{ 1838{
1839 char *dest; 1839 char *dest;
1840 uch r1, r2, g1, g2, b1, b2; 1840 uch r1, r2, g1, g2, b1, b2;
1841 uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv; 1841 uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;
1842 int k, hmax, max; 1842 int k, hmax, max;
1843 int xidx, yidx, yidx_max; 1843 int xidx, yidx, yidx_max;
1844 int even_odd_vert, even_odd_horiz, even_odd; 1844 int even_odd_vert, even_odd_horiz, even_odd;
1845 int invert_gradient2 = (bg[pat].type & 0x08); 1845 int invert_gradient2 = (bg[pat].type & 0x08);
1846 int invert_column; 1846 int invert_column;
1847 ulg i, row; 1847 ulg i, row;
1848 1848
1849 1849
1850 bgscale = (pat == 0)? 8 : bgscale_default; 1850 bgscale = (pat == 0)? 8 : bgscale_default;
1851 yidx_max = bgscale - 1; 1851 yidx_max = bgscale - 1;
1852 1852
1853/*--------------------------------------------------------------------------- 1853/*---------------------------------------------------------------------------
1854 Vertical gradients (ramps) in NxN squares, alternating direction and 1854 Vertical gradients (ramps) in NxN squares, alternating direction and
1855 colors (N == bgscale). 1855 colors (N == bgscale).
1856 ---------------------------------------------------------------------------*/ 1856 ---------------------------------------------------------------------------*/
1857 1857
1858 if ((bg[pat].type & 0x07) == 0) { 1858 if ((bg[pat].type & 0x07) == 0) {
1859 uch r1_min = rgb[bg[pat].rgb1_min].r; 1859 uch r1_min = rgb[bg[pat].rgb1_min].r;
1860 uch g1_min = rgb[bg[pat].rgb1_min].g; 1860 uch g1_min = rgb[bg[pat].rgb1_min].g;
1861 uch b1_min = rgb[bg[pat].rgb1_min].b; 1861 uch b1_min = rgb[bg[pat].rgb1_min].b;
1862 uch r2_min = rgb[bg[pat].rgb2_min].r; 1862 uch r2_min = rgb[bg[pat].rgb2_min].r;
1863 uch g2_min = rgb[bg[pat].rgb2_min].g; 1863 uch g2_min = rgb[bg[pat].rgb2_min].g;
1864 uch b2_min = rgb[bg[pat].rgb2_min].b; 1864 uch b2_min = rgb[bg[pat].rgb2_min].b;
1865 int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min; 1865 int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;
1866 int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min; 1866 int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;
1867 int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min; 1867 int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;
1868 int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min; 1868 int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;
1869 int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min; 1869 int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;
1870 int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min; 1870 int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
1871 1871
1872 for (row = 0; row < rpng2_info.height; ++row) { 1872 for (row = 0; row < rpng2_info.height; ++row) {
1873 yidx = (int)(row % bgscale); 1873 yidx = (int)(row % bgscale);
1874 even_odd_vert = (int)((row / bgscale) & 1); 1874 even_odd_vert = (int)((row / bgscale) & 1);
1875 1875
1876 r1 = r1_min + (r1_diff * yidx) / yidx_max; 1876 r1 = r1_min + (r1_diff * yidx) / yidx_max;
1877 g1 = g1_min + (g1_diff * yidx) / yidx_max; 1877 g1 = g1_min + (g1_diff * yidx) / yidx_max;
1878 b1 = b1_min + (b1_diff * yidx) / yidx_max; 1878 b1 = b1_min + (b1_diff * yidx) / yidx_max;
1879 r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max; 1879 r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;
1880 g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max; 1880 g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;
1881 b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max; 1881 b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;
1882 1882
1883 r2 = r2_min + (r2_diff * yidx) / yidx_max; 1883 r2 = r2_min + (r2_diff * yidx) / yidx_max;
1884 g2 = g2_min + (g2_diff * yidx) / yidx_max; 1884 g2 = g2_min + (g2_diff * yidx) / yidx_max;
1885 b2 = b2_min + (b2_diff * yidx) / yidx_max; 1885 b2 = b2_min + (b2_diff * yidx) / yidx_max;
1886 r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max; 1886 r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;
1887 g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max; 1887 g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
1888 b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max; 1888 b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
1889 1889
1890 dest = (char *)bg_data + row*bg_rowbytes; 1890 dest = (char *)bg_data + row*bg_rowbytes;
1891 for (i = 0; i < rpng2_info.width; ++i) { 1891 for (i = 0; i < rpng2_info.width; ++i) {
1892 even_odd_horiz = (int)((i / bgscale) & 1); 1892 even_odd_horiz = (int)((i / bgscale) & 1);
1893 even_odd = even_odd_vert ^ even_odd_horiz; 1893 even_odd = even_odd_vert ^ even_odd_horiz;
1894 invert_column = 1894 invert_column =
1895 (even_odd_horiz && (bg[pat].type & 0x10)); 1895 (even_odd_horiz && (bg[pat].type & 0x10));
1896 if (even_odd == 0) { /* gradient #1 */ 1896 if (even_odd == 0) { /* gradient #1 */
1897 if (invert_column) { 1897 if (invert_column) {
1898 *dest++ = r1_inv; 1898 *dest++ = r1_inv;
1899 *dest++ = g1_inv; 1899 *dest++ = g1_inv;
1900 *dest++ = b1_inv; 1900 *dest++ = b1_inv;
1901 } else { 1901 } else {
1902 *dest++ = r1; 1902 *dest++ = r1;
1903 *dest++ = g1; 1903 *dest++ = g1;
1904 *dest++ = b1; 1904 *dest++ = b1;
1905 } 1905 }
1906 } else { /* gradient #2 */ 1906 } else { /* gradient #2 */
1907 if ((invert_column && invert_gradient2) || 1907 if ((invert_column && invert_gradient2) ||
1908 (!invert_column && !invert_gradient2)) 1908 (!invert_column && !invert_gradient2))
1909 { 1909 {
1910 *dest++ = r2; /* not inverted or */ 1910 *dest++ = r2; /* not inverted or */
1911 *dest++ = g2; /* doubly inverted */ 1911 *dest++ = g2; /* doubly inverted */
1912 *dest++ = b2; 1912 *dest++ = b2;
1913 } else { 1913 } else {
1914 *dest++ = r2_inv; 1914 *dest++ = r2_inv;
1915 *dest++ = g2_inv; /* singly inverted */ 1915 *dest++ = g2_inv; /* singly inverted */
1916 *dest++ = b2_inv; 1916 *dest++ = b2_inv;
1917 } 1917 }
1918 } 1918 }
1919 } 1919 }
1920 } 1920 }
1921 1921
1922/*--------------------------------------------------------------------------- 1922/*---------------------------------------------------------------------------
1923 Soft gradient-diamonds with scale = bgscale. Code contributed by Adam 1923 Soft gradient-diamonds with scale = bgscale. Code contributed by Adam
1924 M. Costello. 1924 M. Costello.
1925 ---------------------------------------------------------------------------*/ 1925 ---------------------------------------------------------------------------*/
1926 1926
1927 } else if ((bg[pat].type & 0x07) == 1) { 1927 } else if ((bg[pat].type & 0x07) == 1) {
1928 1928
1929 hmax = (bgscale-1)/2; /* half the max weight of a color */ 1929 hmax = (bgscale-1)/2; /* half the max weight of a color */
1930 max = 2*hmax; /* the max weight of a color */ 1930 max = 2*hmax; /* the max weight of a color */
1931 1931
1932 r1 = rgb[bg[pat].rgb1_max].r; 1932 r1 = rgb[bg[pat].rgb1_max].r;
1933 g1 = rgb[bg[pat].rgb1_max].g; 1933 g1 = rgb[bg[pat].rgb1_max].g;
1934 b1 = rgb[bg[pat].rgb1_max].b; 1934 b1 = rgb[bg[pat].rgb1_max].b;
1935 r2 = rgb[bg[pat].rgb2_max].r; 1935 r2 = rgb[bg[pat].rgb2_max].r;
1936 g2 = rgb[bg[pat].rgb2_max].g; 1936 g2 = rgb[bg[pat].rgb2_max].g;
1937 b2 = rgb[bg[pat].rgb2_max].b; 1937 b2 = rgb[bg[pat].rgb2_max].b;
1938 1938
1939 for (row = 0; row < rpng2_info.height; ++row) { 1939 for (row = 0; row < rpng2_info.height; ++row) {
1940 yidx = (int)(row % bgscale); 1940 yidx = (int)(row % bgscale);
1941 if (yidx > hmax) 1941 if (yidx > hmax)
1942 yidx = bgscale-1 - yidx; 1942 yidx = bgscale-1 - yidx;
1943 dest = (char *)bg_data + row*bg_rowbytes; 1943 dest = (char *)bg_data + row*bg_rowbytes;
1944 for (i = 0; i < rpng2_info.width; ++i) { 1944 for (i = 0; i < rpng2_info.width; ++i) {
1945 xidx = (int)(i % bgscale); 1945 xidx = (int)(i % bgscale);
1946 if (xidx > hmax) 1946 if (xidx > hmax)
1947 xidx = bgscale-1 - xidx; 1947 xidx = bgscale-1 - xidx;
1948 k = xidx + yidx; 1948 k = xidx + yidx;
1949 *dest++ = (k*r1 + (max-k)*r2) / max; 1949 *dest++ = (k*r1 + (max-k)*r2) / max;
1950 *dest++ = (k*g1 + (max-k)*g2) / max; 1950 *dest++ = (k*g1 + (max-k)*g2) / max;
1951 *dest++ = (k*b1 + (max-k)*b2) / max; 1951 *dest++ = (k*b1 + (max-k)*b2) / max;
1952 } 1952 }
1953 } 1953 }
1954 1954
1955/*--------------------------------------------------------------------------- 1955/*---------------------------------------------------------------------------
1956 Radial "starburst" with azimuthal sinusoids; [eventually number of sinu- 1956 Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
1957 soids will equal bgscale?]. This one is slow but very cool. Code con- 1957 soids will equal bgscale?]. This one is slow but very cool. Code con-
1958 tributed by Pieter S. van der Meulen (originally in Smalltalk). 1958 tributed by Pieter S. van der Meulen (originally in Smalltalk).
1959 ---------------------------------------------------------------------------*/ 1959 ---------------------------------------------------------------------------*/
1960 1960
1961 } else if ((bg[pat].type & 0x07) == 2) { 1961 } else if ((bg[pat].type & 0x07) == 2) {
1962 uch ch; 1962 uch ch;
1963 int ii, x, y, hw, hh, grayspot; 1963 int ii, x, y, hw, hh, grayspot;
1964 double freq, rotate, saturate, gray, intensity; 1964 double freq, rotate, saturate, gray, intensity;
1965 double angle=0.0, aoffset=0.0, maxDist, dist; 1965 double angle=0.0, aoffset=0.0, maxDist, dist;
1966 double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t; 1966 double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;
1967 1967
1968 hh = (int)(rpng2_info.height / 2); 1968 hh = (int)(rpng2_info.height / 2);
1969 hw = (int)(rpng2_info.width / 2); 1969 hw = (int)(rpng2_info.width / 2);
1970 1970
1971 /* variables for radial waves: 1971 /* variables for radial waves:
1972 * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED] 1972 * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED]
1973 * freq: number of color beams originating from the center 1973 * freq: number of color beams originating from the center
1974 * grayspot: size of the graying center area (anti-alias) 1974 * grayspot: size of the graying center area (anti-alias)
1975 * rotate: rotation of the beams as a function of radius 1975 * rotate: rotation of the beams as a function of radius
1976 * saturate: saturation of beams' shape azimuthally 1976 * saturate: saturation of beams' shape azimuthally
1977 */ 1977 */
1978 angle = CLIP(angle, 0.0, 360.0); 1978 angle = CLIP(angle, 0.0, 360.0);
1979 grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw)); 1979 grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
1980 freq = MAX((double)bg[pat].bg_freq, 0.0); 1980 freq = MAX((double)bg[pat].bg_freq, 0.0);
1981 saturate = (double)bg[pat].bg_bsat * 0.1; 1981 saturate = (double)bg[pat].bg_bsat * 0.1;
1982 rotate = (double)bg[pat].bg_brot * 0.1; 1982 rotate = (double)bg[pat].bg_brot * 0.1;
1983 gray = 0.0; 1983 gray = 0.0;
1984 intensity = 0.0; 1984 intensity = 0.0;
1985 maxDist = (double)((hw*hw) + (hh*hh)); 1985 maxDist = (double)((hw*hw) + (hh*hh));
1986 1986
1987 for (row = 0; row < rpng2_info.height; ++row) { 1987 for (row = 0; row < rpng2_info.height; ++row) {
1988 y = (int)(row - hh); 1988 y = (int)(row - hh);
1989 dest = (char *)bg_data + row*bg_rowbytes; 1989 dest = (char *)bg_data + row*bg_rowbytes;
1990 for (i = 0; i < rpng2_info.width; ++i) { 1990 for (i = 0; i < rpng2_info.width; ++i) {
1991 x = (int)(i - hw); 1991 x = (int)(i - hw);
1992 angle = (x == 0)? PI_2 : atan((double)y / (double)x); 1992 angle = (x == 0)? PI_2 : atan((double)y / (double)x);
1993 gray = (double)MAX(ABS(y), ABS(x)) / grayspot; 1993 gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
1994 gray = MIN(1.0, gray); 1994 gray = MIN(1.0, gray);
1995 dist = (double)((x*x) + (y*y)) / maxDist; 1995 dist = (double)((x*x) + (y*y)) / maxDist;
1996 intensity = cos((angle+(rotate*dist*PI)) * freq) * 1996 intensity = cos((angle+(rotate*dist*PI)) * freq) *
1997 gray * saturate; 1997 gray * saturate;
1998 intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5; 1998 intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
1999 hue = (angle + PI) * INV_PI_360 + aoffset; 1999 hue = (angle + PI) * INV_PI_360 + aoffset;
2000 s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh)); 2000 s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
2001 s = MIN(MAX(s,0.0), 1.0); 2001 s = MIN(MAX(s,0.0), 1.0);
2002 v = MIN(MAX(intensity,0.0), 1.0); 2002 v = MIN(MAX(intensity,0.0), 1.0);
2003 2003
2004 if (s == 0.0) { 2004 if (s == 0.0) {
2005 ch = (uch)(v * 255.0); 2005 ch = (uch)(v * 255.0);
2006 *dest++ = ch; 2006 *dest++ = ch;
2007 *dest++ = ch; 2007 *dest++ = ch;
2008 *dest++ = ch; 2008 *dest++ = ch;
2009 } else { 2009 } else {
2010 if ((hue < 0.0) || (hue >= 360.0)) 2010 if ((hue < 0.0) || (hue >= 360.0))
2011 hue -= (((int)(hue / 360.0)) * 360.0); 2011 hue -= (((int)(hue / 360.0)) * 360.0);
2012 hue /= 60.0; 2012 hue /= 60.0;
2013 ii = (int)hue; 2013 ii = (int)hue;
2014 f = hue - (double)ii; 2014 f = hue - (double)ii;
2015 p = (1.0 - s) * v; 2015 p = (1.0 - s) * v;
2016 q = (1.0 - (s * f)) * v; 2016 q = (1.0 - (s * f)) * v;
2017 t = (1.0 - (s * (1.0 - f))) * v; 2017 t = (1.0 - (s * (1.0 - f))) * v;
2018 if (ii == 0) { red = v; green = t; blue = p; } 2018 if (ii == 0) { red = v; green = t; blue = p; }
2019 else if (ii == 1) { red = q; green = v; blue = p; } 2019 else if (ii == 1) { red = q; green = v; blue = p; }
2020 else if (ii == 2) { red = p; green = v; blue = t; } 2020 else if (ii == 2) { red = p; green = v; blue = t; }
2021 else if (ii == 3) { red = p; green = q; blue = v; } 2021 else if (ii == 3) { red = p; green = q; blue = v; }
2022 else if (ii == 4) { red = t; green = p; blue = v; } 2022 else if (ii == 4) { red = t; green = p; blue = v; }
2023 else if (ii == 5) { red = v; green = p; blue = q; } 2023 else if (ii == 5) { red = v; green = p; blue = q; }
2024 *dest++ = (uch)(red * 255.0); 2024 *dest++ = (uch)(red * 255.0);
2025 *dest++ = (uch)(green * 255.0); 2025 *dest++ = (uch)(green * 255.0);
2026 *dest++ = (uch)(blue * 255.0); 2026 *dest++ = (uch)(blue * 255.0);
2027 } 2027 }
2028 } 2028 }
2029 } 2029 }
2030 } 2030 }
2031 2031
2032} /* end function rpng2_x_reload_bg_image() */ 2032} /* end function rpng2_x_reload_bg_image() */
2033 2033
2034 2034
2035 2035
2036 2036
2037 2037
2038static int is_number(char *p) 2038static int is_number(char *p)
2039{ 2039{
2040 while (*p) { 2040 while (*p) {
2041 if (!isdigit(*p)) 2041 if (!isdigit(*p))
2042 return FALSE; 2042 return FALSE;
2043 ++p; 2043 ++p;
2044 } 2044 }
2045 return TRUE; 2045 return TRUE;
2046} 2046}
2047 2047
2048#endif /* FEATURE_LOOP */ 2048#endif /* FEATURE_LOOP */
2049 2049
2050 2050
2051 2051
2052 2052
2053 2053
2054static void rpng2_x_cleanup(void) 2054static void rpng2_x_cleanup(void)
2055{ 2055{
2056 if (bg_image && bg_data) { 2056 if (bg_image && bg_data) {
2057 free(bg_data); 2057 free(bg_data);
2058 bg_data = NULL; 2058 bg_data = NULL;
2059 } 2059 }
2060 2060
2061 if (rpng2_info.image_data) { 2061 if (rpng2_info.image_data) {
2062 free(rpng2_info.image_data); 2062 free(rpng2_info.image_data);
2063 rpng2_info.image_data = NULL; 2063 rpng2_info.image_data = NULL;
2064 } 2064 }
2065 2065
2066 if (rpng2_info.row_pointers) { 2066 if (rpng2_info.row_pointers) {
2067 free(rpng2_info.row_pointers); 2067 free(rpng2_info.row_pointers);
2068 rpng2_info.row_pointers = NULL; 2068 rpng2_info.row_pointers = NULL;
2069 } 2069 }
2070 2070
2071 if (ximage) { 2071 if (ximage) {
2072 if (ximage->data) { 2072 if (ximage->data) {
2073 free(ximage->data); /* we allocated it, so we free it */ 2073 free(ximage->data); /* we allocated it, so we free it */
2074 ximage->data = (char *)NULL; /* instead of XDestroyImage() */ 2074 ximage->data = (char *)NULL; /* instead of XDestroyImage() */
2075 } 2075 }
2076 XDestroyImage(ximage); 2076 XDestroyImage(ximage);
2077 ximage = NULL; 2077 ximage = NULL;
2078 } 2078 }
2079 2079
2080 if (have_gc) 2080 if (have_gc)
2081 XFreeGC(display, gc); 2081 XFreeGC(display, gc);
2082 2082
2083 if (have_window) 2083 if (have_window)
2084 XDestroyWindow(display, window); 2084 XDestroyWindow(display, window);
2085 2085
2086 if (have_colormap) 2086 if (have_colormap)
2087 XFreeColormap(display, colormap); 2087 XFreeColormap(display, colormap);
2088 2088
2089 if (have_nondefault_visual) 2089 if (have_nondefault_visual)
2090 XFree(visual_list); 2090 XFree(visual_list);
2091} 2091}
2092 2092
2093 2093
2094 2094
2095 2095
2096 2096
2097static int rpng2_x_msb(ulg u32val) 2097static int rpng2_x_msb(ulg u32val)
2098{ 2098{
2099 int i; 2099 int i;
2100 2100
2101 for (i = 31; i >= 0; --i) { 2101 for (i = 31; i >= 0; --i) {
2102 if (u32val & 0x80000000L) 2102 if (u32val & 0x80000000L)
2103 break; 2103 break;
2104 u32val <<= 1; 2104 u32val <<= 1;
2105 } 2105 }
2106 return i; 2106 return i;
2107} 2107}
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/wpng.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/wpng.c
index 30372a3..a06e352 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/wpng.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/wpng.c
@@ -1,853 +1,853 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 wpng - simple PNG-writing program wpng.c 3 wpng - simple PNG-writing program wpng.c
4 4
5 This program converts certain NetPBM binary files (grayscale and RGB, 5 This program converts certain NetPBM binary files (grayscale and RGB,
6 maxval = 255) to PNG. Non-interlaced PNGs are written progressively; 6 maxval = 255) to PNG. Non-interlaced PNGs are written progressively;
7 interlaced PNGs are read and written in one memory-intensive blast. 7 interlaced PNGs are read and written in one memory-intensive blast.
8 8
9 Thanks to Jean-loup Gailly for providing the necessary trick to read 9 Thanks to Jean-loup Gailly for providing the necessary trick to read
10 interactive text from the keyboard while stdin is redirected. Thanks 10 interactive text from the keyboard while stdin is redirected. Thanks
11 to Cosmin Truta for Cygwin fixes. 11 to Cosmin Truta for Cygwin fixes.
12 12
13 NOTE: includes provisional support for PNM type "8" (portable alphamap) 13 NOTE: includes provisional support for PNM type "8" (portable alphamap)
14 images, presumed to be a 32-bit interleaved RGBA format; no pro- 14 images, presumed to be a 32-bit interleaved RGBA format; no pro-
15 vision for possible interleaved grayscale+alpha (16-bit) format. 15 vision for possible interleaved grayscale+alpha (16-bit) format.
16 THIS IS UNLIKELY TO BECOME AN OFFICIAL NETPBM ALPHA FORMAT! 16 THIS IS UNLIKELY TO BECOME AN OFFICIAL NETPBM ALPHA FORMAT!
17 17
18 to do: 18 to do:
19 - delete output file if quit before calling any writepng routines 19 - delete output file if quit before calling any writepng routines
20 - process backspace with -text option under DOS/Win? (currently get ^H) 20 - process backspace with -text option under DOS/Win? (currently get ^H)
21 21
22 --------------------------------------------------------------------------- 22 ---------------------------------------------------------------------------
23 23
24 Changelog: 24 Changelog:
25 - 1.01: initial public release 25 - 1.01: initial public release
26 - 1.02: modified to allow abbreviated options 26 - 1.02: modified to allow abbreviated options
27 - 1.03: removed extraneous character from usage screen; fixed bug in 27 - 1.03: removed extraneous character from usage screen; fixed bug in
28 command-line parsing 28 command-line parsing
29 - 1.04: fixed DOS/OS2/Win32 detection, including partial Cygwin fix 29 - 1.04: fixed DOS/OS2/Win32 detection, including partial Cygwin fix
30 (see http://home.att.net/~perlspinr/diffs/GregBook_cygwin.diff) 30 (see http://home.att.net/~perlspinr/diffs/GregBook_cygwin.diff)
31 - 2.00: dual-licensed (added GNU GPL) 31 - 2.00: dual-licensed (added GNU GPL)
32 32
33 [REPORTED BUG (win32 only): "contrib/gregbook/wpng.c - cmd line 33 [REPORTED BUG (win32 only): "contrib/gregbook/wpng.c - cmd line
34 dose not work! In order to do something useful I needed to redirect 34 dose not work! In order to do something useful I needed to redirect
35 both input and output, with cygwin and with bcc32 as well. Under 35 both input and output, with cygwin and with bcc32 as well. Under
36 Linux, the same wpng appears to work fine. I don't know what is 36 Linux, the same wpng appears to work fine. I don't know what is
37 the problem."] 37 the problem."]
38 38
39 --------------------------------------------------------------------------- 39 ---------------------------------------------------------------------------
40 40
41 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. 41 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved.
42 42
43 This software is provided "as is," without warranty of any kind, 43 This software is provided "as is," without warranty of any kind,
44 express or implied. In no event shall the author or contributors 44 express or implied. In no event shall the author or contributors
45 be held liable for any damages arising in any way from the use of 45 be held liable for any damages arising in any way from the use of
46 this software. 46 this software.
47 47
48 The contents of this file are DUAL-LICENSED. You may modify and/or 48 The contents of this file are DUAL-LICENSED. You may modify and/or
49 redistribute this software according to the terms of one of the 49 redistribute this software according to the terms of one of the
50 following two licenses (at your option): 50 following two licenses (at your option):
51 51
52 52
53 LICENSE 1 ("BSD-like with advertising clause"): 53 LICENSE 1 ("BSD-like with advertising clause"):
54 54
55 Permission is granted to anyone to use this software for any purpose, 55 Permission is granted to anyone to use this software for any purpose,
56 including commercial applications, and to alter it and redistribute 56 including commercial applications, and to alter it and redistribute
57 it freely, subject to the following restrictions: 57 it freely, subject to the following restrictions:
58 58
59 1. Redistributions of source code must retain the above copyright 59 1. Redistributions of source code must retain the above copyright
60 notice, disclaimer, and this list of conditions. 60 notice, disclaimer, and this list of conditions.
61 2. Redistributions in binary form must reproduce the above copyright 61 2. Redistributions in binary form must reproduce the above copyright
62 notice, disclaimer, and this list of conditions in the documenta- 62 notice, disclaimer, and this list of conditions in the documenta-
63 tion and/or other materials provided with the distribution. 63 tion and/or other materials provided with the distribution.
64 3. All advertising materials mentioning features or use of this 64 3. All advertising materials mentioning features or use of this
65 software must display the following acknowledgment: 65 software must display the following acknowledgment:
66 66
67 This product includes software developed by Greg Roelofs 67 This product includes software developed by Greg Roelofs
68 and contributors for the book, "PNG: The Definitive Guide," 68 and contributors for the book, "PNG: The Definitive Guide,"
69 published by O'Reilly and Associates. 69 published by O'Reilly and Associates.
70 70
71 71
72 LICENSE 2 (GNU GPL v2 or later): 72 LICENSE 2 (GNU GPL v2 or later):
73 73
74 This program is free software; you can redistribute it and/or modify 74 This program is free software; you can redistribute it and/or modify
75 it under the terms of the GNU General Public License as published by 75 it under the terms of the GNU General Public License as published by
76 the Free Software Foundation; either version 2 of the License, or 76 the Free Software Foundation; either version 2 of the License, or
77 (at your option) any later version. 77 (at your option) any later version.
78 78
79 This program is distributed in the hope that it will be useful, 79 This program is distributed in the hope that it will be useful,
80 but WITHOUT ANY WARRANTY; without even the implied warranty of 80 but WITHOUT ANY WARRANTY; without even the implied warranty of
81 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 81 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
82 GNU General Public License for more details. 82 GNU General Public License for more details.
83 83
84 You should have received a copy of the GNU General Public License 84 You should have received a copy of the GNU General Public License
85 along with this program; if not, write to the Free Software Foundation, 85 along with this program; if not, write to the Free Software Foundation,
86 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 86 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
87 87
88 ---------------------------------------------------------------------------*/ 88 ---------------------------------------------------------------------------*/
89 89
90#define PROGNAME "wpng" 90#define PROGNAME "wpng"
91#define VERSION "2.00 of 2 June 2007" 91#define VERSION "2.00 of 2 June 2007"
92#define APPNAME "Simple PGM/PPM/PAM to PNG Converter" 92#define APPNAME "Simple PGM/PPM/PAM to PNG Converter"
93 93
94#if defined(__MSDOS__) || defined(__OS2__) 94#if defined(__MSDOS__) || defined(__OS2__)
95# define DOS_OS2_W32 95# define DOS_OS2_W32
96#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) 96#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
97# ifndef __GNUC__ /* treat Win32 native ports of gcc as Unix environments */ 97# ifndef __GNUC__ /* treat Win32 native ports of gcc as Unix environments */
98# define DOS_OS2_W32 98# define DOS_OS2_W32
99# endif 99# endif
100#endif 100#endif
101 101
102#include <stdio.h> 102#include <stdio.h>
103#include <stdlib.h> 103#include <stdlib.h>
104#include <string.h> 104#include <string.h>
105#include <setjmp.h> /* for jmpbuf declaration in writepng.h */ 105#include <setjmp.h> /* for jmpbuf declaration in writepng.h */
106#include <time.h> 106#include <time.h>
107 107
108#ifdef DOS_OS2_W32 108#ifdef DOS_OS2_W32
109# include <io.h> /* for isatty(), setmode() prototypes */ 109# include <io.h> /* for isatty(), setmode() prototypes */
110# include <fcntl.h> /* O_BINARY for fdopen() without text translation */ 110# include <fcntl.h> /* O_BINARY for fdopen() without text translation */
111# ifdef __EMX__ 111# ifdef __EMX__
112# ifndef getch 112# ifndef getch
113# define getch() _read_kbd(0, 1, 0) /* need getche() */ 113# define getch() _read_kbd(0, 1, 0) /* need getche() */
114# endif 114# endif
115# else /* !__EMX__ */ 115# else /* !__EMX__ */
116# ifdef __GO32__ 116# ifdef __GO32__
117# include <pc.h> 117# include <pc.h>
118# define getch() getkey() /* GRR: need getche() */ 118# define getch() getkey() /* GRR: need getche() */
119# else 119# else
120# include <conio.h> /* for getche() console input */ 120# include <conio.h> /* for getche() console input */
121# endif 121# endif
122# endif /* ?__EMX__ */ 122# endif /* ?__EMX__ */
123# define FGETS(buf,len,stream) dos_kbd_gets(buf,len) 123# define FGETS(buf,len,stream) dos_kbd_gets(buf,len)
124#else 124#else
125# include <unistd.h> /* for isatty() prototype */ 125# include <unistd.h> /* for isatty() prototype */
126# define FGETS fgets 126# define FGETS fgets
127#endif 127#endif
128 128
129/* #define DEBUG : this enables the Trace() macros */ 129/* #define DEBUG : this enables the Trace() macros */
130 130
131/* #define FORBID_LATIN1_CTRL : this requires the user to re-enter any 131/* #define FORBID_LATIN1_CTRL : this requires the user to re-enter any
132 text that includes control characters discouraged by the PNG spec; text 132 text that includes control characters discouraged by the PNG spec; text
133 that includes an escape character (27) must be re-entered regardless */ 133 that includes an escape character (27) must be re-entered regardless */
134 134
135#include "writepng.h" /* typedefs, common macros, writepng prototypes */ 135#include "writepng.h" /* typedefs, common macros, writepng prototypes */
136 136
137 137
138 138
139/* local prototypes */ 139/* local prototypes */
140 140
141static int wpng_isvalid_latin1(uch *p, int len); 141static int wpng_isvalid_latin1(uch *p, int len);
142static void wpng_cleanup(void); 142static void wpng_cleanup(void);
143 143
144#ifdef DOS_OS2_W32 144#ifdef DOS_OS2_W32
145 static char *dos_kbd_gets(char *buf, int len); 145 static char *dos_kbd_gets(char *buf, int len);
146#endif 146#endif
147 147
148 148
149 149
150static mainprog_info wpng_info; /* lone global */ 150static mainprog_info wpng_info; /* lone global */
151 151
152 152
153 153
154int main(int argc, char **argv) 154int main(int argc, char **argv)
155{ 155{
156#ifndef DOS_OS2_W32 156#ifndef DOS_OS2_W32
157 FILE *keybd; 157 FILE *keybd;
158#endif 158#endif
159#ifdef sgi 159#ifdef sgi
160 FILE *tmpfile; /* or we could just use keybd, since no overlap */ 160 FILE *tmpfile; /* or we could just use keybd, since no overlap */
161 char tmpline[80]; 161 char tmpline[80];
162#endif 162#endif
163 char *inname = NULL, outname[256]; 163 char *inname = NULL, outname[256];
164 char *p, pnmchar, pnmline[256]; 164 char *p, pnmchar, pnmline[256];
165 char *bgstr, *textbuf = NULL; 165 char *bgstr, *textbuf = NULL;
166 ulg rowbytes; 166 ulg rowbytes;
167 int rc, len = 0; 167 int rc, len = 0;
168 int error = 0; 168 int error = 0;
169 int text = FALSE; 169 int text = FALSE;
170 int maxval; 170 int maxval;
171 double LUT_exponent; /* just the lookup table */ 171 double LUT_exponent; /* just the lookup table */
172 double CRT_exponent = 2.2; /* just the monitor */ 172 double CRT_exponent = 2.2; /* just the monitor */
173 double default_display_exponent; /* whole display system */ 173 double default_display_exponent; /* whole display system */
174 double default_gamma = 0.0; 174 double default_gamma = 0.0;
175 175
176 176
177 wpng_info.infile = NULL; 177 wpng_info.infile = NULL;
178 wpng_info.outfile = NULL; 178 wpng_info.outfile = NULL;
179 wpng_info.image_data = NULL; 179 wpng_info.image_data = NULL;
180 wpng_info.row_pointers = NULL; 180 wpng_info.row_pointers = NULL;
181 wpng_info.filter = FALSE; 181 wpng_info.filter = FALSE;
182 wpng_info.interlaced = FALSE; 182 wpng_info.interlaced = FALSE;
183 wpng_info.have_bg = FALSE; 183 wpng_info.have_bg = FALSE;
184 wpng_info.have_time = FALSE; 184 wpng_info.have_time = FALSE;
185 wpng_info.have_text = 0; 185 wpng_info.have_text = 0;
186 wpng_info.gamma = 0.0; 186 wpng_info.gamma = 0.0;
187 187
188 188
189 /* First get the default value for our display-system exponent, i.e., 189 /* First get the default value for our display-system exponent, i.e.,
190 * the product of the CRT exponent and the exponent corresponding to 190 * the product of the CRT exponent and the exponent corresponding to
191 * the frame-buffer's lookup table (LUT), if any. If the PNM image 191 * the frame-buffer's lookup table (LUT), if any. If the PNM image
192 * looks correct on the user's display system, its file gamma is the 192 * looks correct on the user's display system, its file gamma is the
193 * inverse of this value. (Note that this is not an exhaustive list 193 * inverse of this value. (Note that this is not an exhaustive list
194 * of LUT values--e.g., OpenStep has a lot of weird ones--but it should 194 * of LUT values--e.g., OpenStep has a lot of weird ones--but it should
195 * cover 99% of the current possibilities. This section must ensure 195 * cover 99% of the current possibilities. This section must ensure
196 * that default_display_exponent is positive.) */ 196 * that default_display_exponent is positive.) */
197 197
198#if defined(NeXT) 198#if defined(NeXT)
199 /* third-party utilities can modify the default LUT exponent */ 199 /* third-party utilities can modify the default LUT exponent */
200 LUT_exponent = 1.0 / 2.2; 200 LUT_exponent = 1.0 / 2.2;
201 /* 201 /*
202 if (some_next_function_that_returns_gamma(&next_gamma)) 202 if (some_next_function_that_returns_gamma(&next_gamma))
203 LUT_exponent = 1.0 / next_gamma; 203 LUT_exponent = 1.0 / next_gamma;
204 */ 204 */
205#elif defined(sgi) 205#elif defined(sgi)
206 LUT_exponent = 1.0 / 1.7; 206 LUT_exponent = 1.0 / 1.7;
207 /* there doesn't seem to be any documented function to 207 /* there doesn't seem to be any documented function to
208 * get the "gamma" value, so we do it the hard way */ 208 * get the "gamma" value, so we do it the hard way */
209 tmpfile = fopen("/etc/config/system.glGammaVal", "r"); 209 tmpfile = fopen("/etc/config/system.glGammaVal", "r");
210 if (tmpfile) { 210 if (tmpfile) {
211 double sgi_gamma; 211 double sgi_gamma;
212 212
213 fgets(tmpline, 80, tmpfile); 213 fgets(tmpline, 80, tmpfile);
214 fclose(tmpfile); 214 fclose(tmpfile);
215 sgi_gamma = atof(tmpline); 215 sgi_gamma = atof(tmpline);
216 if (sgi_gamma > 0.0) 216 if (sgi_gamma > 0.0)
217 LUT_exponent = 1.0 / sgi_gamma; 217 LUT_exponent = 1.0 / sgi_gamma;
218 } 218 }
219#elif defined(Macintosh) 219#elif defined(Macintosh)
220 LUT_exponent = 1.8 / 2.61; 220 LUT_exponent = 1.8 / 2.61;
221 /* 221 /*
222 if (some_mac_function_that_returns_gamma(&mac_gamma)) 222 if (some_mac_function_that_returns_gamma(&mac_gamma))
223 LUT_exponent = mac_gamma / 2.61; 223 LUT_exponent = mac_gamma / 2.61;
224 */ 224 */
225#else 225#else
226 LUT_exponent = 1.0; /* assume no LUT: most PCs */ 226 LUT_exponent = 1.0; /* assume no LUT: most PCs */
227#endif 227#endif
228 228
229 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ 229 /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
230 default_display_exponent = LUT_exponent * CRT_exponent; 230 default_display_exponent = LUT_exponent * CRT_exponent;
231 231
232 232
233 /* If the user has set the SCREEN_GAMMA environment variable as suggested 233 /* If the user has set the SCREEN_GAMMA environment variable as suggested
234 * (somewhat imprecisely) in the libpng documentation, use that; otherwise 234 * (somewhat imprecisely) in the libpng documentation, use that; otherwise
235 * use the default value we just calculated. Either way, the user may 235 * use the default value we just calculated. Either way, the user may
236 * override this via a command-line option. */ 236 * override this via a command-line option. */
237 237
238 if ((p = getenv("SCREEN_GAMMA")) != NULL) { 238 if ((p = getenv("SCREEN_GAMMA")) != NULL) {
239 double exponent = atof(p); 239 double exponent = atof(p);
240 240
241 if (exponent > 0.0) 241 if (exponent > 0.0)
242 default_gamma = 1.0 / exponent; 242 default_gamma = 1.0 / exponent;
243 } 243 }
244 244
245 if (default_gamma == 0.0) 245 if (default_gamma == 0.0)
246 default_gamma = 1.0 / default_display_exponent; 246 default_gamma = 1.0 / default_display_exponent;
247 247
248 248
249 /* Now parse the command line for options and the PNM filename. */ 249 /* Now parse the command line for options and the PNM filename. */
250 250
251 while (*++argv && !error) { 251 while (*++argv && !error) {
252 if (!strncmp(*argv, "-i", 2)) { 252 if (!strncmp(*argv, "-i", 2)) {
253 wpng_info.interlaced = TRUE; 253 wpng_info.interlaced = TRUE;
254 } else if (!strncmp(*argv, "-time", 3)) { 254 } else if (!strncmp(*argv, "-time", 3)) {
255 wpng_info.modtime = time(NULL); 255 wpng_info.modtime = time(NULL);
256 wpng_info.have_time = TRUE; 256 wpng_info.have_time = TRUE;
257 } else if (!strncmp(*argv, "-text", 3)) { 257 } else if (!strncmp(*argv, "-text", 3)) {
258 text = TRUE; 258 text = TRUE;
259 } else if (!strncmp(*argv, "-gamma", 2)) { 259 } else if (!strncmp(*argv, "-gamma", 2)) {
260 if (!*++argv) 260 if (!*++argv)
261 ++error; 261 ++error;
262 else { 262 else {
263 wpng_info.gamma = atof(*argv); 263 wpng_info.gamma = atof(*argv);
264 if (wpng_info.gamma <= 0.0) 264 if (wpng_info.gamma <= 0.0)
265 ++error; 265 ++error;
266 else if (wpng_info.gamma > 1.01) 266 else if (wpng_info.gamma > 1.01)
267 fprintf(stderr, PROGNAME 267 fprintf(stderr, PROGNAME
268 " warning: file gammas are usually less than 1.0\n"); 268 " warning: file gammas are usually less than 1.0\n");
269 } 269 }
270 } else if (!strncmp(*argv, "-bgcolor", 4)) { 270 } else if (!strncmp(*argv, "-bgcolor", 4)) {
271 if (!*++argv) 271 if (!*++argv)
272 ++error; 272 ++error;
273 else { 273 else {
274 bgstr = *argv; 274 bgstr = *argv;
275 if (strlen(bgstr) != 7 || bgstr[0] != '#') 275 if (strlen(bgstr) != 7 || bgstr[0] != '#')
276 ++error; 276 ++error;
277 else { 277 else {
278 unsigned r, g, b; /* this way quiets compiler warnings */ 278 unsigned r, g, b; /* this way quiets compiler warnings */
279 279
280 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); 280 sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
281 wpng_info.bg_red = (uch)r; 281 wpng_info.bg_red = (uch)r;
282 wpng_info.bg_green = (uch)g; 282 wpng_info.bg_green = (uch)g;
283 wpng_info.bg_blue = (uch)b; 283 wpng_info.bg_blue = (uch)b;
284 wpng_info.have_bg = TRUE; 284 wpng_info.have_bg = TRUE;
285 } 285 }
286 } 286 }
287 } else { 287 } else {
288 if (**argv != '-') { 288 if (**argv != '-') {
289 inname = *argv; 289 inname = *argv;
290 if (argv[1]) /* shouldn't be any more args after filename */ 290 if (argv[1]) /* shouldn't be any more args after filename */
291 ++error; 291 ++error;
292 } else 292 } else
293 ++error; /* not expecting any other options */ 293 ++error; /* not expecting any other options */
294 } 294 }
295 } 295 }
296 296
297 297
298 /* open the input and output files, or register an error and abort */ 298 /* open the input and output files, or register an error and abort */
299 299
300 if (!inname) { 300 if (!inname) {
301 if (isatty(0)) { 301 if (isatty(0)) {
302 fprintf(stderr, PROGNAME 302 fprintf(stderr, PROGNAME
303 ": must give input filename or provide image data via stdin\n"); 303 ": must give input filename or provide image data via stdin\n");
304 ++error; 304 ++error;
305 } else { 305 } else {
306#ifdef DOS_OS2_W32 306#ifdef DOS_OS2_W32
307 /* some buggy C libraries require BOTH setmode() and fdopen(bin) */ 307 /* some buggy C libraries require BOTH setmode() and fdopen(bin) */
308 setmode(fileno(stdin), O_BINARY); 308 setmode(fileno(stdin), O_BINARY);
309 setmode(fileno(stdout), O_BINARY); 309 setmode(fileno(stdout), O_BINARY);
310#endif 310#endif
311 if ((wpng_info.infile = fdopen(fileno(stdin), "rb")) == NULL) { 311 if ((wpng_info.infile = fdopen(fileno(stdin), "rb")) == NULL) {
312 fprintf(stderr, PROGNAME 312 fprintf(stderr, PROGNAME
313 ": unable to reopen stdin in binary mode\n"); 313 ": unable to reopen stdin in binary mode\n");
314 ++error; 314 ++error;
315 } else 315 } else
316 if ((wpng_info.outfile = fdopen(fileno(stdout), "wb")) == NULL) { 316 if ((wpng_info.outfile = fdopen(fileno(stdout), "wb")) == NULL) {
317 fprintf(stderr, PROGNAME 317 fprintf(stderr, PROGNAME
318 ": unable to reopen stdout in binary mode\n"); 318 ": unable to reopen stdout in binary mode\n");
319 fclose(wpng_info.infile); 319 fclose(wpng_info.infile);
320 ++error; 320 ++error;
321 } else 321 } else
322 wpng_info.filter = TRUE; 322 wpng_info.filter = TRUE;
323 } 323 }
324 } else if ((len = strlen(inname)) > 250) { 324 } else if ((len = strlen(inname)) > 250) {
325 fprintf(stderr, PROGNAME ": input filename is too long [%d chars]\n", 325 fprintf(stderr, PROGNAME ": input filename is too long [%d chars]\n",
326 len); 326 len);
327 ++error; 327 ++error;
328 } else if (!(wpng_info.infile = fopen(inname, "rb"))) { 328 } else if (!(wpng_info.infile = fopen(inname, "rb"))) {
329 fprintf(stderr, PROGNAME ": can't open input file [%s]\n", inname); 329 fprintf(stderr, PROGNAME ": can't open input file [%s]\n", inname);
330 ++error; 330 ++error;
331 } 331 }
332 332
333 if (!error) { 333 if (!error) {
334 fgets(pnmline, 256, wpng_info.infile); 334 fgets(pnmline, 256, wpng_info.infile);
335 if (pnmline[0] != 'P' || ((pnmchar = pnmline[1]) != '5' && 335 if (pnmline[0] != 'P' || ((pnmchar = pnmline[1]) != '5' &&
336 pnmchar != '6' && pnmchar != '8')) 336 pnmchar != '6' && pnmchar != '8'))
337 { 337 {
338 fprintf(stderr, PROGNAME 338 fprintf(stderr, PROGNAME
339 ": input file [%s] is not a binary PGM, PPM or PAM file\n", 339 ": input file [%s] is not a binary PGM, PPM or PAM file\n",
340 inname); 340 inname);
341 ++error; 341 ++error;
342 } else { 342 } else {
343 wpng_info.pnmtype = (int)(pnmchar - '0'); 343 wpng_info.pnmtype = (int)(pnmchar - '0');
344 if (wpng_info.pnmtype != 8) 344 if (wpng_info.pnmtype != 8)
345 wpng_info.have_bg = FALSE; /* no need for bg if opaque */ 345 wpng_info.have_bg = FALSE; /* no need for bg if opaque */
346 do { 346 do {
347 fgets(pnmline, 256, wpng_info.infile); /* lose any comments */ 347 fgets(pnmline, 256, wpng_info.infile); /* lose any comments */
348 } while (pnmline[0] == '#'); 348 } while (pnmline[0] == '#');
349 sscanf(pnmline, "%ld %ld", &wpng_info.width, &wpng_info.height); 349 sscanf(pnmline, "%ld %ld", &wpng_info.width, &wpng_info.height);
350 do { 350 do {
351 fgets(pnmline, 256, wpng_info.infile); /* more comment lines */ 351 fgets(pnmline, 256, wpng_info.infile); /* more comment lines */
352 } while (pnmline[0] == '#'); 352 } while (pnmline[0] == '#');
353 sscanf(pnmline, "%d", &maxval); 353 sscanf(pnmline, "%d", &maxval);
354 if (wpng_info.width <= 0L || wpng_info.height <= 0L || 354 if (wpng_info.width <= 0L || wpng_info.height <= 0L ||
355 maxval != 255) 355 maxval != 255)
356 { 356 {
357 fprintf(stderr, PROGNAME 357 fprintf(stderr, PROGNAME
358 ": only positive width/height, maxval == 255 allowed \n"); 358 ": only positive width/height, maxval == 255 allowed \n");
359 ++error; 359 ++error;
360 } 360 }
361 wpng_info.sample_depth = 8; /* <==> maxval 255 */ 361 wpng_info.sample_depth = 8; /* <==> maxval 255 */
362 362
363 if (!wpng_info.filter) { 363 if (!wpng_info.filter) {
364 /* make outname from inname */ 364 /* make outname from inname */
365 if ((p = strrchr(inname, '.')) == NULL || 365 if ((p = strrchr(inname, '.')) == NULL ||
366 (p - inname) != (len - 4)) 366 (p - inname) != (len - 4))
367 { 367 {
368 strcpy(outname, inname); 368 strcpy(outname, inname);
369 strcpy(outname+len, ".png"); 369 strcpy(outname+len, ".png");
370 } else { 370 } else {
371 len -= 4; 371 len -= 4;
372 strncpy(outname, inname, len); 372 strncpy(outname, inname, len);
373 strcpy(outname+len, ".png"); 373 strcpy(outname+len, ".png");
374 } 374 }
375 /* check if outname already exists; if not, open */ 375 /* check if outname already exists; if not, open */
376 if ((wpng_info.outfile = fopen(outname, "rb")) != NULL) { 376 if ((wpng_info.outfile = fopen(outname, "rb")) != NULL) {
377 fprintf(stderr, PROGNAME ": output file exists [%s]\n", 377 fprintf(stderr, PROGNAME ": output file exists [%s]\n",
378 outname); 378 outname);
379 fclose(wpng_info.outfile); 379 fclose(wpng_info.outfile);
380 ++error; 380 ++error;
381 } else if (!(wpng_info.outfile = fopen(outname, "wb"))) { 381 } else if (!(wpng_info.outfile = fopen(outname, "wb"))) {
382 fprintf(stderr, PROGNAME ": can't open output file [%s]\n", 382 fprintf(stderr, PROGNAME ": can't open output file [%s]\n",
383 outname); 383 outname);
384 ++error; 384 ++error;
385 } 385 }
386 } 386 }
387 } 387 }
388 if (error) { 388 if (error) {
389 fclose(wpng_info.infile); 389 fclose(wpng_info.infile);
390 wpng_info.infile = NULL; 390 wpng_info.infile = NULL;
391 if (wpng_info.filter) { 391 if (wpng_info.filter) {
392 fclose(wpng_info.outfile); 392 fclose(wpng_info.outfile);
393 wpng_info.outfile = NULL; 393 wpng_info.outfile = NULL;
394 } 394 }
395 } 395 }
396 } 396 }
397 397
398 398
399 /* if we had any errors, print usage and die horrible death...arrr! */ 399 /* if we had any errors, print usage and die horrible death...arrr! */
400 400
401 if (error) { 401 if (error) {
402 fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, APPNAME); 402 fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, APPNAME);
403 writepng_version_info(); 403 writepng_version_info();
404 fprintf(stderr, "\n" 404 fprintf(stderr, "\n"
405"Usage: %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] pnmfile\n" 405"Usage: %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] pnmfile\n"
406"or: ... | %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] | ...\n" 406"or: ... | %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] | ...\n"
407 " exp \ttransfer-function exponent (``gamma'') of the image in\n" 407 " exp \ttransfer-function exponent (``gamma'') of the image in\n"
408 "\t\t floating-point format (e.g., ``%.5f''); if image looks\n" 408 "\t\t floating-point format (e.g., ``%.5f''); if image looks\n"
409 "\t\t correct on given display system, image gamma is equal to\n" 409 "\t\t correct on given display system, image gamma is equal to\n"
410 "\t\t inverse of display-system exponent, i.e., 1 / (LUT * CRT)\n" 410 "\t\t inverse of display-system exponent, i.e., 1 / (LUT * CRT)\n"
411 "\t\t (where LUT = lookup-table exponent and CRT = CRT exponent;\n" 411 "\t\t (where LUT = lookup-table exponent and CRT = CRT exponent;\n"
412 "\t\t first varies, second is usually 2.2, all are positive)\n" 412 "\t\t first varies, second is usually 2.2, all are positive)\n"
413 " bg \tdesired background color for alpha-channel images, in\n" 413 " bg \tdesired background color for alpha-channel images, in\n"
414 "\t\t 7-character hex RGB format (e.g., ``#ff7700'' for orange:\n" 414 "\t\t 7-character hex RGB format (e.g., ``#ff7700'' for orange:\n"
415 "\t\t same as HTML colors)\n" 415 "\t\t same as HTML colors)\n"
416 " -text\tprompt interactively for text info (tEXt chunks)\n" 416 " -text\tprompt interactively for text info (tEXt chunks)\n"
417 " -time\tinclude a tIME chunk (last modification time)\n" 417 " -time\tinclude a tIME chunk (last modification time)\n"
418 " -interlace\twrite interlaced PNG image\n" 418 " -interlace\twrite interlaced PNG image\n"
419 "\n" 419 "\n"
420"pnmfile or stdin must be a binary PGM (`P5'), PPM (`P6') or (extremely\n" 420"pnmfile or stdin must be a binary PGM (`P5'), PPM (`P6') or (extremely\n"
421"unofficial and unsupported!) PAM (`P8') file. Currently it is required\n" 421"unofficial and unsupported!) PAM (`P8') file. Currently it is required\n"
422"to have maxval == 255 (i.e., no scaling). If pnmfile is specified, it\n" 422"to have maxval == 255 (i.e., no scaling). If pnmfile is specified, it\n"
423"is converted to the corresponding PNG file with the same base name but a\n" 423"is converted to the corresponding PNG file with the same base name but a\n"
424"``.png'' extension; files read from stdin are converted and sent to stdout.\n" 424"``.png'' extension; files read from stdin are converted and sent to stdout.\n"
425"The conversion is progressive (low memory usage) unless interlacing is\n" 425"The conversion is progressive (low memory usage) unless interlacing is\n"
426"requested; in that case the whole image will be buffered in memory and\n" 426"requested; in that case the whole image will be buffered in memory and\n"
427"written in one call.\n" 427"written in one call.\n"
428 "\n", PROGNAME, PROGNAME, default_gamma); 428 "\n", PROGNAME, PROGNAME, default_gamma);
429 exit(1); 429 exit(1);
430 } 430 }
431 431
432 432
433 /* prepare the text buffers for libpng's use; note that even though 433 /* prepare the text buffers for libpng's use; note that even though
434 * PNG's png_text struct includes a length field, we don't have to fill 434 * PNG's png_text struct includes a length field, we don't have to fill
435 * it out */ 435 * it out */
436 436
437 if (text && 437 if (text &&
438#ifndef DOS_OS2_W32 438#ifndef DOS_OS2_W32
439 (keybd = fdopen(fileno(stderr), "r")) != NULL && 439 (keybd = fdopen(fileno(stderr), "r")) != NULL &&
440#endif 440#endif
441 (textbuf = (char *)malloc((5 + 9)*75)) != NULL) 441 (textbuf = (char *)malloc((5 + 9)*75)) != NULL)
442 { 442 {
443 int i, valid, result; 443 int i, valid, result;
444 444
445 fprintf(stderr, 445 fprintf(stderr,
446 "Enter text info (no more than 72 characters per line);\n"); 446 "Enter text info (no more than 72 characters per line);\n");
447 fprintf(stderr, "to skip a field, hit the <Enter> key.\n"); 447 fprintf(stderr, "to skip a field, hit the <Enter> key.\n");
448 /* note: just <Enter> leaves len == 1 */ 448 /* note: just <Enter> leaves len == 1 */
449 449
450 do { 450 do {
451 valid = TRUE; 451 valid = TRUE;
452 p = textbuf + TEXT_TITLE_OFFSET; 452 p = textbuf + TEXT_TITLE_OFFSET;
453 fprintf(stderr, " Title: "); 453 fprintf(stderr, " Title: ");
454 fflush(stderr); 454 fflush(stderr);
455 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { 455 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
456 if (p[len-1] == '\n') 456 if (p[len-1] == '\n')
457 p[--len] = '\0'; 457 p[--len] = '\0';
458 wpng_info.title = p; 458 wpng_info.title = p;
459 wpng_info.have_text |= TEXT_TITLE; 459 wpng_info.have_text |= TEXT_TITLE;
460 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { 460 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
461 fprintf(stderr, " " PROGNAME " warning: character code" 461 fprintf(stderr, " " PROGNAME " warning: character code"
462 " %u is %sdiscouraged by the PNG\n specification " 462 " %u is %sdiscouraged by the PNG\n specification "
463 "[first occurrence was at character position #%d]\n", 463 "[first occurrence was at character position #%d]\n",
464 (unsigned)p[result], (p[result] == 27)? "strongly " : "", 464 (unsigned)p[result], (p[result] == 27)? "strongly " : "",
465 result+1); 465 result+1);
466 fflush(stderr); 466 fflush(stderr);
467#ifdef FORBID_LATIN1_CTRL 467#ifdef FORBID_LATIN1_CTRL
468 wpng_info.have_text &= ~TEXT_TITLE; 468 wpng_info.have_text &= ~TEXT_TITLE;
469 valid = FALSE; 469 valid = FALSE;
470#else 470#else
471 if (p[result] == 27) { /* escape character */ 471 if (p[result] == 27) { /* escape character */
472 wpng_info.have_text &= ~TEXT_TITLE; 472 wpng_info.have_text &= ~TEXT_TITLE;
473 valid = FALSE; 473 valid = FALSE;
474 } 474 }
475#endif 475#endif
476 } 476 }
477 } 477 }
478 } while (!valid); 478 } while (!valid);
479 479
480 do { 480 do {
481 valid = TRUE; 481 valid = TRUE;
482 p = textbuf + TEXT_AUTHOR_OFFSET; 482 p = textbuf + TEXT_AUTHOR_OFFSET;
483 fprintf(stderr, " Author: "); 483 fprintf(stderr, " Author: ");
484 fflush(stderr); 484 fflush(stderr);
485 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { 485 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
486 if (p[len-1] == '\n') 486 if (p[len-1] == '\n')
487 p[--len] = '\0'; 487 p[--len] = '\0';
488 wpng_info.author = p; 488 wpng_info.author = p;
489 wpng_info.have_text |= TEXT_AUTHOR; 489 wpng_info.have_text |= TEXT_AUTHOR;
490 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { 490 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
491 fprintf(stderr, " " PROGNAME " warning: character code" 491 fprintf(stderr, " " PROGNAME " warning: character code"
492 " %u is %sdiscouraged by the PNG\n specification " 492 " %u is %sdiscouraged by the PNG\n specification "
493 "[first occurrence was at character position #%d]\n", 493 "[first occurrence was at character position #%d]\n",
494 (unsigned)p[result], (p[result] == 27)? "strongly " : "", 494 (unsigned)p[result], (p[result] == 27)? "strongly " : "",
495 result+1); 495 result+1);
496 fflush(stderr); 496 fflush(stderr);
497#ifdef FORBID_LATIN1_CTRL 497#ifdef FORBID_LATIN1_CTRL
498 wpng_info.have_text &= ~TEXT_AUTHOR; 498 wpng_info.have_text &= ~TEXT_AUTHOR;
499 valid = FALSE; 499 valid = FALSE;
500#else 500#else
501 if (p[result] == 27) { /* escape character */ 501 if (p[result] == 27) { /* escape character */
502 wpng_info.have_text &= ~TEXT_AUTHOR; 502 wpng_info.have_text &= ~TEXT_AUTHOR;
503 valid = FALSE; 503 valid = FALSE;
504 } 504 }
505#endif 505#endif
506 } 506 }
507 } 507 }
508 } while (!valid); 508 } while (!valid);
509 509
510 do { 510 do {
511 valid = TRUE; 511 valid = TRUE;
512 p = textbuf + TEXT_DESC_OFFSET; 512 p = textbuf + TEXT_DESC_OFFSET;
513 fprintf(stderr, " Description (up to 9 lines):\n"); 513 fprintf(stderr, " Description (up to 9 lines):\n");
514 for (i = 1; i < 10; ++i) { 514 for (i = 1; i < 10; ++i) {
515 fprintf(stderr, " [%d] ", i); 515 fprintf(stderr, " [%d] ", i);
516 fflush(stderr); 516 fflush(stderr);
517 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) 517 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1)
518 p += len; /* now points at NULL; char before is newline */ 518 p += len; /* now points at NULL; char before is newline */
519 else 519 else
520 break; 520 break;
521 } 521 }
522 if ((len = p - (textbuf + TEXT_DESC_OFFSET)) > 1) { 522 if ((len = p - (textbuf + TEXT_DESC_OFFSET)) > 1) {
523 if (p[-1] == '\n') { 523 if (p[-1] == '\n') {
524 p[-1] = '\0'; 524 p[-1] = '\0';
525 --len; 525 --len;
526 } 526 }
527 wpng_info.desc = textbuf + TEXT_DESC_OFFSET; 527 wpng_info.desc = textbuf + TEXT_DESC_OFFSET;
528 wpng_info.have_text |= TEXT_DESC; 528 wpng_info.have_text |= TEXT_DESC;
529 p = textbuf + TEXT_DESC_OFFSET; 529 p = textbuf + TEXT_DESC_OFFSET;
530 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { 530 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
531 fprintf(stderr, " " PROGNAME " warning: character code" 531 fprintf(stderr, " " PROGNAME " warning: character code"
532 " %u is %sdiscouraged by the PNG\n specification " 532 " %u is %sdiscouraged by the PNG\n specification "
533 "[first occurrence was at character position #%d]\n", 533 "[first occurrence was at character position #%d]\n",
534 (unsigned)p[result], (p[result] == 27)? "strongly " : "", 534 (unsigned)p[result], (p[result] == 27)? "strongly " : "",
535 result+1); 535 result+1);
536 fflush(stderr); 536 fflush(stderr);
537#ifdef FORBID_LATIN1_CTRL 537#ifdef FORBID_LATIN1_CTRL
538 wpng_info.have_text &= ~TEXT_DESC; 538 wpng_info.have_text &= ~TEXT_DESC;
539 valid = FALSE; 539 valid = FALSE;
540#else 540#else
541 if (p[result] == 27) { /* escape character */ 541 if (p[result] == 27) { /* escape character */
542 wpng_info.have_text &= ~TEXT_DESC; 542 wpng_info.have_text &= ~TEXT_DESC;
543 valid = FALSE; 543 valid = FALSE;
544 } 544 }
545#endif 545#endif
546 } 546 }
547 } 547 }
548 } while (!valid); 548 } while (!valid);
549 549
550 do { 550 do {
551 valid = TRUE; 551 valid = TRUE;
552 p = textbuf + TEXT_COPY_OFFSET; 552 p = textbuf + TEXT_COPY_OFFSET;
553 fprintf(stderr, " Copyright: "); 553 fprintf(stderr, " Copyright: ");
554 fflush(stderr); 554 fflush(stderr);
555 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { 555 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
556 if (p[len-1] == '\n') 556 if (p[len-1] == '\n')
557 p[--len] = '\0'; 557 p[--len] = '\0';
558 wpng_info.copyright = p; 558 wpng_info.copyright = p;
559 wpng_info.have_text |= TEXT_COPY; 559 wpng_info.have_text |= TEXT_COPY;
560 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { 560 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
561 fprintf(stderr, " " PROGNAME " warning: character code" 561 fprintf(stderr, " " PROGNAME " warning: character code"
562 " %u is %sdiscouraged by the PNG\n specification " 562 " %u is %sdiscouraged by the PNG\n specification "
563 "[first occurrence was at character position #%d]\n", 563 "[first occurrence was at character position #%d]\n",
564 (unsigned)p[result], (p[result] == 27)? "strongly " : "", 564 (unsigned)p[result], (p[result] == 27)? "strongly " : "",
565 result+1); 565 result+1);
566 fflush(stderr); 566 fflush(stderr);
567#ifdef FORBID_LATIN1_CTRL 567#ifdef FORBID_LATIN1_CTRL
568 wpng_info.have_text &= ~TEXT_COPY; 568 wpng_info.have_text &= ~TEXT_COPY;
569 valid = FALSE; 569 valid = FALSE;
570#else 570#else
571 if (p[result] == 27) { /* escape character */ 571 if (p[result] == 27) { /* escape character */
572 wpng_info.have_text &= ~TEXT_COPY; 572 wpng_info.have_text &= ~TEXT_COPY;
573 valid = FALSE; 573 valid = FALSE;
574 } 574 }
575#endif 575#endif
576 } 576 }
577 } 577 }
578 } while (!valid); 578 } while (!valid);
579 579
580 do { 580 do {
581 valid = TRUE; 581 valid = TRUE;
582 p = textbuf + TEXT_EMAIL_OFFSET; 582 p = textbuf + TEXT_EMAIL_OFFSET;
583 fprintf(stderr, " E-mail: "); 583 fprintf(stderr, " E-mail: ");
584 fflush(stderr); 584 fflush(stderr);
585 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { 585 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
586 if (p[len-1] == '\n') 586 if (p[len-1] == '\n')
587 p[--len] = '\0'; 587 p[--len] = '\0';
588 wpng_info.email = p; 588 wpng_info.email = p;
589 wpng_info.have_text |= TEXT_EMAIL; 589 wpng_info.have_text |= TEXT_EMAIL;
590 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { 590 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
591 fprintf(stderr, " " PROGNAME " warning: character code" 591 fprintf(stderr, " " PROGNAME " warning: character code"
592 " %u is %sdiscouraged by the PNG\n specification " 592 " %u is %sdiscouraged by the PNG\n specification "
593 "[first occurrence was at character position #%d]\n", 593 "[first occurrence was at character position #%d]\n",
594 (unsigned)p[result], (p[result] == 27)? "strongly " : "", 594 (unsigned)p[result], (p[result] == 27)? "strongly " : "",
595 result+1); 595 result+1);
596 fflush(stderr); 596 fflush(stderr);
597#ifdef FORBID_LATIN1_CTRL 597#ifdef FORBID_LATIN1_CTRL
598 wpng_info.have_text &= ~TEXT_EMAIL; 598 wpng_info.have_text &= ~TEXT_EMAIL;
599 valid = FALSE; 599 valid = FALSE;
600#else 600#else
601 if (p[result] == 27) { /* escape character */ 601 if (p[result] == 27) { /* escape character */
602 wpng_info.have_text &= ~TEXT_EMAIL; 602 wpng_info.have_text &= ~TEXT_EMAIL;
603 valid = FALSE; 603 valid = FALSE;
604 } 604 }
605#endif 605#endif
606 } 606 }
607 } 607 }
608 } while (!valid); 608 } while (!valid);
609 609
610 do { 610 do {
611 valid = TRUE; 611 valid = TRUE;
612 p = textbuf + TEXT_URL_OFFSET; 612 p = textbuf + TEXT_URL_OFFSET;
613 fprintf(stderr, " URL: "); 613 fprintf(stderr, " URL: ");
614 fflush(stderr); 614 fflush(stderr);
615 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { 615 if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
616 if (p[len-1] == '\n') 616 if (p[len-1] == '\n')
617 p[--len] = '\0'; 617 p[--len] = '\0';
618 wpng_info.url = p; 618 wpng_info.url = p;
619 wpng_info.have_text |= TEXT_URL; 619 wpng_info.have_text |= TEXT_URL;
620 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { 620 if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
621 fprintf(stderr, " " PROGNAME " warning: character code" 621 fprintf(stderr, " " PROGNAME " warning: character code"
622 " %u is %sdiscouraged by the PNG\n specification " 622 " %u is %sdiscouraged by the PNG\n specification "
623 "[first occurrence was at character position #%d]\n", 623 "[first occurrence was at character position #%d]\n",
624 (unsigned)p[result], (p[result] == 27)? "strongly " : "", 624 (unsigned)p[result], (p[result] == 27)? "strongly " : "",
625 result+1); 625 result+1);
626 fflush(stderr); 626 fflush(stderr);
627#ifdef FORBID_LATIN1_CTRL 627#ifdef FORBID_LATIN1_CTRL
628 wpng_info.have_text &= ~TEXT_URL; 628 wpng_info.have_text &= ~TEXT_URL;
629 valid = FALSE; 629 valid = FALSE;
630#else 630#else
631 if (p[result] == 27) { /* escape character */ 631 if (p[result] == 27) { /* escape character */
632 wpng_info.have_text &= ~TEXT_URL; 632 wpng_info.have_text &= ~TEXT_URL;
633 valid = FALSE; 633 valid = FALSE;
634 } 634 }
635#endif 635#endif
636 } 636 }
637 } 637 }
638 } while (!valid); 638 } while (!valid);
639 639
640#ifndef DOS_OS2_W32 640#ifndef DOS_OS2_W32
641 fclose(keybd); 641 fclose(keybd);
642#endif 642#endif
643 643
644 } else if (text) { 644 } else if (text) {
645 fprintf(stderr, PROGNAME ": unable to allocate memory for text\n"); 645 fprintf(stderr, PROGNAME ": unable to allocate memory for text\n");
646 text = FALSE; 646 text = FALSE;
647 wpng_info.have_text = 0; 647 wpng_info.have_text = 0;
648 } 648 }
649 649
650 650
651 /* allocate libpng stuff, initialize transformations, write pre-IDAT data */ 651 /* allocate libpng stuff, initialize transformations, write pre-IDAT data */
652 652
653 if ((rc = writepng_init(&wpng_info)) != 0) { 653 if ((rc = writepng_init(&wpng_info)) != 0) {
654 switch (rc) { 654 switch (rc) {
655 case 2: 655 case 2:
656 fprintf(stderr, PROGNAME 656 fprintf(stderr, PROGNAME
657 ": libpng initialization problem (longjmp)\n"); 657 ": libpng initialization problem (longjmp)\n");
658 break; 658 break;
659 case 4: 659 case 4:
660 fprintf(stderr, PROGNAME ": insufficient memory\n"); 660 fprintf(stderr, PROGNAME ": insufficient memory\n");
661 break; 661 break;
662 case 11: 662 case 11:
663 fprintf(stderr, PROGNAME 663 fprintf(stderr, PROGNAME
664 ": internal logic error (unexpected PNM type)\n"); 664 ": internal logic error (unexpected PNM type)\n");
665 break; 665 break;
666 default: 666 default:
667 fprintf(stderr, PROGNAME 667 fprintf(stderr, PROGNAME
668 ": unknown writepng_init() error\n"); 668 ": unknown writepng_init() error\n");
669 break; 669 break;
670 } 670 }
671 exit(rc); 671 exit(rc);
672 } 672 }
673 673
674 674
675 /* free textbuf, since it's a completely local variable and all text info 675 /* free textbuf, since it's a completely local variable and all text info
676 * has just been written to the PNG file */ 676 * has just been written to the PNG file */
677 677
678 if (text && textbuf) { 678 if (text && textbuf) {
679 free(textbuf); 679 free(textbuf);
680 textbuf = NULL; 680 textbuf = NULL;
681 } 681 }
682 682
683 683
684 /* calculate rowbytes on basis of image type; note that this becomes much 684 /* calculate rowbytes on basis of image type; note that this becomes much
685 * more complicated if we choose to support PBM type, ASCII PNM types, or 685 * more complicated if we choose to support PBM type, ASCII PNM types, or
686 * 16-bit-per-sample binary data [currently not an official NetPBM type] */ 686 * 16-bit-per-sample binary data [currently not an official NetPBM type] */
687 687
688 if (wpng_info.pnmtype == 5) 688 if (wpng_info.pnmtype == 5)
689 rowbytes = wpng_info.width; 689 rowbytes = wpng_info.width;
690 else if (wpng_info.pnmtype == 6) 690 else if (wpng_info.pnmtype == 6)
691 rowbytes = wpng_info.width * 3; 691 rowbytes = wpng_info.width * 3;
692 else /* if (wpng_info.pnmtype == 8) */ 692 else /* if (wpng_info.pnmtype == 8) */
693 rowbytes = wpng_info.width * 4; 693 rowbytes = wpng_info.width * 4;
694 694
695 695
696 /* read and write the image, either in its entirety (if writing interlaced 696 /* read and write the image, either in its entirety (if writing interlaced
697 * PNG) or row by row (if non-interlaced) */ 697 * PNG) or row by row (if non-interlaced) */
698 698
699 fprintf(stderr, "Encoding image data...\n"); 699 fprintf(stderr, "Encoding image data...\n");
700 fflush(stderr); 700 fflush(stderr);
701 701
702 if (wpng_info.interlaced) { 702 if (wpng_info.interlaced) {
703 long i; 703 long i;
704 ulg bytes; 704 ulg bytes;
705 ulg image_bytes = rowbytes * wpng_info.height; /* overflow? */ 705 ulg image_bytes = rowbytes * wpng_info.height; /* overflow? */
706 706
707 wpng_info.image_data = (uch *)malloc(image_bytes); 707 wpng_info.image_data = (uch *)malloc(image_bytes);
708 wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *)); 708 wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *));
709 if (wpng_info.image_data == NULL || wpng_info.row_pointers == NULL) { 709 if (wpng_info.image_data == NULL || wpng_info.row_pointers == NULL) {
710 fprintf(stderr, PROGNAME ": insufficient memory for image data\n"); 710 fprintf(stderr, PROGNAME ": insufficient memory for image data\n");
711 writepng_cleanup(&wpng_info); 711 writepng_cleanup(&wpng_info);
712 wpng_cleanup(); 712 wpng_cleanup();
713 exit(5); 713 exit(5);
714 } 714 }
715 for (i = 0; i < wpng_info.height; ++i) 715 for (i = 0; i < wpng_info.height; ++i)
716 wpng_info.row_pointers[i] = wpng_info.image_data + i*rowbytes; 716 wpng_info.row_pointers[i] = wpng_info.image_data + i*rowbytes;
717 bytes = fread(wpng_info.image_data, 1, image_bytes, wpng_info.infile); 717 bytes = fread(wpng_info.image_data, 1, image_bytes, wpng_info.infile);
718 if (bytes != image_bytes) { 718 if (bytes != image_bytes) {
719 fprintf(stderr, PROGNAME ": expected %lu bytes, got %lu bytes\n", 719 fprintf(stderr, PROGNAME ": expected %lu bytes, got %lu bytes\n",
720 image_bytes, bytes); 720 image_bytes, bytes);
721 fprintf(stderr, " (continuing anyway)\n"); 721 fprintf(stderr, " (continuing anyway)\n");
722 } 722 }
723 if (writepng_encode_image(&wpng_info) != 0) { 723 if (writepng_encode_image(&wpng_info) != 0) {
724 fprintf(stderr, PROGNAME 724 fprintf(stderr, PROGNAME
725 ": libpng problem (longjmp) while writing image data\n"); 725 ": libpng problem (longjmp) while writing image data\n");
726 writepng_cleanup(&wpng_info); 726 writepng_cleanup(&wpng_info);
727 wpng_cleanup(); 727 wpng_cleanup();
728 exit(2); 728 exit(2);
729 } 729 }
730 730
731 } else /* not interlaced: write progressively (row by row) */ { 731 } else /* not interlaced: write progressively (row by row) */ {
732 long j; 732 long j;
733 ulg bytes; 733 ulg bytes;
734 734
735 wpng_info.image_data = (uch *)malloc(rowbytes); 735 wpng_info.image_data = (uch *)malloc(rowbytes);
736 if (wpng_info.image_data == NULL) { 736 if (wpng_info.image_data == NULL) {
737 fprintf(stderr, PROGNAME ": insufficient memory for row data\n"); 737 fprintf(stderr, PROGNAME ": insufficient memory for row data\n");
738 writepng_cleanup(&wpng_info); 738 writepng_cleanup(&wpng_info);
739 wpng_cleanup(); 739 wpng_cleanup();
740 exit(5); 740 exit(5);
741 } 741 }
742 error = 0; 742 error = 0;
743 for (j = wpng_info.height; j > 0L; --j) { 743 for (j = wpng_info.height; j > 0L; --j) {
744 bytes = fread(wpng_info.image_data, 1, rowbytes, wpng_info.infile); 744 bytes = fread(wpng_info.image_data, 1, rowbytes, wpng_info.infile);
745 if (bytes != rowbytes) { 745 if (bytes != rowbytes) {
746 fprintf(stderr, PROGNAME 746 fprintf(stderr, PROGNAME
747 ": expected %lu bytes, got %lu bytes (row %ld)\n", rowbytes, 747 ": expected %lu bytes, got %lu bytes (row %ld)\n", rowbytes,
748 bytes, wpng_info.height-j); 748 bytes, wpng_info.height-j);
749 ++error; 749 ++error;
750 break; 750 break;
751 } 751 }
752 if (writepng_encode_row(&wpng_info) != 0) { 752 if (writepng_encode_row(&wpng_info) != 0) {
753 fprintf(stderr, PROGNAME 753 fprintf(stderr, PROGNAME
754 ": libpng problem (longjmp) while writing row %ld\n", 754 ": libpng problem (longjmp) while writing row %ld\n",
755 wpng_info.height-j); 755 wpng_info.height-j);
756 ++error; 756 ++error;
757 break; 757 break;
758 } 758 }
759 } 759 }
760 if (error) { 760 if (error) {
761 writepng_cleanup(&wpng_info); 761 writepng_cleanup(&wpng_info);
762 wpng_cleanup(); 762 wpng_cleanup();
763 exit(2); 763 exit(2);
764 } 764 }
765 if (writepng_encode_finish(&wpng_info) != 0) { 765 if (writepng_encode_finish(&wpng_info) != 0) {
766 fprintf(stderr, PROGNAME ": error on final libpng call\n"); 766 fprintf(stderr, PROGNAME ": error on final libpng call\n");
767 writepng_cleanup(&wpng_info); 767 writepng_cleanup(&wpng_info);
768 wpng_cleanup(); 768 wpng_cleanup();
769 exit(2); 769 exit(2);
770 } 770 }
771 } 771 }
772 772
773 773
774 /* OK, we're done (successfully): clean up all resources and quit */ 774 /* OK, we're done (successfully): clean up all resources and quit */
775 775
776 fprintf(stderr, "Done.\n"); 776 fprintf(stderr, "Done.\n");
777 fflush(stderr); 777 fflush(stderr);
778 778
779 writepng_cleanup(&wpng_info); 779 writepng_cleanup(&wpng_info);
780 wpng_cleanup(); 780 wpng_cleanup();
781 781
782 return 0; 782 return 0;
783} 783}
784 784
785 785
786 786
787 787
788 788
789static int wpng_isvalid_latin1(uch *p, int len) 789static int wpng_isvalid_latin1(uch *p, int len)
790{ 790{
791 int i, result = -1; 791 int i, result = -1;
792 792
793 for (i = 0; i < len; ++i) { 793 for (i = 0; i < len; ++i) {
794 if (p[i] == 10 || (p[i] > 31 && p[i] < 127) || p[i] > 160) 794 if (p[i] == 10 || (p[i] > 31 && p[i] < 127) || p[i] > 160)
795 continue; /* character is completely OK */ 795 continue; /* character is completely OK */
796 if (result < 0 || (p[result] != 27 && p[i] == 27)) 796 if (result < 0 || (p[result] != 27 && p[i] == 27))
797 result = i; /* mark location of first questionable one */ 797 result = i; /* mark location of first questionable one */
798 } /* or of first escape character (bad) */ 798 } /* or of first escape character (bad) */
799 799
800 return result; 800 return result;
801} 801}
802 802
803 803
804 804
805 805
806 806
807static void wpng_cleanup(void) 807static void wpng_cleanup(void)
808{ 808{
809 if (wpng_info.outfile) { 809 if (wpng_info.outfile) {
810 fclose(wpng_info.outfile); 810 fclose(wpng_info.outfile);
811 wpng_info.outfile = NULL; 811 wpng_info.outfile = NULL;
812 } 812 }
813 813
814 if (wpng_info.infile) { 814 if (wpng_info.infile) {
815 fclose(wpng_info.infile); 815 fclose(wpng_info.infile);
816 wpng_info.infile = NULL; 816 wpng_info.infile = NULL;
817 } 817 }
818 818
819 if (wpng_info.image_data) { 819 if (wpng_info.image_data) {
820 free(wpng_info.image_data); 820 free(wpng_info.image_data);
821 wpng_info.image_data = NULL; 821 wpng_info.image_data = NULL;
822 } 822 }
823 823
824 if (wpng_info.row_pointers) { 824 if (wpng_info.row_pointers) {
825 free(wpng_info.row_pointers); 825 free(wpng_info.row_pointers);
826 wpng_info.row_pointers = NULL; 826 wpng_info.row_pointers = NULL;
827 } 827 }
828} 828}
829 829
830 830
831 831
832 832
833#ifdef DOS_OS2_W32 833#ifdef DOS_OS2_W32
834 834
835static char *dos_kbd_gets(char *buf, int len) 835static char *dos_kbd_gets(char *buf, int len)
836{ 836{
837 int ch, count=0; 837 int ch, count=0;
838 838
839 do { 839 do {
840 buf[count++] = ch = getche(); 840 buf[count++] = ch = getche();
841 } while (ch != '\r' && count < len-1); 841 } while (ch != '\r' && count < len-1);
842 842
843 buf[count--] = '\0'; /* terminate string */ 843 buf[count--] = '\0'; /* terminate string */
844 if (buf[count] == '\r') /* Enter key makes CR, so change to newline */ 844 if (buf[count] == '\r') /* Enter key makes CR, so change to newline */
845 buf[count] = '\n'; 845 buf[count] = '\n';
846 846
847 fprintf(stderr, "\n"); /* Enter key does *not* cause a newline */ 847 fprintf(stderr, "\n"); /* Enter key does *not* cause a newline */
848 fflush(stderr); 848 fflush(stderr);
849 849
850 return buf; 850 return buf;
851} 851}
852 852
853#endif /* DOS_OS2_W32 */ 853#endif /* DOS_OS2_W32 */
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.c
index 8373c16..f07f4a8 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.c
@@ -1,400 +1,400 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 wpng - simple PNG-writing program writepng.c 3 wpng - simple PNG-writing program writepng.c
4 4
5 --------------------------------------------------------------------------- 5 ---------------------------------------------------------------------------
6 6
7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. 7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved.
8 8
9 This software is provided "as is," without warranty of any kind, 9 This software is provided "as is," without warranty of any kind,
10 express or implied. In no event shall the author or contributors 10 express or implied. In no event shall the author or contributors
11 be held liable for any damages arising in any way from the use of 11 be held liable for any damages arising in any way from the use of
12 this software. 12 this software.
13 13
14 The contents of this file are DUAL-LICENSED. You may modify and/or 14 The contents of this file are DUAL-LICENSED. You may modify and/or
15 redistribute this software according to the terms of one of the 15 redistribute this software according to the terms of one of the
16 following two licenses (at your option): 16 following two licenses (at your option):
17 17
18 18
19 LICENSE 1 ("BSD-like with advertising clause"): 19 LICENSE 1 ("BSD-like with advertising clause"):
20 20
21 Permission is granted to anyone to use this software for any purpose, 21 Permission is granted to anyone to use this software for any purpose,
22 including commercial applications, and to alter it and redistribute 22 including commercial applications, and to alter it and redistribute
23 it freely, subject to the following restrictions: 23 it freely, subject to the following restrictions:
24 24
25 1. Redistributions of source code must retain the above copyright 25 1. Redistributions of source code must retain the above copyright
26 notice, disclaimer, and this list of conditions. 26 notice, disclaimer, and this list of conditions.
27 2. Redistributions in binary form must reproduce the above copyright 27 2. Redistributions in binary form must reproduce the above copyright
28 notice, disclaimer, and this list of conditions in the documenta- 28 notice, disclaimer, and this list of conditions in the documenta-
29 tion and/or other materials provided with the distribution. 29 tion and/or other materials provided with the distribution.
30 3. All advertising materials mentioning features or use of this 30 3. All advertising materials mentioning features or use of this
31 software must display the following acknowledgment: 31 software must display the following acknowledgment:
32 32
33 This product includes software developed by Greg Roelofs 33 This product includes software developed by Greg Roelofs
34 and contributors for the book, "PNG: The Definitive Guide," 34 and contributors for the book, "PNG: The Definitive Guide,"
35 published by O'Reilly and Associates. 35 published by O'Reilly and Associates.
36 36
37 37
38 LICENSE 2 (GNU GPL v2 or later): 38 LICENSE 2 (GNU GPL v2 or later):
39 39
40 This program is free software; you can redistribute it and/or modify 40 This program is free software; you can redistribute it and/or modify
41 it under the terms of the GNU General Public License as published by 41 it under the terms of the GNU General Public License as published by
42 the Free Software Foundation; either version 2 of the License, or 42 the Free Software Foundation; either version 2 of the License, or
43 (at your option) any later version. 43 (at your option) any later version.
44 44
45 This program is distributed in the hope that it will be useful, 45 This program is distributed in the hope that it will be useful,
46 but WITHOUT ANY WARRANTY; without even the implied warranty of 46 but WITHOUT ANY WARRANTY; without even the implied warranty of
47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 GNU General Public License for more details. 48 GNU General Public License for more details.
49 49
50 You should have received a copy of the GNU General Public License 50 You should have received a copy of the GNU General Public License
51 along with this program; if not, write to the Free Software Foundation, 51 along with this program; if not, write to the Free Software Foundation,
52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53 53
54 ---------------------------------------------------------------------------*/ 54 ---------------------------------------------------------------------------*/
55 55
56 56
57#include <stdlib.h> /* for exit() prototype */ 57#include <stdlib.h> /* for exit() prototype */
58 58
59#include "png.h" /* libpng header; includes zlib.h and setjmp.h */ 59#include "png.h" /* libpng header; includes zlib.h and setjmp.h */
60#include "writepng.h" /* typedefs, common macros, public prototypes */ 60#include "writepng.h" /* typedefs, common macros, public prototypes */
61 61
62 62
63/* local prototype */ 63/* local prototype */
64 64
65static void writepng_error_handler(png_structp png_ptr, png_const_charp msg); 65static void writepng_error_handler(png_structp png_ptr, png_const_charp msg);
66 66
67 67
68 68
69void writepng_version_info(void) 69void writepng_version_info(void)
70{ 70{
71 fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n", 71 fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
72 PNG_LIBPNG_VER_STRING, png_libpng_ver); 72 PNG_LIBPNG_VER_STRING, png_libpng_ver);
73 fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n", 73 fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n",
74 ZLIB_VERSION, zlib_version); 74 ZLIB_VERSION, zlib_version);
75} 75}
76 76
77 77
78 78
79 79
80/* returns 0 for success, 2 for libpng problem, 4 for out of memory, 11 for 80/* returns 0 for success, 2 for libpng problem, 4 for out of memory, 11 for
81 * unexpected pnmtype; note that outfile might be stdout */ 81 * unexpected pnmtype; note that outfile might be stdout */
82 82
83int writepng_init(mainprog_info *mainprog_ptr) 83int writepng_init(mainprog_info *mainprog_ptr)
84{ 84{
85 png_structp png_ptr; /* note: temporary variables! */ 85 png_structp png_ptr; /* note: temporary variables! */
86 png_infop info_ptr; 86 png_infop info_ptr;
87 int color_type, interlace_type; 87 int color_type, interlace_type;
88 88
89 89
90 /* could also replace libpng warning-handler (final NULL), but no need: */ 90 /* could also replace libpng warning-handler (final NULL), but no need: */
91 91
92 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr, 92 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
93 writepng_error_handler, NULL); 93 writepng_error_handler, NULL);
94 if (!png_ptr) 94 if (!png_ptr)
95 return 4; /* out of memory */ 95 return 4; /* out of memory */
96 96
97 info_ptr = png_create_info_struct(png_ptr); 97 info_ptr = png_create_info_struct(png_ptr);
98 if (!info_ptr) { 98 if (!info_ptr) {
99 png_destroy_write_struct(&png_ptr, NULL); 99 png_destroy_write_struct(&png_ptr, NULL);
100 return 4; /* out of memory */ 100 return 4; /* out of memory */
101 } 101 }
102 102
103 103
104 /* setjmp() must be called in every function that calls a PNG-writing 104 /* setjmp() must be called in every function that calls a PNG-writing
105 * libpng function, unless an alternate error handler was installed-- 105 * libpng function, unless an alternate error handler was installed--
106 * but compatible error handlers must either use longjmp() themselves 106 * but compatible error handlers must either use longjmp() themselves
107 * (as in this program) or some other method to return control to 107 * (as in this program) or some other method to return control to
108 * application code, so here we go: */ 108 * application code, so here we go: */
109 109
110 if (setjmp(mainprog_ptr->jmpbuf)) { 110 if (setjmp(mainprog_ptr->jmpbuf)) {
111 png_destroy_write_struct(&png_ptr, &info_ptr); 111 png_destroy_write_struct(&png_ptr, &info_ptr);
112 return 2; 112 return 2;
113 } 113 }
114 114
115 115
116 /* make sure outfile is (re)opened in BINARY mode */ 116 /* make sure outfile is (re)opened in BINARY mode */
117 117
118 png_init_io(png_ptr, mainprog_ptr->outfile); 118 png_init_io(png_ptr, mainprog_ptr->outfile);
119 119
120 120
121 /* set the compression levels--in general, always want to leave filtering 121 /* set the compression levels--in general, always want to leave filtering
122 * turned on (except for palette images) and allow all of the filters, 122 * turned on (except for palette images) and allow all of the filters,
123 * which is the default; want 32K zlib window, unless entire image buffer 123 * which is the default; want 32K zlib window, unless entire image buffer
124 * is 16K or smaller (unknown here)--also the default; usually want max 124 * is 16K or smaller (unknown here)--also the default; usually want max
125 * compression (NOT the default); and remaining compression flags should 125 * compression (NOT the default); and remaining compression flags should
126 * be left alone */ 126 * be left alone */
127 127
128 png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); 128 png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
129/* 129/*
130 >> this is default for no filtering; Z_FILTERED is default otherwise: 130 >> this is default for no filtering; Z_FILTERED is default otherwise:
131 png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); 131 png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
132 >> these are all defaults: 132 >> these are all defaults:
133 png_set_compression_mem_level(png_ptr, 8); 133 png_set_compression_mem_level(png_ptr, 8);
134 png_set_compression_window_bits(png_ptr, 15); 134 png_set_compression_window_bits(png_ptr, 15);
135 png_set_compression_method(png_ptr, 8); 135 png_set_compression_method(png_ptr, 8);
136 */ 136 */
137 137
138 138
139 /* set the image parameters appropriately */ 139 /* set the image parameters appropriately */
140 140
141 if (mainprog_ptr->pnmtype == 5) 141 if (mainprog_ptr->pnmtype == 5)
142 color_type = PNG_COLOR_TYPE_GRAY; 142 color_type = PNG_COLOR_TYPE_GRAY;
143 else if (mainprog_ptr->pnmtype == 6) 143 else if (mainprog_ptr->pnmtype == 6)
144 color_type = PNG_COLOR_TYPE_RGB; 144 color_type = PNG_COLOR_TYPE_RGB;
145 else if (mainprog_ptr->pnmtype == 8) 145 else if (mainprog_ptr->pnmtype == 8)
146 color_type = PNG_COLOR_TYPE_RGB_ALPHA; 146 color_type = PNG_COLOR_TYPE_RGB_ALPHA;
147 else { 147 else {
148 png_destroy_write_struct(&png_ptr, &info_ptr); 148 png_destroy_write_struct(&png_ptr, &info_ptr);
149 return 11; 149 return 11;
150 } 150 }
151 151
152 interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 : 152 interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 :
153 PNG_INTERLACE_NONE; 153 PNG_INTERLACE_NONE;
154 154
155 png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height, 155 png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height,
156 mainprog_ptr->sample_depth, color_type, interlace_type, 156 mainprog_ptr->sample_depth, color_type, interlace_type,
157 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 157 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
158 158
159 if (mainprog_ptr->gamma > 0.0) 159 if (mainprog_ptr->gamma > 0.0)
160 png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma); 160 png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma);
161 161
162 if (mainprog_ptr->have_bg) { /* we know it's RGBA, not gray+alpha */ 162 if (mainprog_ptr->have_bg) { /* we know it's RGBA, not gray+alpha */
163 png_color_16 background; 163 png_color_16 background;
164 164
165 background.red = mainprog_ptr->bg_red; 165 background.red = mainprog_ptr->bg_red;
166 background.green = mainprog_ptr->bg_green; 166 background.green = mainprog_ptr->bg_green;
167 background.blue = mainprog_ptr->bg_blue; 167 background.blue = mainprog_ptr->bg_blue;
168 png_set_bKGD(png_ptr, info_ptr, &background); 168 png_set_bKGD(png_ptr, info_ptr, &background);
169 } 169 }
170 170
171 if (mainprog_ptr->have_time) { 171 if (mainprog_ptr->have_time) {
172 png_time modtime; 172 png_time modtime;
173 173
174 png_convert_from_time_t(&modtime, mainprog_ptr->modtime); 174 png_convert_from_time_t(&modtime, mainprog_ptr->modtime);
175 png_set_tIME(png_ptr, info_ptr, &modtime); 175 png_set_tIME(png_ptr, info_ptr, &modtime);
176 } 176 }
177 177
178 if (mainprog_ptr->have_text) { 178 if (mainprog_ptr->have_text) {
179 png_text text[6]; 179 png_text text[6];
180 int num_text = 0; 180 int num_text = 0;
181 181
182 if (mainprog_ptr->have_text & TEXT_TITLE) { 182 if (mainprog_ptr->have_text & TEXT_TITLE) {
183 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 183 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
184 text[num_text].key = "Title"; 184 text[num_text].key = "Title";
185 text[num_text].text = mainprog_ptr->title; 185 text[num_text].text = mainprog_ptr->title;
186 ++num_text; 186 ++num_text;
187 } 187 }
188 if (mainprog_ptr->have_text & TEXT_AUTHOR) { 188 if (mainprog_ptr->have_text & TEXT_AUTHOR) {
189 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 189 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
190 text[num_text].key = "Author"; 190 text[num_text].key = "Author";
191 text[num_text].text = mainprog_ptr->author; 191 text[num_text].text = mainprog_ptr->author;
192 ++num_text; 192 ++num_text;
193 } 193 }
194 if (mainprog_ptr->have_text & TEXT_DESC) { 194 if (mainprog_ptr->have_text & TEXT_DESC) {
195 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 195 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
196 text[num_text].key = "Description"; 196 text[num_text].key = "Description";
197 text[num_text].text = mainprog_ptr->desc; 197 text[num_text].text = mainprog_ptr->desc;
198 ++num_text; 198 ++num_text;
199 } 199 }
200 if (mainprog_ptr->have_text & TEXT_COPY) { 200 if (mainprog_ptr->have_text & TEXT_COPY) {
201 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 201 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
202 text[num_text].key = "Copyright"; 202 text[num_text].key = "Copyright";
203 text[num_text].text = mainprog_ptr->copyright; 203 text[num_text].text = mainprog_ptr->copyright;
204 ++num_text; 204 ++num_text;
205 } 205 }
206 if (mainprog_ptr->have_text & TEXT_EMAIL) { 206 if (mainprog_ptr->have_text & TEXT_EMAIL) {
207 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 207 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
208 text[num_text].key = "E-mail"; 208 text[num_text].key = "E-mail";
209 text[num_text].text = mainprog_ptr->email; 209 text[num_text].text = mainprog_ptr->email;
210 ++num_text; 210 ++num_text;
211 } 211 }
212 if (mainprog_ptr->have_text & TEXT_URL) { 212 if (mainprog_ptr->have_text & TEXT_URL) {
213 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 213 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
214 text[num_text].key = "URL"; 214 text[num_text].key = "URL";
215 text[num_text].text = mainprog_ptr->url; 215 text[num_text].text = mainprog_ptr->url;
216 ++num_text; 216 ++num_text;
217 } 217 }
218 png_set_text(png_ptr, info_ptr, text, num_text); 218 png_set_text(png_ptr, info_ptr, text, num_text);
219 } 219 }
220 220
221 221
222 /* write all chunks up to (but not including) first IDAT */ 222 /* write all chunks up to (but not including) first IDAT */
223 223
224 png_write_info(png_ptr, info_ptr); 224 png_write_info(png_ptr, info_ptr);
225 225
226 226
227 /* if we wanted to write any more text info *after* the image data, we 227 /* if we wanted to write any more text info *after* the image data, we
228 * would set up text struct(s) here and call png_set_text() again, with 228 * would set up text struct(s) here and call png_set_text() again, with
229 * just the new data; png_set_tIME() could also go here, but it would 229 * just the new data; png_set_tIME() could also go here, but it would
230 * have no effect since we already called it above (only one tIME chunk 230 * have no effect since we already called it above (only one tIME chunk
231 * allowed) */ 231 * allowed) */
232 232
233 233
234 /* set up the transformations: for now, just pack low-bit-depth pixels 234 /* set up the transformations: for now, just pack low-bit-depth pixels
235 * into bytes (one, two or four pixels per byte) */ 235 * into bytes (one, two or four pixels per byte) */
236 236
237 png_set_packing(png_ptr); 237 png_set_packing(png_ptr);
238/* png_set_shift(png_ptr, &sig_bit); to scale low-bit-depth values */ 238/* png_set_shift(png_ptr, &sig_bit); to scale low-bit-depth values */
239 239
240 240
241 /* make sure we save our pointers for use in writepng_encode_image() */ 241 /* make sure we save our pointers for use in writepng_encode_image() */
242 242
243 mainprog_ptr->png_ptr = png_ptr; 243 mainprog_ptr->png_ptr = png_ptr;
244 mainprog_ptr->info_ptr = info_ptr; 244 mainprog_ptr->info_ptr = info_ptr;
245 245
246 246
247 /* OK, that's all we need to do for now; return happy */ 247 /* OK, that's all we need to do for now; return happy */
248 248
249 return 0; 249 return 0;
250} 250}
251 251
252 252
253 253
254 254
255 255
256/* returns 0 for success, 2 for libpng (longjmp) problem */ 256/* returns 0 for success, 2 for libpng (longjmp) problem */
257 257
258int writepng_encode_image(mainprog_info *mainprog_ptr) 258int writepng_encode_image(mainprog_info *mainprog_ptr)
259{ 259{
260 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 260 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
261 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 261 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
262 262
263 263
264 /* as always, setjmp() must be called in every function that calls a 264 /* as always, setjmp() must be called in every function that calls a
265 * PNG-writing libpng function */ 265 * PNG-writing libpng function */
266 266
267 if (setjmp(mainprog_ptr->jmpbuf)) { 267 if (setjmp(mainprog_ptr->jmpbuf)) {
268 png_destroy_write_struct(&png_ptr, &info_ptr); 268 png_destroy_write_struct(&png_ptr, &info_ptr);
269 mainprog_ptr->png_ptr = NULL; 269 mainprog_ptr->png_ptr = NULL;
270 mainprog_ptr->info_ptr = NULL; 270 mainprog_ptr->info_ptr = NULL;
271 return 2; 271 return 2;
272 } 272 }
273 273
274 274
275 /* and now we just write the whole image; libpng takes care of interlacing 275 /* and now we just write the whole image; libpng takes care of interlacing
276 * for us */ 276 * for us */
277 277
278 png_write_image(png_ptr, mainprog_ptr->row_pointers); 278 png_write_image(png_ptr, mainprog_ptr->row_pointers);
279 279
280 280
281 /* since that's it, we also close out the end of the PNG file now--if we 281 /* since that's it, we also close out the end of the PNG file now--if we
282 * had any text or time info to write after the IDATs, second argument 282 * had any text or time info to write after the IDATs, second argument
283 * would be info_ptr, but we optimize slightly by sending NULL pointer: */ 283 * would be info_ptr, but we optimize slightly by sending NULL pointer: */
284 284
285 png_write_end(png_ptr, NULL); 285 png_write_end(png_ptr, NULL);
286 286
287 return 0; 287 return 0;
288} 288}
289 289
290 290
291 291
292 292
293 293
294/* returns 0 if succeeds, 2 if libpng problem */ 294/* returns 0 if succeeds, 2 if libpng problem */
295 295
296int writepng_encode_row(mainprog_info *mainprog_ptr) /* NON-interlaced only! */ 296int writepng_encode_row(mainprog_info *mainprog_ptr) /* NON-interlaced only! */
297{ 297{
298 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 298 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
299 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 299 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
300 300
301 301
302 /* as always, setjmp() must be called in every function that calls a 302 /* as always, setjmp() must be called in every function that calls a
303 * PNG-writing libpng function */ 303 * PNG-writing libpng function */
304 304
305 if (setjmp(mainprog_ptr->jmpbuf)) { 305 if (setjmp(mainprog_ptr->jmpbuf)) {
306 png_destroy_write_struct(&png_ptr, &info_ptr); 306 png_destroy_write_struct(&png_ptr, &info_ptr);
307 mainprog_ptr->png_ptr = NULL; 307 mainprog_ptr->png_ptr = NULL;
308 mainprog_ptr->info_ptr = NULL; 308 mainprog_ptr->info_ptr = NULL;
309 return 2; 309 return 2;
310 } 310 }
311 311
312 312
313 /* image_data points at our one row of image data */ 313 /* image_data points at our one row of image data */
314 314
315 png_write_row(png_ptr, mainprog_ptr->image_data); 315 png_write_row(png_ptr, mainprog_ptr->image_data);
316 316
317 return 0; 317 return 0;
318} 318}
319 319
320 320
321 321
322 322
323 323
324/* returns 0 if succeeds, 2 if libpng problem */ 324/* returns 0 if succeeds, 2 if libpng problem */
325 325
326int writepng_encode_finish(mainprog_info *mainprog_ptr) /* NON-interlaced! */ 326int writepng_encode_finish(mainprog_info *mainprog_ptr) /* NON-interlaced! */
327{ 327{
328 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 328 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
329 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 329 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
330 330
331 331
332 /* as always, setjmp() must be called in every function that calls a 332 /* as always, setjmp() must be called in every function that calls a
333 * PNG-writing libpng function */ 333 * PNG-writing libpng function */
334 334
335 if (setjmp(mainprog_ptr->jmpbuf)) { 335 if (setjmp(mainprog_ptr->jmpbuf)) {
336 png_destroy_write_struct(&png_ptr, &info_ptr); 336 png_destroy_write_struct(&png_ptr, &info_ptr);
337 mainprog_ptr->png_ptr = NULL; 337 mainprog_ptr->png_ptr = NULL;
338 mainprog_ptr->info_ptr = NULL; 338 mainprog_ptr->info_ptr = NULL;
339 return 2; 339 return 2;
340 } 340 }
341 341
342 342
343 /* close out PNG file; if we had any text or time info to write after 343 /* close out PNG file; if we had any text or time info to write after
344 * the IDATs, second argument would be info_ptr: */ 344 * the IDATs, second argument would be info_ptr: */
345 345
346 png_write_end(png_ptr, NULL); 346 png_write_end(png_ptr, NULL);
347 347
348 return 0; 348 return 0;
349} 349}
350 350
351 351
352 352
353 353
354 354
355void writepng_cleanup(mainprog_info *mainprog_ptr) 355void writepng_cleanup(mainprog_info *mainprog_ptr)
356{ 356{
357 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 357 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
358 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 358 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
359 359
360 if (png_ptr && info_ptr) 360 if (png_ptr && info_ptr)
361 png_destroy_write_struct(&png_ptr, &info_ptr); 361 png_destroy_write_struct(&png_ptr, &info_ptr);
362} 362}
363 363
364 364
365 365
366 366
367 367
368static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) 368static void writepng_error_handler(png_structp png_ptr, png_const_charp msg)
369{ 369{
370 mainprog_info *mainprog_ptr; 370 mainprog_info *mainprog_ptr;
371 371
372 /* This function, aside from the extra step of retrieving the "error 372 /* This function, aside from the extra step of retrieving the "error
373 * pointer" (below) and the fact that it exists within the application 373 * pointer" (below) and the fact that it exists within the application
374 * rather than within libpng, is essentially identical to libpng's 374 * rather than within libpng, is essentially identical to libpng's
375 * default error handler. The second point is critical: since both 375 * default error handler. The second point is critical: since both
376 * setjmp() and longjmp() are called from the same code, they are 376 * setjmp() and longjmp() are called from the same code, they are
377 * guaranteed to have compatible notions of how big a jmp_buf is, 377 * guaranteed to have compatible notions of how big a jmp_buf is,
378 * regardless of whether _BSD_SOURCE or anything else has (or has not) 378 * regardless of whether _BSD_SOURCE or anything else has (or has not)
379 * been defined. */ 379 * been defined. */
380 380
381 fprintf(stderr, "writepng libpng error: %s\n", msg); 381 fprintf(stderr, "writepng libpng error: %s\n", msg);
382 fflush(stderr); 382 fflush(stderr);
383 383
384 mainprog_ptr = png_get_error_ptr(png_ptr); 384 mainprog_ptr = png_get_error_ptr(png_ptr);
385 if (mainprog_ptr == NULL) { /* we are completely hosed now */ 385 if (mainprog_ptr == NULL) { /* we are completely hosed now */
386 fprintf(stderr, 386 fprintf(stderr,
387 "writepng severe error: jmpbuf not recoverable; terminating.\n"); 387 "writepng severe error: jmpbuf not recoverable; terminating.\n");
388 fflush(stderr); 388 fflush(stderr);
389 exit(99); 389 exit(99);
390 } 390 }
391 391
392 /* Now we have our data structure we can use the information in it 392 /* Now we have our data structure we can use the information in it
393 * to return control to our own higher level code (all the points 393 * to return control to our own higher level code (all the points
394 * where 'setjmp' is called in this file.) This will work with other 394 * where 'setjmp' is called in this file.) This will work with other
395 * error handling mechanisms as well - libpng always calls png_error 395 * error handling mechanisms as well - libpng always calls png_error
396 * when it can proceed no further, thus, so long as the error handler 396 * when it can proceed no further, thus, so long as the error handler
397 * is intercepted, application code can do its own error recovery. 397 * is intercepted, application code can do its own error recovery.
398 */ 398 */
399 longjmp(mainprog_ptr->jmpbuf, 1); 399 longjmp(mainprog_ptr->jmpbuf, 1);
400} 400}
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.h
index 904e4fb..78b966b 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.h
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/gregbook/writepng.h
@@ -1,133 +1,133 @@
1/*--------------------------------------------------------------------------- 1/*---------------------------------------------------------------------------
2 2
3 wpng - simple PNG-writing program writepng.h 3 wpng - simple PNG-writing program writepng.h
4 4
5 --------------------------------------------------------------------------- 5 ---------------------------------------------------------------------------
6 6
7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. 7 Copyright (c) 1998-2007 Greg Roelofs. All rights reserved.
8 8
9 This software is provided "as is," without warranty of any kind, 9 This software is provided "as is," without warranty of any kind,
10 express or implied. In no event shall the author or contributors 10 express or implied. In no event shall the author or contributors
11 be held liable for any damages arising in any way from the use of 11 be held liable for any damages arising in any way from the use of
12 this software. 12 this software.
13 13
14 The contents of this file are DUAL-LICENSED. You may modify and/or 14 The contents of this file are DUAL-LICENSED. You may modify and/or
15 redistribute this software according to the terms of one of the 15 redistribute this software according to the terms of one of the
16 following two licenses (at your option): 16 following two licenses (at your option):
17 17
18 18
19 LICENSE 1 ("BSD-like with advertising clause"): 19 LICENSE 1 ("BSD-like with advertising clause"):
20 20
21 Permission is granted to anyone to use this software for any purpose, 21 Permission is granted to anyone to use this software for any purpose,
22 including commercial applications, and to alter it and redistribute 22 including commercial applications, and to alter it and redistribute
23 it freely, subject to the following restrictions: 23 it freely, subject to the following restrictions:
24 24
25 1. Redistributions of source code must retain the above copyright 25 1. Redistributions of source code must retain the above copyright
26 notice, disclaimer, and this list of conditions. 26 notice, disclaimer, and this list of conditions.
27 2. Redistributions in binary form must reproduce the above copyright 27 2. Redistributions in binary form must reproduce the above copyright
28 notice, disclaimer, and this list of conditions in the documenta- 28 notice, disclaimer, and this list of conditions in the documenta-
29 tion and/or other materials provided with the distribution. 29 tion and/or other materials provided with the distribution.
30 3. All advertising materials mentioning features or use of this 30 3. All advertising materials mentioning features or use of this
31 software must display the following acknowledgment: 31 software must display the following acknowledgment:
32 32
33 This product includes software developed by Greg Roelofs 33 This product includes software developed by Greg Roelofs
34 and contributors for the book, "PNG: The Definitive Guide," 34 and contributors for the book, "PNG: The Definitive Guide,"
35 published by O'Reilly and Associates. 35 published by O'Reilly and Associates.
36 36
37 37
38 LICENSE 2 (GNU GPL v2 or later): 38 LICENSE 2 (GNU GPL v2 or later):
39 39
40 This program is free software; you can redistribute it and/or modify 40 This program is free software; you can redistribute it and/or modify
41 it under the terms of the GNU General Public License as published by 41 it under the terms of the GNU General Public License as published by
42 the Free Software Foundation; either version 2 of the License, or 42 the Free Software Foundation; either version 2 of the License, or
43 (at your option) any later version. 43 (at your option) any later version.
44 44
45 This program is distributed in the hope that it will be useful, 45 This program is distributed in the hope that it will be useful,
46 but WITHOUT ANY WARRANTY; without even the implied warranty of 46 but WITHOUT ANY WARRANTY; without even the implied warranty of
47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 GNU General Public License for more details. 48 GNU General Public License for more details.
49 49
50 You should have received a copy of the GNU General Public License 50 You should have received a copy of the GNU General Public License
51 along with this program; if not, write to the Free Software Foundation, 51 along with this program; if not, write to the Free Software Foundation,
52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 52 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53 53
54 ---------------------------------------------------------------------------*/ 54 ---------------------------------------------------------------------------*/
55 55
56#ifndef TRUE 56#ifndef TRUE
57# define TRUE 1 57# define TRUE 1
58# define FALSE 0 58# define FALSE 0
59#endif 59#endif
60 60
61#ifndef MAX 61#ifndef MAX
62# define MAX(a,b) ((a) > (b)? (a) : (b)) 62# define MAX(a,b) ((a) > (b)? (a) : (b))
63# define MIN(a,b) ((a) < (b)? (a) : (b)) 63# define MIN(a,b) ((a) < (b)? (a) : (b))
64#endif 64#endif
65 65
66#ifdef DEBUG 66#ifdef DEBUG
67# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);} 67# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);}
68#else 68#else
69# define Trace(x) ; 69# define Trace(x) ;
70#endif 70#endif
71 71
72#define TEXT_TITLE 0x01 72#define TEXT_TITLE 0x01
73#define TEXT_AUTHOR 0x02 73#define TEXT_AUTHOR 0x02
74#define TEXT_DESC 0x04 74#define TEXT_DESC 0x04
75#define TEXT_COPY 0x08 75#define TEXT_COPY 0x08
76#define TEXT_EMAIL 0x10 76#define TEXT_EMAIL 0x10
77#define TEXT_URL 0x20 77#define TEXT_URL 0x20
78 78
79#define TEXT_TITLE_OFFSET 0 79#define TEXT_TITLE_OFFSET 0
80#define TEXT_AUTHOR_OFFSET 72 80#define TEXT_AUTHOR_OFFSET 72
81#define TEXT_COPY_OFFSET (2*72) 81#define TEXT_COPY_OFFSET (2*72)
82#define TEXT_EMAIL_OFFSET (3*72) 82#define TEXT_EMAIL_OFFSET (3*72)
83#define TEXT_URL_OFFSET (4*72) 83#define TEXT_URL_OFFSET (4*72)
84#define TEXT_DESC_OFFSET (5*72) 84#define TEXT_DESC_OFFSET (5*72)
85 85
86typedef unsigned char uch; 86typedef unsigned char uch;
87typedef unsigned short ush; 87typedef unsigned short ush;
88typedef unsigned long ulg; 88typedef unsigned long ulg;
89 89
90typedef struct _mainprog_info { 90typedef struct _mainprog_info {
91 double gamma; 91 double gamma;
92 long width; 92 long width;
93 long height; 93 long height;
94 time_t modtime; 94 time_t modtime;
95 FILE *infile; 95 FILE *infile;
96 FILE *outfile; 96 FILE *outfile;
97 void *png_ptr; 97 void *png_ptr;
98 void *info_ptr; 98 void *info_ptr;
99 uch *image_data; 99 uch *image_data;
100 uch **row_pointers; 100 uch **row_pointers;
101 char *title; 101 char *title;
102 char *author; 102 char *author;
103 char *desc; 103 char *desc;
104 char *copyright; 104 char *copyright;
105 char *email; 105 char *email;
106 char *url; 106 char *url;
107 int filter; /* command-line-filter flag, not PNG row filter! */ 107 int filter; /* command-line-filter flag, not PNG row filter! */
108 int pnmtype; 108 int pnmtype;
109 int sample_depth; 109 int sample_depth;
110 int interlaced; 110 int interlaced;
111 int have_bg; 111 int have_bg;
112 int have_time; 112 int have_time;
113 int have_text; 113 int have_text;
114 jmp_buf jmpbuf; 114 jmp_buf jmpbuf;
115 uch bg_red; 115 uch bg_red;
116 uch bg_green; 116 uch bg_green;
117 uch bg_blue; 117 uch bg_blue;
118} mainprog_info; 118} mainprog_info;
119 119
120 120
121/* prototypes for public functions in writepng.c */ 121/* prototypes for public functions in writepng.c */
122 122
123void writepng_version_info(void); 123void writepng_version_info(void);
124 124
125int writepng_init(mainprog_info *mainprog_ptr); 125int writepng_init(mainprog_info *mainprog_ptr);
126 126
127int writepng_encode_image(mainprog_info *mainprog_ptr); 127int writepng_encode_image(mainprog_info *mainprog_ptr);
128 128
129int writepng_encode_row(mainprog_info *mainprog_ptr); 129int writepng_encode_row(mainprog_info *mainprog_ptr);
130 130
131int writepng_encode_finish(mainprog_info *mainprog_ptr); 131int writepng_encode_finish(mainprog_info *mainprog_ptr);
132 132
133void writepng_cleanup(mainprog_info *mainprog_ptr); 133void writepng_cleanup(mainprog_info *mainprog_ptr);
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/libtests/pngvalid.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/libtests/pngvalid.c
index c7068fa..3dd6f21 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/libtests/pngvalid.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/libtests/pngvalid.c
@@ -1,9837 +1,9837 @@
1 1
2/* pngvalid.c - validate libpng by constructing then reading png files. 2/* pngvalid.c - validate libpng by constructing then reading png files.
3 * 3 *
4 * Last changed in libpng 1.5.8 [%RDATE%] 4 * Last changed in libpng 1.5.8 [%RDATE%]
5 * Copyright (c) 2012 Glenn Randers-Pehrson 5 * Copyright (c) 2012 Glenn Randers-Pehrson
6 * Written by John Cunningham Bowler 6 * Written by John Cunningham Bowler
7 * 7 *
8 * This code is released under the libpng license. 8 * This code is released under the libpng license.
9 * For conditions of distribution and use, see the disclaimer 9 * For conditions of distribution and use, see the disclaimer
10 * and license in png.h 10 * and license in png.h
11 * 11 *
12 * NOTES: 12 * NOTES:
13 * This is a C program that is intended to be linked against libpng. It 13 * This is a C program that is intended to be linked against libpng. It
14 * generates bitmaps internally, stores them as PNG files (using the 14 * generates bitmaps internally, stores them as PNG files (using the
15 * sequential write code) then reads them back (using the sequential 15 * sequential write code) then reads them back (using the sequential
16 * read code) and validates that the result has the correct data. 16 * read code) and validates that the result has the correct data.
17 * 17 *
18 * The program can be modified and extended to test the correctness of 18 * The program can be modified and extended to test the correctness of
19 * transformations performed by libpng. 19 * transformations performed by libpng.
20 */ 20 */
21 21
22#define _POSIX_SOURCE 1 22#define _POSIX_SOURCE 1
23#define _ISOC99_SOURCE 1 /* For floating point */ 23#define _ISOC99_SOURCE 1 /* For floating point */
24#define _GNU_SOURCE 1 /* For the floating point exception extension */ 24#define _GNU_SOURCE 1 /* For the floating point exception extension */
25 25
26#include <signal.h> 26#include <signal.h>
27 27
28#ifdef HAVE_FEENABLEEXCEPT 28#ifdef HAVE_FEENABLEEXCEPT
29# include <fenv.h> 29# include <fenv.h>
30#endif 30#endif
31 31
32/* Define the following to use this test against your installed libpng, rather 32/* Define the following to use this test against your installed libpng, rather
33 * than the one being built here: 33 * than the one being built here:
34 */ 34 */
35#ifdef PNG_FREESTANDING_TESTS 35#ifdef PNG_FREESTANDING_TESTS
36# include <png.h> 36# include <png.h>
37#else 37#else
38# include "../../png.h" 38# include "../../png.h"
39#endif 39#endif
40 40
41#if PNG_LIBPNG_VER < 10500 41#if PNG_LIBPNG_VER < 10500
42/* This deliberately lacks the PNG_CONST. */ 42/* This deliberately lacks the PNG_CONST. */
43typedef png_byte *png_const_bytep; 43typedef png_byte *png_const_bytep;
44 44
45/* This is copied from 1.5.1 png.h: */ 45/* This is copied from 1.5.1 png.h: */
46#define PNG_INTERLACE_ADAM7_PASSES 7 46#define PNG_INTERLACE_ADAM7_PASSES 7
47#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7) 47#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
48#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7) 48#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
49#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) 49#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
50#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) 50#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
51#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\ 51#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
52 -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass)) 52 -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
53#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\ 53#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
54 -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass)) 54 -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
55#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ 55#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
56 (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass)) 56 (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
57#define PNG_COL_FROM_PASS_COL(xIn, pass) \ 57#define PNG_COL_FROM_PASS_COL(xIn, pass) \
58 (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass)) 58 (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
59#define PNG_PASS_MASK(pass,off) ( \ 59#define PNG_PASS_MASK(pass,off) ( \
60 ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \ 60 ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
61 ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U)) 61 ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
62#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ 62#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
63 ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) 63 ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
64#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ 64#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
65 ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) 65 ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
66 66
67/* These are needed too for the default build: */ 67/* These are needed too for the default build: */
68#define PNG_WRITE_16BIT_SUPPORTED 68#define PNG_WRITE_16BIT_SUPPORTED
69#define PNG_READ_16BIT_SUPPORTED 69#define PNG_READ_16BIT_SUPPORTED
70 70
71/* This comes from pnglibconf.h afer 1.5: */ 71/* This comes from pnglibconf.h afer 1.5: */
72#define PNG_FP_1 100000 72#define PNG_FP_1 100000
73#define PNG_GAMMA_THRESHOLD_FIXED\ 73#define PNG_GAMMA_THRESHOLD_FIXED\
74 ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1)) 74 ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
75#endif 75#endif
76 76
77#include "zlib.h" /* For crc32 */ 77#include "zlib.h" /* For crc32 */
78 78
79#include <float.h> /* For floating point constants */ 79#include <float.h> /* For floating point constants */
80#include <stdlib.h> /* For malloc */ 80#include <stdlib.h> /* For malloc */
81#include <string.h> /* For memcpy, memset */ 81#include <string.h> /* For memcpy, memset */
82#include <math.h> /* For floor */ 82#include <math.h> /* For floor */
83 83
84/* Unused formal parameter errors are removed using the following macro which is 84/* Unused formal parameter errors are removed using the following macro which is
85 * expected to have no bad effects on performance. 85 * expected to have no bad effects on performance.
86 */ 86 */
87#ifndef UNUSED 87#ifndef UNUSED
88# if defined(__GNUC__) || defined(_MSC_VER) 88# if defined(__GNUC__) || defined(_MSC_VER)
89# define UNUSED(param) (void)param; 89# define UNUSED(param) (void)param;
90# else 90# else
91# define UNUSED(param) 91# define UNUSED(param)
92# endif 92# endif
93#endif 93#endif
94 94
95/***************************** EXCEPTION HANDLING *****************************/ 95/***************************** EXCEPTION HANDLING *****************************/
96#include "../visupng/cexcept.h" 96#include "../visupng/cexcept.h"
97 97
98#ifdef __cplusplus 98#ifdef __cplusplus
99# define this not_the_cpp_this 99# define this not_the_cpp_this
100# define new not_the_cpp_new 100# define new not_the_cpp_new
101# define voidcast(type, value) static_cast<type>(value) 101# define voidcast(type, value) static_cast<type>(value)
102#else 102#else
103# define voidcast(type, value) (value) 103# define voidcast(type, value) (value)
104#endif /* __cplusplus */ 104#endif /* __cplusplus */
105 105
106struct png_store; 106struct png_store;
107define_exception_type(struct png_store*); 107define_exception_type(struct png_store*);
108 108
109/* The following are macros to reduce typing everywhere where the well known 109/* The following are macros to reduce typing everywhere where the well known
110 * name 'the_exception_context' must be defined. 110 * name 'the_exception_context' must be defined.
111 */ 111 */
112#define anon_context(ps) struct exception_context *the_exception_context = \ 112#define anon_context(ps) struct exception_context *the_exception_context = \
113 &(ps)->exception_context 113 &(ps)->exception_context
114#define context(ps,fault) anon_context(ps); png_store *fault 114#define context(ps,fault) anon_context(ps); png_store *fault
115 115
116/******************************* UTILITIES ************************************/ 116/******************************* UTILITIES ************************************/
117/* Error handling is particularly problematic in production code - error 117/* Error handling is particularly problematic in production code - error
118 * handlers often themselves have bugs which lead to programs that detect 118 * handlers often themselves have bugs which lead to programs that detect
119 * minor errors crashing. The following functions deal with one very 119 * minor errors crashing. The following functions deal with one very
120 * common class of errors in error handlers - attempting to format error or 120 * common class of errors in error handlers - attempting to format error or
121 * warning messages into buffers that are too small. 121 * warning messages into buffers that are too small.
122 */ 122 */
123static size_t safecat(char *buffer, size_t bufsize, size_t pos, 123static size_t safecat(char *buffer, size_t bufsize, size_t pos,
124 PNG_CONST char *cat) 124 PNG_CONST char *cat)
125{ 125{
126 while (pos < bufsize && cat != NULL && *cat != 0) 126 while (pos < bufsize && cat != NULL && *cat != 0)
127 buffer[pos++] = *cat++; 127 buffer[pos++] = *cat++;
128 128
129 if (pos >= bufsize) 129 if (pos >= bufsize)
130 pos = bufsize-1; 130 pos = bufsize-1;
131 131
132 buffer[pos] = 0; 132 buffer[pos] = 0;
133 return pos; 133 return pos;
134} 134}
135 135
136static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n) 136static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n)
137{ 137{
138 char number[64]; 138 char number[64];
139 sprintf(number, "%d", n); 139 sprintf(number, "%d", n);
140 return safecat(buffer, bufsize, pos, number); 140 return safecat(buffer, bufsize, pos, number);
141} 141}
142 142
143#ifdef PNG_READ_TRANSFORMS_SUPPORTED 143#ifdef PNG_READ_TRANSFORMS_SUPPORTED
144static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d, 144static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d,
145 int precision) 145 int precision)
146{ 146{
147 char number[64]; 147 char number[64];
148 sprintf(number, "%.*f", precision, d); 148 sprintf(number, "%.*f", precision, d);
149 return safecat(buffer, bufsize, pos, number); 149 return safecat(buffer, bufsize, pos, number);
150} 150}
151#endif 151#endif
152 152
153static PNG_CONST char invalid[] = "invalid"; 153static PNG_CONST char invalid[] = "invalid";
154static PNG_CONST char sep[] = ": "; 154static PNG_CONST char sep[] = ": ";
155 155
156static PNG_CONST char *colour_types[8] = 156static PNG_CONST char *colour_types[8] =
157{ 157{
158 "grayscale", invalid, "truecolour", "indexed-colour", 158 "grayscale", invalid, "truecolour", "indexed-colour",
159 "grayscale with alpha", invalid, "truecolour with alpha", invalid 159 "grayscale with alpha", invalid, "truecolour with alpha", invalid
160}; 160};
161 161
162/* Convert a double precision value to fixed point. */ 162/* Convert a double precision value to fixed point. */
163static png_fixed_point 163static png_fixed_point
164fix(double d) 164fix(double d)
165{ 165{
166 d = floor(d * PNG_FP_1 + .5); 166 d = floor(d * PNG_FP_1 + .5);
167 return (png_fixed_point)d; 167 return (png_fixed_point)d;
168} 168}
169 169
170/* Generate random bytes. This uses a boring repeatable algorithm and it 170/* Generate random bytes. This uses a boring repeatable algorithm and it
171 * is implemented here so that it gives the same set of numbers on every 171 * is implemented here so that it gives the same set of numbers on every
172 * architecture. It's a linear congruential generator (Knuth or Sedgewick 172 * architecture. It's a linear congruential generator (Knuth or Sedgewick
173 * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and 173 * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
174 * Hill, "The Art of Electronics". 174 * Hill, "The Art of Electronics".
175 */ 175 */
176static void 176static void
177make_random_bytes(png_uint_32* seed, void* pv, size_t size) 177make_random_bytes(png_uint_32* seed, void* pv, size_t size)
178{ 178{
179 png_uint_32 u0 = seed[0], u1 = seed[1]; 179 png_uint_32 u0 = seed[0], u1 = seed[1];
180 png_bytep bytes = voidcast(png_bytep, pv); 180 png_bytep bytes = voidcast(png_bytep, pv);
181 181
182 /* There are thirty three bits, the next bit in the sequence is bit-33 XOR 182 /* There are thirty three bits, the next bit in the sequence is bit-33 XOR
183 * bit-20. The top 1 bit is in u1, the bottom 32 are in u0. 183 * bit-20. The top 1 bit is in u1, the bottom 32 are in u0.
184 */ 184 */
185 size_t i; 185 size_t i;
186 for (i=0; i<size; ++i) 186 for (i=0; i<size; ++i)
187 { 187 {
188 /* First generate 8 new bits then shift them in at the end. */ 188 /* First generate 8 new bits then shift them in at the end. */
189 png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff; 189 png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
190 u1 <<= 8; 190 u1 <<= 8;
191 u1 |= u0 >> 24; 191 u1 |= u0 >> 24;
192 u0 <<= 8; 192 u0 <<= 8;
193 u0 |= u; 193 u0 |= u;
194 *bytes++ = (png_byte)u; 194 *bytes++ = (png_byte)u;
195 } 195 }
196 196
197 seed[0] = u0; 197 seed[0] = u0;
198 seed[1] = u1; 198 seed[1] = u1;
199} 199}
200 200
201static void 201static void
202make_four_random_bytes(png_uint_32* seed, png_bytep bytes) 202make_four_random_bytes(png_uint_32* seed, png_bytep bytes)
203{ 203{
204 make_random_bytes(seed, bytes, 4); 204 make_random_bytes(seed, bytes, 4);
205} 205}
206 206
207static void 207static void
208randomize(void *pv, size_t size) 208randomize(void *pv, size_t size)
209{ 209{
210 static png_uint_32 random_seed[2] = {0x56789abc, 0xd}; 210 static png_uint_32 random_seed[2] = {0x56789abc, 0xd};
211 make_random_bytes(random_seed, pv, size); 211 make_random_bytes(random_seed, pv, size);
212} 212}
213 213
214#define RANDOMIZE(this) randomize(&(this), sizeof (this)) 214#define RANDOMIZE(this) randomize(&(this), sizeof (this))
215 215
216static unsigned int 216static unsigned int
217random_mod(unsigned int max) 217random_mod(unsigned int max)
218{ 218{
219 unsigned int x; 219 unsigned int x;
220 220
221 RANDOMIZE(x); 221 RANDOMIZE(x);
222 222
223 return x % max; /* 0 .. max-1 */ 223 return x % max; /* 0 .. max-1 */
224} 224}
225 225
226static int 226static int
227random_choice(void) 227random_choice(void)
228{ 228{
229 unsigned char x; 229 unsigned char x;
230 230
231 RANDOMIZE(x); 231 RANDOMIZE(x);
232 232
233 return x & 1; 233 return x & 1;
234} 234}
235 235
236/* A numeric ID based on PNG file characteristics. The 'do_interlace' field 236/* A numeric ID based on PNG file characteristics. The 'do_interlace' field
237 * simply records whether pngvalid did the interlace itself or whether it 237 * simply records whether pngvalid did the interlace itself or whether it
238 * was done by libpng. Width and height must be less than 256. 'palette' is an 238 * was done by libpng. Width and height must be less than 256. 'palette' is an
239 * index of the palette to use for formats with a palette (0 otherwise.) 239 * index of the palette to use for formats with a palette (0 otherwise.)
240 */ 240 */
241#define FILEID(col, depth, palette, interlace, width, height, do_interlace) \ 241#define FILEID(col, depth, palette, interlace, width, height, do_interlace) \
242 ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \ 242 ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \
243 (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24))) 243 (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24)))
244 244
245#define COL_FROM_ID(id) ((png_byte)((id)& 0x7U)) 245#define COL_FROM_ID(id) ((png_byte)((id)& 0x7U))
246#define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU)) 246#define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU))
247#define PALETTE_FROM_ID(id) ((int)(((id) >> 8) & 0x1f)) 247#define PALETTE_FROM_ID(id) ((int)(((id) >> 8) & 0x1f))
248#define INTERLACE_FROM_ID(id) ((int)(((id) >> 13) & 0x3)) 248#define INTERLACE_FROM_ID(id) ((int)(((id) >> 13) & 0x3))
249#define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1)) 249#define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1))
250#define WIDTH_FROM_ID(id) (((id)>>16) & 0xff) 250#define WIDTH_FROM_ID(id) (((id)>>16) & 0xff)
251#define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff) 251#define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff)
252 252
253/* Utility to construct a standard name for a standard image. */ 253/* Utility to construct a standard name for a standard image. */
254static size_t 254static size_t
255standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type, 255standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type,
256 int bit_depth, int npalette, int interlace_type, 256 int bit_depth, int npalette, int interlace_type,
257 png_uint_32 w, png_uint_32 h, int do_interlace) 257 png_uint_32 w, png_uint_32 h, int do_interlace)
258{ 258{
259 pos = safecat(buffer, bufsize, pos, colour_types[colour_type]); 259 pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);
260 if (npalette > 0) 260 if (npalette > 0)
261 { 261 {
262 pos = safecat(buffer, bufsize, pos, "["); 262 pos = safecat(buffer, bufsize, pos, "[");
263 pos = safecatn(buffer, bufsize, pos, npalette); 263 pos = safecatn(buffer, bufsize, pos, npalette);
264 pos = safecat(buffer, bufsize, pos, "]"); 264 pos = safecat(buffer, bufsize, pos, "]");
265 } 265 }
266 pos = safecat(buffer, bufsize, pos, " "); 266 pos = safecat(buffer, bufsize, pos, " ");
267 pos = safecatn(buffer, bufsize, pos, bit_depth); 267 pos = safecatn(buffer, bufsize, pos, bit_depth);
268 pos = safecat(buffer, bufsize, pos, " bit"); 268 pos = safecat(buffer, bufsize, pos, " bit");
269 269
270 if (interlace_type != PNG_INTERLACE_NONE) 270 if (interlace_type != PNG_INTERLACE_NONE)
271 { 271 {
272 pos = safecat(buffer, bufsize, pos, " interlaced"); 272 pos = safecat(buffer, bufsize, pos, " interlaced");
273 if (do_interlace) 273 if (do_interlace)
274 pos = safecat(buffer, bufsize, pos, "(pngvalid)"); 274 pos = safecat(buffer, bufsize, pos, "(pngvalid)");
275 else 275 else
276 pos = safecat(buffer, bufsize, pos, "(libpng)"); 276 pos = safecat(buffer, bufsize, pos, "(libpng)");
277 } 277 }
278 278
279 if (w > 0 || h > 0) 279 if (w > 0 || h > 0)
280 { 280 {
281 pos = safecat(buffer, bufsize, pos, " "); 281 pos = safecat(buffer, bufsize, pos, " ");
282 pos = safecatn(buffer, bufsize, pos, w); 282 pos = safecatn(buffer, bufsize, pos, w);
283 pos = safecat(buffer, bufsize, pos, "x"); 283 pos = safecat(buffer, bufsize, pos, "x");
284 pos = safecatn(buffer, bufsize, pos, h); 284 pos = safecatn(buffer, bufsize, pos, h);
285 } 285 }
286 286
287 return pos; 287 return pos;
288} 288}
289 289
290static size_t 290static size_t
291standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id) 291standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)
292{ 292{
293 return standard_name(buffer, bufsize, pos, COL_FROM_ID(id), 293 return standard_name(buffer, bufsize, pos, COL_FROM_ID(id),
294 DEPTH_FROM_ID(id), PALETTE_FROM_ID(id), INTERLACE_FROM_ID(id), 294 DEPTH_FROM_ID(id), PALETTE_FROM_ID(id), INTERLACE_FROM_ID(id),
295 WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id)); 295 WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id));
296} 296}
297 297
298/* Convenience API and defines to list valid formats. Note that 16 bit read and 298/* Convenience API and defines to list valid formats. Note that 16 bit read and
299 * write support is required to do 16 bit read tests (we must be able to make a 299 * write support is required to do 16 bit read tests (we must be able to make a
300 * 16 bit image to test!) 300 * 16 bit image to test!)
301 */ 301 */
302#ifdef PNG_WRITE_16BIT_SUPPORTED 302#ifdef PNG_WRITE_16BIT_SUPPORTED
303# define WRITE_BDHI 4 303# define WRITE_BDHI 4
304# ifdef PNG_READ_16BIT_SUPPORTED 304# ifdef PNG_READ_16BIT_SUPPORTED
305# define READ_BDHI 4 305# define READ_BDHI 4
306# define DO_16BIT 306# define DO_16BIT
307# endif 307# endif
308#else 308#else
309# define WRITE_BDHI 3 309# define WRITE_BDHI 3
310#endif 310#endif
311#ifndef DO_16BIT 311#ifndef DO_16BIT
312# define READ_BDHI 3 312# define READ_BDHI 3
313#endif 313#endif
314 314
315/* The following defines the number of different palettes to generate for 315/* The following defines the number of different palettes to generate for
316 * each log bit depth of a colour type 3 standard image. 316 * each log bit depth of a colour type 3 standard image.
317 */ 317 */
318#define PALETTE_COUNT(bit_depth) ((bit_depth) > 4 ? 1 : 16) 318#define PALETTE_COUNT(bit_depth) ((bit_depth) > 4 ? 1 : 16)
319 319
320static int 320static int
321next_format(png_bytep colour_type, png_bytep bit_depth, int* palette_number) 321next_format(png_bytep colour_type, png_bytep bit_depth, int* palette_number)
322{ 322{
323 if (*bit_depth == 0) 323 if (*bit_depth == 0)
324 { 324 {
325 *colour_type = 0, *bit_depth = 1, *palette_number = 0; 325 *colour_type = 0, *bit_depth = 1, *palette_number = 0;
326 return 1; 326 return 1;
327 } 327 }
328 328
329 if (*colour_type == 3) 329 if (*colour_type == 3)
330 { 330 {
331 /* Add multiple palettes for colour type 3. */ 331 /* Add multiple palettes for colour type 3. */
332 if (++*palette_number < PALETTE_COUNT(*bit_depth)) 332 if (++*palette_number < PALETTE_COUNT(*bit_depth))
333 return 1; 333 return 1;
334 334
335 *palette_number = 0; 335 *palette_number = 0;
336 } 336 }
337 337
338 *bit_depth = (png_byte)(*bit_depth << 1); 338 *bit_depth = (png_byte)(*bit_depth << 1);
339 339
340 /* Palette images are restricted to 8 bit depth */ 340 /* Palette images are restricted to 8 bit depth */
341 if (*bit_depth <= 8 341 if (*bit_depth <= 8
342# ifdef DO_16BIT 342# ifdef DO_16BIT
343 || (*colour_type != 3 && *bit_depth <= 16) 343 || (*colour_type != 3 && *bit_depth <= 16)
344# endif 344# endif
345 ) 345 )
346 return 1; 346 return 1;
347 347
348 /* Move to the next color type, or return 0 at the end. */ 348 /* Move to the next color type, or return 0 at the end. */
349 switch (*colour_type) 349 switch (*colour_type)
350 { 350 {
351 case 0: 351 case 0:
352 *colour_type = 2; 352 *colour_type = 2;
353 *bit_depth = 8; 353 *bit_depth = 8;
354 return 1; 354 return 1;
355 355
356 case 2: 356 case 2:
357 *colour_type = 3; 357 *colour_type = 3;
358 *bit_depth = 1; 358 *bit_depth = 1;
359 return 1; 359 return 1;
360 360
361 case 3: 361 case 3:
362 *colour_type = 4; 362 *colour_type = 4;
363 *bit_depth = 8; 363 *bit_depth = 8;
364 return 1; 364 return 1;
365 365
366 case 4: 366 case 4:
367 *colour_type = 6; 367 *colour_type = 6;
368 *bit_depth = 8; 368 *bit_depth = 8;
369 return 1; 369 return 1;
370 370
371 default: 371 default:
372 return 0; 372 return 0;
373 } 373 }
374} 374}
375 375
376#ifdef PNG_READ_TRANSFORMS_SUPPORTED 376#ifdef PNG_READ_TRANSFORMS_SUPPORTED
377static unsigned int 377static unsigned int
378sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth, 378sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth,
379 png_uint_32 x, unsigned int sample_index) 379 png_uint_32 x, unsigned int sample_index)
380{ 380{
381 png_uint_32 bit_index, result; 381 png_uint_32 bit_index, result;
382 382
383 /* Find a sample index for the desired sample: */ 383 /* Find a sample index for the desired sample: */
384 x *= bit_depth; 384 x *= bit_depth;
385 bit_index = x; 385 bit_index = x;
386 386
387 if ((colour_type & 1) == 0) /* !palette */ 387 if ((colour_type & 1) == 0) /* !palette */
388 { 388 {
389 if (colour_type & 2) 389 if (colour_type & 2)
390 bit_index *= 3; 390 bit_index *= 3;
391 391
392 if (colour_type & 4) 392 if (colour_type & 4)
393 bit_index += x; /* Alpha channel */ 393 bit_index += x; /* Alpha channel */
394 394
395 /* Multiple channels; select one: */ 395 /* Multiple channels; select one: */
396 if (colour_type & (2+4)) 396 if (colour_type & (2+4))
397 bit_index += sample_index * bit_depth; 397 bit_index += sample_index * bit_depth;
398 } 398 }
399 399
400 /* Return the sample from the row as an integer. */ 400 /* Return the sample from the row as an integer. */
401 row += bit_index >> 3; 401 row += bit_index >> 3;
402 result = *row; 402 result = *row;
403 403
404 if (bit_depth == 8) 404 if (bit_depth == 8)
405 return result; 405 return result;
406 406
407 else if (bit_depth > 8) 407 else if (bit_depth > 8)
408 return (result << 8) + *++row; 408 return (result << 8) + *++row;
409 409
410 /* Less than 8 bits per sample. */ 410 /* Less than 8 bits per sample. */
411 bit_index &= 7; 411 bit_index &= 7;
412 return (result >> (8-bit_index-bit_depth)) & ((1U<<bit_depth)-1); 412 return (result >> (8-bit_index-bit_depth)) & ((1U<<bit_depth)-1);
413} 413}
414#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 414#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
415 415
416/* Copy a single pixel, of a given size, from one buffer to another - 416/* Copy a single pixel, of a given size, from one buffer to another -
417 * while this is basically bit addressed there is an implicit assumption 417 * while this is basically bit addressed there is an implicit assumption
418 * that pixels 8 or more bits in size are byte aligned and that pixels 418 * that pixels 8 or more bits in size are byte aligned and that pixels
419 * do not otherwise cross byte boundaries. (This is, so far as I know, 419 * do not otherwise cross byte boundaries. (This is, so far as I know,
420 * universally true in bitmap computer graphics. [JCB 20101212]) 420 * universally true in bitmap computer graphics. [JCB 20101212])
421 * 421 *
422 * NOTE: The to and from buffers may be the same. 422 * NOTE: The to and from buffers may be the same.
423 */ 423 */
424static void 424static void
425pixel_copy(png_bytep toBuffer, png_uint_32 toIndex, 425pixel_copy(png_bytep toBuffer, png_uint_32 toIndex,
426 png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize) 426 png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize)
427{ 427{
428 /* Assume we can multiply by 'size' without overflow because we are 428 /* Assume we can multiply by 'size' without overflow because we are
429 * just working in a single buffer. 429 * just working in a single buffer.
430 */ 430 */
431 toIndex *= pixelSize; 431 toIndex *= pixelSize;
432 fromIndex *= pixelSize; 432 fromIndex *= pixelSize;
433 if (pixelSize < 8) /* Sub-byte */ 433 if (pixelSize < 8) /* Sub-byte */
434 { 434 {
435 /* Mask to select the location of the copied pixel: */ 435 /* Mask to select the location of the copied pixel: */
436 unsigned int destMask = ((1U<<pixelSize)-1) << (8-pixelSize-(toIndex&7)); 436 unsigned int destMask = ((1U<<pixelSize)-1) << (8-pixelSize-(toIndex&7));
437 /* The following read the entire pixels and clears the extra: */ 437 /* The following read the entire pixels and clears the extra: */
438 unsigned int destByte = toBuffer[toIndex >> 3] & ~destMask; 438 unsigned int destByte = toBuffer[toIndex >> 3] & ~destMask;
439 unsigned int sourceByte = fromBuffer[fromIndex >> 3]; 439 unsigned int sourceByte = fromBuffer[fromIndex >> 3];
440 440
441 /* Don't rely on << or >> supporting '0' here, just in case: */ 441 /* Don't rely on << or >> supporting '0' here, just in case: */
442 fromIndex &= 7; 442 fromIndex &= 7;
443 if (fromIndex > 0) sourceByte <<= fromIndex; 443 if (fromIndex > 0) sourceByte <<= fromIndex;
444 if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7; 444 if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7;
445 445
446 toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask)); 446 toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask));
447 } 447 }
448 else /* One or more bytes */ 448 else /* One or more bytes */
449 memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3); 449 memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3);
450} 450}
451 451
452/* Copy a complete row of pixels, taking into account potential partial 452/* Copy a complete row of pixels, taking into account potential partial
453 * bytes at the end. 453 * bytes at the end.
454 */ 454 */
455static void 455static void
456row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth) 456row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth)
457{ 457{
458 memcpy(toBuffer, fromBuffer, bitWidth >> 3); 458 memcpy(toBuffer, fromBuffer, bitWidth >> 3);
459 459
460 if ((bitWidth & 7) != 0) 460 if ((bitWidth & 7) != 0)
461 { 461 {
462 unsigned int mask; 462 unsigned int mask;
463 463
464 toBuffer += bitWidth >> 3; 464 toBuffer += bitWidth >> 3;
465 fromBuffer += bitWidth >> 3; 465 fromBuffer += bitWidth >> 3;
466 /* The remaining bits are in the top of the byte, the mask is the bits to 466 /* The remaining bits are in the top of the byte, the mask is the bits to
467 * retain. 467 * retain.
468 */ 468 */
469 mask = 0xff >> (bitWidth & 7); 469 mask = 0xff >> (bitWidth & 7);
470 *toBuffer = (png_byte)((*toBuffer & mask) | (*fromBuffer & ~mask)); 470 *toBuffer = (png_byte)((*toBuffer & mask) | (*fromBuffer & ~mask));
471 } 471 }
472} 472}
473 473
474/* Compare pixels - they are assumed to start at the first byte in the 474/* Compare pixels - they are assumed to start at the first byte in the
475 * given buffers. 475 * given buffers.
476 */ 476 */
477static int 477static int
478pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width) 478pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width)
479{ 479{
480#if PNG_LIBPNG_VER < 10506 480#if PNG_LIBPNG_VER < 10506
481 if (memcmp(pa, pb, bit_width>>3) == 0) 481 if (memcmp(pa, pb, bit_width>>3) == 0)
482 { 482 {
483 png_uint_32 p; 483 png_uint_32 p;
484 484
485 if ((bit_width & 7) == 0) return 0; 485 if ((bit_width & 7) == 0) return 0;
486 486
487 /* Ok, any differences? */ 487 /* Ok, any differences? */
488 p = pa[bit_width >> 3]; 488 p = pa[bit_width >> 3];
489 p ^= pb[bit_width >> 3]; 489 p ^= pb[bit_width >> 3];
490 490
491 if (p == 0) return 0; 491 if (p == 0) return 0;
492 492
493 /* There are, but they may not be significant, remove the bits 493 /* There are, but they may not be significant, remove the bits
494 * after the end (the low order bits in PNG.) 494 * after the end (the low order bits in PNG.)
495 */ 495 */
496 bit_width &= 7; 496 bit_width &= 7;
497 p >>= 8-bit_width; 497 p >>= 8-bit_width;
498 498
499 if (p == 0) return 0; 499 if (p == 0) return 0;
500 } 500 }
501#else 501#else
502 /* From libpng-1.5.6 the overwrite should be fixed, so compare the trailing 502 /* From libpng-1.5.6 the overwrite should be fixed, so compare the trailing
503 * bits too: 503 * bits too:
504 */ 504 */
505 if (memcmp(pa, pb, (bit_width+7)>>3) == 0) 505 if (memcmp(pa, pb, (bit_width+7)>>3) == 0)
506 return 0; 506 return 0;
507#endif 507#endif
508 508
509 /* Return the index of the changed byte. */ 509 /* Return the index of the changed byte. */
510 { 510 {
511 png_uint_32 where = 0; 511 png_uint_32 where = 0;
512 512
513 while (pa[where] == pb[where]) ++where; 513 while (pa[where] == pb[where]) ++where;
514 return 1+where; 514 return 1+where;
515 } 515 }
516} 516}
517 517
518/*************************** BASIC PNG FILE WRITING ***************************/ 518/*************************** BASIC PNG FILE WRITING ***************************/
519/* A png_store takes data from the sequential writer or provides data 519/* A png_store takes data from the sequential writer or provides data
520 * to the sequential reader. It can also store the result of a PNG 520 * to the sequential reader. It can also store the result of a PNG
521 * write for later retrieval. 521 * write for later retrieval.
522 */ 522 */
523#define STORE_BUFFER_SIZE 500 /* arbitrary */ 523#define STORE_BUFFER_SIZE 500 /* arbitrary */
524typedef struct png_store_buffer 524typedef struct png_store_buffer
525{ 525{
526 struct png_store_buffer* prev; /* NOTE: stored in reverse order */ 526 struct png_store_buffer* prev; /* NOTE: stored in reverse order */
527 png_byte buffer[STORE_BUFFER_SIZE]; 527 png_byte buffer[STORE_BUFFER_SIZE];
528} png_store_buffer; 528} png_store_buffer;
529 529
530#define FILE_NAME_SIZE 64 530#define FILE_NAME_SIZE 64
531 531
532typedef struct store_palette_entry /* record of a single palette entry */ 532typedef struct store_palette_entry /* record of a single palette entry */
533{ 533{
534 png_byte red; 534 png_byte red;
535 png_byte green; 535 png_byte green;
536 png_byte blue; 536 png_byte blue;
537 png_byte alpha; 537 png_byte alpha;
538} store_palette_entry, store_palette[256]; 538} store_palette_entry, store_palette[256];
539 539
540typedef struct png_store_file 540typedef struct png_store_file
541{ 541{
542 struct png_store_file* next; /* as many as you like... */ 542 struct png_store_file* next; /* as many as you like... */
543 char name[FILE_NAME_SIZE]; 543 char name[FILE_NAME_SIZE];
544 png_uint_32 id; /* must be correct (see FILEID) */ 544 png_uint_32 id; /* must be correct (see FILEID) */
545 png_size_t datacount; /* In this (the last) buffer */ 545 png_size_t datacount; /* In this (the last) buffer */
546 png_store_buffer data; /* Last buffer in file */ 546 png_store_buffer data; /* Last buffer in file */
547 int npalette; /* Number of entries in palette */ 547 int npalette; /* Number of entries in palette */
548 store_palette_entry* palette; /* May be NULL */ 548 store_palette_entry* palette; /* May be NULL */
549} png_store_file; 549} png_store_file;
550 550
551/* The following is a pool of memory allocated by a single libpng read or write 551/* The following is a pool of memory allocated by a single libpng read or write
552 * operation. 552 * operation.
553 */ 553 */
554typedef struct store_pool 554typedef struct store_pool
555{ 555{
556 struct png_store *store; /* Back pointer */ 556 struct png_store *store; /* Back pointer */
557 struct store_memory *list; /* List of allocated memory */ 557 struct store_memory *list; /* List of allocated memory */
558 png_byte mark[4]; /* Before and after data */ 558 png_byte mark[4]; /* Before and after data */
559 559
560 /* Statistics for this run. */ 560 /* Statistics for this run. */
561 png_alloc_size_t max; /* Maximum single allocation */ 561 png_alloc_size_t max; /* Maximum single allocation */
562 png_alloc_size_t current; /* Current allocation */ 562 png_alloc_size_t current; /* Current allocation */
563 png_alloc_size_t limit; /* Highest current allocation */ 563 png_alloc_size_t limit; /* Highest current allocation */
564 png_alloc_size_t total; /* Total allocation */ 564 png_alloc_size_t total; /* Total allocation */
565 565
566 /* Overall statistics (retained across successive runs). */ 566 /* Overall statistics (retained across successive runs). */
567 png_alloc_size_t max_max; 567 png_alloc_size_t max_max;
568 png_alloc_size_t max_limit; 568 png_alloc_size_t max_limit;
569 png_alloc_size_t max_total; 569 png_alloc_size_t max_total;
570} store_pool; 570} store_pool;
571 571
572typedef struct png_store 572typedef struct png_store
573{ 573{
574 /* For cexcept.h exception handling - simply store one of these; 574 /* For cexcept.h exception handling - simply store one of these;
575 * the context is a self pointer but it may point to a different 575 * the context is a self pointer but it may point to a different
576 * png_store (in fact it never does in this program.) 576 * png_store (in fact it never does in this program.)
577 */ 577 */
578 struct exception_context 578 struct exception_context
579 exception_context; 579 exception_context;
580 580
581 unsigned int verbose :1; 581 unsigned int verbose :1;
582 unsigned int treat_warnings_as_errors :1; 582 unsigned int treat_warnings_as_errors :1;
583 unsigned int expect_error :1; 583 unsigned int expect_error :1;
584 unsigned int expect_warning :1; 584 unsigned int expect_warning :1;
585 unsigned int saw_warning :1; 585 unsigned int saw_warning :1;
586 unsigned int speed :1; 586 unsigned int speed :1;
587 unsigned int progressive :1; /* use progressive read */ 587 unsigned int progressive :1; /* use progressive read */
588 unsigned int validated :1; /* used as a temporary flag */ 588 unsigned int validated :1; /* used as a temporary flag */
589 int nerrors; 589 int nerrors;
590 int nwarnings; 590 int nwarnings;
591 char test[128]; /* Name of test */ 591 char test[128]; /* Name of test */
592 char error[256]; 592 char error[256];
593 593
594 /* Read fields */ 594 /* Read fields */
595 png_structp pread; /* Used to read a saved file */ 595 png_structp pread; /* Used to read a saved file */
596 png_infop piread; 596 png_infop piread;
597 png_store_file* current; /* Set when reading */ 597 png_store_file* current; /* Set when reading */
598 png_store_buffer* next; /* Set when reading */ 598 png_store_buffer* next; /* Set when reading */
599 png_size_t readpos; /* Position in *next */ 599 png_size_t readpos; /* Position in *next */
600 png_byte* image; /* Buffer for reading interlaced images */ 600 png_byte* image; /* Buffer for reading interlaced images */
601 png_size_t cb_image; /* Size of this buffer */ 601 png_size_t cb_image; /* Size of this buffer */
602 png_size_t cb_row; /* Row size of the image(s) */ 602 png_size_t cb_row; /* Row size of the image(s) */
603 png_uint_32 image_h; /* Number of rows in a single image */ 603 png_uint_32 image_h; /* Number of rows in a single image */
604 store_pool read_memory_pool; 604 store_pool read_memory_pool;
605 605
606 /* Write fields */ 606 /* Write fields */
607 png_store_file* saved; 607 png_store_file* saved;
608 png_structp pwrite; /* Used when writing a new file */ 608 png_structp pwrite; /* Used when writing a new file */
609 png_infop piwrite; 609 png_infop piwrite;
610 png_size_t writepos; /* Position in .new */ 610 png_size_t writepos; /* Position in .new */
611 char wname[FILE_NAME_SIZE]; 611 char wname[FILE_NAME_SIZE];
612 png_store_buffer new; /* The end of the new PNG file being written. */ 612 png_store_buffer new; /* The end of the new PNG file being written. */
613 store_pool write_memory_pool; 613 store_pool write_memory_pool;
614 store_palette_entry* palette; 614 store_palette_entry* palette;
615 int npalette; 615 int npalette;
616} png_store; 616} png_store;
617 617
618/* Initialization and cleanup */ 618/* Initialization and cleanup */
619static void 619static void
620store_pool_mark(png_bytep mark) 620store_pool_mark(png_bytep mark)
621{ 621{
622 static png_uint_32 store_seed[2] = { 0x12345678, 1}; 622 static png_uint_32 store_seed[2] = { 0x12345678, 1};
623 623
624 make_four_random_bytes(store_seed, mark); 624 make_four_random_bytes(store_seed, mark);
625} 625}
626 626
627/* Use this for random 32 bit values; this function makes sure the result is 627/* Use this for random 32 bit values; this function makes sure the result is
628 * non-zero. 628 * non-zero.
629 */ 629 */
630static png_uint_32 630static png_uint_32
631random_32(void) 631random_32(void)
632{ 632{
633 633
634 for(;;) 634 for(;;)
635 { 635 {
636 png_byte mark[4]; 636 png_byte mark[4];
637 png_uint_32 result; 637 png_uint_32 result;
638 638
639 store_pool_mark(mark); 639 store_pool_mark(mark);
640 result = png_get_uint_32(mark); 640 result = png_get_uint_32(mark);
641 641
642 if (result != 0) 642 if (result != 0)
643 return result; 643 return result;
644 } 644 }
645} 645}
646 646
647static void 647static void
648store_pool_init(png_store *ps, store_pool *pool) 648store_pool_init(png_store *ps, store_pool *pool)
649{ 649{
650 memset(pool, 0, sizeof *pool); 650 memset(pool, 0, sizeof *pool);
651 651
652 pool->store = ps; 652 pool->store = ps;
653 pool->list = NULL; 653 pool->list = NULL;
654 pool->max = pool->current = pool->limit = pool->total = 0; 654 pool->max = pool->current = pool->limit = pool->total = 0;
655 pool->max_max = pool->max_limit = pool->max_total = 0; 655 pool->max_max = pool->max_limit = pool->max_total = 0;
656 store_pool_mark(pool->mark); 656 store_pool_mark(pool->mark);
657} 657}
658 658
659static void 659static void
660store_init(png_store* ps) 660store_init(png_store* ps)
661{ 661{
662 memset(ps, 0, sizeof *ps); 662 memset(ps, 0, sizeof *ps);
663 init_exception_context(&ps->exception_context); 663 init_exception_context(&ps->exception_context);
664 store_pool_init(ps, &ps->read_memory_pool); 664 store_pool_init(ps, &ps->read_memory_pool);
665 store_pool_init(ps, &ps->write_memory_pool); 665 store_pool_init(ps, &ps->write_memory_pool);
666 ps->verbose = 0; 666 ps->verbose = 0;
667 ps->treat_warnings_as_errors = 0; 667 ps->treat_warnings_as_errors = 0;
668 ps->expect_error = 0; 668 ps->expect_error = 0;
669 ps->expect_warning = 0; 669 ps->expect_warning = 0;
670 ps->saw_warning = 0; 670 ps->saw_warning = 0;
671 ps->speed = 0; 671 ps->speed = 0;
672 ps->progressive = 0; 672 ps->progressive = 0;
673 ps->validated = 0; 673 ps->validated = 0;
674 ps->nerrors = ps->nwarnings = 0; 674 ps->nerrors = ps->nwarnings = 0;
675 ps->pread = NULL; 675 ps->pread = NULL;
676 ps->piread = NULL; 676 ps->piread = NULL;
677 ps->saved = ps->current = NULL; 677 ps->saved = ps->current = NULL;
678 ps->next = NULL; 678 ps->next = NULL;
679 ps->readpos = 0; 679 ps->readpos = 0;
680 ps->image = NULL; 680 ps->image = NULL;
681 ps->cb_image = 0; 681 ps->cb_image = 0;
682 ps->cb_row = 0; 682 ps->cb_row = 0;
683 ps->image_h = 0; 683 ps->image_h = 0;
684 ps->pwrite = NULL; 684 ps->pwrite = NULL;
685 ps->piwrite = NULL; 685 ps->piwrite = NULL;
686 ps->writepos = 0; 686 ps->writepos = 0;
687 ps->new.prev = NULL; 687 ps->new.prev = NULL;
688 ps->palette = NULL; 688 ps->palette = NULL;
689 ps->npalette = 0; 689 ps->npalette = 0;
690} 690}
691 691
692static void 692static void
693store_freebuffer(png_store_buffer* psb) 693store_freebuffer(png_store_buffer* psb)
694{ 694{
695 if (psb->prev) 695 if (psb->prev)
696 { 696 {
697 store_freebuffer(psb->prev); 697 store_freebuffer(psb->prev);
698 free(psb->prev); 698 free(psb->prev);
699 psb->prev = NULL; 699 psb->prev = NULL;
700 } 700 }
701} 701}
702 702
703static void 703static void
704store_freenew(png_store *ps) 704store_freenew(png_store *ps)
705{ 705{
706 store_freebuffer(&ps->new); 706 store_freebuffer(&ps->new);
707 ps->writepos = 0; 707 ps->writepos = 0;
708 if (ps->palette != NULL) 708 if (ps->palette != NULL)
709 { 709 {
710 free(ps->palette); 710 free(ps->palette);
711 ps->palette = NULL; 711 ps->palette = NULL;
712 ps->npalette = 0; 712 ps->npalette = 0;
713 } 713 }
714} 714}
715 715
716static void 716static void
717store_storenew(png_store *ps) 717store_storenew(png_store *ps)
718{ 718{
719 png_store_buffer *pb; 719 png_store_buffer *pb;
720 720
721 if (ps->writepos != STORE_BUFFER_SIZE) 721 if (ps->writepos != STORE_BUFFER_SIZE)
722 png_error(ps->pwrite, "invalid store call"); 722 png_error(ps->pwrite, "invalid store call");
723 723
724 pb = voidcast(png_store_buffer*, malloc(sizeof *pb)); 724 pb = voidcast(png_store_buffer*, malloc(sizeof *pb));
725 725
726 if (pb == NULL) 726 if (pb == NULL)
727 png_error(ps->pwrite, "store new: OOM"); 727 png_error(ps->pwrite, "store new: OOM");
728 728
729 *pb = ps->new; 729 *pb = ps->new;
730 ps->new.prev = pb; 730 ps->new.prev = pb;
731 ps->writepos = 0; 731 ps->writepos = 0;
732} 732}
733 733
734static void 734static void
735store_freefile(png_store_file **ppf) 735store_freefile(png_store_file **ppf)
736{ 736{
737 if (*ppf != NULL) 737 if (*ppf != NULL)
738 { 738 {
739 store_freefile(&(*ppf)->next); 739 store_freefile(&(*ppf)->next);
740 740
741 store_freebuffer(&(*ppf)->data); 741 store_freebuffer(&(*ppf)->data);
742 (*ppf)->datacount = 0; 742 (*ppf)->datacount = 0;
743 if ((*ppf)->palette != NULL) 743 if ((*ppf)->palette != NULL)
744 { 744 {
745 free((*ppf)->palette); 745 free((*ppf)->palette);
746 (*ppf)->palette = NULL; 746 (*ppf)->palette = NULL;
747 (*ppf)->npalette = 0; 747 (*ppf)->npalette = 0;
748 } 748 }
749 free(*ppf); 749 free(*ppf);
750 *ppf = NULL; 750 *ppf = NULL;
751 } 751 }
752} 752}
753 753
754/* Main interface to file storeage, after writing a new PNG file (see the API 754/* Main interface to file storeage, after writing a new PNG file (see the API
755 * below) call store_storefile to store the result with the given name and id. 755 * below) call store_storefile to store the result with the given name and id.
756 */ 756 */
757static void 757static void
758store_storefile(png_store *ps, png_uint_32 id) 758store_storefile(png_store *ps, png_uint_32 id)
759{ 759{
760 png_store_file *pf = voidcast(png_store_file*, malloc(sizeof *pf)); 760 png_store_file *pf = voidcast(png_store_file*, malloc(sizeof *pf));
761 if (pf == NULL) 761 if (pf == NULL)
762 png_error(ps->pwrite, "storefile: OOM"); 762 png_error(ps->pwrite, "storefile: OOM");
763 safecat(pf->name, sizeof pf->name, 0, ps->wname); 763 safecat(pf->name, sizeof pf->name, 0, ps->wname);
764 pf->id = id; 764 pf->id = id;
765 pf->data = ps->new; 765 pf->data = ps->new;
766 pf->datacount = ps->writepos; 766 pf->datacount = ps->writepos;
767 ps->new.prev = NULL; 767 ps->new.prev = NULL;
768 ps->writepos = 0; 768 ps->writepos = 0;
769 pf->palette = ps->palette; 769 pf->palette = ps->palette;
770 pf->npalette = ps->npalette; 770 pf->npalette = ps->npalette;
771 ps->palette = 0; 771 ps->palette = 0;
772 ps->npalette = 0; 772 ps->npalette = 0;
773 773
774 /* And save it. */ 774 /* And save it. */
775 pf->next = ps->saved; 775 pf->next = ps->saved;
776 ps->saved = pf; 776 ps->saved = pf;
777} 777}
778 778
779/* Generate an error message (in the given buffer) */ 779/* Generate an error message (in the given buffer) */
780static size_t 780static size_t
781store_message(png_store *ps, png_structp pp, char *buffer, size_t bufsize, 781store_message(png_store *ps, png_structp pp, char *buffer, size_t bufsize,
782 size_t pos, PNG_CONST char *msg) 782 size_t pos, PNG_CONST char *msg)
783{ 783{
784 if (pp != NULL && pp == ps->pread) 784 if (pp != NULL && pp == ps->pread)
785 { 785 {
786 /* Reading a file */ 786 /* Reading a file */
787 pos = safecat(buffer, bufsize, pos, "read: "); 787 pos = safecat(buffer, bufsize, pos, "read: ");
788 788
789 if (ps->current != NULL) 789 if (ps->current != NULL)
790 { 790 {
791 pos = safecat(buffer, bufsize, pos, ps->current->name); 791 pos = safecat(buffer, bufsize, pos, ps->current->name);
792 pos = safecat(buffer, bufsize, pos, sep); 792 pos = safecat(buffer, bufsize, pos, sep);
793 } 793 }
794 } 794 }
795 795
796 else if (pp != NULL && pp == ps->pwrite) 796 else if (pp != NULL && pp == ps->pwrite)
797 { 797 {
798 /* Writing a file */ 798 /* Writing a file */
799 pos = safecat(buffer, bufsize, pos, "write: "); 799 pos = safecat(buffer, bufsize, pos, "write: ");
800 pos = safecat(buffer, bufsize, pos, ps->wname); 800 pos = safecat(buffer, bufsize, pos, ps->wname);
801 pos = safecat(buffer, bufsize, pos, sep); 801 pos = safecat(buffer, bufsize, pos, sep);
802 } 802 }
803 803
804 else 804 else
805 { 805 {
806 /* Neither reading nor writing (or a memory error in struct delete) */ 806 /* Neither reading nor writing (or a memory error in struct delete) */
807 pos = safecat(buffer, bufsize, pos, "pngvalid: "); 807 pos = safecat(buffer, bufsize, pos, "pngvalid: ");
808 } 808 }
809 809
810 if (ps->test[0] != 0) 810 if (ps->test[0] != 0)
811 { 811 {
812 pos = safecat(buffer, bufsize, pos, ps->test); 812 pos = safecat(buffer, bufsize, pos, ps->test);
813 pos = safecat(buffer, bufsize, pos, sep); 813 pos = safecat(buffer, bufsize, pos, sep);
814 } 814 }
815 pos = safecat(buffer, bufsize, pos, msg); 815 pos = safecat(buffer, bufsize, pos, msg);
816 return pos; 816 return pos;
817} 817}
818 818
819/* Verbose output to the error stream: */ 819/* Verbose output to the error stream: */
820static void 820static void
821store_verbose(png_store *ps, png_structp pp, png_const_charp prefix, 821store_verbose(png_store *ps, png_structp pp, png_const_charp prefix,
822 png_const_charp message) 822 png_const_charp message)
823{ 823{
824 char buffer[512]; 824 char buffer[512];
825 825
826 if (prefix) 826 if (prefix)
827 fputs(prefix, stderr); 827 fputs(prefix, stderr);
828 828
829 (void)store_message(ps, pp, buffer, sizeof buffer, 0, message); 829 (void)store_message(ps, pp, buffer, sizeof buffer, 0, message);
830 fputs(buffer, stderr); 830 fputs(buffer, stderr);
831 fputc('\n', stderr); 831 fputc('\n', stderr);
832} 832}
833 833
834/* Log an error or warning - the relevant count is always incremented. */ 834/* Log an error or warning - the relevant count is always incremented. */
835static void 835static void
836store_log(png_store* ps, png_structp pp, png_const_charp message, int is_error) 836store_log(png_store* ps, png_structp pp, png_const_charp message, int is_error)
837{ 837{
838 /* The warning is copied to the error buffer if there are no errors and it is 838 /* The warning is copied to the error buffer if there are no errors and it is
839 * the first warning. The error is copied to the error buffer if it is the 839 * the first warning. The error is copied to the error buffer if it is the
840 * first error (overwriting any prior warnings). 840 * first error (overwriting any prior warnings).
841 */ 841 */
842 if (is_error ? (ps->nerrors)++ == 0 : 842 if (is_error ? (ps->nerrors)++ == 0 :
843 (ps->nwarnings)++ == 0 && ps->nerrors == 0) 843 (ps->nwarnings)++ == 0 && ps->nerrors == 0)
844 store_message(ps, pp, ps->error, sizeof ps->error, 0, message); 844 store_message(ps, pp, ps->error, sizeof ps->error, 0, message);
845 845
846 if (ps->verbose) 846 if (ps->verbose)
847 store_verbose(ps, pp, is_error ? "error: " : "warning: ", message); 847 store_verbose(ps, pp, is_error ? "error: " : "warning: ", message);
848} 848}
849 849
850/* Internal error function, called with a png_store but no libpng stuff. */ 850/* Internal error function, called with a png_store but no libpng stuff. */
851static void 851static void
852internal_error(png_store *ps, png_const_charp message) 852internal_error(png_store *ps, png_const_charp message)
853{ 853{
854 store_log(ps, NULL, message, 1 /* error */); 854 store_log(ps, NULL, message, 1 /* error */);
855 855
856 /* And finally throw an exception. */ 856 /* And finally throw an exception. */
857 { 857 {
858 struct exception_context *the_exception_context = &ps->exception_context; 858 struct exception_context *the_exception_context = &ps->exception_context;
859 Throw ps; 859 Throw ps;
860 } 860 }
861} 861}
862 862
863/* Functions to use as PNG callbacks. */ 863/* Functions to use as PNG callbacks. */
864static void 864static void
865store_error(png_structp pp, png_const_charp message) /* PNG_NORETURN */ 865store_error(png_structp pp, png_const_charp message) /* PNG_NORETURN */
866{ 866{
867 png_store *ps = voidcast(png_store*, png_get_error_ptr(pp)); 867 png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));
868 868
869 if (!ps->expect_error) 869 if (!ps->expect_error)
870 store_log(ps, pp, message, 1 /* error */); 870 store_log(ps, pp, message, 1 /* error */);
871 871
872 /* And finally throw an exception. */ 872 /* And finally throw an exception. */
873 { 873 {
874 struct exception_context *the_exception_context = &ps->exception_context; 874 struct exception_context *the_exception_context = &ps->exception_context;
875 Throw ps; 875 Throw ps;
876 } 876 }
877} 877}
878 878
879static void 879static void
880store_warning(png_structp pp, png_const_charp message) 880store_warning(png_structp pp, png_const_charp message)
881{ 881{
882 png_store *ps = voidcast(png_store*, png_get_error_ptr(pp)); 882 png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));
883 883
884 if (!ps->expect_warning) 884 if (!ps->expect_warning)
885 store_log(ps, pp, message, 0 /* warning */); 885 store_log(ps, pp, message, 0 /* warning */);
886 else 886 else
887 ps->saw_warning = 1; 887 ps->saw_warning = 1;
888} 888}
889 889
890/* These somewhat odd functions are used when reading an image to ensure that 890/* These somewhat odd functions are used when reading an image to ensure that
891 * the buffer is big enough, the png_structp is for errors. 891 * the buffer is big enough, the png_structp is for errors.
892 */ 892 */
893/* Return a single row from the correct image. */ 893/* Return a single row from the correct image. */
894static png_bytep 894static png_bytep
895store_image_row(PNG_CONST png_store* ps, png_structp pp, int nImage, 895store_image_row(PNG_CONST png_store* ps, png_structp pp, int nImage,
896 png_uint_32 y) 896 png_uint_32 y)
897{ 897{
898 png_size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2; 898 png_size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2;
899 899
900 if (ps->image == NULL) 900 if (ps->image == NULL)
901 png_error(pp, "no allocated image"); 901 png_error(pp, "no allocated image");
902 902
903 if (coffset + ps->cb_row + 3 > ps->cb_image) 903 if (coffset + ps->cb_row + 3 > ps->cb_image)
904 png_error(pp, "image too small"); 904 png_error(pp, "image too small");
905 905
906 return ps->image + coffset; 906 return ps->image + coffset;
907} 907}
908 908
909static void 909static void
910store_image_free(png_store *ps, png_structp pp) 910store_image_free(png_store *ps, png_structp pp)
911{ 911{
912 if (ps->image != NULL) 912 if (ps->image != NULL)
913 { 913 {
914 png_bytep image = ps->image; 914 png_bytep image = ps->image;
915 915
916 if (image[-1] != 0xed || image[ps->cb_image] != 0xfe) 916 if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)
917 { 917 {
918 if (pp != NULL) 918 if (pp != NULL)
919 png_error(pp, "png_store image overwrite (1)"); 919 png_error(pp, "png_store image overwrite (1)");
920 else 920 else
921 store_log(ps, NULL, "png_store image overwrite (2)", 1); 921 store_log(ps, NULL, "png_store image overwrite (2)", 1);
922 } 922 }
923 923
924 ps->image = NULL; 924 ps->image = NULL;
925 ps->cb_image = 0; 925 ps->cb_image = 0;
926 --image; 926 --image;
927 free(image); 927 free(image);
928 } 928 }
929} 929}
930 930
931static void 931static void
932store_ensure_image(png_store *ps, png_structp pp, int nImages, png_size_t cbRow, 932store_ensure_image(png_store *ps, png_structp pp, int nImages, png_size_t cbRow,
933 png_uint_32 cRows) 933 png_uint_32 cRows)
934{ 934{
935 png_size_t cb = nImages * cRows * (cbRow + 5); 935 png_size_t cb = nImages * cRows * (cbRow + 5);
936 936
937 if (ps->cb_image < cb) 937 if (ps->cb_image < cb)
938 { 938 {
939 png_bytep image; 939 png_bytep image;
940 940
941 store_image_free(ps, pp); 941 store_image_free(ps, pp);
942 942
943 /* The buffer is deliberately mis-aligned. */ 943 /* The buffer is deliberately mis-aligned. */
944 image = voidcast(png_bytep, malloc(cb+2)); 944 image = voidcast(png_bytep, malloc(cb+2));
945 if (image == NULL) 945 if (image == NULL)
946 { 946 {
947 /* Called from the startup - ignore the error for the moment. */ 947 /* Called from the startup - ignore the error for the moment. */
948 if (pp == NULL) 948 if (pp == NULL)
949 return; 949 return;
950 950
951 png_error(pp, "OOM allocating image buffer"); 951 png_error(pp, "OOM allocating image buffer");
952 } 952 }
953 953
954 /* These magic tags are used to detect overwrites above. */ 954 /* These magic tags are used to detect overwrites above. */
955 ++image; 955 ++image;
956 image[-1] = 0xed; 956 image[-1] = 0xed;
957 image[cb] = 0xfe; 957 image[cb] = 0xfe;
958 958
959 ps->image = image; 959 ps->image = image;
960 ps->cb_image = cb; 960 ps->cb_image = cb;
961 } 961 }
962 962
963 /* We have an adequate sized image; lay out the rows. There are 2 bytes at 963 /* We have an adequate sized image; lay out the rows. There are 2 bytes at
964 * the start and three at the end of each (this ensures that the row 964 * the start and three at the end of each (this ensures that the row
965 * alignment starts out odd - 2+1 and changes for larger images on each row.) 965 * alignment starts out odd - 2+1 and changes for larger images on each row.)
966 */ 966 */
967 ps->cb_row = cbRow; 967 ps->cb_row = cbRow;
968 ps->image_h = cRows; 968 ps->image_h = cRows;
969 969
970 /* For error checking, the whole buffer is set to 10110010 (0xb2 - 178). 970 /* For error checking, the whole buffer is set to 10110010 (0xb2 - 178).
971 * This deliberately doesn't match the bits in the size test image which are 971 * This deliberately doesn't match the bits in the size test image which are
972 * outside the image; these are set to 0xff (all 1). To make the row 972 * outside the image; these are set to 0xff (all 1). To make the row
973 * comparison work in the 'size' test case the size rows are pre-initialized 973 * comparison work in the 'size' test case the size rows are pre-initialized
974 * to the same value prior to calling 'standard_row'. 974 * to the same value prior to calling 'standard_row'.
975 */ 975 */
976 memset(ps->image, 178, cb); 976 memset(ps->image, 178, cb);
977 977
978 /* Then put in the marks. */ 978 /* Then put in the marks. */
979 while (--nImages >= 0) 979 while (--nImages >= 0)
980 { 980 {
981 png_uint_32 y; 981 png_uint_32 y;
982 982
983 for (y=0; y<cRows; ++y) 983 for (y=0; y<cRows; ++y)
984 { 984 {
985 png_bytep row = store_image_row(ps, pp, nImages, y); 985 png_bytep row = store_image_row(ps, pp, nImages, y);
986 986
987 /* The markers: */ 987 /* The markers: */
988 row[-2] = 190; 988 row[-2] = 190;
989 row[-1] = 239; 989 row[-1] = 239;
990 row[cbRow] = 222; 990 row[cbRow] = 222;
991 row[cbRow+1] = 173; 991 row[cbRow+1] = 173;
992 row[cbRow+2] = 17; 992 row[cbRow+2] = 17;
993 } 993 }
994 } 994 }
995} 995}
996 996
997static void 997static void
998store_image_check(PNG_CONST png_store* ps, png_structp pp, int iImage) 998store_image_check(PNG_CONST png_store* ps, png_structp pp, int iImage)
999{ 999{
1000 png_const_bytep image = ps->image; 1000 png_const_bytep image = ps->image;
1001 1001
1002 if (image[-1] != 0xed || image[ps->cb_image] != 0xfe) 1002 if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)
1003 png_error(pp, "image overwrite"); 1003 png_error(pp, "image overwrite");
1004 else 1004 else
1005 { 1005 {
1006 png_size_t cbRow = ps->cb_row; 1006 png_size_t cbRow = ps->cb_row;
1007 png_uint_32 rows = ps->image_h; 1007 png_uint_32 rows = ps->image_h;
1008 1008
1009 image += iImage * (cbRow+5) * ps->image_h; 1009 image += iImage * (cbRow+5) * ps->image_h;
1010 1010
1011 image += 2; /* skip image first row markers */ 1011 image += 2; /* skip image first row markers */
1012 1012
1013 while (rows-- > 0) 1013 while (rows-- > 0)
1014 { 1014 {
1015 if (image[-2] != 190 || image[-1] != 239) 1015 if (image[-2] != 190 || image[-1] != 239)
1016 png_error(pp, "row start overwritten"); 1016 png_error(pp, "row start overwritten");
1017 1017
1018 if (image[cbRow] != 222 || image[cbRow+1] != 173 || 1018 if (image[cbRow] != 222 || image[cbRow+1] != 173 ||
1019 image[cbRow+2] != 17) 1019 image[cbRow+2] != 17)
1020 png_error(pp, "row end overwritten"); 1020 png_error(pp, "row end overwritten");
1021 1021
1022 image += cbRow+5; 1022 image += cbRow+5;
1023 } 1023 }
1024 } 1024 }
1025} 1025}
1026 1026
1027static void 1027static void
1028store_write(png_structp pp, png_bytep pb, png_size_t st) 1028store_write(png_structp pp, png_bytep pb, png_size_t st)
1029{ 1029{
1030 png_store *ps = voidcast(png_store*, png_get_io_ptr(pp)); 1030 png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
1031 1031
1032 if (ps->pwrite != pp) 1032 if (ps->pwrite != pp)
1033 png_error(pp, "store state damaged"); 1033 png_error(pp, "store state damaged");
1034 1034
1035 while (st > 0) 1035 while (st > 0)
1036 { 1036 {
1037 size_t cb; 1037 size_t cb;
1038 1038
1039 if (ps->writepos >= STORE_BUFFER_SIZE) 1039 if (ps->writepos >= STORE_BUFFER_SIZE)
1040 store_storenew(ps); 1040 store_storenew(ps);
1041 1041
1042 cb = st; 1042 cb = st;
1043 1043
1044 if (cb > STORE_BUFFER_SIZE - ps->writepos) 1044 if (cb > STORE_BUFFER_SIZE - ps->writepos)
1045 cb = STORE_BUFFER_SIZE - ps->writepos; 1045 cb = STORE_BUFFER_SIZE - ps->writepos;
1046 1046
1047 memcpy(ps->new.buffer + ps->writepos, pb, cb); 1047 memcpy(ps->new.buffer + ps->writepos, pb, cb);
1048 pb += cb; 1048 pb += cb;
1049 st -= cb; 1049 st -= cb;
1050 ps->writepos += cb; 1050 ps->writepos += cb;
1051 } 1051 }
1052} 1052}
1053 1053
1054static void 1054static void
1055store_flush(png_structp pp) 1055store_flush(png_structp pp)
1056{ 1056{
1057 UNUSED(pp) /*DOES NOTHING*/ 1057 UNUSED(pp) /*DOES NOTHING*/
1058} 1058}
1059 1059
1060static size_t 1060static size_t
1061store_read_buffer_size(png_store *ps) 1061store_read_buffer_size(png_store *ps)
1062{ 1062{
1063 /* Return the bytes available for read in the current buffer. */ 1063 /* Return the bytes available for read in the current buffer. */
1064 if (ps->next != &ps->current->data) 1064 if (ps->next != &ps->current->data)
1065 return STORE_BUFFER_SIZE; 1065 return STORE_BUFFER_SIZE;
1066 1066
1067 return ps->current->datacount; 1067 return ps->current->datacount;
1068} 1068}
1069 1069
1070#ifdef PNG_READ_TRANSFORMS_SUPPORTED 1070#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1071/* Return total bytes available for read. */ 1071/* Return total bytes available for read. */
1072static size_t 1072static size_t
1073store_read_buffer_avail(png_store *ps) 1073store_read_buffer_avail(png_store *ps)
1074{ 1074{
1075 if (ps->current != NULL && ps->next != NULL) 1075 if (ps->current != NULL && ps->next != NULL)
1076 { 1076 {
1077 png_store_buffer *next = &ps->current->data; 1077 png_store_buffer *next = &ps->current->data;
1078 size_t cbAvail = ps->current->datacount; 1078 size_t cbAvail = ps->current->datacount;
1079 1079
1080 while (next != ps->next && next != NULL) 1080 while (next != ps->next && next != NULL)
1081 { 1081 {
1082 next = next->prev; 1082 next = next->prev;
1083 cbAvail += STORE_BUFFER_SIZE; 1083 cbAvail += STORE_BUFFER_SIZE;
1084 } 1084 }
1085 1085
1086 if (next != ps->next) 1086 if (next != ps->next)
1087 png_error(ps->pread, "buffer read error"); 1087 png_error(ps->pread, "buffer read error");
1088 1088
1089 if (cbAvail > ps->readpos) 1089 if (cbAvail > ps->readpos)
1090 return cbAvail - ps->readpos; 1090 return cbAvail - ps->readpos;
1091 } 1091 }
1092 1092
1093 return 0; 1093 return 0;
1094} 1094}
1095#endif 1095#endif
1096 1096
1097static int 1097static int
1098store_read_buffer_next(png_store *ps) 1098store_read_buffer_next(png_store *ps)
1099{ 1099{
1100 png_store_buffer *pbOld = ps->next; 1100 png_store_buffer *pbOld = ps->next;
1101 png_store_buffer *pbNew = &ps->current->data; 1101 png_store_buffer *pbNew = &ps->current->data;
1102 if (pbOld != pbNew) 1102 if (pbOld != pbNew)
1103 { 1103 {
1104 while (pbNew != NULL && pbNew->prev != pbOld) 1104 while (pbNew != NULL && pbNew->prev != pbOld)
1105 pbNew = pbNew->prev; 1105 pbNew = pbNew->prev;
1106 1106
1107 if (pbNew != NULL) 1107 if (pbNew != NULL)
1108 { 1108 {
1109 ps->next = pbNew; 1109 ps->next = pbNew;
1110 ps->readpos = 0; 1110 ps->readpos = 0;
1111 return 1; 1111 return 1;
1112 } 1112 }
1113 1113
1114 png_error(ps->pread, "buffer lost"); 1114 png_error(ps->pread, "buffer lost");
1115 } 1115 }
1116 1116
1117 return 0; /* EOF or error */ 1117 return 0; /* EOF or error */
1118} 1118}
1119 1119
1120/* Need separate implementation and callback to allow use of the same code 1120/* Need separate implementation and callback to allow use of the same code
1121 * during progressive read, where the io_ptr is set internally by libpng. 1121 * during progressive read, where the io_ptr is set internally by libpng.
1122 */ 1122 */
1123static void 1123static void
1124store_read_imp(png_store *ps, png_bytep pb, png_size_t st) 1124store_read_imp(png_store *ps, png_bytep pb, png_size_t st)
1125{ 1125{
1126 if (ps->current == NULL || ps->next == NULL) 1126 if (ps->current == NULL || ps->next == NULL)
1127 png_error(ps->pread, "store state damaged"); 1127 png_error(ps->pread, "store state damaged");
1128 1128
1129 while (st > 0) 1129 while (st > 0)
1130 { 1130 {
1131 size_t cbAvail = store_read_buffer_size(ps) - ps->readpos; 1131 size_t cbAvail = store_read_buffer_size(ps) - ps->readpos;
1132 1132
1133 if (cbAvail > 0) 1133 if (cbAvail > 0)
1134 { 1134 {
1135 if (cbAvail > st) cbAvail = st; 1135 if (cbAvail > st) cbAvail = st;
1136 memcpy(pb, ps->next->buffer + ps->readpos, cbAvail); 1136 memcpy(pb, ps->next->buffer + ps->readpos, cbAvail);
1137 st -= cbAvail; 1137 st -= cbAvail;
1138 pb += cbAvail; 1138 pb += cbAvail;
1139 ps->readpos += cbAvail; 1139 ps->readpos += cbAvail;
1140 } 1140 }
1141 1141
1142 else if (!store_read_buffer_next(ps)) 1142 else if (!store_read_buffer_next(ps))
1143 png_error(ps->pread, "read beyond end of file"); 1143 png_error(ps->pread, "read beyond end of file");
1144 } 1144 }
1145} 1145}
1146 1146
1147static void 1147static void
1148store_read(png_structp pp, png_bytep pb, png_size_t st) 1148store_read(png_structp pp, png_bytep pb, png_size_t st)
1149{ 1149{
1150 png_store *ps = voidcast(png_store*, png_get_io_ptr(pp)); 1150 png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
1151 1151
1152 if (ps == NULL || ps->pread != pp) 1152 if (ps == NULL || ps->pread != pp)
1153 png_error(pp, "bad store read call"); 1153 png_error(pp, "bad store read call");
1154 1154
1155 store_read_imp(ps, pb, st); 1155 store_read_imp(ps, pb, st);
1156} 1156}
1157 1157
1158static void 1158static void
1159store_progressive_read(png_store *ps, png_structp pp, png_infop pi) 1159store_progressive_read(png_store *ps, png_structp pp, png_infop pi)
1160{ 1160{
1161 /* Notice that a call to store_read will cause this function to fail because 1161 /* Notice that a call to store_read will cause this function to fail because
1162 * readpos will be set. 1162 * readpos will be set.
1163 */ 1163 */
1164 if (ps->pread != pp || ps->current == NULL || ps->next == NULL) 1164 if (ps->pread != pp || ps->current == NULL || ps->next == NULL)
1165 png_error(pp, "store state damaged (progressive)"); 1165 png_error(pp, "store state damaged (progressive)");
1166 1166
1167 do 1167 do
1168 { 1168 {
1169 if (ps->readpos != 0) 1169 if (ps->readpos != 0)
1170 png_error(pp, "store_read called during progressive read"); 1170 png_error(pp, "store_read called during progressive read");
1171 1171
1172 png_process_data(pp, pi, ps->next->buffer, store_read_buffer_size(ps)); 1172 png_process_data(pp, pi, ps->next->buffer, store_read_buffer_size(ps));
1173 } 1173 }
1174 while (store_read_buffer_next(ps)); 1174 while (store_read_buffer_next(ps));
1175} 1175}
1176 1176
1177/* The caller must fill this in: */ 1177/* The caller must fill this in: */
1178static store_palette_entry * 1178static store_palette_entry *
1179store_write_palette(png_store *ps, int npalette) 1179store_write_palette(png_store *ps, int npalette)
1180{ 1180{
1181 if (ps->pwrite == NULL) 1181 if (ps->pwrite == NULL)
1182 store_log(ps, NULL, "attempt to write palette without write stream", 1); 1182 store_log(ps, NULL, "attempt to write palette without write stream", 1);
1183 1183
1184 if (ps->palette != NULL) 1184 if (ps->palette != NULL)
1185 png_error(ps->pwrite, "multiple store_write_palette calls"); 1185 png_error(ps->pwrite, "multiple store_write_palette calls");
1186 1186
1187 /* This function can only return NULL if called with '0'! */ 1187 /* This function can only return NULL if called with '0'! */
1188 if (npalette > 0) 1188 if (npalette > 0)
1189 { 1189 {
1190 ps->palette = voidcast(store_palette_entry*, malloc(npalette * 1190 ps->palette = voidcast(store_palette_entry*, malloc(npalette *
1191 sizeof *ps->palette)); 1191 sizeof *ps->palette));
1192 1192
1193 if (ps->palette == NULL) 1193 if (ps->palette == NULL)
1194 png_error(ps->pwrite, "store new palette: OOM"); 1194 png_error(ps->pwrite, "store new palette: OOM");
1195 1195
1196 ps->npalette = npalette; 1196 ps->npalette = npalette;
1197 } 1197 }
1198 1198
1199 return ps->palette; 1199 return ps->palette;
1200} 1200}
1201 1201
1202static store_palette_entry * 1202static store_palette_entry *
1203store_current_palette(png_store *ps, int *npalette) 1203store_current_palette(png_store *ps, int *npalette)
1204{ 1204{
1205 /* This is an internal error (the call has been made outside a read 1205 /* This is an internal error (the call has been made outside a read
1206 * operation.) 1206 * operation.)
1207 */ 1207 */
1208 if (ps->current == NULL) 1208 if (ps->current == NULL)
1209 store_log(ps, ps->pread, "no current stream for palette", 1); 1209 store_log(ps, ps->pread, "no current stream for palette", 1);
1210 1210
1211 /* The result may be null if there is no palette. */ 1211 /* The result may be null if there is no palette. */
1212 *npalette = ps->current->npalette; 1212 *npalette = ps->current->npalette;
1213 return ps->current->palette; 1213 return ps->current->palette;
1214} 1214}
1215 1215
1216/***************************** MEMORY MANAGEMENT*** ***************************/ 1216/***************************** MEMORY MANAGEMENT*** ***************************/
1217/* A store_memory is simply the header for an allocated block of memory. The 1217/* A store_memory is simply the header for an allocated block of memory. The
1218 * pointer returned to libpng is just after the end of the header block, the 1218 * pointer returned to libpng is just after the end of the header block, the
1219 * allocated memory is followed by a second copy of the 'mark'. 1219 * allocated memory is followed by a second copy of the 'mark'.
1220 */ 1220 */
1221typedef struct store_memory 1221typedef struct store_memory
1222{ 1222{
1223 store_pool *pool; /* Originating pool */ 1223 store_pool *pool; /* Originating pool */
1224 struct store_memory *next; /* Singly linked list */ 1224 struct store_memory *next; /* Singly linked list */
1225 png_alloc_size_t size; /* Size of memory allocated */ 1225 png_alloc_size_t size; /* Size of memory allocated */
1226 png_byte mark[4]; /* ID marker */ 1226 png_byte mark[4]; /* ID marker */
1227} store_memory; 1227} store_memory;
1228 1228
1229/* Handle a fatal error in memory allocation. This calls png_error if the 1229/* Handle a fatal error in memory allocation. This calls png_error if the
1230 * libpng struct is non-NULL, else it outputs a message and returns. This means 1230 * libpng struct is non-NULL, else it outputs a message and returns. This means
1231 * that a memory problem while libpng is running will abort (png_error) the 1231 * that a memory problem while libpng is running will abort (png_error) the
1232 * handling of particular file while one in cleanup (after the destroy of the 1232 * handling of particular file while one in cleanup (after the destroy of the
1233 * struct has returned) will simply keep going and free (or attempt to free) 1233 * struct has returned) will simply keep going and free (or attempt to free)
1234 * all the memory. 1234 * all the memory.
1235 */ 1235 */
1236static void 1236static void
1237store_pool_error(png_store *ps, png_structp pp, PNG_CONST char *msg) 1237store_pool_error(png_store *ps, png_structp pp, PNG_CONST char *msg)
1238{ 1238{
1239 if (pp != NULL) 1239 if (pp != NULL)
1240 png_error(pp, msg); 1240 png_error(pp, msg);
1241 1241
1242 /* Else we have to do it ourselves. png_error eventually calls store_log, 1242 /* Else we have to do it ourselves. png_error eventually calls store_log,
1243 * above. store_log accepts a NULL png_structp - it just changes what gets 1243 * above. store_log accepts a NULL png_structp - it just changes what gets
1244 * output by store_message. 1244 * output by store_message.
1245 */ 1245 */
1246 store_log(ps, pp, msg, 1 /* error */); 1246 store_log(ps, pp, msg, 1 /* error */);
1247} 1247}
1248 1248
1249static void 1249static void
1250store_memory_free(png_structp pp, store_pool *pool, store_memory *memory) 1250store_memory_free(png_structp pp, store_pool *pool, store_memory *memory)
1251{ 1251{
1252 /* Note that pp may be NULL (see store_pool_delete below), the caller has 1252 /* Note that pp may be NULL (see store_pool_delete below), the caller has
1253 * found 'memory' in pool->list *and* unlinked this entry, so this is a valid 1253 * found 'memory' in pool->list *and* unlinked this entry, so this is a valid
1254 * pointer (for sure), but the contents may have been trashed. 1254 * pointer (for sure), but the contents may have been trashed.
1255 */ 1255 */
1256 if (memory->pool != pool) 1256 if (memory->pool != pool)
1257 store_pool_error(pool->store, pp, "memory corrupted (pool)"); 1257 store_pool_error(pool->store, pp, "memory corrupted (pool)");
1258 1258
1259 else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0) 1259 else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0)
1260 store_pool_error(pool->store, pp, "memory corrupted (start)"); 1260 store_pool_error(pool->store, pp, "memory corrupted (start)");
1261 1261
1262 /* It should be safe to read the size field now. */ 1262 /* It should be safe to read the size field now. */
1263 else 1263 else
1264 { 1264 {
1265 png_alloc_size_t cb = memory->size; 1265 png_alloc_size_t cb = memory->size;
1266 1266
1267 if (cb > pool->max) 1267 if (cb > pool->max)
1268 store_pool_error(pool->store, pp, "memory corrupted (size)"); 1268 store_pool_error(pool->store, pp, "memory corrupted (size)");
1269 1269
1270 else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark) 1270 else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark)
1271 != 0) 1271 != 0)
1272 store_pool_error(pool->store, pp, "memory corrupted (end)"); 1272 store_pool_error(pool->store, pp, "memory corrupted (end)");
1273 1273
1274 /* Finally give the library a chance to find problems too: */ 1274 /* Finally give the library a chance to find problems too: */
1275 else 1275 else
1276 { 1276 {
1277 pool->current -= cb; 1277 pool->current -= cb;
1278 free(memory); 1278 free(memory);
1279 } 1279 }
1280 } 1280 }
1281} 1281}
1282 1282
1283static void 1283static void
1284store_pool_delete(png_store *ps, store_pool *pool) 1284store_pool_delete(png_store *ps, store_pool *pool)
1285{ 1285{
1286 if (pool->list != NULL) 1286 if (pool->list != NULL)
1287 { 1287 {
1288 fprintf(stderr, "%s: %s %s: memory lost (list follows):\n", ps->test, 1288 fprintf(stderr, "%s: %s %s: memory lost (list follows):\n", ps->test,
1289 pool == &ps->read_memory_pool ? "read" : "write", 1289 pool == &ps->read_memory_pool ? "read" : "write",
1290 pool == &ps->read_memory_pool ? (ps->current != NULL ? 1290 pool == &ps->read_memory_pool ? (ps->current != NULL ?
1291 ps->current->name : "unknown file") : ps->wname); 1291 ps->current->name : "unknown file") : ps->wname);
1292 ++ps->nerrors; 1292 ++ps->nerrors;
1293 1293
1294 do 1294 do
1295 { 1295 {
1296 store_memory *next = pool->list; 1296 store_memory *next = pool->list;
1297 pool->list = next->next; 1297 pool->list = next->next;
1298 next->next = NULL; 1298 next->next = NULL;
1299 1299
1300 fprintf(stderr, "\t%lu bytes @ %p\n", 1300 fprintf(stderr, "\t%lu bytes @ %p\n",
1301 (unsigned long)next->size, (PNG_CONST void*)(next+1)); 1301 (unsigned long)next->size, (PNG_CONST void*)(next+1));
1302 /* The NULL means this will always return, even if the memory is 1302 /* The NULL means this will always return, even if the memory is
1303 * corrupted. 1303 * corrupted.
1304 */ 1304 */
1305 store_memory_free(NULL, pool, next); 1305 store_memory_free(NULL, pool, next);
1306 } 1306 }
1307 while (pool->list != NULL); 1307 while (pool->list != NULL);
1308 } 1308 }
1309 1309
1310 /* And reset the other fields too for the next time. */ 1310 /* And reset the other fields too for the next time. */
1311 if (pool->max > pool->max_max) pool->max_max = pool->max; 1311 if (pool->max > pool->max_max) pool->max_max = pool->max;
1312 pool->max = 0; 1312 pool->max = 0;
1313 if (pool->current != 0) /* unexpected internal error */ 1313 if (pool->current != 0) /* unexpected internal error */
1314 fprintf(stderr, "%s: %s %s: memory counter mismatch (internal error)\n", 1314 fprintf(stderr, "%s: %s %s: memory counter mismatch (internal error)\n",
1315 ps->test, pool == &ps->read_memory_pool ? "read" : "write", 1315 ps->test, pool == &ps->read_memory_pool ? "read" : "write",
1316 pool == &ps->read_memory_pool ? (ps->current != NULL ? 1316 pool == &ps->read_memory_pool ? (ps->current != NULL ?
1317 ps->current->name : "unknown file") : ps->wname); 1317 ps->current->name : "unknown file") : ps->wname);
1318 pool->current = 0; 1318 pool->current = 0;
1319 1319
1320 if (pool->limit > pool->max_limit) 1320 if (pool->limit > pool->max_limit)
1321 pool->max_limit = pool->limit; 1321 pool->max_limit = pool->limit;
1322 1322
1323 pool->limit = 0; 1323 pool->limit = 0;
1324 1324
1325 if (pool->total > pool->max_total) 1325 if (pool->total > pool->max_total)
1326 pool->max_total = pool->total; 1326 pool->max_total = pool->total;
1327 1327
1328 pool->total = 0; 1328 pool->total = 0;
1329 1329
1330 /* Get a new mark too. */ 1330 /* Get a new mark too. */
1331 store_pool_mark(pool->mark); 1331 store_pool_mark(pool->mark);
1332} 1332}
1333 1333
1334/* The memory callbacks: */ 1334/* The memory callbacks: */
1335static png_voidp 1335static png_voidp
1336store_malloc(png_structp pp, png_alloc_size_t cb) 1336store_malloc(png_structp pp, png_alloc_size_t cb)
1337{ 1337{
1338 store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp)); 1338 store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));
1339 store_memory *new = voidcast(store_memory*, malloc(cb + (sizeof *new) + 1339 store_memory *new = voidcast(store_memory*, malloc(cb + (sizeof *new) +
1340 (sizeof pool->mark))); 1340 (sizeof pool->mark)));
1341 1341
1342 if (new != NULL) 1342 if (new != NULL)
1343 { 1343 {
1344 if (cb > pool->max) 1344 if (cb > pool->max)
1345 pool->max = cb; 1345 pool->max = cb;
1346 1346
1347 pool->current += cb; 1347 pool->current += cb;
1348 1348
1349 if (pool->current > pool->limit) 1349 if (pool->current > pool->limit)
1350 pool->limit = pool->current; 1350 pool->limit = pool->current;
1351 1351
1352 pool->total += cb; 1352 pool->total += cb;
1353 1353
1354 new->size = cb; 1354 new->size = cb;
1355 memcpy(new->mark, pool->mark, sizeof new->mark); 1355 memcpy(new->mark, pool->mark, sizeof new->mark);
1356 memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark); 1356 memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark);
1357 new->pool = pool; 1357 new->pool = pool;
1358 new->next = pool->list; 1358 new->next = pool->list;
1359 pool->list = new; 1359 pool->list = new;
1360 ++new; 1360 ++new;
1361 } 1361 }
1362 1362
1363 else 1363 else
1364 { 1364 {
1365 /* NOTE: the PNG user malloc function cannot use the png_ptr it is passed 1365 /* NOTE: the PNG user malloc function cannot use the png_ptr it is passed
1366 * other than to retrieve the allocation pointer! libpng calls the 1366 * other than to retrieve the allocation pointer! libpng calls the
1367 * store_malloc callback in two basic cases: 1367 * store_malloc callback in two basic cases:
1368 * 1368 *
1369 * 1) From png_malloc; png_malloc will do a png_error itself if NULL is 1369 * 1) From png_malloc; png_malloc will do a png_error itself if NULL is
1370 * returned. 1370 * returned.
1371 * 2) From png_struct or png_info structure creation; png_malloc is 1371 * 2) From png_struct or png_info structure creation; png_malloc is
1372 * to return so cleanup can be performed. 1372 * to return so cleanup can be performed.
1373 * 1373 *
1374 * To handle this store_malloc can log a message, but can't do anything 1374 * To handle this store_malloc can log a message, but can't do anything
1375 * else. 1375 * else.
1376 */ 1376 */
1377 store_log(pool->store, pp, "out of memory", 1 /* is_error */); 1377 store_log(pool->store, pp, "out of memory", 1 /* is_error */);
1378 } 1378 }
1379 1379
1380 return new; 1380 return new;
1381} 1381}
1382 1382
1383static void 1383static void
1384store_free(png_structp pp, png_voidp memory) 1384store_free(png_structp pp, png_voidp memory)
1385{ 1385{
1386 store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp)); 1386 store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));
1387 store_memory *this = voidcast(store_memory*, memory), **test; 1387 store_memory *this = voidcast(store_memory*, memory), **test;
1388 1388
1389 /* Because libpng calls store_free with a dummy png_struct when deleting 1389 /* Because libpng calls store_free with a dummy png_struct when deleting
1390 * png_struct or png_info via png_destroy_struct_2 it is necessary to check 1390 * png_struct or png_info via png_destroy_struct_2 it is necessary to check
1391 * the passed in png_structp to ensure it is valid, and not pass it to 1391 * the passed in png_structp to ensure it is valid, and not pass it to
1392 * png_error if it is not. 1392 * png_error if it is not.
1393 */ 1393 */
1394 if (pp != pool->store->pread && pp != pool->store->pwrite) 1394 if (pp != pool->store->pread && pp != pool->store->pwrite)
1395 pp = NULL; 1395 pp = NULL;
1396 1396
1397 /* First check that this 'memory' really is valid memory - it must be in the 1397 /* First check that this 'memory' really is valid memory - it must be in the
1398 * pool list. If it is, use the shared memory_free function to free it. 1398 * pool list. If it is, use the shared memory_free function to free it.
1399 */ 1399 */
1400 --this; 1400 --this;
1401 for (test = &pool->list; *test != this; test = &(*test)->next) 1401 for (test = &pool->list; *test != this; test = &(*test)->next)
1402 { 1402 {
1403 if (*test == NULL) 1403 if (*test == NULL)
1404 { 1404 {
1405 store_pool_error(pool->store, pp, "bad pointer to free"); 1405 store_pool_error(pool->store, pp, "bad pointer to free");
1406 return; 1406 return;
1407 } 1407 }
1408 } 1408 }
1409 1409
1410 /* Unlink this entry, *test == this. */ 1410 /* Unlink this entry, *test == this. */
1411 *test = this->next; 1411 *test = this->next;
1412 this->next = NULL; 1412 this->next = NULL;
1413 store_memory_free(pp, pool, this); 1413 store_memory_free(pp, pool, this);
1414} 1414}
1415 1415
1416/* Setup functions. */ 1416/* Setup functions. */
1417/* Cleanup when aborting a write or after storing the new file. */ 1417/* Cleanup when aborting a write or after storing the new file. */
1418static void 1418static void
1419store_write_reset(png_store *ps) 1419store_write_reset(png_store *ps)
1420{ 1420{
1421 if (ps->pwrite != NULL) 1421 if (ps->pwrite != NULL)
1422 { 1422 {
1423 anon_context(ps); 1423 anon_context(ps);
1424 1424
1425 Try 1425 Try
1426 png_destroy_write_struct(&ps->pwrite, &ps->piwrite); 1426 png_destroy_write_struct(&ps->pwrite, &ps->piwrite);
1427 1427
1428 Catch_anonymous 1428 Catch_anonymous
1429 { 1429 {
1430 /* memory corruption: continue. */ 1430 /* memory corruption: continue. */
1431 } 1431 }
1432 1432
1433 ps->pwrite = NULL; 1433 ps->pwrite = NULL;
1434 ps->piwrite = NULL; 1434 ps->piwrite = NULL;
1435 } 1435 }
1436 1436
1437 /* And make sure that all the memory has been freed - this will output 1437 /* And make sure that all the memory has been freed - this will output
1438 * spurious errors in the case of memory corruption above, but this is safe. 1438 * spurious errors in the case of memory corruption above, but this is safe.
1439 */ 1439 */
1440 store_pool_delete(ps, &ps->write_memory_pool); 1440 store_pool_delete(ps, &ps->write_memory_pool);
1441 1441
1442 store_freenew(ps); 1442 store_freenew(ps);
1443} 1443}
1444 1444
1445/* The following is the main write function, it returns a png_struct and, 1445/* The following is the main write function, it returns a png_struct and,
1446 * optionally, a png_info suitable for writiing a new PNG file. Use 1446 * optionally, a png_info suitable for writiing a new PNG file. Use
1447 * store_storefile above to record this file after it has been written. The 1447 * store_storefile above to record this file after it has been written. The
1448 * returned libpng structures as destroyed by store_write_reset above. 1448 * returned libpng structures as destroyed by store_write_reset above.
1449 */ 1449 */
1450static png_structp 1450static png_structp
1451set_store_for_write(png_store *ps, png_infopp ppi, 1451set_store_for_write(png_store *ps, png_infopp ppi,
1452 PNG_CONST char * volatile name) 1452 PNG_CONST char * volatile name)
1453{ 1453{
1454 anon_context(ps); 1454 anon_context(ps);
1455 1455
1456 Try 1456 Try
1457 { 1457 {
1458 if (ps->pwrite != NULL) 1458 if (ps->pwrite != NULL)
1459 png_error(ps->pwrite, "write store already in use"); 1459 png_error(ps->pwrite, "write store already in use");
1460 1460
1461 store_write_reset(ps); 1461 store_write_reset(ps);
1462 safecat(ps->wname, sizeof ps->wname, 0, name); 1462 safecat(ps->wname, sizeof ps->wname, 0, name);
1463 1463
1464 /* Don't do the slow memory checks if doing a speed test. */ 1464 /* Don't do the slow memory checks if doing a speed test. */
1465 if (ps->speed) 1465 if (ps->speed)
1466 ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING, 1466 ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1467 ps, store_error, store_warning); 1467 ps, store_error, store_warning);
1468 1468
1469 else 1469 else
1470 ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, 1470 ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
1471 ps, store_error, store_warning, &ps->write_memory_pool, 1471 ps, store_error, store_warning, &ps->write_memory_pool,
1472 store_malloc, store_free); 1472 store_malloc, store_free);
1473 1473
1474 png_set_write_fn(ps->pwrite, ps, store_write, store_flush); 1474 png_set_write_fn(ps->pwrite, ps, store_write, store_flush);
1475 1475
1476 if (ppi != NULL) 1476 if (ppi != NULL)
1477 *ppi = ps->piwrite = png_create_info_struct(ps->pwrite); 1477 *ppi = ps->piwrite = png_create_info_struct(ps->pwrite);
1478 } 1478 }
1479 1479
1480 Catch_anonymous 1480 Catch_anonymous
1481 return NULL; 1481 return NULL;
1482 1482
1483 return ps->pwrite; 1483 return ps->pwrite;
1484} 1484}
1485 1485
1486/* Cleanup when finished reading (either due to error or in the success case). 1486/* Cleanup when finished reading (either due to error or in the success case).
1487 */ 1487 */
1488static void 1488static void
1489store_read_reset(png_store *ps) 1489store_read_reset(png_store *ps)
1490{ 1490{
1491 if (ps->pread != NULL) 1491 if (ps->pread != NULL)
1492 { 1492 {
1493 anon_context(ps); 1493 anon_context(ps);
1494 1494
1495 Try 1495 Try
1496 png_destroy_read_struct(&ps->pread, &ps->piread, NULL); 1496 png_destroy_read_struct(&ps->pread, &ps->piread, NULL);
1497 1497
1498 Catch_anonymous 1498 Catch_anonymous
1499 { 1499 {
1500 /* error already output: continue */ 1500 /* error already output: continue */
1501 } 1501 }
1502 1502
1503 ps->pread = NULL; 1503 ps->pread = NULL;
1504 ps->piread = NULL; 1504 ps->piread = NULL;
1505 } 1505 }
1506 1506
1507 /* Always do this to be safe. */ 1507 /* Always do this to be safe. */
1508 store_pool_delete(ps, &ps->read_memory_pool); 1508 store_pool_delete(ps, &ps->read_memory_pool);
1509 1509
1510 ps->current = NULL; 1510 ps->current = NULL;
1511 ps->next = NULL; 1511 ps->next = NULL;
1512 ps->readpos = 0; 1512 ps->readpos = 0;
1513 ps->validated = 0; 1513 ps->validated = 0;
1514} 1514}
1515 1515
1516static void 1516static void
1517store_read_set(png_store *ps, png_uint_32 id) 1517store_read_set(png_store *ps, png_uint_32 id)
1518{ 1518{
1519 png_store_file *pf = ps->saved; 1519 png_store_file *pf = ps->saved;
1520 1520
1521 while (pf != NULL) 1521 while (pf != NULL)
1522 { 1522 {
1523 if (pf->id == id) 1523 if (pf->id == id)
1524 { 1524 {
1525 ps->current = pf; 1525 ps->current = pf;
1526 ps->next = NULL; 1526 ps->next = NULL;
1527 store_read_buffer_next(ps); 1527 store_read_buffer_next(ps);
1528 return; 1528 return;
1529 } 1529 }
1530 1530
1531 pf = pf->next; 1531 pf = pf->next;
1532 } 1532 }
1533 1533
1534 { 1534 {
1535 size_t pos; 1535 size_t pos;
1536 char msg[FILE_NAME_SIZE+64]; 1536 char msg[FILE_NAME_SIZE+64];
1537 1537
1538 pos = standard_name_from_id(msg, sizeof msg, 0, id); 1538 pos = standard_name_from_id(msg, sizeof msg, 0, id);
1539 pos = safecat(msg, sizeof msg, pos, ": file not found"); 1539 pos = safecat(msg, sizeof msg, pos, ": file not found");
1540 png_error(ps->pread, msg); 1540 png_error(ps->pread, msg);
1541 } 1541 }
1542} 1542}
1543 1543
1544/* The main interface for reading a saved file - pass the id number of the file 1544/* The main interface for reading a saved file - pass the id number of the file
1545 * to retrieve. Ids must be unique or the earlier file will be hidden. The API 1545 * to retrieve. Ids must be unique or the earlier file will be hidden. The API
1546 * returns a png_struct and, optionally, a png_info. Both of these will be 1546 * returns a png_struct and, optionally, a png_info. Both of these will be
1547 * destroyed by store_read_reset above. 1547 * destroyed by store_read_reset above.
1548 */ 1548 */
1549static png_structp 1549static png_structp
1550set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id, 1550set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id,
1551 PNG_CONST char *name) 1551 PNG_CONST char *name)
1552{ 1552{
1553 /* Set the name for png_error */ 1553 /* Set the name for png_error */
1554 safecat(ps->test, sizeof ps->test, 0, name); 1554 safecat(ps->test, sizeof ps->test, 0, name);
1555 1555
1556 if (ps->pread != NULL) 1556 if (ps->pread != NULL)
1557 png_error(ps->pread, "read store already in use"); 1557 png_error(ps->pread, "read store already in use");
1558 1558
1559 store_read_reset(ps); 1559 store_read_reset(ps);
1560 1560
1561 /* Both the create APIs can return NULL if used in their default mode 1561 /* Both the create APIs can return NULL if used in their default mode
1562 * (because there is no other way of handling an error because the jmp_buf 1562 * (because there is no other way of handling an error because the jmp_buf
1563 * by default is stored in png_struct and that has not been allocated!) 1563 * by default is stored in png_struct and that has not been allocated!)
1564 * However, given that store_error works correctly in these circumstances 1564 * However, given that store_error works correctly in these circumstances
1565 * we don't ever expect NULL in this program. 1565 * we don't ever expect NULL in this program.
1566 */ 1566 */
1567 if (ps->speed) 1567 if (ps->speed)
1568 ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps, 1568 ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps,
1569 store_error, store_warning); 1569 store_error, store_warning);
1570 1570
1571 else 1571 else
1572 ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps, 1572 ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps,
1573 store_error, store_warning, &ps->read_memory_pool, store_malloc, 1573 store_error, store_warning, &ps->read_memory_pool, store_malloc,
1574 store_free); 1574 store_free);
1575 1575
1576 if (ps->pread == NULL) 1576 if (ps->pread == NULL)
1577 { 1577 {
1578 struct exception_context *the_exception_context = &ps->exception_context; 1578 struct exception_context *the_exception_context = &ps->exception_context;
1579 1579
1580 store_log(ps, NULL, "png_create_read_struct returned NULL (unexpected)", 1580 store_log(ps, NULL, "png_create_read_struct returned NULL (unexpected)",
1581 1 /*error*/); 1581 1 /*error*/);
1582 1582
1583 Throw ps; 1583 Throw ps;
1584 } 1584 }
1585 1585
1586 store_read_set(ps, id); 1586 store_read_set(ps, id);
1587 1587
1588 if (ppi != NULL) 1588 if (ppi != NULL)
1589 *ppi = ps->piread = png_create_info_struct(ps->pread); 1589 *ppi = ps->piread = png_create_info_struct(ps->pread);
1590 1590
1591 return ps->pread; 1591 return ps->pread;
1592} 1592}
1593 1593
1594/* The overall cleanup of a store simply calls the above then removes all the 1594/* The overall cleanup of a store simply calls the above then removes all the
1595 * saved files. This does not delete the store itself. 1595 * saved files. This does not delete the store itself.
1596 */ 1596 */
1597static void 1597static void
1598store_delete(png_store *ps) 1598store_delete(png_store *ps)
1599{ 1599{
1600 store_write_reset(ps); 1600 store_write_reset(ps);
1601 store_read_reset(ps); 1601 store_read_reset(ps);
1602 store_freefile(&ps->saved); 1602 store_freefile(&ps->saved);
1603 store_image_free(ps, NULL); 1603 store_image_free(ps, NULL);
1604} 1604}
1605 1605
1606/*********************** PNG FILE MODIFICATION ON READ ************************/ 1606/*********************** PNG FILE MODIFICATION ON READ ************************/
1607/* Files may be modified on read. The following structure contains a complete 1607/* Files may be modified on read. The following structure contains a complete
1608 * png_store together with extra members to handle modification and a special 1608 * png_store together with extra members to handle modification and a special
1609 * read callback for libpng. To use this the 'modifications' field must be set 1609 * read callback for libpng. To use this the 'modifications' field must be set
1610 * to a list of png_modification structures that actually perform the 1610 * to a list of png_modification structures that actually perform the
1611 * modification, otherwise a png_modifier is functionally equivalent to a 1611 * modification, otherwise a png_modifier is functionally equivalent to a
1612 * png_store. There is a special read function, set_modifier_for_read, which 1612 * png_store. There is a special read function, set_modifier_for_read, which
1613 * replaces set_store_for_read. 1613 * replaces set_store_for_read.
1614 */ 1614 */
1615typedef enum modifier_state 1615typedef enum modifier_state
1616{ 1616{
1617 modifier_start, /* Initial value */ 1617 modifier_start, /* Initial value */
1618 modifier_signature, /* Have a signature */ 1618 modifier_signature, /* Have a signature */
1619 modifier_IHDR /* Have an IHDR */ 1619 modifier_IHDR /* Have an IHDR */
1620} modifier_state; 1620} modifier_state;
1621 1621
1622typedef struct CIE_color 1622typedef struct CIE_color
1623{ 1623{
1624 /* A single CIE tristimulus value, representing the unique response of a 1624 /* A single CIE tristimulus value, representing the unique response of a
1625 * standard observer to a variety of light spectra. The observer recognizes 1625 * standard observer to a variety of light spectra. The observer recognizes
1626 * all spectra that produce this response as the same color, therefore this 1626 * all spectra that produce this response as the same color, therefore this
1627 * is effectively a description of a color. 1627 * is effectively a description of a color.
1628 */ 1628 */
1629 double X, Y, Z; 1629 double X, Y, Z;
1630} CIE_color; 1630} CIE_color;
1631 1631
1632static double 1632static double
1633chromaticity_x(CIE_color c) 1633chromaticity_x(CIE_color c)
1634{ 1634{
1635 return c.X / (c.X + c.Y + c.Z); 1635 return c.X / (c.X + c.Y + c.Z);
1636} 1636}
1637 1637
1638static double 1638static double
1639chromaticity_y(CIE_color c) 1639chromaticity_y(CIE_color c)
1640{ 1640{
1641 return c.Y / (c.X + c.Y + c.Z); 1641 return c.Y / (c.X + c.Y + c.Z);
1642} 1642}
1643 1643
1644typedef struct color_encoding 1644typedef struct color_encoding
1645{ 1645{
1646 /* A description of an (R,G,B) encoding of color (as defined above); this 1646 /* A description of an (R,G,B) encoding of color (as defined above); this
1647 * includes the actual colors of the (R,G,B) triples (1,0,0), (0,1,0) and 1647 * includes the actual colors of the (R,G,B) triples (1,0,0), (0,1,0) and
1648 * (0,0,1) plus an encoding value that is used to encode the linear 1648 * (0,0,1) plus an encoding value that is used to encode the linear
1649 * components R, G and B to give the actual values R^gamma, G^gamma and 1649 * components R, G and B to give the actual values R^gamma, G^gamma and
1650 * B^gamma that are stored. 1650 * B^gamma that are stored.
1651 */ 1651 */
1652 double gamma; /* Encoding (file) gamma of space */ 1652 double gamma; /* Encoding (file) gamma of space */
1653 CIE_color red, green, blue; /* End points */ 1653 CIE_color red, green, blue; /* End points */
1654} color_encoding; 1654} color_encoding;
1655 1655
1656static CIE_color 1656static CIE_color
1657white_point(PNG_CONST color_encoding *encoding) 1657white_point(PNG_CONST color_encoding *encoding)
1658{ 1658{
1659 CIE_color white; 1659 CIE_color white;
1660 1660
1661 white.X = encoding->red.X + encoding->green.X + encoding->blue.X; 1661 white.X = encoding->red.X + encoding->green.X + encoding->blue.X;
1662 white.Y = encoding->red.Y + encoding->green.Y + encoding->blue.Y; 1662 white.Y = encoding->red.Y + encoding->green.Y + encoding->blue.Y;
1663 white.Z = encoding->red.Z + encoding->green.Z + encoding->blue.Z; 1663 white.Z = encoding->red.Z + encoding->green.Z + encoding->blue.Z;
1664 1664
1665 return white; 1665 return white;
1666} 1666}
1667 1667
1668static void 1668static void
1669normalize_color_encoding(color_encoding *encoding) 1669normalize_color_encoding(color_encoding *encoding)
1670{ 1670{
1671 PNG_CONST double whiteY = encoding->red.Y + encoding->green.Y + 1671 PNG_CONST double whiteY = encoding->red.Y + encoding->green.Y +
1672 encoding->blue.Y; 1672 encoding->blue.Y;
1673 1673
1674 if (whiteY != 1) 1674 if (whiteY != 1)
1675 { 1675 {
1676 encoding->red.X /= whiteY; 1676 encoding->red.X /= whiteY;
1677 encoding->red.Y /= whiteY; 1677 encoding->red.Y /= whiteY;
1678 encoding->red.Z /= whiteY; 1678 encoding->red.Z /= whiteY;
1679 encoding->green.X /= whiteY; 1679 encoding->green.X /= whiteY;
1680 encoding->green.Y /= whiteY; 1680 encoding->green.Y /= whiteY;
1681 encoding->green.Z /= whiteY; 1681 encoding->green.Z /= whiteY;
1682 encoding->blue.X /= whiteY; 1682 encoding->blue.X /= whiteY;
1683 encoding->blue.Y /= whiteY; 1683 encoding->blue.Y /= whiteY;
1684 encoding->blue.Z /= whiteY; 1684 encoding->blue.Z /= whiteY;
1685 } 1685 }
1686} 1686}
1687 1687
1688static size_t 1688static size_t
1689safecat_color_encoding(char *buffer, size_t bufsize, size_t pos, 1689safecat_color_encoding(char *buffer, size_t bufsize, size_t pos,
1690 PNG_CONST color_encoding *e, double encoding_gamma) 1690 PNG_CONST color_encoding *e, double encoding_gamma)
1691{ 1691{
1692 if (e != 0) 1692 if (e != 0)
1693 { 1693 {
1694 if (encoding_gamma != 0) 1694 if (encoding_gamma != 0)
1695 pos = safecat(buffer, bufsize, pos, "("); 1695 pos = safecat(buffer, bufsize, pos, "(");
1696 pos = safecat(buffer, bufsize, pos, "R("); 1696 pos = safecat(buffer, bufsize, pos, "R(");
1697 pos = safecatd(buffer, bufsize, pos, e->red.X, 4); 1697 pos = safecatd(buffer, bufsize, pos, e->red.X, 4);
1698 pos = safecat(buffer, bufsize, pos, ","); 1698 pos = safecat(buffer, bufsize, pos, ",");
1699 pos = safecatd(buffer, bufsize, pos, e->red.Y, 4); 1699 pos = safecatd(buffer, bufsize, pos, e->red.Y, 4);
1700 pos = safecat(buffer, bufsize, pos, ","); 1700 pos = safecat(buffer, bufsize, pos, ",");
1701 pos = safecatd(buffer, bufsize, pos, e->red.Z, 4); 1701 pos = safecatd(buffer, bufsize, pos, e->red.Z, 4);
1702 pos = safecat(buffer, bufsize, pos, "),G("); 1702 pos = safecat(buffer, bufsize, pos, "),G(");
1703 pos = safecatd(buffer, bufsize, pos, e->green.X, 4); 1703 pos = safecatd(buffer, bufsize, pos, e->green.X, 4);
1704 pos = safecat(buffer, bufsize, pos, ","); 1704 pos = safecat(buffer, bufsize, pos, ",");
1705 pos = safecatd(buffer, bufsize, pos, e->green.Y, 4); 1705 pos = safecatd(buffer, bufsize, pos, e->green.Y, 4);
1706 pos = safecat(buffer, bufsize, pos, ","); 1706 pos = safecat(buffer, bufsize, pos, ",");
1707 pos = safecatd(buffer, bufsize, pos, e->green.Z, 4); 1707 pos = safecatd(buffer, bufsize, pos, e->green.Z, 4);
1708 pos = safecat(buffer, bufsize, pos, "),B("); 1708 pos = safecat(buffer, bufsize, pos, "),B(");
1709 pos = safecatd(buffer, bufsize, pos, e->blue.X, 4); 1709 pos = safecatd(buffer, bufsize, pos, e->blue.X, 4);
1710 pos = safecat(buffer, bufsize, pos, ","); 1710 pos = safecat(buffer, bufsize, pos, ",");
1711 pos = safecatd(buffer, bufsize, pos, e->blue.Y, 4); 1711 pos = safecatd(buffer, bufsize, pos, e->blue.Y, 4);
1712 pos = safecat(buffer, bufsize, pos, ","); 1712 pos = safecat(buffer, bufsize, pos, ",");
1713 pos = safecatd(buffer, bufsize, pos, e->blue.Z, 4); 1713 pos = safecatd(buffer, bufsize, pos, e->blue.Z, 4);
1714 pos = safecat(buffer, bufsize, pos, ")"); 1714 pos = safecat(buffer, bufsize, pos, ")");
1715 if (encoding_gamma != 0) 1715 if (encoding_gamma != 0)
1716 pos = safecat(buffer, bufsize, pos, ")"); 1716 pos = safecat(buffer, bufsize, pos, ")");
1717 } 1717 }
1718 1718
1719 if (encoding_gamma != 0) 1719 if (encoding_gamma != 0)
1720 { 1720 {
1721 pos = safecat(buffer, bufsize, pos, "^"); 1721 pos = safecat(buffer, bufsize, pos, "^");
1722 pos = safecatd(buffer, bufsize, pos, encoding_gamma, 5); 1722 pos = safecatd(buffer, bufsize, pos, encoding_gamma, 5);
1723 } 1723 }
1724 1724
1725 return pos; 1725 return pos;
1726} 1726}
1727 1727
1728typedef struct png_modifier 1728typedef struct png_modifier
1729{ 1729{
1730 png_store this; /* I am a png_store */ 1730 png_store this; /* I am a png_store */
1731 struct png_modification *modifications; /* Changes to make */ 1731 struct png_modification *modifications; /* Changes to make */
1732 1732
1733 modifier_state state; /* My state */ 1733 modifier_state state; /* My state */
1734 1734
1735 /* Information from IHDR: */ 1735 /* Information from IHDR: */
1736 png_byte bit_depth; /* From IHDR */ 1736 png_byte bit_depth; /* From IHDR */
1737 png_byte colour_type; /* From IHDR */ 1737 png_byte colour_type; /* From IHDR */
1738 1738
1739 /* While handling PLTE, IDAT and IEND these chunks may be pended to allow 1739 /* While handling PLTE, IDAT and IEND these chunks may be pended to allow
1740 * other chunks to be inserted. 1740 * other chunks to be inserted.
1741 */ 1741 */
1742 png_uint_32 pending_len; 1742 png_uint_32 pending_len;
1743 png_uint_32 pending_chunk; 1743 png_uint_32 pending_chunk;
1744 1744
1745 /* Test values */ 1745 /* Test values */
1746 double *gammas; 1746 double *gammas;
1747 unsigned int ngammas; 1747 unsigned int ngammas;
1748 unsigned int ngamma_tests; /* Number of gamma tests to run*/ 1748 unsigned int ngamma_tests; /* Number of gamma tests to run*/
1749 double current_gamma; /* 0 if not set */ 1749 double current_gamma; /* 0 if not set */
1750 PNG_CONST color_encoding *encodings; 1750 PNG_CONST color_encoding *encodings;
1751 unsigned int nencodings; 1751 unsigned int nencodings;
1752 PNG_CONST color_encoding *current_encoding; /* If an encoding has been set */ 1752 PNG_CONST color_encoding *current_encoding; /* If an encoding has been set */
1753 unsigned int encoding_counter; /* For iteration */ 1753 unsigned int encoding_counter; /* For iteration */
1754 int encoding_ignored; /* Something overwrote it */ 1754 int encoding_ignored; /* Something overwrote it */
1755 1755
1756 /* Control variables used to iterate through possible encodings, the 1756 /* Control variables used to iterate through possible encodings, the
1757 * following must be set to 0 and tested by the function that uses the 1757 * following must be set to 0 and tested by the function that uses the
1758 * png_modifier because the modifier only sets it to 1 (true.) 1758 * png_modifier because the modifier only sets it to 1 (true.)
1759 */ 1759 */
1760 unsigned int repeat :1; /* Repeat this transform test. */ 1760 unsigned int repeat :1; /* Repeat this transform test. */
1761 unsigned int test_uses_encoding :1; 1761 unsigned int test_uses_encoding :1;
1762 1762
1763 /* Lowest sbit to test (libpng fails for sbit < 8) */ 1763 /* Lowest sbit to test (libpng fails for sbit < 8) */
1764 png_byte sbitlow; 1764 png_byte sbitlow;
1765 1765
1766 /* Error control - these are the limits on errors accepted by the gamma tests 1766 /* Error control - these are the limits on errors accepted by the gamma tests
1767 * below. 1767 * below.
1768 */ 1768 */
1769 double maxout8; /* Maximum output value error */ 1769 double maxout8; /* Maximum output value error */
1770 double maxabs8; /* Absolute sample error 0..1 */ 1770 double maxabs8; /* Absolute sample error 0..1 */
1771 double maxcalc8; /* Absolute sample error 0..1 */ 1771 double maxcalc8; /* Absolute sample error 0..1 */
1772 double maxpc8; /* Percentage sample error 0..100% */ 1772 double maxpc8; /* Percentage sample error 0..100% */
1773 double maxout16; /* Maximum output value error */ 1773 double maxout16; /* Maximum output value error */
1774 double maxabs16; /* Absolute sample error 0..1 */ 1774 double maxabs16; /* Absolute sample error 0..1 */
1775 double maxcalc16;/* Absolute sample error 0..1 */ 1775 double maxcalc16;/* Absolute sample error 0..1 */
1776 double maxpc16; /* Percentage sample error 0..100% */ 1776 double maxpc16; /* Percentage sample error 0..100% */
1777 1777
1778 /* This is set by transforms that need to allow a higher limit, it is an 1778 /* This is set by transforms that need to allow a higher limit, it is an
1779 * internal check on pngvalid to ensure that the calculated error limits are 1779 * internal check on pngvalid to ensure that the calculated error limits are
1780 * not ridiculous; without this it is too easy to make a mistake in pngvalid 1780 * not ridiculous; without this it is too easy to make a mistake in pngvalid
1781 * that allows any value through. 1781 * that allows any value through.
1782 */ 1782 */
1783 double limit; /* limit on error values, normally 4E-3 */ 1783 double limit; /* limit on error values, normally 4E-3 */
1784 1784
1785 /* Log limits - values above this are logged, but not necessarily 1785 /* Log limits - values above this are logged, but not necessarily
1786 * warned. 1786 * warned.
1787 */ 1787 */
1788 double log8; /* Absolute error in 8 bits to log */ 1788 double log8; /* Absolute error in 8 bits to log */
1789 double log16; /* Absolute error in 16 bits to log */ 1789 double log16; /* Absolute error in 16 bits to log */
1790 1790
1791 /* Logged 8 and 16 bit errors ('output' values): */ 1791 /* Logged 8 and 16 bit errors ('output' values): */
1792 double error_gray_2; 1792 double error_gray_2;
1793 double error_gray_4; 1793 double error_gray_4;
1794 double error_gray_8; 1794 double error_gray_8;
1795 double error_gray_16; 1795 double error_gray_16;
1796 double error_color_8; 1796 double error_color_8;
1797 double error_color_16; 1797 double error_color_16;
1798 double error_indexed; 1798 double error_indexed;
1799 1799
1800 /* Flags: */ 1800 /* Flags: */
1801 /* Whether to call png_read_update_info, not png_read_start_image, and how 1801 /* Whether to call png_read_update_info, not png_read_start_image, and how
1802 * many times to call it. 1802 * many times to call it.
1803 */ 1803 */
1804 int use_update_info; 1804 int use_update_info;
1805 1805
1806 /* Whether or not to interlace. */ 1806 /* Whether or not to interlace. */
1807 int interlace_type :9; /* int, but must store '1' */ 1807 int interlace_type :9; /* int, but must store '1' */
1808 1808
1809 /* Run the standard tests? */ 1809 /* Run the standard tests? */
1810 unsigned int test_standard :1; 1810 unsigned int test_standard :1;
1811 1811
1812 /* Run the odd-sized image and interlace read/write tests? */ 1812 /* Run the odd-sized image and interlace read/write tests? */
1813 unsigned int test_size :1; 1813 unsigned int test_size :1;
1814 1814
1815 /* Run tests on reading with a combiniation of transforms, */ 1815 /* Run tests on reading with a combiniation of transforms, */
1816 unsigned int test_transform :1; 1816 unsigned int test_transform :1;
1817 1817
1818 /* When to use the use_input_precision option: */ 1818 /* When to use the use_input_precision option: */
1819 unsigned int use_input_precision :1; 1819 unsigned int use_input_precision :1;
1820 unsigned int use_input_precision_sbit :1; 1820 unsigned int use_input_precision_sbit :1;
1821 unsigned int use_input_precision_16to8 :1; 1821 unsigned int use_input_precision_16to8 :1;
1822 1822
1823 /* If set assume that the calculation bit depth is set by the input 1823 /* If set assume that the calculation bit depth is set by the input
1824 * precision, not the output precision. 1824 * precision, not the output precision.
1825 */ 1825 */
1826 unsigned int calculations_use_input_precision :1; 1826 unsigned int calculations_use_input_precision :1;
1827 1827
1828 /* If set assume that the calculations are done in 16 bits even if both input 1828 /* If set assume that the calculations are done in 16 bits even if both input
1829 * and output are 8 bit or less. 1829 * and output are 8 bit or less.
1830 */ 1830 */
1831 unsigned int assume_16_bit_calculations :1; 1831 unsigned int assume_16_bit_calculations :1;
1832 1832
1833 /* Which gamma tests to run: */ 1833 /* Which gamma tests to run: */
1834 unsigned int test_gamma_threshold :1; 1834 unsigned int test_gamma_threshold :1;
1835 unsigned int test_gamma_transform :1; /* main tests */ 1835 unsigned int test_gamma_transform :1; /* main tests */
1836 unsigned int test_gamma_sbit :1; 1836 unsigned int test_gamma_sbit :1;
1837 unsigned int test_gamma_scale16 :1; 1837 unsigned int test_gamma_scale16 :1;
1838 unsigned int test_gamma_background :1; 1838 unsigned int test_gamma_background :1;
1839 unsigned int test_gamma_alpha_mode :1; 1839 unsigned int test_gamma_alpha_mode :1;
1840 unsigned int test_gamma_expand16 :1; 1840 unsigned int test_gamma_expand16 :1;
1841 unsigned int test_exhaustive :1; 1841 unsigned int test_exhaustive :1;
1842 1842
1843 unsigned int log :1; /* Log max error */ 1843 unsigned int log :1; /* Log max error */
1844 1844
1845 /* Buffer information, the buffer size limits the size of the chunks that can 1845 /* Buffer information, the buffer size limits the size of the chunks that can
1846 * be modified - they must fit (including header and CRC) into the buffer! 1846 * be modified - they must fit (including header and CRC) into the buffer!
1847 */ 1847 */
1848 size_t flush; /* Count of bytes to flush */ 1848 size_t flush; /* Count of bytes to flush */
1849 size_t buffer_count; /* Bytes in buffer */ 1849 size_t buffer_count; /* Bytes in buffer */
1850 size_t buffer_position; /* Position in buffer */ 1850 size_t buffer_position; /* Position in buffer */
1851 png_byte buffer[1024]; 1851 png_byte buffer[1024];
1852} png_modifier; 1852} png_modifier;
1853 1853
1854/* This returns true if the test should be stopped now because it has already 1854/* This returns true if the test should be stopped now because it has already
1855 * failed and it is running silently. 1855 * failed and it is running silently.
1856 */ 1856 */
1857static int fail(png_modifier *pm) 1857static int fail(png_modifier *pm)
1858{ 1858{
1859 return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 || 1859 return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 ||
1860 (pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0)); 1860 (pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0));
1861} 1861}
1862 1862
1863static void 1863static void
1864modifier_init(png_modifier *pm) 1864modifier_init(png_modifier *pm)
1865{ 1865{
1866 memset(pm, 0, sizeof *pm); 1866 memset(pm, 0, sizeof *pm);
1867 store_init(&pm->this); 1867 store_init(&pm->this);
1868 pm->modifications = NULL; 1868 pm->modifications = NULL;
1869 pm->state = modifier_start; 1869 pm->state = modifier_start;
1870 pm->sbitlow = 1U; 1870 pm->sbitlow = 1U;
1871 pm->ngammas = 0; 1871 pm->ngammas = 0;
1872 pm->ngamma_tests = 0; 1872 pm->ngamma_tests = 0;
1873 pm->gammas = 0; 1873 pm->gammas = 0;
1874 pm->current_gamma = 0; 1874 pm->current_gamma = 0;
1875 pm->encodings = 0; 1875 pm->encodings = 0;
1876 pm->nencodings = 0; 1876 pm->nencodings = 0;
1877 pm->current_encoding = 0; 1877 pm->current_encoding = 0;
1878 pm->encoding_counter = 0; 1878 pm->encoding_counter = 0;
1879 pm->encoding_ignored = 0; 1879 pm->encoding_ignored = 0;
1880 pm->repeat = 0; 1880 pm->repeat = 0;
1881 pm->test_uses_encoding = 0; 1881 pm->test_uses_encoding = 0;
1882 pm->maxout8 = pm->maxpc8 = pm->maxabs8 = pm->maxcalc8 = 0; 1882 pm->maxout8 = pm->maxpc8 = pm->maxabs8 = pm->maxcalc8 = 0;
1883 pm->maxout16 = pm->maxpc16 = pm->maxabs16 = pm->maxcalc16 = 0; 1883 pm->maxout16 = pm->maxpc16 = pm->maxabs16 = pm->maxcalc16 = 0;
1884 pm->limit = 4E-3; 1884 pm->limit = 4E-3;
1885 pm->log8 = pm->log16 = 0; /* Means 'off' */ 1885 pm->log8 = pm->log16 = 0; /* Means 'off' */
1886 pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0; 1886 pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;
1887 pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0; 1887 pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
1888 pm->error_indexed = 0; 1888 pm->error_indexed = 0;
1889 pm->use_update_info = 0; 1889 pm->use_update_info = 0;
1890 pm->interlace_type = PNG_INTERLACE_NONE; 1890 pm->interlace_type = PNG_INTERLACE_NONE;
1891 pm->test_standard = 0; 1891 pm->test_standard = 0;
1892 pm->test_size = 0; 1892 pm->test_size = 0;
1893 pm->test_transform = 0; 1893 pm->test_transform = 0;
1894 pm->use_input_precision = 0; 1894 pm->use_input_precision = 0;
1895 pm->use_input_precision_sbit = 0; 1895 pm->use_input_precision_sbit = 0;
1896 pm->use_input_precision_16to8 = 0; 1896 pm->use_input_precision_16to8 = 0;
1897 pm->calculations_use_input_precision = 0; 1897 pm->calculations_use_input_precision = 0;
1898 pm->test_gamma_threshold = 0; 1898 pm->test_gamma_threshold = 0;
1899 pm->test_gamma_transform = 0; 1899 pm->test_gamma_transform = 0;
1900 pm->test_gamma_sbit = 0; 1900 pm->test_gamma_sbit = 0;
1901 pm->test_gamma_scale16 = 0; 1901 pm->test_gamma_scale16 = 0;
1902 pm->test_gamma_background = 0; 1902 pm->test_gamma_background = 0;
1903 pm->test_gamma_alpha_mode = 0; 1903 pm->test_gamma_alpha_mode = 0;
1904 pm->test_gamma_expand16 = 0; 1904 pm->test_gamma_expand16 = 0;
1905 pm->test_exhaustive = 0; 1905 pm->test_exhaustive = 0;
1906 pm->log = 0; 1906 pm->log = 0;
1907 1907
1908 /* Rely on the memset for all the other fields - there are no pointers */ 1908 /* Rely on the memset for all the other fields - there are no pointers */
1909} 1909}
1910 1910
1911#ifdef PNG_READ_TRANSFORMS_SUPPORTED 1911#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1912/* If pm->calculations_use_input_precision is set then operations will happen 1912/* If pm->calculations_use_input_precision is set then operations will happen
1913 * with only 8 bit precision unless both the input and output bit depth are 16. 1913 * with only 8 bit precision unless both the input and output bit depth are 16.
1914 * 1914 *
1915 * If pm->assume_16_bit_calculations is set then even 8 bit calculations use 16 1915 * If pm->assume_16_bit_calculations is set then even 8 bit calculations use 16
1916 * bit precision. This only affects those of the following limits that pertain 1916 * bit precision. This only affects those of the following limits that pertain
1917 * to a calculation - not a digitization operation - unless the following API is 1917 * to a calculation - not a digitization operation - unless the following API is
1918 * called directly. 1918 * called directly.
1919 */ 1919 */
1920static double digitize(PNG_CONST png_modifier *pm, double value, 1920static double digitize(PNG_CONST png_modifier *pm, double value,
1921 int sample_depth, int do_round) 1921 int sample_depth, int do_round)
1922{ 1922{
1923 /* 'value' is in the range 0 to 1, the result is the same value rounded to a 1923 /* 'value' is in the range 0 to 1, the result is the same value rounded to a
1924 * multiple of the digitization factor - 8 or 16 bits depending on both the 1924 * multiple of the digitization factor - 8 or 16 bits depending on both the
1925 * sample depth and the 'assume' setting. Digitization is normally by 1925 * sample depth and the 'assume' setting. Digitization is normally by
1926 * rounding and 'do_round' should be 1, if it is 0 the digitized value will 1926 * rounding and 'do_round' should be 1, if it is 0 the digitized value will
1927 * be truncated. 1927 * be truncated.
1928 */ 1928 */
1929 PNG_CONST unsigned int digitization_factor = 1929 PNG_CONST unsigned int digitization_factor =
1930 (pm->assume_16_bit_calculations || sample_depth == 16) ? 65535 : 255; 1930 (pm->assume_16_bit_calculations || sample_depth == 16) ? 65535 : 255;
1931 1931
1932 /* Limiting the range is done as a convenience to the caller - it's easier to 1932 /* Limiting the range is done as a convenience to the caller - it's easier to
1933 * do it once here than every time at the call site. 1933 * do it once here than every time at the call site.
1934 */ 1934 */
1935 if (value <= 0) 1935 if (value <= 0)
1936 value = 0; 1936 value = 0;
1937 else if (value >= 1) 1937 else if (value >= 1)
1938 value = 1; 1938 value = 1;
1939 1939
1940 value *= digitization_factor; 1940 value *= digitization_factor;
1941 if (do_round) value += .5; 1941 if (do_round) value += .5;
1942 return floor(value)/digitization_factor; 1942 return floor(value)/digitization_factor;
1943} 1943}
1944 1944
1945static double abserr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) 1945static double abserr(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
1946{ 1946{
1947 /* Absolute error permitted in linear values - affected by the bit depth of 1947 /* Absolute error permitted in linear values - affected by the bit depth of
1948 * the calculations. 1948 * the calculations.
1949 */ 1949 */
1950 if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 || 1950 if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 ||
1951 !pm->calculations_use_input_precision))) 1951 !pm->calculations_use_input_precision)))
1952 return pm->maxabs16; 1952 return pm->maxabs16;
1953 else 1953 else
1954 return pm->maxabs8; 1954 return pm->maxabs8;
1955} 1955}
1956 1956
1957static double calcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) 1957static double calcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
1958{ 1958{
1959 /* Error in the linear composition arithmetic - only relevant when 1959 /* Error in the linear composition arithmetic - only relevant when
1960 * composition actually happens (0 < alpha < 1). 1960 * composition actually happens (0 < alpha < 1).
1961 */ 1961 */
1962 if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 || 1962 if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 ||
1963 !pm->calculations_use_input_precision))) 1963 !pm->calculations_use_input_precision)))
1964 return pm->maxcalc16; 1964 return pm->maxcalc16;
1965 else 1965 else
1966 return pm->maxcalc8; 1966 return pm->maxcalc8;
1967} 1967}
1968 1968
1969static double pcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) 1969static double pcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
1970{ 1970{
1971 /* Percentage error permitted in the linear values. Note that the specified 1971 /* Percentage error permitted in the linear values. Note that the specified
1972 * value is a percentage but this routine returns a simple number. 1972 * value is a percentage but this routine returns a simple number.
1973 */ 1973 */
1974 if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 || 1974 if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 ||
1975 !pm->calculations_use_input_precision))) 1975 !pm->calculations_use_input_precision)))
1976 return pm->maxpc16 * .01; 1976 return pm->maxpc16 * .01;
1977 else 1977 else
1978 return pm->maxpc8 * .01; 1978 return pm->maxpc8 * .01;
1979} 1979}
1980 1980
1981/* Output error - the error in the encoded value. This is determined by the 1981/* Output error - the error in the encoded value. This is determined by the
1982 * digitization of the output so can be +/-0.5 in the actual output value. In 1982 * digitization of the output so can be +/-0.5 in the actual output value. In
1983 * the expand_16 case with the current code in libpng the expand happens after 1983 * the expand_16 case with the current code in libpng the expand happens after
1984 * all the calculations are done in 8 bit arithmetic, so even though the output 1984 * all the calculations are done in 8 bit arithmetic, so even though the output
1985 * depth is 16 the output error is determined by the 8 bit calculation. 1985 * depth is 16 the output error is determined by the 8 bit calculation.
1986 * 1986 *
1987 * This limit is not determined by the bit depth of internal calculations. 1987 * This limit is not determined by the bit depth of internal calculations.
1988 * 1988 *
1989 * The specified parameter does *not* include the base .5 digitization error but 1989 * The specified parameter does *not* include the base .5 digitization error but
1990 * it is added here. 1990 * it is added here.
1991 */ 1991 */
1992static double outerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) 1992static double outerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
1993{ 1993{
1994 /* There is a serious error in the 2 and 4 bit grayscale transform because 1994 /* There is a serious error in the 2 and 4 bit grayscale transform because
1995 * the gamma table value (8 bits) is simply shifted, not rounded, so the 1995 * the gamma table value (8 bits) is simply shifted, not rounded, so the
1996 * error in 4 bit grayscale gamma is up to the value below. This is a hack 1996 * error in 4 bit grayscale gamma is up to the value below. This is a hack
1997 * to allow pngvalid to succeed: 1997 * to allow pngvalid to succeed:
1998 * 1998 *
1999 * TODO: fix this in libpng 1999 * TODO: fix this in libpng
2000 */ 2000 */
2001 if (out_depth == 2) 2001 if (out_depth == 2)
2002 return .73182-.5; 2002 return .73182-.5;
2003 2003
2004 if (out_depth == 4) 2004 if (out_depth == 4)
2005 return .90644-.5; 2005 return .90644-.5;
2006 2006
2007 if (out_depth == 16 && (in_depth == 16 || 2007 if (out_depth == 16 && (in_depth == 16 ||
2008 !pm->calculations_use_input_precision)) 2008 !pm->calculations_use_input_precision))
2009 return pm->maxout16; 2009 return pm->maxout16;
2010 2010
2011 /* This is the case where the value was calculated at 8-bit precision then 2011 /* This is the case where the value was calculated at 8-bit precision then
2012 * scaled to 16 bits. 2012 * scaled to 16 bits.
2013 */ 2013 */
2014 else if (out_depth == 16) 2014 else if (out_depth == 16)
2015 return pm->maxout8 * 257; 2015 return pm->maxout8 * 257;
2016 2016
2017 else 2017 else
2018 return pm->maxout8; 2018 return pm->maxout8;
2019} 2019}
2020 2020
2021/* This does the same thing as the above however it returns the value to log, 2021/* This does the same thing as the above however it returns the value to log,
2022 * rather than raising a warning. This is useful for debugging to track down 2022 * rather than raising a warning. This is useful for debugging to track down
2023 * exactly what set of parameters cause high error values. 2023 * exactly what set of parameters cause high error values.
2024 */ 2024 */
2025static double outlog(PNG_CONST png_modifier *pm, int in_depth, int out_depth) 2025static double outlog(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
2026{ 2026{
2027 /* The command line parameters are either 8 bit (0..255) or 16 bit (0..65535) 2027 /* The command line parameters are either 8 bit (0..255) or 16 bit (0..65535)
2028 * and so must be adjusted for low bit depth grayscale: 2028 * and so must be adjusted for low bit depth grayscale:
2029 */ 2029 */
2030 if (out_depth <= 8) 2030 if (out_depth <= 8)
2031 { 2031 {
2032 if (pm->log8 == 0) /* switched off */ 2032 if (pm->log8 == 0) /* switched off */
2033 return 256; 2033 return 256;
2034 2034
2035 if (out_depth < 8) 2035 if (out_depth < 8)
2036 return pm->log8 / 255 * ((1<<out_depth)-1); 2036 return pm->log8 / 255 * ((1<<out_depth)-1);
2037 2037
2038 return pm->log8; 2038 return pm->log8;
2039 } 2039 }
2040 2040
2041 if (out_depth == 16 && (in_depth == 16 || 2041 if (out_depth == 16 && (in_depth == 16 ||
2042 !pm->calculations_use_input_precision)) 2042 !pm->calculations_use_input_precision))
2043 { 2043 {
2044 if (pm->log16 == 0) 2044 if (pm->log16 == 0)
2045 return 65536; 2045 return 65536;
2046 2046
2047 return pm->log16; 2047 return pm->log16;
2048 } 2048 }
2049 2049
2050 /* This is the case where the value was calculated at 8-bit precision then 2050 /* This is the case where the value was calculated at 8-bit precision then
2051 * scaled to 16 bits. 2051 * scaled to 16 bits.
2052 */ 2052 */
2053 if (pm->log8 == 0) 2053 if (pm->log8 == 0)
2054 return 65536; 2054 return 65536;
2055 2055
2056 return pm->log8 * 257; 2056 return pm->log8 * 257;
2057} 2057}
2058 2058
2059/* This complements the above by providing the appropriate quantization for the 2059/* This complements the above by providing the appropriate quantization for the
2060 * final value. Normally this would just be quantization to an integral value, 2060 * final value. Normally this would just be quantization to an integral value,
2061 * but in the 8 bit calculation case it's actually quantization to a multiple of 2061 * but in the 8 bit calculation case it's actually quantization to a multiple of
2062 * 257! 2062 * 257!
2063 */ 2063 */
2064static int output_quantization_factor(PNG_CONST png_modifier *pm, int in_depth, 2064static int output_quantization_factor(PNG_CONST png_modifier *pm, int in_depth,
2065 int out_depth) 2065 int out_depth)
2066{ 2066{
2067 if (out_depth == 16 && in_depth != 16 2067 if (out_depth == 16 && in_depth != 16
2068 && pm->calculations_use_input_precision) 2068 && pm->calculations_use_input_precision)
2069 return 257; 2069 return 257;
2070 else 2070 else
2071 return 1; 2071 return 1;
2072} 2072}
2073 2073
2074/* One modification structure must be provided for each chunk to be modified (in 2074/* One modification structure must be provided for each chunk to be modified (in
2075 * fact more than one can be provided if multiple separate changes are desired 2075 * fact more than one can be provided if multiple separate changes are desired
2076 * for a single chunk.) Modifications include adding a new chunk when a 2076 * for a single chunk.) Modifications include adding a new chunk when a
2077 * suitable chunk does not exist. 2077 * suitable chunk does not exist.
2078 * 2078 *
2079 * The caller of modify_fn will reset the CRC of the chunk and record 'modified' 2079 * The caller of modify_fn will reset the CRC of the chunk and record 'modified'
2080 * or 'added' as appropriate if the modify_fn returns 1 (true). If the 2080 * or 'added' as appropriate if the modify_fn returns 1 (true). If the
2081 * modify_fn is NULL the chunk is simply removed. 2081 * modify_fn is NULL the chunk is simply removed.
2082 */ 2082 */
2083typedef struct png_modification 2083typedef struct png_modification
2084{ 2084{
2085 struct png_modification *next; 2085 struct png_modification *next;
2086 png_uint_32 chunk; 2086 png_uint_32 chunk;
2087 2087
2088 /* If the following is NULL all matching chunks will be removed: */ 2088 /* If the following is NULL all matching chunks will be removed: */
2089 int (*modify_fn)(struct png_modifier *pm, 2089 int (*modify_fn)(struct png_modifier *pm,
2090 struct png_modification *me, int add); 2090 struct png_modification *me, int add);
2091 2091
2092 /* If the following is set to PLTE, IDAT or IEND and the chunk has not been 2092 /* If the following is set to PLTE, IDAT or IEND and the chunk has not been
2093 * found and modified (and there is a modify_fn) the modify_fn will be called 2093 * found and modified (and there is a modify_fn) the modify_fn will be called
2094 * to add the chunk before the relevant chunk. 2094 * to add the chunk before the relevant chunk.
2095 */ 2095 */
2096 png_uint_32 add; 2096 png_uint_32 add;
2097 unsigned int modified :1; /* Chunk was modified */ 2097 unsigned int modified :1; /* Chunk was modified */
2098 unsigned int added :1; /* Chunk was added */ 2098 unsigned int added :1; /* Chunk was added */
2099 unsigned int removed :1; /* Chunk was removed */ 2099 unsigned int removed :1; /* Chunk was removed */
2100} png_modification; 2100} png_modification;
2101 2101
2102static void 2102static void
2103modification_reset(png_modification *pmm) 2103modification_reset(png_modification *pmm)
2104{ 2104{
2105 if (pmm != NULL) 2105 if (pmm != NULL)
2106 { 2106 {
2107 pmm->modified = 0; 2107 pmm->modified = 0;
2108 pmm->added = 0; 2108 pmm->added = 0;
2109 pmm->removed = 0; 2109 pmm->removed = 0;
2110 modification_reset(pmm->next); 2110 modification_reset(pmm->next);
2111 } 2111 }
2112} 2112}
2113 2113
2114static void 2114static void
2115modification_init(png_modification *pmm) 2115modification_init(png_modification *pmm)
2116{ 2116{
2117 memset(pmm, 0, sizeof *pmm); 2117 memset(pmm, 0, sizeof *pmm);
2118 pmm->next = NULL; 2118 pmm->next = NULL;
2119 pmm->chunk = 0; 2119 pmm->chunk = 0;
2120 pmm->modify_fn = NULL; 2120 pmm->modify_fn = NULL;
2121 pmm->add = 0; 2121 pmm->add = 0;
2122 modification_reset(pmm); 2122 modification_reset(pmm);
2123} 2123}
2124 2124
2125static void 2125static void
2126modifier_current_encoding(PNG_CONST png_modifier *pm, color_encoding *ce) 2126modifier_current_encoding(PNG_CONST png_modifier *pm, color_encoding *ce)
2127{ 2127{
2128 if (pm->current_encoding != 0) 2128 if (pm->current_encoding != 0)
2129 *ce = *pm->current_encoding; 2129 *ce = *pm->current_encoding;
2130 2130
2131 else 2131 else
2132 memset(ce, 0, sizeof *ce); 2132 memset(ce, 0, sizeof *ce);
2133 2133
2134 ce->gamma = pm->current_gamma; 2134 ce->gamma = pm->current_gamma;
2135} 2135}
2136 2136
2137static size_t 2137static size_t
2138safecat_current_encoding(char *buffer, size_t bufsize, size_t pos, 2138safecat_current_encoding(char *buffer, size_t bufsize, size_t pos,
2139 PNG_CONST png_modifier *pm) 2139 PNG_CONST png_modifier *pm)
2140{ 2140{
2141 pos = safecat_color_encoding(buffer, bufsize, pos, pm->current_encoding, 2141 pos = safecat_color_encoding(buffer, bufsize, pos, pm->current_encoding,
2142 pm->current_gamma); 2142 pm->current_gamma);
2143 2143
2144 if (pm->encoding_ignored) 2144 if (pm->encoding_ignored)
2145 pos = safecat(buffer, bufsize, pos, "[overridden]"); 2145 pos = safecat(buffer, bufsize, pos, "[overridden]");
2146 2146
2147 return pos; 2147 return pos;
2148} 2148}
2149 2149
2150/* Iterate through the usefully testable color encodings. An encoding is one 2150/* Iterate through the usefully testable color encodings. An encoding is one
2151 * of: 2151 * of:
2152 * 2152 *
2153 * 1) Nothing (no color space, no gamma). 2153 * 1) Nothing (no color space, no gamma).
2154 * 2) Just a gamma value from the gamma array (including 1.0) 2154 * 2) Just a gamma value from the gamma array (including 1.0)
2155 * 3) A color space from the encodings array with the corresponding gamma. 2155 * 3) A color space from the encodings array with the corresponding gamma.
2156 * 4) The same, but with gamma 1.0 (only really useful with 16 bit calculations) 2156 * 4) The same, but with gamma 1.0 (only really useful with 16 bit calculations)
2157 * 2157 *
2158 * The iterator selects these in turn, the randomizer selects one at random, 2158 * The iterator selects these in turn, the randomizer selects one at random,
2159 * which is used depends on the setting of the 'test_exhaustive' flag. Notice 2159 * which is used depends on the setting of the 'test_exhaustive' flag. Notice
2160 * that this function changes the colour space encoding so it must only be 2160 * that this function changes the colour space encoding so it must only be
2161 * called on completion of the previous test. This is what 'modifier_reset' 2161 * called on completion of the previous test. This is what 'modifier_reset'
2162 * does, below. 2162 * does, below.
2163 * 2163 *
2164 * After the function has been called the 'repeat' flag will still be set; the 2164 * After the function has been called the 'repeat' flag will still be set; the
2165 * caller of modifier_reset must reset it at the start of each run of the test! 2165 * caller of modifier_reset must reset it at the start of each run of the test!
2166 */ 2166 */
2167static unsigned int 2167static unsigned int
2168modifier_total_encodings(PNG_CONST png_modifier *pm) 2168modifier_total_encodings(PNG_CONST png_modifier *pm)
2169{ 2169{
2170 return 1 + /* (1) nothing */ 2170 return 1 + /* (1) nothing */
2171 pm->ngammas + /* (2) gamma values to test */ 2171 pm->ngammas + /* (2) gamma values to test */
2172 pm->nencodings + /* (3) total number of encodings */ 2172 pm->nencodings + /* (3) total number of encodings */
2173 /* The following test only works after the first time through the 2173 /* The following test only works after the first time through the
2174 * png_modifier code because 'bit_depth' is set when the IHDR is read. 2174 * png_modifier code because 'bit_depth' is set when the IHDR is read.
2175 * modifier_reset, below, preserves the setting until after it has called 2175 * modifier_reset, below, preserves the setting until after it has called
2176 * the iterate function (also below.) 2176 * the iterate function (also below.)
2177 * 2177 *
2178 * For this reason do not rely on this function outside a call to 2178 * For this reason do not rely on this function outside a call to
2179 * modifier_reset. 2179 * modifier_reset.
2180 */ 2180 */
2181 ((pm->bit_depth == 16 || pm->assume_16_bit_calculations) ? 2181 ((pm->bit_depth == 16 || pm->assume_16_bit_calculations) ?
2182 pm->nencodings : 0); /* (4) encodings with gamma == 1.0 */ 2182 pm->nencodings : 0); /* (4) encodings with gamma == 1.0 */
2183} 2183}
2184 2184
2185static void 2185static void
2186modifier_encoding_iterate(png_modifier *pm) 2186modifier_encoding_iterate(png_modifier *pm)
2187{ 2187{
2188 if (!pm->repeat && /* Else something needs the current encoding again. */ 2188 if (!pm->repeat && /* Else something needs the current encoding again. */
2189 pm->test_uses_encoding) /* Some transform is encoding dependent */ 2189 pm->test_uses_encoding) /* Some transform is encoding dependent */
2190 { 2190 {
2191 if (pm->test_exhaustive) 2191 if (pm->test_exhaustive)
2192 { 2192 {
2193 if (++pm->encoding_counter >= modifier_total_encodings(pm)) 2193 if (++pm->encoding_counter >= modifier_total_encodings(pm))
2194 pm->encoding_counter = 0; /* This will stop the repeat */ 2194 pm->encoding_counter = 0; /* This will stop the repeat */
2195 } 2195 }
2196 2196
2197 else 2197 else
2198 { 2198 {
2199 /* Not exhaustive - choose an encoding at random; generate a number in 2199 /* Not exhaustive - choose an encoding at random; generate a number in
2200 * the range 1..(max-1), so the result is always non-zero: 2200 * the range 1..(max-1), so the result is always non-zero:
2201 */ 2201 */
2202 if (pm->encoding_counter == 0) 2202 if (pm->encoding_counter == 0)
2203 pm->encoding_counter = random_mod(modifier_total_encodings(pm)-1)+1; 2203 pm->encoding_counter = random_mod(modifier_total_encodings(pm)-1)+1;
2204 else 2204 else
2205 pm->encoding_counter = 0; 2205 pm->encoding_counter = 0;
2206 } 2206 }
2207 2207
2208 if (pm->encoding_counter > 0) 2208 if (pm->encoding_counter > 0)
2209 pm->repeat = 1; 2209 pm->repeat = 1;
2210 } 2210 }
2211 2211
2212 else if (!pm->repeat) 2212 else if (!pm->repeat)
2213 pm->encoding_counter = 0; 2213 pm->encoding_counter = 0;
2214} 2214}
2215 2215
2216static void 2216static void
2217modifier_reset(png_modifier *pm) 2217modifier_reset(png_modifier *pm)
2218{ 2218{
2219 store_read_reset(&pm->this); 2219 store_read_reset(&pm->this);
2220 pm->limit = 4E-3; 2220 pm->limit = 4E-3;
2221 pm->pending_len = pm->pending_chunk = 0; 2221 pm->pending_len = pm->pending_chunk = 0;
2222 pm->flush = pm->buffer_count = pm->buffer_position = 0; 2222 pm->flush = pm->buffer_count = pm->buffer_position = 0;
2223 pm->modifications = NULL; 2223 pm->modifications = NULL;
2224 pm->state = modifier_start; 2224 pm->state = modifier_start;
2225 modifier_encoding_iterate(pm); 2225 modifier_encoding_iterate(pm);
2226 /* The following must be set in the next run. In particular 2226 /* The following must be set in the next run. In particular
2227 * test_uses_encodings must be set in the _ini function of each transform 2227 * test_uses_encodings must be set in the _ini function of each transform
2228 * that looks at the encodings. (Not the 'add' function!) 2228 * that looks at the encodings. (Not the 'add' function!)
2229 */ 2229 */
2230 pm->test_uses_encoding = 0; 2230 pm->test_uses_encoding = 0;
2231 pm->current_gamma = 0; 2231 pm->current_gamma = 0;
2232 pm->current_encoding = 0; 2232 pm->current_encoding = 0;
2233 pm->encoding_ignored = 0; 2233 pm->encoding_ignored = 0;
2234 /* These only become value after IHDR is read: */ 2234 /* These only become value after IHDR is read: */
2235 pm->bit_depth = pm->colour_type = 0; 2235 pm->bit_depth = pm->colour_type = 0;
2236} 2236}
2237 2237
2238/* The following must be called before anything else to get the encoding set up 2238/* The following must be called before anything else to get the encoding set up
2239 * on the modifier. In particular it must be called before the transform init 2239 * on the modifier. In particular it must be called before the transform init
2240 * functions are called. 2240 * functions are called.
2241 */ 2241 */
2242static void 2242static void
2243modifier_set_encoding(png_modifier *pm) 2243modifier_set_encoding(png_modifier *pm)
2244{ 2244{
2245 /* Set the encoding to the one specified by the current encoding counter, 2245 /* Set the encoding to the one specified by the current encoding counter,
2246 * first clear out all the settings - this corresponds to an encoding_counter 2246 * first clear out all the settings - this corresponds to an encoding_counter
2247 * of 0. 2247 * of 0.
2248 */ 2248 */
2249 pm->current_gamma = 0; 2249 pm->current_gamma = 0;
2250 pm->current_encoding = 0; 2250 pm->current_encoding = 0;
2251 pm->encoding_ignored = 0; /* not ignored yet - happens in _ini functions. */ 2251 pm->encoding_ignored = 0; /* not ignored yet - happens in _ini functions. */
2252 2252
2253 /* Now, if required, set the gamma and encoding fields. */ 2253 /* Now, if required, set the gamma and encoding fields. */
2254 if (pm->encoding_counter > 0) 2254 if (pm->encoding_counter > 0)
2255 { 2255 {
2256 /* The gammas[] array is an array of screen gammas, not encoding gammas, 2256 /* The gammas[] array is an array of screen gammas, not encoding gammas,
2257 * so we need the inverse: 2257 * so we need the inverse:
2258 */ 2258 */
2259 if (pm->encoding_counter <= pm->ngammas) 2259 if (pm->encoding_counter <= pm->ngammas)
2260 pm->current_gamma = 1/pm->gammas[pm->encoding_counter-1]; 2260 pm->current_gamma = 1/pm->gammas[pm->encoding_counter-1];
2261 2261
2262 else 2262 else
2263 { 2263 {
2264 unsigned int i = pm->encoding_counter - pm->ngammas; 2264 unsigned int i = pm->encoding_counter - pm->ngammas;
2265 2265
2266 if (i >= pm->nencodings) 2266 if (i >= pm->nencodings)
2267 { 2267 {
2268 i %= pm->nencodings; 2268 i %= pm->nencodings;
2269 pm->current_gamma = 1; /* Linear, only in the 16 bit case */ 2269 pm->current_gamma = 1; /* Linear, only in the 16 bit case */
2270 } 2270 }
2271 2271
2272 else 2272 else
2273 pm->current_gamma = pm->encodings[i].gamma; 2273 pm->current_gamma = pm->encodings[i].gamma;
2274 2274
2275 pm->current_encoding = pm->encodings + i; 2275 pm->current_encoding = pm->encodings + i;
2276 } 2276 }
2277 } 2277 }
2278} 2278}
2279 2279
2280/* Enquiry functions to find out what is set. Notice that there is an implicit 2280/* Enquiry functions to find out what is set. Notice that there is an implicit
2281 * assumption below that the first encoding in the list is the one for sRGB. 2281 * assumption below that the first encoding in the list is the one for sRGB.
2282 */ 2282 */
2283static int 2283static int
2284modifier_color_encoding_is_sRGB(PNG_CONST png_modifier *pm) 2284modifier_color_encoding_is_sRGB(PNG_CONST png_modifier *pm)
2285{ 2285{
2286 return pm->current_encoding != 0 && pm->current_encoding == pm->encodings && 2286 return pm->current_encoding != 0 && pm->current_encoding == pm->encodings &&
2287 pm->current_encoding->gamma == pm->current_gamma; 2287 pm->current_encoding->gamma == pm->current_gamma;
2288} 2288}
2289 2289
2290static int 2290static int
2291modifier_color_encoding_is_set(PNG_CONST png_modifier *pm) 2291modifier_color_encoding_is_set(PNG_CONST png_modifier *pm)
2292{ 2292{
2293 return pm->current_gamma != 0; 2293 return pm->current_gamma != 0;
2294} 2294}
2295 2295
2296/* Convenience macros. */ 2296/* Convenience macros. */
2297#define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d)) 2297#define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))
2298#define CHUNK_IHDR CHUNK(73,72,68,82) 2298#define CHUNK_IHDR CHUNK(73,72,68,82)
2299#define CHUNK_PLTE CHUNK(80,76,84,69) 2299#define CHUNK_PLTE CHUNK(80,76,84,69)
2300#define CHUNK_IDAT CHUNK(73,68,65,84) 2300#define CHUNK_IDAT CHUNK(73,68,65,84)
2301#define CHUNK_IEND CHUNK(73,69,78,68) 2301#define CHUNK_IEND CHUNK(73,69,78,68)
2302#define CHUNK_cHRM CHUNK(99,72,82,77) 2302#define CHUNK_cHRM CHUNK(99,72,82,77)
2303#define CHUNK_gAMA CHUNK(103,65,77,65) 2303#define CHUNK_gAMA CHUNK(103,65,77,65)
2304#define CHUNK_sBIT CHUNK(115,66,73,84) 2304#define CHUNK_sBIT CHUNK(115,66,73,84)
2305#define CHUNK_sRGB CHUNK(115,82,71,66) 2305#define CHUNK_sRGB CHUNK(115,82,71,66)
2306 2306
2307/* The guts of modification are performed during a read. */ 2307/* The guts of modification are performed during a read. */
2308static void 2308static void
2309modifier_crc(png_bytep buffer) 2309modifier_crc(png_bytep buffer)
2310{ 2310{
2311 /* Recalculate the chunk CRC - a complete chunk must be in 2311 /* Recalculate the chunk CRC - a complete chunk must be in
2312 * the buffer, at the start. 2312 * the buffer, at the start.
2313 */ 2313 */
2314 uInt datalen = png_get_uint_32(buffer); 2314 uInt datalen = png_get_uint_32(buffer);
2315 uLong crc = crc32(0, buffer+4, datalen+4); 2315 uLong crc = crc32(0, buffer+4, datalen+4);
2316 /* The cast to png_uint_32 is safe because a crc32 is always a 32 bit value. 2316 /* The cast to png_uint_32 is safe because a crc32 is always a 32 bit value.
2317 */ 2317 */
2318 png_save_uint_32(buffer+datalen+8, (png_uint_32)crc); 2318 png_save_uint_32(buffer+datalen+8, (png_uint_32)crc);
2319} 2319}
2320 2320
2321static void 2321static void
2322modifier_setbuffer(png_modifier *pm) 2322modifier_setbuffer(png_modifier *pm)
2323{ 2323{
2324 modifier_crc(pm->buffer); 2324 modifier_crc(pm->buffer);
2325 pm->buffer_count = png_get_uint_32(pm->buffer)+12; 2325 pm->buffer_count = png_get_uint_32(pm->buffer)+12;
2326 pm->buffer_position = 0; 2326 pm->buffer_position = 0;
2327} 2327}
2328 2328
2329/* Separate the callback into the actual implementation (which is passed the 2329/* Separate the callback into the actual implementation (which is passed the
2330 * png_modifier explicitly) and the callback, which gets the modifier from the 2330 * png_modifier explicitly) and the callback, which gets the modifier from the
2331 * png_struct. 2331 * png_struct.
2332 */ 2332 */
2333static void 2333static void
2334modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st) 2334modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
2335{ 2335{
2336 while (st > 0) 2336 while (st > 0)
2337 { 2337 {
2338 size_t cb; 2338 size_t cb;
2339 png_uint_32 len, chunk; 2339 png_uint_32 len, chunk;
2340 png_modification *mod; 2340 png_modification *mod;
2341 2341
2342 if (pm->buffer_position >= pm->buffer_count) switch (pm->state) 2342 if (pm->buffer_position >= pm->buffer_count) switch (pm->state)
2343 { 2343 {
2344 static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; 2344 static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
2345 case modifier_start: 2345 case modifier_start:
2346 store_read_imp(&pm->this, pm->buffer, 8); /* size of signature. */ 2346 store_read_imp(&pm->this, pm->buffer, 8); /* size of signature. */
2347 pm->buffer_count = 8; 2347 pm->buffer_count = 8;
2348 pm->buffer_position = 0; 2348 pm->buffer_position = 0;
2349 2349
2350 if (memcmp(pm->buffer, sign, 8) != 0) 2350 if (memcmp(pm->buffer, sign, 8) != 0)
2351 png_error(pm->this.pread, "invalid PNG file signature"); 2351 png_error(pm->this.pread, "invalid PNG file signature");
2352 pm->state = modifier_signature; 2352 pm->state = modifier_signature;
2353 break; 2353 break;
2354 2354
2355 case modifier_signature: 2355 case modifier_signature:
2356 store_read_imp(&pm->this, pm->buffer, 13+12); /* size of IHDR */ 2356 store_read_imp(&pm->this, pm->buffer, 13+12); /* size of IHDR */
2357 pm->buffer_count = 13+12; 2357 pm->buffer_count = 13+12;
2358 pm->buffer_position = 0; 2358 pm->buffer_position = 0;
2359 2359
2360 if (png_get_uint_32(pm->buffer) != 13 || 2360 if (png_get_uint_32(pm->buffer) != 13 ||
2361 png_get_uint_32(pm->buffer+4) != CHUNK_IHDR) 2361 png_get_uint_32(pm->buffer+4) != CHUNK_IHDR)
2362 png_error(pm->this.pread, "invalid IHDR"); 2362 png_error(pm->this.pread, "invalid IHDR");
2363 2363
2364 /* Check the list of modifiers for modifications to the IHDR. */ 2364 /* Check the list of modifiers for modifications to the IHDR. */
2365 mod = pm->modifications; 2365 mod = pm->modifications;
2366 while (mod != NULL) 2366 while (mod != NULL)
2367 { 2367 {
2368 if (mod->chunk == CHUNK_IHDR && mod->modify_fn && 2368 if (mod->chunk == CHUNK_IHDR && mod->modify_fn &&
2369 (*mod->modify_fn)(pm, mod, 0)) 2369 (*mod->modify_fn)(pm, mod, 0))
2370 { 2370 {
2371 mod->modified = 1; 2371 mod->modified = 1;
2372 modifier_setbuffer(pm); 2372 modifier_setbuffer(pm);
2373 } 2373 }
2374 2374
2375 /* Ignore removal or add if IHDR! */ 2375 /* Ignore removal or add if IHDR! */
2376 mod = mod->next; 2376 mod = mod->next;
2377 } 2377 }
2378 2378
2379 /* Cache information from the IHDR (the modified one.) */ 2379 /* Cache information from the IHDR (the modified one.) */
2380 pm->bit_depth = pm->buffer[8+8]; 2380 pm->bit_depth = pm->buffer[8+8];
2381 pm->colour_type = pm->buffer[8+8+1]; 2381 pm->colour_type = pm->buffer[8+8+1];
2382 2382
2383 pm->state = modifier_IHDR; 2383 pm->state = modifier_IHDR;
2384 pm->flush = 0; 2384 pm->flush = 0;
2385 break; 2385 break;
2386 2386
2387 case modifier_IHDR: 2387 case modifier_IHDR:
2388 default: 2388 default:
2389 /* Read a new chunk and process it until we see PLTE, IDAT or 2389 /* Read a new chunk and process it until we see PLTE, IDAT or
2390 * IEND. 'flush' indicates that there is still some data to 2390 * IEND. 'flush' indicates that there is still some data to
2391 * output from the preceding chunk. 2391 * output from the preceding chunk.
2392 */ 2392 */
2393 if ((cb = pm->flush) > 0) 2393 if ((cb = pm->flush) > 0)
2394 { 2394 {
2395 if (cb > st) cb = st; 2395 if (cb > st) cb = st;
2396 pm->flush -= cb; 2396 pm->flush -= cb;
2397 store_read_imp(&pm->this, pb, cb); 2397 store_read_imp(&pm->this, pb, cb);
2398 pb += cb; 2398 pb += cb;
2399 st -= cb; 2399 st -= cb;
2400 if (st == 0) return; 2400 if (st == 0) return;
2401 } 2401 }
2402 2402
2403 /* No more bytes to flush, read a header, or handle a pending 2403 /* No more bytes to flush, read a header, or handle a pending
2404 * chunk. 2404 * chunk.
2405 */ 2405 */
2406 if (pm->pending_chunk != 0) 2406 if (pm->pending_chunk != 0)
2407 { 2407 {
2408 png_save_uint_32(pm->buffer, pm->pending_len); 2408 png_save_uint_32(pm->buffer, pm->pending_len);
2409 png_save_uint_32(pm->buffer+4, pm->pending_chunk); 2409 png_save_uint_32(pm->buffer+4, pm->pending_chunk);
2410 pm->pending_len = 0; 2410 pm->pending_len = 0;
2411 pm->pending_chunk = 0; 2411 pm->pending_chunk = 0;
2412 } 2412 }
2413 else 2413 else
2414 store_read_imp(&pm->this, pm->buffer, 8); 2414 store_read_imp(&pm->this, pm->buffer, 8);
2415 2415
2416 pm->buffer_count = 8; 2416 pm->buffer_count = 8;
2417 pm->buffer_position = 0; 2417 pm->buffer_position = 0;
2418 2418
2419 /* Check for something to modify or a terminator chunk. */ 2419 /* Check for something to modify or a terminator chunk. */
2420 len = png_get_uint_32(pm->buffer); 2420 len = png_get_uint_32(pm->buffer);
2421 chunk = png_get_uint_32(pm->buffer+4); 2421 chunk = png_get_uint_32(pm->buffer+4);
2422 2422
2423 /* Terminators first, they may have to be delayed for added 2423 /* Terminators first, they may have to be delayed for added
2424 * chunks 2424 * chunks
2425 */ 2425 */
2426 if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT || 2426 if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT ||
2427 chunk == CHUNK_IEND) 2427 chunk == CHUNK_IEND)
2428 { 2428 {
2429 mod = pm->modifications; 2429 mod = pm->modifications;
2430 2430
2431 while (mod != NULL) 2431 while (mod != NULL)
2432 { 2432 {
2433 if ((mod->add == chunk || 2433 if ((mod->add == chunk ||
2434 (mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT)) && 2434 (mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT)) &&
2435 mod->modify_fn != NULL && !mod->modified && !mod->added) 2435 mod->modify_fn != NULL && !mod->modified && !mod->added)
2436 { 2436 {
2437 /* Regardless of what the modify function does do not run 2437 /* Regardless of what the modify function does do not run
2438 * this again. 2438 * this again.
2439 */ 2439 */
2440 mod->added = 1; 2440 mod->added = 1;
2441 2441
2442 if ((*mod->modify_fn)(pm, mod, 1 /*add*/)) 2442 if ((*mod->modify_fn)(pm, mod, 1 /*add*/))
2443 { 2443 {
2444 /* Reset the CRC on a new chunk */ 2444 /* Reset the CRC on a new chunk */
2445 if (pm->buffer_count > 0) 2445 if (pm->buffer_count > 0)
2446 modifier_setbuffer(pm); 2446 modifier_setbuffer(pm);
2447 2447
2448 else 2448 else
2449 { 2449 {
2450 pm->buffer_position = 0; 2450 pm->buffer_position = 0;
2451 mod->removed = 1; 2451 mod->removed = 1;
2452 } 2452 }
2453 2453
2454 /* The buffer has been filled with something (we assume) 2454 /* The buffer has been filled with something (we assume)
2455 * so output this. Pend the current chunk. 2455 * so output this. Pend the current chunk.
2456 */ 2456 */
2457 pm->pending_len = len; 2457 pm->pending_len = len;
2458 pm->pending_chunk = chunk; 2458 pm->pending_chunk = chunk;
2459 break; /* out of while */ 2459 break; /* out of while */
2460 } 2460 }
2461 } 2461 }
2462 2462
2463 mod = mod->next; 2463 mod = mod->next;
2464 } 2464 }
2465 2465
2466 /* Don't do any further processing if the buffer was modified - 2466 /* Don't do any further processing if the buffer was modified -
2467 * otherwise the code will end up modifying a chunk that was 2467 * otherwise the code will end up modifying a chunk that was
2468 * just added. 2468 * just added.
2469 */ 2469 */
2470 if (mod != NULL) 2470 if (mod != NULL)
2471 break; /* out of switch */ 2471 break; /* out of switch */
2472 } 2472 }
2473 2473
2474 /* If we get to here then this chunk may need to be modified. To 2474 /* If we get to here then this chunk may need to be modified. To
2475 * do this it must be less than 1024 bytes in total size, otherwise 2475 * do this it must be less than 1024 bytes in total size, otherwise
2476 * it just gets flushed. 2476 * it just gets flushed.
2477 */ 2477 */
2478 if (len+12 <= sizeof pm->buffer) 2478 if (len+12 <= sizeof pm->buffer)
2479 { 2479 {
2480 store_read_imp(&pm->this, pm->buffer+pm->buffer_count, 2480 store_read_imp(&pm->this, pm->buffer+pm->buffer_count,
2481 len+12-pm->buffer_count); 2481 len+12-pm->buffer_count);
2482 pm->buffer_count = len+12; 2482 pm->buffer_count = len+12;
2483 2483
2484 /* Check for a modification, else leave it be. */ 2484 /* Check for a modification, else leave it be. */
2485 mod = pm->modifications; 2485 mod = pm->modifications;
2486 while (mod != NULL) 2486 while (mod != NULL)
2487 { 2487 {
2488 if (mod->chunk == chunk) 2488 if (mod->chunk == chunk)
2489 { 2489 {
2490 if (mod->modify_fn == NULL) 2490 if (mod->modify_fn == NULL)
2491 { 2491 {
2492 /* Remove this chunk */ 2492 /* Remove this chunk */
2493 pm->buffer_count = pm->buffer_position = 0; 2493 pm->buffer_count = pm->buffer_position = 0;
2494 mod->removed = 1; 2494 mod->removed = 1;
2495 break; /* Terminate the while loop */ 2495 break; /* Terminate the while loop */
2496 } 2496 }
2497 2497
2498 else if ((*mod->modify_fn)(pm, mod, 0)) 2498 else if ((*mod->modify_fn)(pm, mod, 0))
2499 { 2499 {
2500 mod->modified = 1; 2500 mod->modified = 1;
2501 /* The chunk may have been removed: */ 2501 /* The chunk may have been removed: */
2502 if (pm->buffer_count == 0) 2502 if (pm->buffer_count == 0)
2503 { 2503 {
2504 pm->buffer_position = 0; 2504 pm->buffer_position = 0;
2505 break; 2505 break;
2506 } 2506 }
2507 modifier_setbuffer(pm); 2507 modifier_setbuffer(pm);
2508 } 2508 }
2509 } 2509 }
2510 2510
2511 mod = mod->next; 2511 mod = mod->next;
2512 } 2512 }
2513 } 2513 }
2514 2514
2515 else 2515 else
2516 pm->flush = len+12 - pm->buffer_count; /* data + crc */ 2516 pm->flush = len+12 - pm->buffer_count; /* data + crc */
2517 2517
2518 /* Take the data from the buffer (if there is any). */ 2518 /* Take the data from the buffer (if there is any). */
2519 break; 2519 break;
2520 } 2520 }
2521 2521
2522 /* Here to read from the modifier buffer (not directly from 2522 /* Here to read from the modifier buffer (not directly from
2523 * the store, as in the flush case above.) 2523 * the store, as in the flush case above.)
2524 */ 2524 */
2525 cb = pm->buffer_count - pm->buffer_position; 2525 cb = pm->buffer_count - pm->buffer_position;
2526 2526
2527 if (cb > st) 2527 if (cb > st)
2528 cb = st; 2528 cb = st;
2529 2529
2530 memcpy(pb, pm->buffer + pm->buffer_position, cb); 2530 memcpy(pb, pm->buffer + pm->buffer_position, cb);
2531 st -= cb; 2531 st -= cb;
2532 pb += cb; 2532 pb += cb;
2533 pm->buffer_position += cb; 2533 pm->buffer_position += cb;
2534 } 2534 }
2535} 2535}
2536 2536
2537/* The callback: */ 2537/* The callback: */
2538static void 2538static void
2539modifier_read(png_structp pp, png_bytep pb, png_size_t st) 2539modifier_read(png_structp pp, png_bytep pb, png_size_t st)
2540{ 2540{
2541 png_modifier *pm = voidcast(png_modifier*, png_get_io_ptr(pp)); 2541 png_modifier *pm = voidcast(png_modifier*, png_get_io_ptr(pp));
2542 2542
2543 if (pm == NULL || pm->this.pread != pp) 2543 if (pm == NULL || pm->this.pread != pp)
2544 png_error(pp, "bad modifier_read call"); 2544 png_error(pp, "bad modifier_read call");
2545 2545
2546 modifier_read_imp(pm, pb, st); 2546 modifier_read_imp(pm, pb, st);
2547} 2547}
2548 2548
2549/* Like store_progressive_read but the data is getting changed as we go so we 2549/* Like store_progressive_read but the data is getting changed as we go so we
2550 * need a local buffer. 2550 * need a local buffer.
2551 */ 2551 */
2552static void 2552static void
2553modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi) 2553modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi)
2554{ 2554{
2555 if (pm->this.pread != pp || pm->this.current == NULL || 2555 if (pm->this.pread != pp || pm->this.current == NULL ||
2556 pm->this.next == NULL) 2556 pm->this.next == NULL)
2557 png_error(pp, "store state damaged (progressive)"); 2557 png_error(pp, "store state damaged (progressive)");
2558 2558
2559 /* This is another Horowitz and Hill random noise generator. In this case 2559 /* This is another Horowitz and Hill random noise generator. In this case
2560 * the aim is to stress the progressive reader with truly horrible variable 2560 * the aim is to stress the progressive reader with truly horrible variable
2561 * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers 2561 * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers
2562 * is generated. We could probably just count from 1 to 32767 and get as 2562 * is generated. We could probably just count from 1 to 32767 and get as
2563 * good a result. 2563 * good a result.
2564 */ 2564 */
2565 for (;;) 2565 for (;;)
2566 { 2566 {
2567 static png_uint_32 noise = 1; 2567 static png_uint_32 noise = 1;
2568 png_size_t cb, cbAvail; 2568 png_size_t cb, cbAvail;
2569 png_byte buffer[512]; 2569 png_byte buffer[512];
2570 2570
2571 /* Generate 15 more bits of stuff: */ 2571 /* Generate 15 more bits of stuff: */
2572 noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff); 2572 noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff);
2573 cb = noise & 0x1ff; 2573 cb = noise & 0x1ff;
2574 2574
2575 /* Check that this number of bytes are available (in the current buffer.) 2575 /* Check that this number of bytes are available (in the current buffer.)
2576 * (This doesn't quite work - the modifier might delete a chunk; unlikely 2576 * (This doesn't quite work - the modifier might delete a chunk; unlikely
2577 * but possible, it doesn't happen at present because the modifier only 2577 * but possible, it doesn't happen at present because the modifier only
2578 * adds chunks to standard images.) 2578 * adds chunks to standard images.)
2579 */ 2579 */
2580 cbAvail = store_read_buffer_avail(&pm->this); 2580 cbAvail = store_read_buffer_avail(&pm->this);
2581 if (pm->buffer_count > pm->buffer_position) 2581 if (pm->buffer_count > pm->buffer_position)
2582 cbAvail += pm->buffer_count - pm->buffer_position; 2582 cbAvail += pm->buffer_count - pm->buffer_position;
2583 2583
2584 if (cb > cbAvail) 2584 if (cb > cbAvail)
2585 { 2585 {
2586 /* Check for EOF: */ 2586 /* Check for EOF: */
2587 if (cbAvail == 0) 2587 if (cbAvail == 0)
2588 break; 2588 break;
2589 2589
2590 cb = cbAvail; 2590 cb = cbAvail;
2591 } 2591 }
2592 2592
2593 modifier_read_imp(pm, buffer, cb); 2593 modifier_read_imp(pm, buffer, cb);
2594 png_process_data(pp, pi, buffer, cb); 2594 png_process_data(pp, pi, buffer, cb);
2595 } 2595 }
2596 2596
2597 /* Check the invariants at the end (if this fails it's a problem in this 2597 /* Check the invariants at the end (if this fails it's a problem in this
2598 * file!) 2598 * file!)
2599 */ 2599 */
2600 if (pm->buffer_count > pm->buffer_position || 2600 if (pm->buffer_count > pm->buffer_position ||
2601 pm->this.next != &pm->this.current->data || 2601 pm->this.next != &pm->this.current->data ||
2602 pm->this.readpos < pm->this.current->datacount) 2602 pm->this.readpos < pm->this.current->datacount)
2603 png_error(pp, "progressive read implementation error"); 2603 png_error(pp, "progressive read implementation error");
2604} 2604}
2605 2605
2606/* Set up a modifier. */ 2606/* Set up a modifier. */
2607static png_structp 2607static png_structp
2608set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id, 2608set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id,
2609 PNG_CONST char *name) 2609 PNG_CONST char *name)
2610{ 2610{
2611 /* Do this first so that the modifier fields are cleared even if an error 2611 /* Do this first so that the modifier fields are cleared even if an error
2612 * happens allocating the png_struct. No allocation is done here so no 2612 * happens allocating the png_struct. No allocation is done here so no
2613 * cleanup is required. 2613 * cleanup is required.
2614 */ 2614 */
2615 pm->state = modifier_start; 2615 pm->state = modifier_start;
2616 pm->bit_depth = 0; 2616 pm->bit_depth = 0;
2617 pm->colour_type = 255; 2617 pm->colour_type = 255;
2618 2618
2619 pm->pending_len = 0; 2619 pm->pending_len = 0;
2620 pm->pending_chunk = 0; 2620 pm->pending_chunk = 0;
2621 pm->flush = 0; 2621 pm->flush = 0;
2622 pm->buffer_count = 0; 2622 pm->buffer_count = 0;
2623 pm->buffer_position = 0; 2623 pm->buffer_position = 0;
2624 2624
2625 return set_store_for_read(&pm->this, ppi, id, name); 2625 return set_store_for_read(&pm->this, ppi, id, name);
2626} 2626}
2627 2627
2628 2628
2629/******************************** MODIFICATIONS *******************************/ 2629/******************************** MODIFICATIONS *******************************/
2630/* Standard modifications to add chunks. These do not require the _SUPPORTED 2630/* Standard modifications to add chunks. These do not require the _SUPPORTED
2631 * macros because the chunks can be there regardless of whether this specific 2631 * macros because the chunks can be there regardless of whether this specific
2632 * libpng supports them. 2632 * libpng supports them.
2633 */ 2633 */
2634typedef struct gama_modification 2634typedef struct gama_modification
2635{ 2635{
2636 png_modification this; 2636 png_modification this;
2637 png_fixed_point gamma; 2637 png_fixed_point gamma;
2638} gama_modification; 2638} gama_modification;
2639 2639
2640static int 2640static int
2641gama_modify(png_modifier *pm, png_modification *me, int add) 2641gama_modify(png_modifier *pm, png_modification *me, int add)
2642{ 2642{
2643 UNUSED(add) 2643 UNUSED(add)
2644 /* This simply dumps the given gamma value into the buffer. */ 2644 /* This simply dumps the given gamma value into the buffer. */
2645 png_save_uint_32(pm->buffer, 4); 2645 png_save_uint_32(pm->buffer, 4);
2646 png_save_uint_32(pm->buffer+4, CHUNK_gAMA); 2646 png_save_uint_32(pm->buffer+4, CHUNK_gAMA);
2647 png_save_uint_32(pm->buffer+8, ((gama_modification*)me)->gamma); 2647 png_save_uint_32(pm->buffer+8, ((gama_modification*)me)->gamma);
2648 return 1; 2648 return 1;
2649} 2649}
2650 2650
2651static void 2651static void
2652gama_modification_init(gama_modification *me, png_modifier *pm, double gammad) 2652gama_modification_init(gama_modification *me, png_modifier *pm, double gammad)
2653{ 2653{
2654 double g; 2654 double g;
2655 2655
2656 modification_init(&me->this); 2656 modification_init(&me->this);
2657 me->this.chunk = CHUNK_gAMA; 2657 me->this.chunk = CHUNK_gAMA;
2658 me->this.modify_fn = gama_modify; 2658 me->this.modify_fn = gama_modify;
2659 me->this.add = CHUNK_PLTE; 2659 me->this.add = CHUNK_PLTE;
2660 g = fix(gammad); 2660 g = fix(gammad);
2661 me->gamma = (png_fixed_point)g; 2661 me->gamma = (png_fixed_point)g;
2662 me->this.next = pm->modifications; 2662 me->this.next = pm->modifications;
2663 pm->modifications = &me->this; 2663 pm->modifications = &me->this;
2664} 2664}
2665 2665
2666typedef struct chrm_modification 2666typedef struct chrm_modification
2667{ 2667{
2668 png_modification this; 2668 png_modification this;
2669 PNG_CONST color_encoding *encoding; 2669 PNG_CONST color_encoding *encoding;
2670 png_fixed_point wx, wy, rx, ry, gx, gy, bx, by; 2670 png_fixed_point wx, wy, rx, ry, gx, gy, bx, by;
2671} chrm_modification; 2671} chrm_modification;
2672 2672
2673static int 2673static int
2674chrm_modify(png_modifier *pm, png_modification *me, int add) 2674chrm_modify(png_modifier *pm, png_modification *me, int add)
2675{ 2675{
2676 UNUSED(add) 2676 UNUSED(add)
2677 /* As with gAMA this just adds the required cHRM chunk to the buffer. */ 2677 /* As with gAMA this just adds the required cHRM chunk to the buffer. */
2678 png_save_uint_32(pm->buffer , 32); 2678 png_save_uint_32(pm->buffer , 32);
2679 png_save_uint_32(pm->buffer+ 4, CHUNK_cHRM); 2679 png_save_uint_32(pm->buffer+ 4, CHUNK_cHRM);
2680 png_save_uint_32(pm->buffer+ 8, ((chrm_modification*)me)->wx); 2680 png_save_uint_32(pm->buffer+ 8, ((chrm_modification*)me)->wx);
2681 png_save_uint_32(pm->buffer+12, ((chrm_modification*)me)->wy); 2681 png_save_uint_32(pm->buffer+12, ((chrm_modification*)me)->wy);
2682 png_save_uint_32(pm->buffer+16, ((chrm_modification*)me)->rx); 2682 png_save_uint_32(pm->buffer+16, ((chrm_modification*)me)->rx);
2683 png_save_uint_32(pm->buffer+20, ((chrm_modification*)me)->ry); 2683 png_save_uint_32(pm->buffer+20, ((chrm_modification*)me)->ry);
2684 png_save_uint_32(pm->buffer+24, ((chrm_modification*)me)->gx); 2684 png_save_uint_32(pm->buffer+24, ((chrm_modification*)me)->gx);
2685 png_save_uint_32(pm->buffer+28, ((chrm_modification*)me)->gy); 2685 png_save_uint_32(pm->buffer+28, ((chrm_modification*)me)->gy);
2686 png_save_uint_32(pm->buffer+32, ((chrm_modification*)me)->bx); 2686 png_save_uint_32(pm->buffer+32, ((chrm_modification*)me)->bx);
2687 png_save_uint_32(pm->buffer+36, ((chrm_modification*)me)->by); 2687 png_save_uint_32(pm->buffer+36, ((chrm_modification*)me)->by);
2688 return 1; 2688 return 1;
2689} 2689}
2690 2690
2691static void 2691static void
2692chrm_modification_init(chrm_modification *me, png_modifier *pm, 2692chrm_modification_init(chrm_modification *me, png_modifier *pm,
2693 PNG_CONST color_encoding *encoding) 2693 PNG_CONST color_encoding *encoding)
2694{ 2694{
2695 CIE_color white = white_point(encoding); 2695 CIE_color white = white_point(encoding);
2696 2696
2697 /* Original end points: */ 2697 /* Original end points: */
2698 me->encoding = encoding; 2698 me->encoding = encoding;
2699 2699
2700 /* Chromaticities (in fixed point): */ 2700 /* Chromaticities (in fixed point): */
2701 me->wx = fix(chromaticity_x(white)); 2701 me->wx = fix(chromaticity_x(white));
2702 me->wy = fix(chromaticity_y(white)); 2702 me->wy = fix(chromaticity_y(white));
2703 2703
2704 me->rx = fix(chromaticity_x(encoding->red)); 2704 me->rx = fix(chromaticity_x(encoding->red));
2705 me->ry = fix(chromaticity_y(encoding->red)); 2705 me->ry = fix(chromaticity_y(encoding->red));
2706 me->gx = fix(chromaticity_x(encoding->green)); 2706 me->gx = fix(chromaticity_x(encoding->green));
2707 me->gy = fix(chromaticity_y(encoding->green)); 2707 me->gy = fix(chromaticity_y(encoding->green));
2708 me->bx = fix(chromaticity_x(encoding->blue)); 2708 me->bx = fix(chromaticity_x(encoding->blue));
2709 me->by = fix(chromaticity_y(encoding->blue)); 2709 me->by = fix(chromaticity_y(encoding->blue));
2710 2710
2711 modification_init(&me->this); 2711 modification_init(&me->this);
2712 me->this.chunk = CHUNK_cHRM; 2712 me->this.chunk = CHUNK_cHRM;
2713 me->this.modify_fn = chrm_modify; 2713 me->this.modify_fn = chrm_modify;
2714 me->this.add = CHUNK_PLTE; 2714 me->this.add = CHUNK_PLTE;
2715 me->this.next = pm->modifications; 2715 me->this.next = pm->modifications;
2716 pm->modifications = &me->this; 2716 pm->modifications = &me->this;
2717} 2717}
2718 2718
2719typedef struct srgb_modification 2719typedef struct srgb_modification
2720{ 2720{
2721 png_modification this; 2721 png_modification this;
2722 png_byte intent; 2722 png_byte intent;
2723} srgb_modification; 2723} srgb_modification;
2724 2724
2725static int 2725static int
2726srgb_modify(png_modifier *pm, png_modification *me, int add) 2726srgb_modify(png_modifier *pm, png_modification *me, int add)
2727{ 2727{
2728 UNUSED(add) 2728 UNUSED(add)
2729 /* As above, ignore add and just make a new chunk */ 2729 /* As above, ignore add and just make a new chunk */
2730 png_save_uint_32(pm->buffer, 1); 2730 png_save_uint_32(pm->buffer, 1);
2731 png_save_uint_32(pm->buffer+4, CHUNK_sRGB); 2731 png_save_uint_32(pm->buffer+4, CHUNK_sRGB);
2732 pm->buffer[8] = ((srgb_modification*)me)->intent; 2732 pm->buffer[8] = ((srgb_modification*)me)->intent;
2733 return 1; 2733 return 1;
2734} 2734}
2735 2735
2736static void 2736static void
2737srgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent) 2737srgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent)
2738{ 2738{
2739 modification_init(&me->this); 2739 modification_init(&me->this);
2740 me->this.chunk = CHUNK_sBIT; 2740 me->this.chunk = CHUNK_sBIT;
2741 2741
2742 if (intent <= 3) /* if valid, else *delete* sRGB chunks */ 2742 if (intent <= 3) /* if valid, else *delete* sRGB chunks */
2743 { 2743 {
2744 me->this.modify_fn = srgb_modify; 2744 me->this.modify_fn = srgb_modify;
2745 me->this.add = CHUNK_PLTE; 2745 me->this.add = CHUNK_PLTE;
2746 me->intent = intent; 2746 me->intent = intent;
2747 } 2747 }
2748 2748
2749 else 2749 else
2750 { 2750 {
2751 me->this.modify_fn = 0; 2751 me->this.modify_fn = 0;
2752 me->this.add = 0; 2752 me->this.add = 0;
2753 me->intent = 0; 2753 me->intent = 0;
2754 } 2754 }
2755 2755
2756 me->this.next = pm->modifications; 2756 me->this.next = pm->modifications;
2757 pm->modifications = &me->this; 2757 pm->modifications = &me->this;
2758} 2758}
2759 2759
2760typedef struct sbit_modification 2760typedef struct sbit_modification
2761{ 2761{
2762 png_modification this; 2762 png_modification this;
2763 png_byte sbit; 2763 png_byte sbit;
2764} sbit_modification; 2764} sbit_modification;
2765 2765
2766static int 2766static int
2767sbit_modify(png_modifier *pm, png_modification *me, int add) 2767sbit_modify(png_modifier *pm, png_modification *me, int add)
2768{ 2768{
2769 png_byte sbit = ((sbit_modification*)me)->sbit; 2769 png_byte sbit = ((sbit_modification*)me)->sbit;
2770 if (pm->bit_depth > sbit) 2770 if (pm->bit_depth > sbit)
2771 { 2771 {
2772 int cb = 0; 2772 int cb = 0;
2773 switch (pm->colour_type) 2773 switch (pm->colour_type)
2774 { 2774 {
2775 case 0: 2775 case 0:
2776 cb = 1; 2776 cb = 1;
2777 break; 2777 break;
2778 2778
2779 case 2: 2779 case 2:
2780 case 3: 2780 case 3:
2781 cb = 3; 2781 cb = 3;
2782 break; 2782 break;
2783 2783
2784 case 4: 2784 case 4:
2785 cb = 2; 2785 cb = 2;
2786 break; 2786 break;
2787 2787
2788 case 6: 2788 case 6:
2789 cb = 4; 2789 cb = 4;
2790 break; 2790 break;
2791 2791
2792 default: 2792 default:
2793 png_error(pm->this.pread, 2793 png_error(pm->this.pread,
2794 "unexpected colour type in sBIT modification"); 2794 "unexpected colour type in sBIT modification");
2795 } 2795 }
2796 2796
2797 png_save_uint_32(pm->buffer, cb); 2797 png_save_uint_32(pm->buffer, cb);
2798 png_save_uint_32(pm->buffer+4, CHUNK_sBIT); 2798 png_save_uint_32(pm->buffer+4, CHUNK_sBIT);
2799 2799
2800 while (cb > 0) 2800 while (cb > 0)
2801 (pm->buffer+8)[--cb] = sbit; 2801 (pm->buffer+8)[--cb] = sbit;
2802 2802
2803 return 1; 2803 return 1;
2804 } 2804 }
2805 else if (!add) 2805 else if (!add)
2806 { 2806 {
2807 /* Remove the sBIT chunk */ 2807 /* Remove the sBIT chunk */
2808 pm->buffer_count = pm->buffer_position = 0; 2808 pm->buffer_count = pm->buffer_position = 0;
2809 return 1; 2809 return 1;
2810 } 2810 }
2811 else 2811 else
2812 return 0; /* do nothing */ 2812 return 0; /* do nothing */
2813} 2813}
2814 2814
2815static void 2815static void
2816sbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit) 2816sbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit)
2817{ 2817{
2818 modification_init(&me->this); 2818 modification_init(&me->this);
2819 me->this.chunk = CHUNK_sBIT; 2819 me->this.chunk = CHUNK_sBIT;
2820 me->this.modify_fn = sbit_modify; 2820 me->this.modify_fn = sbit_modify;
2821 me->this.add = CHUNK_PLTE; 2821 me->this.add = CHUNK_PLTE;
2822 me->sbit = sbit; 2822 me->sbit = sbit;
2823 me->this.next = pm->modifications; 2823 me->this.next = pm->modifications;
2824 pm->modifications = &me->this; 2824 pm->modifications = &me->this;
2825} 2825}
2826#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 2826#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
2827 2827
2828/***************************** STANDARD PNG FILES *****************************/ 2828/***************************** STANDARD PNG FILES *****************************/
2829/* Standard files - write and save standard files. */ 2829/* Standard files - write and save standard files. */
2830/* There are two basic forms of standard images. Those which attempt to have 2830/* There are two basic forms of standard images. Those which attempt to have
2831 * all the possible pixel values (not possible for 16bpp images, but a range of 2831 * all the possible pixel values (not possible for 16bpp images, but a range of
2832 * values are produced) and those which have a range of image sizes. The former 2832 * values are produced) and those which have a range of image sizes. The former
2833 * are used for testing transforms, in particular gamma correction and bit 2833 * are used for testing transforms, in particular gamma correction and bit
2834 * reduction and increase. The latter are reserved for testing the behavior of 2834 * reduction and increase. The latter are reserved for testing the behavior of
2835 * libpng with respect to 'odd' image sizes - particularly small images where 2835 * libpng with respect to 'odd' image sizes - particularly small images where
2836 * rows become 1 byte and interlace passes disappear. 2836 * rows become 1 byte and interlace passes disappear.
2837 * 2837 *
2838 * The first, most useful, set are the 'transform' images, the second set of 2838 * The first, most useful, set are the 'transform' images, the second set of
2839 * small images are the 'size' images. 2839 * small images are the 'size' images.
2840 * 2840 *
2841 * The transform files are constructed with rows which fit into a 1024 byte row 2841 * The transform files are constructed with rows which fit into a 1024 byte row
2842 * buffer. This makes allocation easier below. Further regardless of the file 2842 * buffer. This makes allocation easier below. Further regardless of the file
2843 * format every row has 128 pixels (giving 1024 bytes for 64bpp formats). 2843 * format every row has 128 pixels (giving 1024 bytes for 64bpp formats).
2844 * 2844 *
2845 * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed 2845 * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed
2846 * and with an ID derived from the colour type, bit depth and interlace type 2846 * and with an ID derived from the colour type, bit depth and interlace type
2847 * as above (FILEID). The width (128) and height (variable) are not stored in 2847 * as above (FILEID). The width (128) and height (variable) are not stored in
2848 * the FILEID - instead the fields are set to 0, indicating a transform file. 2848 * the FILEID - instead the fields are set to 0, indicating a transform file.
2849 * 2849 *
2850 * The size files ar constructed with rows a maximum of 128 bytes wide, allowing 2850 * The size files ar constructed with rows a maximum of 128 bytes wide, allowing
2851 * a maximum width of 16 pixels (for the 64bpp case.) They also have a maximum 2851 * a maximum width of 16 pixels (for the 64bpp case.) They also have a maximum
2852 * height of 16 rows. The width and height are stored in the FILEID and, being 2852 * height of 16 rows. The width and height are stored in the FILEID and, being
2853 * non-zero, indicate a size file. 2853 * non-zero, indicate a size file.
2854 * 2854 *
2855 * For palette image (colour type 3) multiple transform images are stored with 2855 * For palette image (colour type 3) multiple transform images are stored with
2856 * the same bit depth to allow testing of more colour combinations - 2856 * the same bit depth to allow testing of more colour combinations -
2857 * particularly important for testing the gamma code because libpng uses a 2857 * particularly important for testing the gamma code because libpng uses a
2858 * different code path for palette images. For size images a single palette is 2858 * different code path for palette images. For size images a single palette is
2859 * used. 2859 * used.
2860 */ 2860 */
2861 2861
2862/* Make a 'standard' palette. Because there are only 256 entries in a palette 2862/* Make a 'standard' palette. Because there are only 256 entries in a palette
2863 * (maximum) this actually makes a random palette in the hope that enough tests 2863 * (maximum) this actually makes a random palette in the hope that enough tests
2864 * will catch enough errors. (Note that the same palette isn't produced every 2864 * will catch enough errors. (Note that the same palette isn't produced every
2865 * time for the same test - it depends on what previous tests have been run - 2865 * time for the same test - it depends on what previous tests have been run -
2866 * but a given set of arguments to pngvalid will always produce the same palette 2866 * but a given set of arguments to pngvalid will always produce the same palette
2867 * at the same test! This is why pseudo-random number generators are useful for 2867 * at the same test! This is why pseudo-random number generators are useful for
2868 * testing.) 2868 * testing.)
2869 * 2869 *
2870 * The store must be open for write when this is called, otherwise an internal 2870 * The store must be open for write when this is called, otherwise an internal
2871 * error will occur. This routine contains its own magic number seed, so the 2871 * error will occur. This routine contains its own magic number seed, so the
2872 * palettes generated don't change if there are intervening errors (changing the 2872 * palettes generated don't change if there are intervening errors (changing the
2873 * calls to the store_mark seed.) 2873 * calls to the store_mark seed.)
2874 */ 2874 */
2875static store_palette_entry * 2875static store_palette_entry *
2876make_standard_palette(png_store* ps, int npalette, int do_tRNS) 2876make_standard_palette(png_store* ps, int npalette, int do_tRNS)
2877{ 2877{
2878 static png_uint_32 palette_seed[2] = { 0x87654321, 9 }; 2878 static png_uint_32 palette_seed[2] = { 0x87654321, 9 };
2879 2879
2880 int i = 0; 2880 int i = 0;
2881 png_byte values[256][4]; 2881 png_byte values[256][4];
2882 2882
2883 /* Always put in black and white plus the six primary and secondary colors. 2883 /* Always put in black and white plus the six primary and secondary colors.
2884 */ 2884 */
2885 for (; i<8; ++i) 2885 for (; i<8; ++i)
2886 { 2886 {
2887 values[i][1] = (i&1) ? 255 : 0; 2887 values[i][1] = (i&1) ? 255 : 0;
2888 values[i][2] = (i&2) ? 255 : 0; 2888 values[i][2] = (i&2) ? 255 : 0;
2889 values[i][3] = (i&4) ? 255 : 0; 2889 values[i][3] = (i&4) ? 255 : 0;
2890 } 2890 }
2891 2891
2892 /* Then add 62 grays (one quarter of the remaining 256 slots). */ 2892 /* Then add 62 grays (one quarter of the remaining 256 slots). */
2893 { 2893 {
2894 int j = 0; 2894 int j = 0;
2895 png_byte random_bytes[4]; 2895 png_byte random_bytes[4];
2896 png_byte need[256]; 2896 png_byte need[256];
2897 2897
2898 need[0] = 0; /*got black*/ 2898 need[0] = 0; /*got black*/
2899 memset(need+1, 1, (sizeof need)-2); /*need these*/ 2899 memset(need+1, 1, (sizeof need)-2); /*need these*/
2900 need[255] = 0; /*but not white*/ 2900 need[255] = 0; /*but not white*/
2901 2901
2902 while (i<70) 2902 while (i<70)
2903 { 2903 {
2904 png_byte b; 2904 png_byte b;
2905 2905
2906 if (j==0) 2906 if (j==0)
2907 { 2907 {
2908 make_four_random_bytes(palette_seed, random_bytes); 2908 make_four_random_bytes(palette_seed, random_bytes);
2909 j = 4; 2909 j = 4;
2910 } 2910 }
2911 2911
2912 b = random_bytes[--j]; 2912 b = random_bytes[--j];
2913 if (need[b]) 2913 if (need[b])
2914 { 2914 {
2915 values[i][1] = b; 2915 values[i][1] = b;
2916 values[i][2] = b; 2916 values[i][2] = b;
2917 values[i++][3] = b; 2917 values[i++][3] = b;
2918 } 2918 }
2919 } 2919 }
2920 } 2920 }
2921 2921
2922 /* Finally add 192 colors at random - don't worry about matches to things we 2922 /* Finally add 192 colors at random - don't worry about matches to things we
2923 * already have, chance is less than 1/65536. Don't worry about grays, 2923 * already have, chance is less than 1/65536. Don't worry about grays,
2924 * chance is the same, so we get a duplicate or extra gray less than 1 time 2924 * chance is the same, so we get a duplicate or extra gray less than 1 time
2925 * in 170. 2925 * in 170.
2926 */ 2926 */
2927 for (; i<256; ++i) 2927 for (; i<256; ++i)
2928 make_four_random_bytes(palette_seed, values[i]); 2928 make_four_random_bytes(palette_seed, values[i]);
2929 2929
2930 /* Fill in the alpha values in the first byte. Just use all possible values 2930 /* Fill in the alpha values in the first byte. Just use all possible values
2931 * (0..255) in an apparently random order: 2931 * (0..255) in an apparently random order:
2932 */ 2932 */
2933 { 2933 {
2934 store_palette_entry *palette; 2934 store_palette_entry *palette;
2935 png_byte selector[4]; 2935 png_byte selector[4];
2936 2936
2937 make_four_random_bytes(palette_seed, selector); 2937 make_four_random_bytes(palette_seed, selector);
2938 2938
2939 if (do_tRNS) 2939 if (do_tRNS)
2940 for (i=0; i<256; ++i) 2940 for (i=0; i<256; ++i)
2941 values[i][0] = (png_byte)(i ^ selector[0]); 2941 values[i][0] = (png_byte)(i ^ selector[0]);
2942 2942
2943 else 2943 else
2944 for (i=0; i<256; ++i) 2944 for (i=0; i<256; ++i)
2945 values[i][0] = 255; /* no transparency/tRNS chunk */ 2945 values[i][0] = 255; /* no transparency/tRNS chunk */
2946 2946
2947 /* 'values' contains 256 ARGB values, but we only need 'npalette'. 2947 /* 'values' contains 256 ARGB values, but we only need 'npalette'.
2948 * 'npalette' will always be a power of 2: 2, 4, 16 or 256. In the low 2948 * 'npalette' will always be a power of 2: 2, 4, 16 or 256. In the low
2949 * bit depth cases select colors at random, else it is difficult to have 2949 * bit depth cases select colors at random, else it is difficult to have
2950 * a set of low bit depth palette test with any chance of a reasonable 2950 * a set of low bit depth palette test with any chance of a reasonable
2951 * range of colors. Do this by randomly permuting values into the low 2951 * range of colors. Do this by randomly permuting values into the low
2952 * 'npalette' entries using an XOR mask generated here. This also 2952 * 'npalette' entries using an XOR mask generated here. This also
2953 * permutes the npalette == 256 case in a potentially useful way (there is 2953 * permutes the npalette == 256 case in a potentially useful way (there is
2954 * no relationship between palette index and the color value therein!) 2954 * no relationship between palette index and the color value therein!)
2955 */ 2955 */
2956 palette = store_write_palette(ps, npalette); 2956 palette = store_write_palette(ps, npalette);
2957 2957
2958 for (i=0; i<npalette; ++i) 2958 for (i=0; i<npalette; ++i)
2959 { 2959 {
2960 palette[i].alpha = values[i ^ selector[1]][0]; 2960 palette[i].alpha = values[i ^ selector[1]][0];
2961 palette[i].red = values[i ^ selector[1]][1]; 2961 palette[i].red = values[i ^ selector[1]][1];
2962 palette[i].green = values[i ^ selector[1]][2]; 2962 palette[i].green = values[i ^ selector[1]][2];
2963 palette[i].blue = values[i ^ selector[1]][3]; 2963 palette[i].blue = values[i ^ selector[1]][3];
2964 } 2964 }
2965 2965
2966 return palette; 2966 return palette;
2967 } 2967 }
2968} 2968}
2969 2969
2970/* Initialize a standard palette on a write stream. The 'do_tRNS' argument 2970/* Initialize a standard palette on a write stream. The 'do_tRNS' argument
2971 * indicates whether or not to also set the tRNS chunk. 2971 * indicates whether or not to also set the tRNS chunk.
2972 */ 2972 */
2973static void 2973static void
2974init_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette, 2974init_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette,
2975 int do_tRNS) 2975 int do_tRNS)
2976{ 2976{
2977 store_palette_entry *ppal = make_standard_palette(ps, npalette, do_tRNS); 2977 store_palette_entry *ppal = make_standard_palette(ps, npalette, do_tRNS);
2978 2978
2979 { 2979 {
2980 int i; 2980 int i;
2981 png_color palette[256]; 2981 png_color palette[256];
2982 2982
2983 /* Set all entries to detect overread errors. */ 2983 /* Set all entries to detect overread errors. */
2984 for (i=0; i<npalette; ++i) 2984 for (i=0; i<npalette; ++i)
2985 { 2985 {
2986 palette[i].red = ppal[i].red; 2986 palette[i].red = ppal[i].red;
2987 palette[i].green = ppal[i].green; 2987 palette[i].green = ppal[i].green;
2988 palette[i].blue = ppal[i].blue; 2988 palette[i].blue = ppal[i].blue;
2989 } 2989 }
2990 2990
2991 /* Just in case fill in the rest with detectable values: */ 2991 /* Just in case fill in the rest with detectable values: */
2992 for (; i<256; ++i) 2992 for (; i<256; ++i)
2993 palette[i].red = palette[i].green = palette[i].blue = 42; 2993 palette[i].red = palette[i].green = palette[i].blue = 42;
2994 2994
2995 png_set_PLTE(pp, pi, palette, npalette); 2995 png_set_PLTE(pp, pi, palette, npalette);
2996 } 2996 }
2997 2997
2998 if (do_tRNS) 2998 if (do_tRNS)
2999 { 2999 {
3000 int i, j; 3000 int i, j;
3001 png_byte tRNS[256]; 3001 png_byte tRNS[256];
3002 3002
3003 /* Set all the entries, but skip trailing opaque entries */ 3003 /* Set all the entries, but skip trailing opaque entries */
3004 for (i=j=0; i<npalette; ++i) 3004 for (i=j=0; i<npalette; ++i)
3005 if ((tRNS[i] = ppal[i].alpha) < 255) 3005 if ((tRNS[i] = ppal[i].alpha) < 255)
3006 j = i+1; 3006 j = i+1;
3007 3007
3008 /* Fill in the remainder with a detectable value: */ 3008 /* Fill in the remainder with a detectable value: */
3009 for (; i<256; ++i) 3009 for (; i<256; ++i)
3010 tRNS[i] = 24; 3010 tRNS[i] = 24;
3011 3011
3012 if (j > 0) 3012 if (j > 0)
3013 png_set_tRNS(pp, pi, tRNS, j, 0/*color*/); 3013 png_set_tRNS(pp, pi, tRNS, j, 0/*color*/);
3014 } 3014 }
3015} 3015}
3016 3016
3017/* The number of passes is related to the interlace type. There was no libpng 3017/* The number of passes is related to the interlace type. There was no libpng
3018 * API to determine this prior to 1.5, so we need an inquiry function: 3018 * API to determine this prior to 1.5, so we need an inquiry function:
3019 */ 3019 */
3020static int 3020static int
3021npasses_from_interlace_type(png_structp pp, int interlace_type) 3021npasses_from_interlace_type(png_structp pp, int interlace_type)
3022{ 3022{
3023 switch (interlace_type) 3023 switch (interlace_type)
3024 { 3024 {
3025 default: 3025 default:
3026 png_error(pp, "invalid interlace type"); 3026 png_error(pp, "invalid interlace type");
3027 3027
3028 case PNG_INTERLACE_NONE: 3028 case PNG_INTERLACE_NONE:
3029 return 1; 3029 return 1;
3030 3030
3031 case PNG_INTERLACE_ADAM7: 3031 case PNG_INTERLACE_ADAM7:
3032 return PNG_INTERLACE_ADAM7_PASSES; 3032 return PNG_INTERLACE_ADAM7_PASSES;
3033 } 3033 }
3034} 3034}
3035 3035
3036static unsigned int 3036static unsigned int
3037bit_size(png_structp pp, png_byte colour_type, png_byte bit_depth) 3037bit_size(png_structp pp, png_byte colour_type, png_byte bit_depth)
3038{ 3038{
3039 switch (colour_type) 3039 switch (colour_type)
3040 { 3040 {
3041 default: png_error(pp, "invalid color type"); 3041 default: png_error(pp, "invalid color type");
3042 3042
3043 case 0: return bit_depth; 3043 case 0: return bit_depth;
3044 3044
3045 case 2: return 3*bit_depth; 3045 case 2: return 3*bit_depth;
3046 3046
3047 case 3: return bit_depth; 3047 case 3: return bit_depth;
3048 3048
3049 case 4: return 2*bit_depth; 3049 case 4: return 2*bit_depth;
3050 3050
3051 case 6: return 4*bit_depth; 3051 case 6: return 4*bit_depth;
3052 } 3052 }
3053} 3053}
3054 3054
3055#define TRANSFORM_WIDTH 128U 3055#define TRANSFORM_WIDTH 128U
3056#define TRANSFORM_ROWMAX (TRANSFORM_WIDTH*8U) 3056#define TRANSFORM_ROWMAX (TRANSFORM_WIDTH*8U)
3057#define SIZE_ROWMAX (16*8U) /* 16 pixels, max 8 bytes each - 128 bytes */ 3057#define SIZE_ROWMAX (16*8U) /* 16 pixels, max 8 bytes each - 128 bytes */
3058#define STANDARD_ROWMAX TRANSFORM_ROWMAX /* The larger of the two */ 3058#define STANDARD_ROWMAX TRANSFORM_ROWMAX /* The larger of the two */
3059#define SIZE_HEIGHTMAX 16 /* Maximum range of size images */ 3059#define SIZE_HEIGHTMAX 16 /* Maximum range of size images */
3060 3060
3061static size_t 3061static size_t
3062transform_rowsize(png_structp pp, png_byte colour_type, png_byte bit_depth) 3062transform_rowsize(png_structp pp, png_byte colour_type, png_byte bit_depth)
3063{ 3063{
3064 return (TRANSFORM_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8; 3064 return (TRANSFORM_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8;
3065} 3065}
3066 3066
3067/* transform_width(pp, colour_type, bit_depth) current returns the same number 3067/* transform_width(pp, colour_type, bit_depth) current returns the same number
3068 * every time, so just use a macro: 3068 * every time, so just use a macro:
3069 */ 3069 */
3070#define transform_width(pp, colour_type, bit_depth) TRANSFORM_WIDTH 3070#define transform_width(pp, colour_type, bit_depth) TRANSFORM_WIDTH
3071 3071
3072static png_uint_32 3072static png_uint_32
3073transform_height(png_structp pp, png_byte colour_type, png_byte bit_depth) 3073transform_height(png_structp pp, png_byte colour_type, png_byte bit_depth)
3074{ 3074{
3075 switch (bit_size(pp, colour_type, bit_depth)) 3075 switch (bit_size(pp, colour_type, bit_depth))
3076 { 3076 {
3077 case 1: 3077 case 1:
3078 case 2: 3078 case 2:
3079 case 4: 3079 case 4:
3080 return 1; /* Total of 128 pixels */ 3080 return 1; /* Total of 128 pixels */
3081 3081
3082 case 8: 3082 case 8:
3083 return 2; /* Total of 256 pixels/bytes */ 3083 return 2; /* Total of 256 pixels/bytes */
3084 3084
3085 case 16: 3085 case 16:
3086 return 512; /* Total of 65536 pixels */ 3086 return 512; /* Total of 65536 pixels */
3087 3087
3088 case 24: 3088 case 24:
3089 case 32: 3089 case 32:
3090 return 512; /* 65536 pixels */ 3090 return 512; /* 65536 pixels */
3091 3091
3092 case 48: 3092 case 48:
3093 case 64: 3093 case 64:
3094 return 2048;/* 4 x 65536 pixels. */ 3094 return 2048;/* 4 x 65536 pixels. */
3095# define TRANSFORM_HEIGHTMAX 2048 3095# define TRANSFORM_HEIGHTMAX 2048
3096 3096
3097 default: 3097 default:
3098 return 0; /* Error, will be caught later */ 3098 return 0; /* Error, will be caught later */
3099 } 3099 }
3100} 3100}
3101 3101
3102/* The following can only be defined here, now we have the definitions 3102/* The following can only be defined here, now we have the definitions
3103 * of the transform image sizes. 3103 * of the transform image sizes.
3104 */ 3104 */
3105static png_uint_32 3105static png_uint_32
3106standard_width(png_structp pp, png_uint_32 id) 3106standard_width(png_structp pp, png_uint_32 id)
3107{ 3107{
3108 png_uint_32 width = WIDTH_FROM_ID(id); 3108 png_uint_32 width = WIDTH_FROM_ID(id);
3109 UNUSED(pp) 3109 UNUSED(pp)
3110 3110
3111 if (width == 0) 3111 if (width == 0)
3112 width = transform_width(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)); 3112 width = transform_width(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
3113 3113
3114 return width; 3114 return width;
3115} 3115}
3116 3116
3117static png_uint_32 3117static png_uint_32
3118standard_height(png_structp pp, png_uint_32 id) 3118standard_height(png_structp pp, png_uint_32 id)
3119{ 3119{
3120 png_uint_32 height = HEIGHT_FROM_ID(id); 3120 png_uint_32 height = HEIGHT_FROM_ID(id);
3121 3121
3122 if (height == 0) 3122 if (height == 0)
3123 height = transform_height(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)); 3123 height = transform_height(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
3124 3124
3125 return height; 3125 return height;
3126} 3126}
3127 3127
3128static png_uint_32 3128static png_uint_32
3129standard_rowsize(png_structp pp, png_uint_32 id) 3129standard_rowsize(png_structp pp, png_uint_32 id)
3130{ 3130{
3131 png_uint_32 width = standard_width(pp, id); 3131 png_uint_32 width = standard_width(pp, id);
3132 3132
3133 /* This won't overflow: */ 3133 /* This won't overflow: */
3134 width *= bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)); 3134 width *= bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
3135 return (width + 7) / 8; 3135 return (width + 7) / 8;
3136} 3136}
3137 3137
3138static void 3138static void
3139transform_row(png_structp pp, png_byte buffer[TRANSFORM_ROWMAX], 3139transform_row(png_structp pp, png_byte buffer[TRANSFORM_ROWMAX],
3140 png_byte colour_type, png_byte bit_depth, png_uint_32 y) 3140 png_byte colour_type, png_byte bit_depth, png_uint_32 y)
3141{ 3141{
3142 png_uint_32 v = y << 7; 3142 png_uint_32 v = y << 7;
3143 png_uint_32 i = 0; 3143 png_uint_32 i = 0;
3144 3144
3145 switch (bit_size(pp, colour_type, bit_depth)) 3145 switch (bit_size(pp, colour_type, bit_depth))
3146 { 3146 {
3147 case 1: 3147 case 1:
3148 while (i<128/8) buffer[i] = v & 0xff, v += 17, ++i; 3148 while (i<128/8) buffer[i] = v & 0xff, v += 17, ++i;
3149 return; 3149 return;
3150 3150
3151 case 2: 3151 case 2:
3152 while (i<128/4) buffer[i] = v & 0xff, v += 33, ++i; 3152 while (i<128/4) buffer[i] = v & 0xff, v += 33, ++i;
3153 return; 3153 return;
3154 3154
3155 case 4: 3155 case 4:
3156 while (i<128/2) buffer[i] = v & 0xff, v += 65, ++i; 3156 while (i<128/2) buffer[i] = v & 0xff, v += 65, ++i;
3157 return; 3157 return;
3158 3158
3159 case 8: 3159 case 8:
3160 /* 256 bytes total, 128 bytes in each row set as follows: */ 3160 /* 256 bytes total, 128 bytes in each row set as follows: */
3161 while (i<128) buffer[i] = v & 0xff, ++v, ++i; 3161 while (i<128) buffer[i] = v & 0xff, ++v, ++i;
3162 return; 3162 return;
3163 3163
3164 case 16: 3164 case 16:
3165 /* Generate all 65536 pixel values in order, which includes the 8 bit 3165 /* Generate all 65536 pixel values in order, which includes the 8 bit
3166 * GA case as well as the 16 bit G case. 3166 * GA case as well as the 16 bit G case.
3167 */ 3167 */
3168 while (i<128) 3168 while (i<128)
3169 buffer[2*i] = (v>>8) & 0xff, buffer[2*i+1] = v & 0xff, ++v, ++i; 3169 buffer[2*i] = (v>>8) & 0xff, buffer[2*i+1] = v & 0xff, ++v, ++i;
3170 3170
3171 return; 3171 return;
3172 3172
3173 case 24: 3173 case 24:
3174 /* 65535 pixels, but rotate the values. */ 3174 /* 65535 pixels, but rotate the values. */
3175 while (i<128) 3175 while (i<128)
3176 { 3176 {
3177 /* Three bytes per pixel, r, g, b, make b by r^g */ 3177 /* Three bytes per pixel, r, g, b, make b by r^g */
3178 buffer[3*i+0] = (v >> 8) & 0xff; 3178 buffer[3*i+0] = (v >> 8) & 0xff;
3179 buffer[3*i+1] = v & 0xff; 3179 buffer[3*i+1] = v & 0xff;
3180 buffer[3*i+2] = ((v >> 8) ^ v) & 0xff; 3180 buffer[3*i+2] = ((v >> 8) ^ v) & 0xff;
3181 ++v; 3181 ++v;
3182 ++i; 3182 ++i;
3183 } 3183 }
3184 3184
3185 return; 3185 return;
3186 3186
3187 case 32: 3187 case 32:
3188 /* 65535 pixels, r, g, b, a; just replicate */ 3188 /* 65535 pixels, r, g, b, a; just replicate */
3189 while (i<128) 3189 while (i<128)
3190 { 3190 {
3191 buffer[4*i+0] = (v >> 8) & 0xff; 3191 buffer[4*i+0] = (v >> 8) & 0xff;
3192 buffer[4*i+1] = v & 0xff; 3192 buffer[4*i+1] = v & 0xff;
3193 buffer[4*i+2] = (v >> 8) & 0xff; 3193 buffer[4*i+2] = (v >> 8) & 0xff;
3194 buffer[4*i+3] = v & 0xff; 3194 buffer[4*i+3] = v & 0xff;
3195 ++v; 3195 ++v;
3196 ++i; 3196 ++i;
3197 } 3197 }
3198 3198
3199 return; 3199 return;
3200 3200
3201 case 48: 3201 case 48:
3202 /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at 3202 /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at
3203 * each pixel, g increase by 257 (0x101) and 'b' by 0x1111: 3203 * each pixel, g increase by 257 (0x101) and 'b' by 0x1111:
3204 */ 3204 */
3205 while (i<128) 3205 while (i<128)
3206 { 3206 {
3207 png_uint_32 t = v++; 3207 png_uint_32 t = v++;
3208 buffer[6*i+0] = (t >> 8) & 0xff; 3208 buffer[6*i+0] = (t >> 8) & 0xff;
3209 buffer[6*i+1] = t & 0xff; 3209 buffer[6*i+1] = t & 0xff;
3210 t *= 257; 3210 t *= 257;
3211 buffer[6*i+2] = (t >> 8) & 0xff; 3211 buffer[6*i+2] = (t >> 8) & 0xff;
3212 buffer[6*i+3] = t & 0xff; 3212 buffer[6*i+3] = t & 0xff;
3213 t *= 17; 3213 t *= 17;
3214 buffer[6*i+4] = (t >> 8) & 0xff; 3214 buffer[6*i+4] = (t >> 8) & 0xff;
3215 buffer[6*i+5] = t & 0xff; 3215 buffer[6*i+5] = t & 0xff;
3216 ++i; 3216 ++i;
3217 } 3217 }
3218 3218
3219 return; 3219 return;
3220 3220
3221 case 64: 3221 case 64:
3222 /* As above in the 32 bit case. */ 3222 /* As above in the 32 bit case. */
3223 while (i<128) 3223 while (i<128)
3224 { 3224 {
3225 png_uint_32 t = v++; 3225 png_uint_32 t = v++;
3226 buffer[8*i+0] = (t >> 8) & 0xff; 3226 buffer[8*i+0] = (t >> 8) & 0xff;
3227 buffer[8*i+1] = t & 0xff; 3227 buffer[8*i+1] = t & 0xff;
3228 buffer[8*i+4] = (t >> 8) & 0xff; 3228 buffer[8*i+4] = (t >> 8) & 0xff;
3229 buffer[8*i+5] = t & 0xff; 3229 buffer[8*i+5] = t & 0xff;
3230 t *= 257; 3230 t *= 257;
3231 buffer[8*i+2] = (t >> 8) & 0xff; 3231 buffer[8*i+2] = (t >> 8) & 0xff;
3232 buffer[8*i+3] = t & 0xff; 3232 buffer[8*i+3] = t & 0xff;
3233 buffer[8*i+6] = (t >> 8) & 0xff; 3233 buffer[8*i+6] = (t >> 8) & 0xff;
3234 buffer[8*i+7] = t & 0xff; 3234 buffer[8*i+7] = t & 0xff;
3235 ++i; 3235 ++i;
3236 } 3236 }
3237 return; 3237 return;
3238 3238
3239 default: 3239 default:
3240 break; 3240 break;
3241 } 3241 }
3242 3242
3243 png_error(pp, "internal error"); 3243 png_error(pp, "internal error");
3244} 3244}
3245 3245
3246/* This is just to do the right cast - could be changed to a function to check 3246/* This is just to do the right cast - could be changed to a function to check
3247 * 'bd' but there isn't much point. 3247 * 'bd' but there isn't much point.
3248 */ 3248 */
3249#define DEPTH(bd) ((png_byte)(1U << (bd))) 3249#define DEPTH(bd) ((png_byte)(1U << (bd)))
3250 3250
3251/* Make a standardized image given a an image colour type, bit depth and 3251/* Make a standardized image given a an image colour type, bit depth and
3252 * interlace type. The standard images have a very restricted range of 3252 * interlace type. The standard images have a very restricted range of
3253 * rows and heights and are used for testing transforms rather than image 3253 * rows and heights and are used for testing transforms rather than image
3254 * layout details. See make_size_images below for a way to make images 3254 * layout details. See make_size_images below for a way to make images
3255 * that test odd sizes along with the libpng interlace handling. 3255 * that test odd sizes along with the libpng interlace handling.
3256 */ 3256 */
3257static void 3257static void
3258make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, 3258make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
3259 png_byte PNG_CONST bit_depth, int palette_number, int interlace_type, 3259 png_byte PNG_CONST bit_depth, int palette_number, int interlace_type,
3260 png_const_charp name) 3260 png_const_charp name)
3261{ 3261{
3262 context(ps, fault); 3262 context(ps, fault);
3263 3263
3264 Try 3264 Try
3265 { 3265 {
3266 png_infop pi; 3266 png_infop pi;
3267 png_structp pp = set_store_for_write(ps, &pi, name); 3267 png_structp pp = set_store_for_write(ps, &pi, name);
3268 png_uint_32 h; 3268 png_uint_32 h;
3269 3269
3270 /* In the event of a problem return control to the Catch statement below 3270 /* In the event of a problem return control to the Catch statement below
3271 * to do the clean up - it is not possible to 'return' directly from a Try 3271 * to do the clean up - it is not possible to 'return' directly from a Try
3272 * block. 3272 * block.
3273 */ 3273 */
3274 if (pp == NULL) 3274 if (pp == NULL)
3275 Throw ps; 3275 Throw ps;
3276 3276
3277 h = transform_height(pp, colour_type, bit_depth); 3277 h = transform_height(pp, colour_type, bit_depth);
3278 3278
3279 png_set_IHDR(pp, pi, transform_width(pp, colour_type, bit_depth), h, 3279 png_set_IHDR(pp, pi, transform_width(pp, colour_type, bit_depth), h,
3280 bit_depth, colour_type, interlace_type, 3280 bit_depth, colour_type, interlace_type,
3281 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 3281 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
3282 3282
3283#ifdef PNG_TEXT_SUPPORTED 3283#ifdef PNG_TEXT_SUPPORTED
3284 { 3284 {
3285 static char key[] = "image name"; /* must be writeable */ 3285 static char key[] = "image name"; /* must be writeable */
3286 size_t pos; 3286 size_t pos;
3287 png_text text; 3287 png_text text;
3288 char copy[FILE_NAME_SIZE]; 3288 char copy[FILE_NAME_SIZE];
3289 3289
3290 /* Use a compressed text string to test the correct interaction of text 3290 /* Use a compressed text string to test the correct interaction of text
3291 * compression and IDAT compression. 3291 * compression and IDAT compression.
3292 */ 3292 */
3293 text.compression = PNG_TEXT_COMPRESSION_zTXt; 3293 text.compression = PNG_TEXT_COMPRESSION_zTXt;
3294 text.key = key; 3294 text.key = key;
3295 /* Yuck: the text must be writable! */ 3295 /* Yuck: the text must be writable! */
3296 pos = safecat(copy, sizeof copy, 0, ps->wname); 3296 pos = safecat(copy, sizeof copy, 0, ps->wname);
3297 text.text = copy; 3297 text.text = copy;
3298 text.text_length = pos; 3298 text.text_length = pos;
3299 text.itxt_length = 0; 3299 text.itxt_length = 0;
3300 text.lang = 0; 3300 text.lang = 0;
3301 text.lang_key = 0; 3301 text.lang_key = 0;
3302 3302
3303 png_set_text(pp, pi, &text, 1); 3303 png_set_text(pp, pi, &text, 1);
3304 } 3304 }
3305#endif 3305#endif
3306 3306
3307 if (colour_type == 3) /* palette */ 3307 if (colour_type == 3) /* palette */
3308 init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/); 3308 init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/);
3309 3309
3310 png_write_info(pp, pi); 3310 png_write_info(pp, pi);
3311 3311
3312 if (png_get_rowbytes(pp, pi) != 3312 if (png_get_rowbytes(pp, pi) !=
3313 transform_rowsize(pp, colour_type, bit_depth)) 3313 transform_rowsize(pp, colour_type, bit_depth))
3314 png_error(pp, "row size incorrect"); 3314 png_error(pp, "row size incorrect");
3315 3315
3316 else 3316 else
3317 { 3317 {
3318 /* Somewhat confusingly this must be called *after* png_write_info 3318 /* Somewhat confusingly this must be called *after* png_write_info
3319 * because if it is called before, the information in *pp has not been 3319 * because if it is called before, the information in *pp has not been
3320 * updated to reflect the interlaced image. 3320 * updated to reflect the interlaced image.
3321 */ 3321 */
3322 int npasses = png_set_interlace_handling(pp); 3322 int npasses = png_set_interlace_handling(pp);
3323 int pass; 3323 int pass;
3324 3324
3325 if (npasses != npasses_from_interlace_type(pp, interlace_type)) 3325 if (npasses != npasses_from_interlace_type(pp, interlace_type))
3326 png_error(pp, "write: png_set_interlace_handling failed"); 3326 png_error(pp, "write: png_set_interlace_handling failed");
3327 3327
3328 for (pass=0; pass<npasses; ++pass) 3328 for (pass=0; pass<npasses; ++pass)
3329 { 3329 {
3330 png_uint_32 y; 3330 png_uint_32 y;
3331 3331
3332 for (y=0; y<h; ++y) 3332 for (y=0; y<h; ++y)
3333 { 3333 {
3334 png_byte buffer[TRANSFORM_ROWMAX]; 3334 png_byte buffer[TRANSFORM_ROWMAX];
3335 3335
3336 transform_row(pp, buffer, colour_type, bit_depth, y); 3336 transform_row(pp, buffer, colour_type, bit_depth, y);
3337 png_write_row(pp, buffer); 3337 png_write_row(pp, buffer);
3338 } 3338 }
3339 } 3339 }
3340 } 3340 }
3341 3341
3342#ifdef PNG_TEXT_SUPPORTED 3342#ifdef PNG_TEXT_SUPPORTED
3343 { 3343 {
3344 static char key[] = "end marker"; 3344 static char key[] = "end marker";
3345 static char comment[] = "end"; 3345 static char comment[] = "end";
3346 png_text text; 3346 png_text text;
3347 3347
3348 /* Use a compressed text string to test the correct interaction of text 3348 /* Use a compressed text string to test the correct interaction of text
3349 * compression and IDAT compression. 3349 * compression and IDAT compression.
3350 */ 3350 */
3351 text.compression = PNG_TEXT_COMPRESSION_zTXt; 3351 text.compression = PNG_TEXT_COMPRESSION_zTXt;
3352 text.key = key; 3352 text.key = key;
3353 text.text = comment; 3353 text.text = comment;
3354 text.text_length = (sizeof comment)-1; 3354 text.text_length = (sizeof comment)-1;
3355 text.itxt_length = 0; 3355 text.itxt_length = 0;
3356 text.lang = 0; 3356 text.lang = 0;
3357 text.lang_key = 0; 3357 text.lang_key = 0;
3358 3358
3359 png_set_text(pp, pi, &text, 1); 3359 png_set_text(pp, pi, &text, 1);
3360 } 3360 }
3361#endif 3361#endif
3362 3362
3363 png_write_end(pp, pi); 3363 png_write_end(pp, pi);
3364 3364
3365 /* And store this under the appropriate id, then clean up. */ 3365 /* And store this under the appropriate id, then clean up. */
3366 store_storefile(ps, FILEID(colour_type, bit_depth, palette_number, 3366 store_storefile(ps, FILEID(colour_type, bit_depth, palette_number,
3367 interlace_type, 0, 0, 0)); 3367 interlace_type, 0, 0, 0));
3368 3368
3369 store_write_reset(ps); 3369 store_write_reset(ps);
3370 } 3370 }
3371 3371
3372 Catch(fault) 3372 Catch(fault)
3373 { 3373 {
3374 /* Use the png_store returned by the exception. This may help the compiler 3374 /* Use the png_store returned by the exception. This may help the compiler
3375 * because 'ps' is not used in this branch of the setjmp. Note that fault 3375 * because 'ps' is not used in this branch of the setjmp. Note that fault
3376 * and ps will always be the same value. 3376 * and ps will always be the same value.
3377 */ 3377 */
3378 store_write_reset(fault); 3378 store_write_reset(fault);
3379 } 3379 }
3380} 3380}
3381 3381
3382static void 3382static void
3383make_transform_images(png_store *ps) 3383make_transform_images(png_store *ps)
3384{ 3384{
3385 png_byte colour_type = 0; 3385 png_byte colour_type = 0;
3386 png_byte bit_depth = 0; 3386 png_byte bit_depth = 0;
3387 int palette_number = 0; 3387 int palette_number = 0;
3388 3388
3389 /* This is in case of errors. */ 3389 /* This is in case of errors. */
3390 safecat(ps->test, sizeof ps->test, 0, "make standard images"); 3390 safecat(ps->test, sizeof ps->test, 0, "make standard images");
3391 3391
3392 /* Use next_format to enumerate all the combinations we test, including 3392 /* Use next_format to enumerate all the combinations we test, including
3393 * generating multiple low bit depth palette images. 3393 * generating multiple low bit depth palette images.
3394 */ 3394 */
3395 while (next_format(&colour_type, &bit_depth, &palette_number)) 3395 while (next_format(&colour_type, &bit_depth, &palette_number))
3396 { 3396 {
3397 int interlace_type; 3397 int interlace_type;
3398 3398
3399 for (interlace_type = PNG_INTERLACE_NONE; 3399 for (interlace_type = PNG_INTERLACE_NONE;
3400 interlace_type < PNG_INTERLACE_LAST; ++interlace_type) 3400 interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
3401 { 3401 {
3402 char name[FILE_NAME_SIZE]; 3402 char name[FILE_NAME_SIZE];
3403 3403
3404 standard_name(name, sizeof name, 0, colour_type, bit_depth, 3404 standard_name(name, sizeof name, 0, colour_type, bit_depth,
3405 palette_number, interlace_type, 0, 0, 0); 3405 palette_number, interlace_type, 0, 0, 0);
3406 make_transform_image(ps, colour_type, bit_depth, palette_number, 3406 make_transform_image(ps, colour_type, bit_depth, palette_number,
3407 interlace_type, name); 3407 interlace_type, name);
3408 } 3408 }
3409 } 3409 }
3410} 3410}
3411 3411
3412/* The following two routines use the PNG interlace support macros from 3412/* The following two routines use the PNG interlace support macros from
3413 * png.h to interlace or deinterlace rows. 3413 * png.h to interlace or deinterlace rows.
3414 */ 3414 */
3415static void 3415static void
3416interlace_row(png_bytep buffer, png_const_bytep imageRow, 3416interlace_row(png_bytep buffer, png_const_bytep imageRow,
3417 unsigned int pixel_size, png_uint_32 w, int pass) 3417 unsigned int pixel_size, png_uint_32 w, int pass)
3418{ 3418{
3419 png_uint_32 xin, xout, xstep; 3419 png_uint_32 xin, xout, xstep;
3420 3420
3421 /* Note that this can, trivially, be optimized to a memcpy on pass 7, the 3421 /* Note that this can, trivially, be optimized to a memcpy on pass 7, the
3422 * code is presented this way to make it easier to understand. In practice 3422 * code is presented this way to make it easier to understand. In practice
3423 * consult the code in the libpng source to see other ways of doing this. 3423 * consult the code in the libpng source to see other ways of doing this.
3424 */ 3424 */
3425 xin = PNG_PASS_START_COL(pass); 3425 xin = PNG_PASS_START_COL(pass);
3426 xstep = 1U<<PNG_PASS_COL_SHIFT(pass); 3426 xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
3427 3427
3428 for (xout=0; xin<w; xin+=xstep) 3428 for (xout=0; xin<w; xin+=xstep)
3429 { 3429 {
3430 pixel_copy(buffer, xout, imageRow, xin, pixel_size); 3430 pixel_copy(buffer, xout, imageRow, xin, pixel_size);
3431 ++xout; 3431 ++xout;
3432 } 3432 }
3433} 3433}
3434 3434
3435static void 3435static void
3436deinterlace_row(png_bytep buffer, png_const_bytep row, 3436deinterlace_row(png_bytep buffer, png_const_bytep row,
3437 unsigned int pixel_size, png_uint_32 w, int pass) 3437 unsigned int pixel_size, png_uint_32 w, int pass)
3438{ 3438{
3439 /* The inverse of the above, 'row' is part of row 'y' of the output image, 3439 /* The inverse of the above, 'row' is part of row 'y' of the output image,
3440 * in 'buffer'. The image is 'w' wide and this is pass 'pass', distribute 3440 * in 'buffer'. The image is 'w' wide and this is pass 'pass', distribute
3441 * the pixels of row into buffer and return the number written (to allow 3441 * the pixels of row into buffer and return the number written (to allow
3442 * this to be checked). 3442 * this to be checked).
3443 */ 3443 */
3444 png_uint_32 xin, xout, xstep; 3444 png_uint_32 xin, xout, xstep;
3445 3445
3446 xout = PNG_PASS_START_COL(pass); 3446 xout = PNG_PASS_START_COL(pass);
3447 xstep = 1U<<PNG_PASS_COL_SHIFT(pass); 3447 xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
3448 3448
3449 for (xin=0; xout<w; xout+=xstep) 3449 for (xin=0; xout<w; xout+=xstep)
3450 { 3450 {
3451 pixel_copy(buffer, xout, row, xin, pixel_size); 3451 pixel_copy(buffer, xout, row, xin, pixel_size);
3452 ++xin; 3452 ++xin;
3453 } 3453 }
3454} 3454}
3455 3455
3456/* Build a single row for the 'size' test images; this fills in only the 3456/* Build a single row for the 'size' test images; this fills in only the
3457 * first bit_width bits of the sample row. 3457 * first bit_width bits of the sample row.
3458 */ 3458 */
3459static void 3459static void
3460size_row(png_byte buffer[SIZE_ROWMAX], png_uint_32 bit_width, png_uint_32 y) 3460size_row(png_byte buffer[SIZE_ROWMAX], png_uint_32 bit_width, png_uint_32 y)
3461{ 3461{
3462 /* height is in the range 1 to 16, so: */ 3462 /* height is in the range 1 to 16, so: */
3463 y = ((y & 1) << 7) + ((y & 2) << 6) + ((y & 4) << 5) + ((y & 8) << 4); 3463 y = ((y & 1) << 7) + ((y & 2) << 6) + ((y & 4) << 5) + ((y & 8) << 4);
3464 /* the following ensures bits are set in small images: */ 3464 /* the following ensures bits are set in small images: */
3465 y ^= 0xA5; 3465 y ^= 0xA5;
3466 3466
3467 while (bit_width >= 8) 3467 while (bit_width >= 8)
3468 *buffer++ = (png_byte)y++, bit_width -= 8; 3468 *buffer++ = (png_byte)y++, bit_width -= 8;
3469 3469
3470 /* There may be up to 7 remaining bits, these go in the most significant 3470 /* There may be up to 7 remaining bits, these go in the most significant
3471 * bits of the byte. 3471 * bits of the byte.
3472 */ 3472 */
3473 if (bit_width > 0) 3473 if (bit_width > 0)
3474 { 3474 {
3475 png_uint_32 mask = (1U<<(8-bit_width))-1; 3475 png_uint_32 mask = (1U<<(8-bit_width))-1;
3476 *buffer = (png_byte)((*buffer & mask) | (y & ~mask)); 3476 *buffer = (png_byte)((*buffer & mask) | (y & ~mask));
3477 } 3477 }
3478} 3478}
3479 3479
3480static void 3480static void
3481make_size_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, 3481make_size_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
3482 png_byte PNG_CONST bit_depth, int PNG_CONST interlace_type, 3482 png_byte PNG_CONST bit_depth, int PNG_CONST interlace_type,
3483 png_uint_32 PNG_CONST w, png_uint_32 PNG_CONST h, 3483 png_uint_32 PNG_CONST w, png_uint_32 PNG_CONST h,
3484 int PNG_CONST do_interlace) 3484 int PNG_CONST do_interlace)
3485{ 3485{
3486 context(ps, fault); 3486 context(ps, fault);
3487 3487
3488 Try 3488 Try
3489 { 3489 {
3490 png_infop pi; 3490 png_infop pi;
3491 png_structp pp; 3491 png_structp pp;
3492 unsigned int pixel_size; 3492 unsigned int pixel_size;
3493 3493
3494 /* Make a name and get an appropriate id for the store: */ 3494 /* Make a name and get an appropriate id for the store: */
3495 char name[FILE_NAME_SIZE]; 3495 char name[FILE_NAME_SIZE];
3496 PNG_CONST png_uint_32 id = FILEID(colour_type, bit_depth, 0/*palette*/, 3496 PNG_CONST png_uint_32 id = FILEID(colour_type, bit_depth, 0/*palette*/,
3497 interlace_type, w, h, do_interlace); 3497 interlace_type, w, h, do_interlace);
3498 3498
3499 standard_name_from_id(name, sizeof name, 0, id); 3499 standard_name_from_id(name, sizeof name, 0, id);
3500 pp = set_store_for_write(ps, &pi, name); 3500 pp = set_store_for_write(ps, &pi, name);
3501 3501
3502 /* In the event of a problem return control to the Catch statement below 3502 /* In the event of a problem return control to the Catch statement below
3503 * to do the clean up - it is not possible to 'return' directly from a Try 3503 * to do the clean up - it is not possible to 'return' directly from a Try
3504 * block. 3504 * block.
3505 */ 3505 */
3506 if (pp == NULL) 3506 if (pp == NULL)
3507 Throw ps; 3507 Throw ps;
3508 3508
3509 png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type, 3509 png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,
3510 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 3510 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
3511 3511
3512 if (colour_type == 3) /* palette */ 3512 if (colour_type == 3) /* palette */
3513 init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/); 3513 init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/);
3514 3514
3515 png_write_info(pp, pi); 3515 png_write_info(pp, pi);
3516 3516
3517 /* Calculate the bit size, divide by 8 to get the byte size - this won't 3517 /* Calculate the bit size, divide by 8 to get the byte size - this won't
3518 * overflow because we know the w values are all small enough even for 3518 * overflow because we know the w values are all small enough even for
3519 * a system where 'unsigned int' is only 16 bits. 3519 * a system where 'unsigned int' is only 16 bits.
3520 */ 3520 */
3521 pixel_size = bit_size(pp, colour_type, bit_depth); 3521 pixel_size = bit_size(pp, colour_type, bit_depth);
3522 if (png_get_rowbytes(pp, pi) != ((w * pixel_size) + 7) / 8) 3522 if (png_get_rowbytes(pp, pi) != ((w * pixel_size) + 7) / 8)
3523 png_error(pp, "row size incorrect"); 3523 png_error(pp, "row size incorrect");
3524 3524
3525 else 3525 else
3526 { 3526 {
3527 int npasses = npasses_from_interlace_type(pp, interlace_type); 3527 int npasses = npasses_from_interlace_type(pp, interlace_type);
3528 png_uint_32 y; 3528 png_uint_32 y;
3529 int pass; 3529 int pass;
3530 png_byte image[16][SIZE_ROWMAX]; 3530 png_byte image[16][SIZE_ROWMAX];
3531 3531
3532 /* To help consistent error detection make the parts of this buffer 3532 /* To help consistent error detection make the parts of this buffer
3533 * that aren't set below all '1': 3533 * that aren't set below all '1':
3534 */ 3534 */
3535 memset(image, 0xff, sizeof image); 3535 memset(image, 0xff, sizeof image);
3536 3536
3537 if (!do_interlace && npasses != png_set_interlace_handling(pp)) 3537 if (!do_interlace && npasses != png_set_interlace_handling(pp))
3538 png_error(pp, "write: png_set_interlace_handling failed"); 3538 png_error(pp, "write: png_set_interlace_handling failed");
3539 3539
3540 /* Prepare the whole image first to avoid making it 7 times: */ 3540 /* Prepare the whole image first to avoid making it 7 times: */
3541 for (y=0; y<h; ++y) 3541 for (y=0; y<h; ++y)
3542 size_row(image[y], w * pixel_size, y); 3542 size_row(image[y], w * pixel_size, y);
3543 3543
3544 for (pass=0; pass<npasses; ++pass) 3544 for (pass=0; pass<npasses; ++pass)
3545 { 3545 {
3546 /* The following two are for checking the macros: */ 3546 /* The following two are for checking the macros: */
3547 PNG_CONST png_uint_32 wPass = PNG_PASS_COLS(w, pass); 3547 PNG_CONST png_uint_32 wPass = PNG_PASS_COLS(w, pass);
3548 3548
3549 /* If do_interlace is set we don't call png_write_row for every 3549 /* If do_interlace is set we don't call png_write_row for every
3550 * row because some of them are empty. In fact, for a 1x1 image, 3550 * row because some of them are empty. In fact, for a 1x1 image,
3551 * most of them are empty! 3551 * most of them are empty!
3552 */ 3552 */
3553 for (y=0; y<h; ++y) 3553 for (y=0; y<h; ++y)
3554 { 3554 {
3555 png_const_bytep row = image[y]; 3555 png_const_bytep row = image[y];
3556 png_byte tempRow[SIZE_ROWMAX]; 3556 png_byte tempRow[SIZE_ROWMAX];
3557 3557
3558 /* If do_interlace *and* the image is interlaced we 3558 /* If do_interlace *and* the image is interlaced we
3559 * need a reduced interlace row; this may be reduced 3559 * need a reduced interlace row; this may be reduced
3560 * to empty. 3560 * to empty.
3561 */ 3561 */
3562 if (do_interlace && interlace_type == PNG_INTERLACE_ADAM7) 3562 if (do_interlace && interlace_type == PNG_INTERLACE_ADAM7)
3563 { 3563 {
3564 /* The row must not be written if it doesn't exist, notice 3564 /* The row must not be written if it doesn't exist, notice
3565 * that there are two conditions here, either the row isn't 3565 * that there are two conditions here, either the row isn't
3566 * ever in the pass or the row would be but isn't wide 3566 * ever in the pass or the row would be but isn't wide
3567 * enough to contribute any pixels. In fact the wPass test 3567 * enough to contribute any pixels. In fact the wPass test
3568 * can be used to skip the whole y loop in this case. 3568 * can be used to skip the whole y loop in this case.
3569 */ 3569 */
3570 if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && wPass > 0) 3570 if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && wPass > 0)
3571 { 3571 {
3572 /* Set to all 1's for error detection (libpng tends to 3572 /* Set to all 1's for error detection (libpng tends to
3573 * set unset things to 0). 3573 * set unset things to 0).
3574 */ 3574 */
3575 memset(tempRow, 0xff, sizeof tempRow); 3575 memset(tempRow, 0xff, sizeof tempRow);
3576 interlace_row(tempRow, row, pixel_size, w, pass); 3576 interlace_row(tempRow, row, pixel_size, w, pass);
3577 row = tempRow; 3577 row = tempRow;
3578 } 3578 }
3579 else 3579 else
3580 continue; 3580 continue;
3581 } 3581 }
3582 3582
3583 /* Only get to here if the row has some pixels in it. */ 3583 /* Only get to here if the row has some pixels in it. */
3584 png_write_row(pp, row); 3584 png_write_row(pp, row);
3585 } 3585 }
3586 } 3586 }
3587 } 3587 }
3588 3588
3589 png_write_end(pp, pi); 3589 png_write_end(pp, pi);
3590 3590
3591 /* And store this under the appropriate id, then clean up. */ 3591 /* And store this under the appropriate id, then clean up. */
3592 store_storefile(ps, id); 3592 store_storefile(ps, id);
3593 3593
3594 store_write_reset(ps); 3594 store_write_reset(ps);
3595 } 3595 }
3596 3596
3597 Catch(fault) 3597 Catch(fault)
3598 { 3598 {
3599 /* Use the png_store returned by the exception. This may help the compiler 3599 /* Use the png_store returned by the exception. This may help the compiler
3600 * because 'ps' is not used in this branch of the setjmp. Note that fault 3600 * because 'ps' is not used in this branch of the setjmp. Note that fault
3601 * and ps will always be the same value. 3601 * and ps will always be the same value.
3602 */ 3602 */
3603 store_write_reset(fault); 3603 store_write_reset(fault);
3604 } 3604 }
3605} 3605}
3606 3606
3607static void 3607static void
3608make_size(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo, 3608make_size(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo,
3609 int PNG_CONST bdhi) 3609 int PNG_CONST bdhi)
3610{ 3610{
3611 for (; bdlo <= bdhi; ++bdlo) 3611 for (; bdlo <= bdhi; ++bdlo)
3612 { 3612 {
3613 png_uint_32 width; 3613 png_uint_32 width;
3614 3614
3615 for (width = 1; width <= 16; ++width) 3615 for (width = 1; width <= 16; ++width)
3616 { 3616 {
3617 png_uint_32 height; 3617 png_uint_32 height;
3618 3618
3619 for (height = 1; height <= 16; ++height) 3619 for (height = 1; height <= 16; ++height)
3620 { 3620 {
3621 /* The four combinations of DIY interlace and interlace or not - 3621 /* The four combinations of DIY interlace and interlace or not -
3622 * no interlace + DIY should be identical to no interlace with 3622 * no interlace + DIY should be identical to no interlace with
3623 * libpng doing it. 3623 * libpng doing it.
3624 */ 3624 */
3625 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE, 3625 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
3626 width, height, 0); 3626 width, height, 0);
3627 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE, 3627 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
3628 width, height, 1); 3628 width, height, 1);
3629 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7, 3629 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
3630 width, height, 0); 3630 width, height, 0);
3631 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7, 3631 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
3632 width, height, 1); 3632 width, height, 1);
3633 } 3633 }
3634 } 3634 }
3635 } 3635 }
3636} 3636}
3637 3637
3638static void 3638static void
3639make_size_images(png_store *ps) 3639make_size_images(png_store *ps)
3640{ 3640{
3641 /* This is in case of errors. */ 3641 /* This is in case of errors. */
3642 safecat(ps->test, sizeof ps->test, 0, "make size images"); 3642 safecat(ps->test, sizeof ps->test, 0, "make size images");
3643 3643
3644 /* Arguments are colour_type, low bit depth, high bit depth 3644 /* Arguments are colour_type, low bit depth, high bit depth
3645 */ 3645 */
3646 make_size(ps, 0, 0, WRITE_BDHI); 3646 make_size(ps, 0, 0, WRITE_BDHI);
3647 make_size(ps, 2, 3, WRITE_BDHI); 3647 make_size(ps, 2, 3, WRITE_BDHI);
3648 make_size(ps, 3, 0, 3 /*palette: max 8 bits*/); 3648 make_size(ps, 3, 0, 3 /*palette: max 8 bits*/);
3649 make_size(ps, 4, 3, WRITE_BDHI); 3649 make_size(ps, 4, 3, WRITE_BDHI);
3650 make_size(ps, 6, 3, WRITE_BDHI); 3650 make_size(ps, 6, 3, WRITE_BDHI);
3651} 3651}
3652 3652
3653/* Return a row based on image id and 'y' for checking: */ 3653/* Return a row based on image id and 'y' for checking: */
3654static void 3654static void
3655standard_row(png_structp pp, png_byte std[STANDARD_ROWMAX], png_uint_32 id, 3655standard_row(png_structp pp, png_byte std[STANDARD_ROWMAX], png_uint_32 id,
3656 png_uint_32 y) 3656 png_uint_32 y)
3657{ 3657{
3658 if (WIDTH_FROM_ID(id) == 0) 3658 if (WIDTH_FROM_ID(id) == 0)
3659 transform_row(pp, std, COL_FROM_ID(id), DEPTH_FROM_ID(id), y); 3659 transform_row(pp, std, COL_FROM_ID(id), DEPTH_FROM_ID(id), y);
3660 else 3660 else
3661 size_row(std, WIDTH_FROM_ID(id) * bit_size(pp, COL_FROM_ID(id), 3661 size_row(std, WIDTH_FROM_ID(id) * bit_size(pp, COL_FROM_ID(id),
3662 DEPTH_FROM_ID(id)), y); 3662 DEPTH_FROM_ID(id)), y);
3663} 3663}
3664 3664
3665/* Tests - individual test cases */ 3665/* Tests - individual test cases */
3666/* Like 'make_standard' but errors are deliberately introduced into the calls 3666/* Like 'make_standard' but errors are deliberately introduced into the calls
3667 * to ensure that they get detected - it should not be possible to write an 3667 * to ensure that they get detected - it should not be possible to write an
3668 * invalid image with libpng! 3668 * invalid image with libpng!
3669 */ 3669 */
3670#ifdef PNG_WARNINGS_SUPPORTED 3670#ifdef PNG_WARNINGS_SUPPORTED
3671static void 3671static void
3672sBIT0_error_fn(png_structp pp, png_infop pi) 3672sBIT0_error_fn(png_structp pp, png_infop pi)
3673{ 3673{
3674 /* 0 is invalid... */ 3674 /* 0 is invalid... */
3675 png_color_8 bad; 3675 png_color_8 bad;
3676 bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 0; 3676 bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 0;
3677 png_set_sBIT(pp, pi, &bad); 3677 png_set_sBIT(pp, pi, &bad);
3678} 3678}
3679 3679
3680static void 3680static void
3681sBIT_error_fn(png_structp pp, png_infop pi) 3681sBIT_error_fn(png_structp pp, png_infop pi)
3682{ 3682{
3683 png_byte bit_depth; 3683 png_byte bit_depth;
3684 png_color_8 bad; 3684 png_color_8 bad;
3685 3685
3686 if (png_get_color_type(pp, pi) == PNG_COLOR_TYPE_PALETTE) 3686 if (png_get_color_type(pp, pi) == PNG_COLOR_TYPE_PALETTE)
3687 bit_depth = 8; 3687 bit_depth = 8;
3688 3688
3689 else 3689 else
3690 bit_depth = png_get_bit_depth(pp, pi); 3690 bit_depth = png_get_bit_depth(pp, pi);
3691 3691
3692 /* Now we know the bit depth we can easily generate an invalid sBIT entry */ 3692 /* Now we know the bit depth we can easily generate an invalid sBIT entry */
3693 bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 3693 bad.red = bad.green = bad.blue = bad.gray = bad.alpha =
3694 (png_byte)(bit_depth+1); 3694 (png_byte)(bit_depth+1);
3695 png_set_sBIT(pp, pi, &bad); 3695 png_set_sBIT(pp, pi, &bad);
3696} 3696}
3697 3697
3698static PNG_CONST struct 3698static PNG_CONST struct
3699{ 3699{
3700 void (*fn)(png_structp, png_infop); 3700 void (*fn)(png_structp, png_infop);
3701 PNG_CONST char *msg; 3701 PNG_CONST char *msg;
3702 unsigned int warning :1; /* the error is a warning... */ 3702 unsigned int warning :1; /* the error is a warning... */
3703} error_test[] = 3703} error_test[] =
3704 { 3704 {
3705 /* no warnings makes these errors undetectable. */ 3705 /* no warnings makes these errors undetectable. */
3706 { sBIT0_error_fn, "sBIT(0): failed to detect error", 1 }, 3706 { sBIT0_error_fn, "sBIT(0): failed to detect error", 1 },
3707 { sBIT_error_fn, "sBIT(too big): failed to detect error", 1 }, 3707 { sBIT_error_fn, "sBIT(too big): failed to detect error", 1 },
3708 }; 3708 };
3709 3709
3710static void 3710static void
3711make_error(png_store* volatile psIn, png_byte PNG_CONST colour_type, 3711make_error(png_store* volatile psIn, png_byte PNG_CONST colour_type,
3712 png_byte bit_depth, int interlace_type, int test, png_const_charp name) 3712 png_byte bit_depth, int interlace_type, int test, png_const_charp name)
3713{ 3713{
3714 png_store * volatile ps = psIn; 3714 png_store * volatile ps = psIn;
3715 3715
3716 context(ps, fault); 3716 context(ps, fault);
3717 3717
3718 Try 3718 Try
3719 { 3719 {
3720 png_structp pp; 3720 png_structp pp;
3721 png_infop pi; 3721 png_infop pi;
3722 3722
3723 pp = set_store_for_write(ps, &pi, name); 3723 pp = set_store_for_write(ps, &pi, name);
3724 3724
3725 if (pp == NULL) 3725 if (pp == NULL)
3726 Throw ps; 3726 Throw ps;
3727 3727
3728 png_set_IHDR(pp, pi, transform_width(pp, colour_type, bit_depth), 3728 png_set_IHDR(pp, pi, transform_width(pp, colour_type, bit_depth),
3729 transform_height(pp, colour_type, bit_depth), bit_depth, colour_type, 3729 transform_height(pp, colour_type, bit_depth), bit_depth, colour_type,
3730 interlace_type, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 3730 interlace_type, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
3731 3731
3732 if (colour_type == 3) /* palette */ 3732 if (colour_type == 3) /* palette */
3733 init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/); 3733 init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/);
3734 3734
3735 /* Time for a few errors; these are in various optional chunks, the 3735 /* Time for a few errors; these are in various optional chunks, the
3736 * standard tests test the standard chunks pretty well. 3736 * standard tests test the standard chunks pretty well.
3737 */ 3737 */
3738# define exception__prev exception_prev_1 3738# define exception__prev exception_prev_1
3739# define exception__env exception_env_1 3739# define exception__env exception_env_1
3740 Try 3740 Try
3741 { 3741 {
3742 /* Expect this to throw: */ 3742 /* Expect this to throw: */
3743 ps->expect_error = !error_test[test].warning; 3743 ps->expect_error = !error_test[test].warning;
3744 ps->expect_warning = error_test[test].warning; 3744 ps->expect_warning = error_test[test].warning;
3745 ps->saw_warning = 0; 3745 ps->saw_warning = 0;
3746 error_test[test].fn(pp, pi); 3746 error_test[test].fn(pp, pi);
3747 3747
3748 /* Normally the error is only detected here: */ 3748 /* Normally the error is only detected here: */
3749 png_write_info(pp, pi); 3749 png_write_info(pp, pi);
3750 3750
3751 /* And handle the case where it was only a warning: */ 3751 /* And handle the case where it was only a warning: */
3752 if (ps->expect_warning && ps->saw_warning) 3752 if (ps->expect_warning && ps->saw_warning)
3753 Throw ps; 3753 Throw ps;
3754 3754
3755 /* If we get here there is a problem, we have success - no error or 3755 /* If we get here there is a problem, we have success - no error or
3756 * no warning - when we shouldn't have success. Log an error. 3756 * no warning - when we shouldn't have success. Log an error.
3757 */ 3757 */
3758 store_log(ps, pp, error_test[test].msg, 1 /*error*/); 3758 store_log(ps, pp, error_test[test].msg, 1 /*error*/);
3759 } 3759 }
3760 3760
3761 Catch (fault) 3761 Catch (fault)
3762 ps = fault; /* expected exit, make sure ps is not clobbered */ 3762 ps = fault; /* expected exit, make sure ps is not clobbered */
3763#undef exception__prev 3763#undef exception__prev
3764#undef exception__env 3764#undef exception__env
3765 3765
3766 /* And clear these flags */ 3766 /* And clear these flags */
3767 ps->expect_error = 0; 3767 ps->expect_error = 0;
3768 ps->expect_warning = 0; 3768 ps->expect_warning = 0;
3769 3769
3770 /* Now write the whole image, just to make sure that the detected, or 3770 /* Now write the whole image, just to make sure that the detected, or
3771 * undetected, errro has not created problems inside libpng. 3771 * undetected, errro has not created problems inside libpng.
3772 */ 3772 */
3773 if (png_get_rowbytes(pp, pi) != 3773 if (png_get_rowbytes(pp, pi) !=
3774 transform_rowsize(pp, colour_type, bit_depth)) 3774 transform_rowsize(pp, colour_type, bit_depth))
3775 png_error(pp, "row size incorrect"); 3775 png_error(pp, "row size incorrect");
3776 3776
3777 else 3777 else
3778 { 3778 {
3779 png_uint_32 h = transform_height(pp, colour_type, bit_depth); 3779 png_uint_32 h = transform_height(pp, colour_type, bit_depth);
3780 int npasses = png_set_interlace_handling(pp); 3780 int npasses = png_set_interlace_handling(pp);
3781 int pass; 3781 int pass;
3782 3782
3783 if (npasses != npasses_from_interlace_type(pp, interlace_type)) 3783 if (npasses != npasses_from_interlace_type(pp, interlace_type))
3784 png_error(pp, "write: png_set_interlace_handling failed"); 3784 png_error(pp, "write: png_set_interlace_handling failed");
3785 3785
3786 for (pass=0; pass<npasses; ++pass) 3786 for (pass=0; pass<npasses; ++pass)
3787 { 3787 {
3788 png_uint_32 y; 3788 png_uint_32 y;
3789 3789
3790 for (y=0; y<h; ++y) 3790 for (y=0; y<h; ++y)
3791 { 3791 {
3792 png_byte buffer[TRANSFORM_ROWMAX]; 3792 png_byte buffer[TRANSFORM_ROWMAX];
3793 3793
3794 transform_row(pp, buffer, colour_type, bit_depth, y); 3794 transform_row(pp, buffer, colour_type, bit_depth, y);
3795 png_write_row(pp, buffer); 3795 png_write_row(pp, buffer);
3796 } 3796 }
3797 } 3797 }
3798 } 3798 }
3799 3799
3800 png_write_end(pp, pi); 3800 png_write_end(pp, pi);
3801 3801
3802 /* The following deletes the file that was just written. */ 3802 /* The following deletes the file that was just written. */
3803 store_write_reset(ps); 3803 store_write_reset(ps);
3804 } 3804 }
3805 3805
3806 Catch(fault) 3806 Catch(fault)
3807 { 3807 {
3808 store_write_reset(fault); 3808 store_write_reset(fault);
3809 } 3809 }
3810} 3810}
3811 3811
3812static int 3812static int
3813make_errors(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, 3813make_errors(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
3814 int bdlo, int PNG_CONST bdhi) 3814 int bdlo, int PNG_CONST bdhi)
3815{ 3815{
3816 for (; bdlo <= bdhi; ++bdlo) 3816 for (; bdlo <= bdhi; ++bdlo)
3817 { 3817 {
3818 int interlace_type; 3818 int interlace_type;
3819 3819
3820 for (interlace_type = PNG_INTERLACE_NONE; 3820 for (interlace_type = PNG_INTERLACE_NONE;
3821 interlace_type < PNG_INTERLACE_LAST; ++interlace_type) 3821 interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
3822 { 3822 {
3823 unsigned int test; 3823 unsigned int test;
3824 char name[FILE_NAME_SIZE]; 3824 char name[FILE_NAME_SIZE];
3825 3825
3826 standard_name(name, sizeof name, 0, colour_type, 1<<bdlo, 0, 3826 standard_name(name, sizeof name, 0, colour_type, 1<<bdlo, 0,
3827 interlace_type, 0, 0, 0); 3827 interlace_type, 0, 0, 0);
3828 3828
3829 for (test=0; test<(sizeof error_test)/(sizeof error_test[0]); ++test) 3829 for (test=0; test<(sizeof error_test)/(sizeof error_test[0]); ++test)
3830 { 3830 {
3831 make_error(&pm->this, colour_type, DEPTH(bdlo), interlace_type, 3831 make_error(&pm->this, colour_type, DEPTH(bdlo), interlace_type,
3832 test, name); 3832 test, name);
3833 3833
3834 if (fail(pm)) 3834 if (fail(pm))
3835 return 0; 3835 return 0;
3836 } 3836 }
3837 } 3837 }
3838 } 3838 }
3839 3839
3840 return 1; /* keep going */ 3840 return 1; /* keep going */
3841} 3841}
3842#endif 3842#endif
3843 3843
3844static void 3844static void
3845perform_error_test(png_modifier *pm) 3845perform_error_test(png_modifier *pm)
3846{ 3846{
3847#ifdef PNG_WARNINGS_SUPPORTED /* else there are no cases that work! */ 3847#ifdef PNG_WARNINGS_SUPPORTED /* else there are no cases that work! */
3848 /* Need to do this here because we just write in this test. */ 3848 /* Need to do this here because we just write in this test. */
3849 safecat(pm->this.test, sizeof pm->this.test, 0, "error test"); 3849 safecat(pm->this.test, sizeof pm->this.test, 0, "error test");
3850 3850
3851 if (!make_errors(pm, 0, 0, WRITE_BDHI)) 3851 if (!make_errors(pm, 0, 0, WRITE_BDHI))
3852 return; 3852 return;
3853 3853
3854 if (!make_errors(pm, 2, 3, WRITE_BDHI)) 3854 if (!make_errors(pm, 2, 3, WRITE_BDHI))
3855 return; 3855 return;
3856 3856
3857 if (!make_errors(pm, 3, 0, 3)) 3857 if (!make_errors(pm, 3, 0, 3))
3858 return; 3858 return;
3859 3859
3860 if (!make_errors(pm, 4, 3, WRITE_BDHI)) 3860 if (!make_errors(pm, 4, 3, WRITE_BDHI))
3861 return; 3861 return;
3862 3862
3863 if (!make_errors(pm, 6, 3, WRITE_BDHI)) 3863 if (!make_errors(pm, 6, 3, WRITE_BDHI))
3864 return; 3864 return;
3865#else 3865#else
3866 UNUSED(pm) 3866 UNUSED(pm)
3867#endif 3867#endif
3868} 3868}
3869 3869
3870/* This is just to validate the internal PNG formatting code - if this fails 3870/* This is just to validate the internal PNG formatting code - if this fails
3871 * then the warning messages the library outputs will probably be garbage. 3871 * then the warning messages the library outputs will probably be garbage.
3872 */ 3872 */
3873static void 3873static void
3874perform_formatting_test(png_store *volatile ps) 3874perform_formatting_test(png_store *volatile ps)
3875{ 3875{
3876#ifdef PNG_TIME_RFC1123_SUPPORTED 3876#ifdef PNG_TIME_RFC1123_SUPPORTED
3877 /* The handle into the formatting code is the RFC1123 support; this test does 3877 /* The handle into the formatting code is the RFC1123 support; this test does
3878 * nothing if that is compiled out. 3878 * nothing if that is compiled out.
3879 */ 3879 */
3880 context(ps, fault); 3880 context(ps, fault);
3881 3881
3882 Try 3882 Try
3883 { 3883 {
3884 png_const_charp correct = "29 Aug 2079 13:53:60 +0000"; 3884 png_const_charp correct = "29 Aug 2079 13:53:60 +0000";
3885 png_const_charp result; 3885 png_const_charp result;
3886 png_structp pp; 3886 png_structp pp;
3887 png_time pt; 3887 png_time pt;
3888 3888
3889 pp = set_store_for_write(ps, NULL, "libpng formatting test"); 3889 pp = set_store_for_write(ps, NULL, "libpng formatting test");
3890 3890
3891 if (pp == NULL) 3891 if (pp == NULL)
3892 Throw ps; 3892 Throw ps;
3893 3893
3894 3894
3895 /* Arbitrary settings: */ 3895 /* Arbitrary settings: */
3896 pt.year = 2079; 3896 pt.year = 2079;
3897 pt.month = 8; 3897 pt.month = 8;
3898 pt.day = 29; 3898 pt.day = 29;
3899 pt.hour = 13; 3899 pt.hour = 13;
3900 pt.minute = 53; 3900 pt.minute = 53;
3901 pt.second = 60; /* a leap second */ 3901 pt.second = 60; /* a leap second */
3902 3902
3903 result = png_convert_to_rfc1123(pp, &pt); 3903 result = png_convert_to_rfc1123(pp, &pt);
3904 3904
3905 if (result == NULL) 3905 if (result == NULL)
3906 png_error(pp, "png_convert_to_rfc1123 failed"); 3906 png_error(pp, "png_convert_to_rfc1123 failed");
3907 3907
3908 if (strcmp(result, correct) != 0) 3908 if (strcmp(result, correct) != 0)
3909 { 3909 {
3910 size_t pos = 0; 3910 size_t pos = 0;
3911 char msg[128]; 3911 char msg[128];
3912 3912
3913 pos = safecat(msg, sizeof msg, pos, "png_convert_to_rfc1123("); 3913 pos = safecat(msg, sizeof msg, pos, "png_convert_to_rfc1123(");
3914 pos = safecat(msg, sizeof msg, pos, correct); 3914 pos = safecat(msg, sizeof msg, pos, correct);
3915 pos = safecat(msg, sizeof msg, pos, ") returned: '"); 3915 pos = safecat(msg, sizeof msg, pos, ") returned: '");
3916 pos = safecat(msg, sizeof msg, pos, result); 3916 pos = safecat(msg, sizeof msg, pos, result);
3917 pos = safecat(msg, sizeof msg, pos, "'"); 3917 pos = safecat(msg, sizeof msg, pos, "'");
3918 3918
3919 png_error(pp, msg); 3919 png_error(pp, msg);
3920 } 3920 }
3921 3921
3922 store_write_reset(ps); 3922 store_write_reset(ps);
3923 } 3923 }
3924 3924
3925 Catch(fault) 3925 Catch(fault)
3926 { 3926 {
3927 store_write_reset(fault); 3927 store_write_reset(fault);
3928 } 3928 }
3929#else 3929#else
3930 UNUSED(ps) 3930 UNUSED(ps)
3931#endif 3931#endif
3932} 3932}
3933 3933
3934/* Because we want to use the same code in both the progressive reader and the 3934/* Because we want to use the same code in both the progressive reader and the
3935 * sequential reader it is necessary to deal with the fact that the progressive 3935 * sequential reader it is necessary to deal with the fact that the progressive
3936 * reader callbacks only have one parameter (png_get_progressive_ptr()), so this 3936 * reader callbacks only have one parameter (png_get_progressive_ptr()), so this
3937 * must contain all the test parameters and all the local variables directly 3937 * must contain all the test parameters and all the local variables directly
3938 * accessible to the sequential reader implementation. 3938 * accessible to the sequential reader implementation.
3939 * 3939 *
3940 * The technique adopted is to reinvent part of what Dijkstra termed a 3940 * The technique adopted is to reinvent part of what Dijkstra termed a
3941 * 'display'; an array of pointers to the stack frames of enclosing functions so 3941 * 'display'; an array of pointers to the stack frames of enclosing functions so
3942 * that a nested function definition can access the local (C auto) variables of 3942 * that a nested function definition can access the local (C auto) variables of
3943 * the functions that contain its definition. In fact C provides the first 3943 * the functions that contain its definition. In fact C provides the first
3944 * pointer (the local variables - the stack frame pointer) and the last (the 3944 * pointer (the local variables - the stack frame pointer) and the last (the
3945 * global variables - the BCPL global vector typically implemented as global 3945 * global variables - the BCPL global vector typically implemented as global
3946 * addresses), this code requires one more pointer to make the display - the 3946 * addresses), this code requires one more pointer to make the display - the
3947 * local variables (and function call parameters) of the function that actually 3947 * local variables (and function call parameters) of the function that actually
3948 * invokes either the progressive or sequential reader. 3948 * invokes either the progressive or sequential reader.
3949 * 3949 *
3950 * Perhaps confusingly this technique is confounded with classes - the 3950 * Perhaps confusingly this technique is confounded with classes - the
3951 * 'standard_display' defined here is sub-classed as the 'gamma_display' below. 3951 * 'standard_display' defined here is sub-classed as the 'gamma_display' below.
3952 * A gamma_display is a standard_display, taking advantage of the ANSI-C 3952 * A gamma_display is a standard_display, taking advantage of the ANSI-C
3953 * requirement that the pointer to the first member of a structure must be the 3953 * requirement that the pointer to the first member of a structure must be the
3954 * same as the pointer to the structure. This allows us to reuse standard_ 3954 * same as the pointer to the structure. This allows us to reuse standard_
3955 * functions in the gamma test code; something that could not be done with 3955 * functions in the gamma test code; something that could not be done with
3956 * nested functions! 3956 * nested functions!
3957 */ 3957 */
3958typedef struct standard_display 3958typedef struct standard_display
3959{ 3959{
3960 png_store* ps; /* Test parameters (passed to the function) */ 3960 png_store* ps; /* Test parameters (passed to the function) */
3961 png_byte colour_type; 3961 png_byte colour_type;
3962 png_byte bit_depth; 3962 png_byte bit_depth;
3963 png_byte red_sBIT; /* Input data sBIT values. */ 3963 png_byte red_sBIT; /* Input data sBIT values. */
3964 png_byte green_sBIT; 3964 png_byte green_sBIT;
3965 png_byte blue_sBIT; 3965 png_byte blue_sBIT;
3966 png_byte alpha_sBIT; 3966 png_byte alpha_sBIT;
3967 int interlace_type; 3967 int interlace_type;
3968 png_uint_32 id; /* Calculated file ID */ 3968 png_uint_32 id; /* Calculated file ID */
3969 png_uint_32 w; /* Width of image */ 3969 png_uint_32 w; /* Width of image */
3970 png_uint_32 h; /* Height of image */ 3970 png_uint_32 h; /* Height of image */
3971 int npasses; /* Number of interlaced passes */ 3971 int npasses; /* Number of interlaced passes */
3972 png_uint_32 pixel_size; /* Width of one pixel in bits */ 3972 png_uint_32 pixel_size; /* Width of one pixel in bits */
3973 png_uint_32 bit_width; /* Width of output row in bits */ 3973 png_uint_32 bit_width; /* Width of output row in bits */
3974 size_t cbRow; /* Bytes in a row of the output image */ 3974 size_t cbRow; /* Bytes in a row of the output image */
3975 int do_interlace; /* Do interlacing internally */ 3975 int do_interlace; /* Do interlacing internally */
3976 int is_transparent; /* Transparency information was present. */ 3976 int is_transparent; /* Transparency information was present. */
3977 int speed; /* Doing a speed test */ 3977 int speed; /* Doing a speed test */
3978 int use_update_info;/* Call update_info, not start_image */ 3978 int use_update_info;/* Call update_info, not start_image */
3979 struct 3979 struct
3980 { 3980 {
3981 png_uint_16 red; 3981 png_uint_16 red;
3982 png_uint_16 green; 3982 png_uint_16 green;
3983 png_uint_16 blue; 3983 png_uint_16 blue;
3984 } transparent; /* The transparent color, if set. */ 3984 } transparent; /* The transparent color, if set. */
3985 int npalette; /* Number of entries in the palette. */ 3985 int npalette; /* Number of entries in the palette. */
3986 store_palette 3986 store_palette
3987 palette; 3987 palette;
3988} standard_display; 3988} standard_display;
3989 3989
3990static void 3990static void
3991standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id, 3991standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id,
3992 int do_interlace, int use_update_info) 3992 int do_interlace, int use_update_info)
3993{ 3993{
3994 memset(dp, 0, sizeof *dp); 3994 memset(dp, 0, sizeof *dp);
3995 3995
3996 dp->ps = ps; 3996 dp->ps = ps;
3997 dp->colour_type = COL_FROM_ID(id); 3997 dp->colour_type = COL_FROM_ID(id);
3998 dp->bit_depth = DEPTH_FROM_ID(id); 3998 dp->bit_depth = DEPTH_FROM_ID(id);
3999 if (dp->bit_depth < 1 || dp->bit_depth > 16) 3999 if (dp->bit_depth < 1 || dp->bit_depth > 16)
4000 internal_error(ps, "internal: bad bit depth"); 4000 internal_error(ps, "internal: bad bit depth");
4001 if (dp->colour_type == 3) 4001 if (dp->colour_type == 3)
4002 dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = 8; 4002 dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = 8;
4003 else 4003 else
4004 dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = 4004 dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT =
4005 dp->bit_depth; 4005 dp->bit_depth;
4006 dp->interlace_type = INTERLACE_FROM_ID(id); 4006 dp->interlace_type = INTERLACE_FROM_ID(id);
4007 dp->id = id; 4007 dp->id = id;
4008 /* All the rest are filled in after the read_info: */ 4008 /* All the rest are filled in after the read_info: */
4009 dp->w = 0; 4009 dp->w = 0;
4010 dp->h = 0; 4010 dp->h = 0;
4011 dp->npasses = 0; 4011 dp->npasses = 0;
4012 dp->pixel_size = 0; 4012 dp->pixel_size = 0;
4013 dp->bit_width = 0; 4013 dp->bit_width = 0;
4014 dp->cbRow = 0; 4014 dp->cbRow = 0;
4015 dp->do_interlace = do_interlace; 4015 dp->do_interlace = do_interlace;
4016 dp->is_transparent = 0; 4016 dp->is_transparent = 0;
4017 dp->speed = ps->speed; 4017 dp->speed = ps->speed;
4018 dp->use_update_info = use_update_info; 4018 dp->use_update_info = use_update_info;
4019 dp->npalette = 0; 4019 dp->npalette = 0;
4020 /* Preset the transparent color to black: */ 4020 /* Preset the transparent color to black: */
4021 memset(&dp->transparent, 0, sizeof dp->transparent); 4021 memset(&dp->transparent, 0, sizeof dp->transparent);
4022 /* Preset the palette to full intensity/opaque througout: */ 4022 /* Preset the palette to full intensity/opaque througout: */
4023 memset(dp->palette, 0xff, sizeof dp->palette); 4023 memset(dp->palette, 0xff, sizeof dp->palette);
4024} 4024}
4025 4025
4026/* Initialize the palette fields - this must be done later because the palette 4026/* Initialize the palette fields - this must be done later because the palette
4027 * comes from the particular png_store_file that is selected. 4027 * comes from the particular png_store_file that is selected.
4028 */ 4028 */
4029static void 4029static void
4030standard_palette_init(standard_display *dp) 4030standard_palette_init(standard_display *dp)
4031{ 4031{
4032 store_palette_entry *palette = store_current_palette(dp->ps, &dp->npalette); 4032 store_palette_entry *palette = store_current_palette(dp->ps, &dp->npalette);
4033 4033
4034 /* The remaining entries remain white/opaque. */ 4034 /* The remaining entries remain white/opaque. */
4035 if (dp->npalette > 0) 4035 if (dp->npalette > 0)
4036 { 4036 {
4037 int i = dp->npalette; 4037 int i = dp->npalette;
4038 memcpy(dp->palette, palette, i * sizeof *palette); 4038 memcpy(dp->palette, palette, i * sizeof *palette);
4039 4039
4040 /* Check for a non-opaque palette entry: */ 4040 /* Check for a non-opaque palette entry: */
4041 while (--i >= 0) 4041 while (--i >= 0)
4042 if (palette[i].alpha < 255) 4042 if (palette[i].alpha < 255)
4043 break; 4043 break;
4044 4044
4045# ifdef __GNUC__ 4045# ifdef __GNUC__
4046 /* GCC can't handle the more obviously optimizable version. */ 4046 /* GCC can't handle the more obviously optimizable version. */
4047 if (i >= 0) 4047 if (i >= 0)
4048 dp->is_transparent = 1; 4048 dp->is_transparent = 1;
4049 else 4049 else
4050 dp->is_transparent = 0; 4050 dp->is_transparent = 0;
4051# else 4051# else
4052 dp->is_transparent = (i >= 0); 4052 dp->is_transparent = (i >= 0);
4053# endif 4053# endif
4054 } 4054 }
4055} 4055}
4056 4056
4057/* Utility to read the palette from the PNG file and convert it into 4057/* Utility to read the palette from the PNG file and convert it into
4058 * store_palette format. This returns 1 if there is any transparency in the 4058 * store_palette format. This returns 1 if there is any transparency in the
4059 * palette (it does not check for a transparent colour in the non-palette case.) 4059 * palette (it does not check for a transparent colour in the non-palette case.)
4060 */ 4060 */
4061static int 4061static int
4062read_palette(store_palette palette, int *npalette, png_structp pp, png_infop pi) 4062read_palette(store_palette palette, int *npalette, png_structp pp, png_infop pi)
4063{ 4063{
4064 png_colorp pal; 4064 png_colorp pal;
4065 png_bytep trans_alpha; 4065 png_bytep trans_alpha;
4066 int num; 4066 int num;
4067 4067
4068 pal = 0; 4068 pal = 0;
4069 *npalette = -1; 4069 *npalette = -1;
4070 4070
4071 if (png_get_PLTE(pp, pi, &pal, npalette) & PNG_INFO_PLTE) 4071 if (png_get_PLTE(pp, pi, &pal, npalette) & PNG_INFO_PLTE)
4072 { 4072 {
4073 int i = *npalette; 4073 int i = *npalette;
4074 4074
4075 if (i <= 0 || i > 256) 4075 if (i <= 0 || i > 256)
4076 png_error(pp, "validate: invalid PLTE count"); 4076 png_error(pp, "validate: invalid PLTE count");
4077 4077
4078 while (--i >= 0) 4078 while (--i >= 0)
4079 { 4079 {
4080 palette[i].red = pal[i].red; 4080 palette[i].red = pal[i].red;
4081 palette[i].green = pal[i].green; 4081 palette[i].green = pal[i].green;
4082 palette[i].blue = pal[i].blue; 4082 palette[i].blue = pal[i].blue;
4083 } 4083 }
4084 4084
4085 /* Mark the remainder of the entries with a flag value (other than 4085 /* Mark the remainder of the entries with a flag value (other than
4086 * white/opaque which is the flag value stored above.) 4086 * white/opaque which is the flag value stored above.)
4087 */ 4087 */
4088 memset(palette + *npalette, 126, (256-*npalette) * sizeof *palette); 4088 memset(palette + *npalette, 126, (256-*npalette) * sizeof *palette);
4089 } 4089 }
4090 4090
4091 else /* !png_get_PLTE */ 4091 else /* !png_get_PLTE */
4092 { 4092 {
4093 if (*npalette != (-1)) 4093 if (*npalette != (-1))
4094 png_error(pp, "validate: invalid PLTE result"); 4094 png_error(pp, "validate: invalid PLTE result");
4095 /* But there is no palette, so record this: */ 4095 /* But there is no palette, so record this: */
4096 *npalette = 0; 4096 *npalette = 0;
4097 memset(palette, 113, sizeof (store_palette)); 4097 memset(palette, 113, sizeof (store_palette));
4098 } 4098 }
4099 4099
4100 trans_alpha = 0; 4100 trans_alpha = 0;
4101 num = 2; /* force error below */ 4101 num = 2; /* force error below */
4102 if ((png_get_tRNS(pp, pi, &trans_alpha, &num, 0) & PNG_INFO_tRNS) != 0 && 4102 if ((png_get_tRNS(pp, pi, &trans_alpha, &num, 0) & PNG_INFO_tRNS) != 0 &&
4103 (trans_alpha != NULL || num != 1/*returns 1 for a transparent color*/) && 4103 (trans_alpha != NULL || num != 1/*returns 1 for a transparent color*/) &&
4104 /* Oops, if a palette tRNS gets expanded png_read_update_info (at least so 4104 /* Oops, if a palette tRNS gets expanded png_read_update_info (at least so
4105 * far as 1.5.4) does not remove the trans_alpha pointer, only num_trans, 4105 * far as 1.5.4) does not remove the trans_alpha pointer, only num_trans,
4106 * so in the above call we get a success, we get a pointer (who knows what 4106 * so in the above call we get a success, we get a pointer (who knows what
4107 * to) and we get num_trans == 0: 4107 * to) and we get num_trans == 0:
4108 */ 4108 */
4109 !(trans_alpha != NULL && num == 0)) /* TODO: fix this in libpng. */ 4109 !(trans_alpha != NULL && num == 0)) /* TODO: fix this in libpng. */
4110 { 4110 {
4111 int i; 4111 int i;
4112 4112
4113 /* Any of these are crash-worthy - given the implementation of 4113 /* Any of these are crash-worthy - given the implementation of
4114 * png_get_tRNS up to 1.5 an app won't crash if it just checks the 4114 * png_get_tRNS up to 1.5 an app won't crash if it just checks the
4115 * result above and fails to check that the variables it passed have 4115 * result above and fails to check that the variables it passed have
4116 * actually been filled in! Note that if the app were to pass the 4116 * actually been filled in! Note that if the app were to pass the
4117 * last, png_color_16p, variable too it couldn't rely on this. 4117 * last, png_color_16p, variable too it couldn't rely on this.
4118 */ 4118 */
4119 if (trans_alpha == NULL || num <= 0 || num > 256 || num > *npalette) 4119 if (trans_alpha == NULL || num <= 0 || num > 256 || num > *npalette)
4120 png_error(pp, "validate: unexpected png_get_tRNS (palette) result"); 4120 png_error(pp, "validate: unexpected png_get_tRNS (palette) result");
4121 4121
4122 for (i=0; i<num; ++i) 4122 for (i=0; i<num; ++i)
4123 palette[i].alpha = trans_alpha[i]; 4123 palette[i].alpha = trans_alpha[i];
4124 4124
4125 for (num=*npalette; i<num; ++i) 4125 for (num=*npalette; i<num; ++i)
4126 palette[i].alpha = 255; 4126 palette[i].alpha = 255;
4127 4127
4128 for (; i<256; ++i) 4128 for (; i<256; ++i)
4129 palette[i].alpha = 33; /* flag value */ 4129 palette[i].alpha = 33; /* flag value */
4130 4130
4131 return 1; /* transparency */ 4131 return 1; /* transparency */
4132 } 4132 }
4133 4133
4134 else 4134 else
4135 { 4135 {
4136 /* No palette transparency - just set the alpha channel to opaque. */ 4136 /* No palette transparency - just set the alpha channel to opaque. */
4137 int i; 4137 int i;
4138 4138
4139 for (i=0, num=*npalette; i<num; ++i) 4139 for (i=0, num=*npalette; i<num; ++i)
4140 palette[i].alpha = 255; 4140 palette[i].alpha = 255;
4141 4141
4142 for (; i<256; ++i) 4142 for (; i<256; ++i)
4143 palette[i].alpha = 55; /* flag value */ 4143 palette[i].alpha = 55; /* flag value */
4144 4144
4145 return 0; /* no transparency */ 4145 return 0; /* no transparency */
4146 } 4146 }
4147} 4147}
4148 4148
4149/* Utility to validate the palette if it should not have changed (the 4149/* Utility to validate the palette if it should not have changed (the
4150 * non-transform case). 4150 * non-transform case).
4151 */ 4151 */
4152static void 4152static void
4153standard_palette_validate(standard_display *dp, png_structp pp, png_infop pi) 4153standard_palette_validate(standard_display *dp, png_structp pp, png_infop pi)
4154{ 4154{
4155 int npalette; 4155 int npalette;
4156 store_palette palette; 4156 store_palette palette;
4157 4157
4158 if (read_palette(palette, &npalette, pp, pi) != dp->is_transparent) 4158 if (read_palette(palette, &npalette, pp, pi) != dp->is_transparent)
4159 png_error(pp, "validate: palette transparency changed"); 4159 png_error(pp, "validate: palette transparency changed");
4160 4160
4161 if (npalette != dp->npalette) 4161 if (npalette != dp->npalette)
4162 { 4162 {
4163 size_t pos = 0; 4163 size_t pos = 0;
4164 char msg[64]; 4164 char msg[64];
4165 4165
4166 pos = safecat(msg, sizeof msg, pos, "validate: palette size changed: "); 4166 pos = safecat(msg, sizeof msg, pos, "validate: palette size changed: ");
4167 pos = safecatn(msg, sizeof msg, pos, dp->npalette); 4167 pos = safecatn(msg, sizeof msg, pos, dp->npalette);
4168 pos = safecat(msg, sizeof msg, pos, " -> "); 4168 pos = safecat(msg, sizeof msg, pos, " -> ");
4169 pos = safecatn(msg, sizeof msg, pos, npalette); 4169 pos = safecatn(msg, sizeof msg, pos, npalette);
4170 png_error(pp, msg); 4170 png_error(pp, msg);
4171 } 4171 }
4172 4172
4173 { 4173 {
4174 int i = npalette; /* npalette is aliased */ 4174 int i = npalette; /* npalette is aliased */
4175 4175
4176 while (--i >= 0) 4176 while (--i >= 0)
4177 if (palette[i].red != dp->palette[i].red || 4177 if (palette[i].red != dp->palette[i].red ||
4178 palette[i].green != dp->palette[i].green || 4178 palette[i].green != dp->palette[i].green ||
4179 palette[i].blue != dp->palette[i].blue || 4179 palette[i].blue != dp->palette[i].blue ||
4180 palette[i].alpha != dp->palette[i].alpha) 4180 palette[i].alpha != dp->palette[i].alpha)
4181 png_error(pp, "validate: PLTE or tRNS chunk changed"); 4181 png_error(pp, "validate: PLTE or tRNS chunk changed");
4182 } 4182 }
4183} 4183}
4184 4184
4185/* By passing a 'standard_display' the progressive callbacks can be used 4185/* By passing a 'standard_display' the progressive callbacks can be used
4186 * directly by the sequential code, the functions suffixed "_imp" are the 4186 * directly by the sequential code, the functions suffixed "_imp" are the
4187 * implementations, the functions without the suffix are the callbacks. 4187 * implementations, the functions without the suffix are the callbacks.
4188 * 4188 *
4189 * The code for the info callback is split into two because this callback calls 4189 * The code for the info callback is split into two because this callback calls
4190 * png_read_update_info or png_start_read_image and what gets called depends on 4190 * png_read_update_info or png_start_read_image and what gets called depends on
4191 * whether the info needs updating (we want to test both calls in pngvalid.) 4191 * whether the info needs updating (we want to test both calls in pngvalid.)
4192 */ 4192 */
4193static void 4193static void
4194standard_info_part1(standard_display *dp, png_structp pp, png_infop pi) 4194standard_info_part1(standard_display *dp, png_structp pp, png_infop pi)
4195{ 4195{
4196 if (png_get_bit_depth(pp, pi) != dp->bit_depth) 4196 if (png_get_bit_depth(pp, pi) != dp->bit_depth)
4197 png_error(pp, "validate: bit depth changed"); 4197 png_error(pp, "validate: bit depth changed");
4198 4198
4199 if (png_get_color_type(pp, pi) != dp->colour_type) 4199 if (png_get_color_type(pp, pi) != dp->colour_type)
4200 png_error(pp, "validate: color type changed"); 4200 png_error(pp, "validate: color type changed");
4201 4201
4202 if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE) 4202 if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE)
4203 png_error(pp, "validate: filter type changed"); 4203 png_error(pp, "validate: filter type changed");
4204 4204
4205 if (png_get_interlace_type(pp, pi) != dp->interlace_type) 4205 if (png_get_interlace_type(pp, pi) != dp->interlace_type)
4206 png_error(pp, "validate: interlacing changed"); 4206 png_error(pp, "validate: interlacing changed");
4207 4207
4208 if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE) 4208 if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE)
4209 png_error(pp, "validate: compression type changed"); 4209 png_error(pp, "validate: compression type changed");
4210 4210
4211 dp->w = png_get_image_width(pp, pi); 4211 dp->w = png_get_image_width(pp, pi);
4212 4212
4213 if (dp->w != standard_width(pp, dp->id)) 4213 if (dp->w != standard_width(pp, dp->id))
4214 png_error(pp, "validate: image width changed"); 4214 png_error(pp, "validate: image width changed");
4215 4215
4216 dp->h = png_get_image_height(pp, pi); 4216 dp->h = png_get_image_height(pp, pi);
4217 4217
4218 if (dp->h != standard_height(pp, dp->id)) 4218 if (dp->h != standard_height(pp, dp->id))
4219 png_error(pp, "validate: image height changed"); 4219 png_error(pp, "validate: image height changed");
4220 4220
4221 /* Record (but don't check at present) the input sBIT according to the colour 4221 /* Record (but don't check at present) the input sBIT according to the colour
4222 * type information. 4222 * type information.
4223 */ 4223 */
4224 { 4224 {
4225 png_color_8p sBIT = 0; 4225 png_color_8p sBIT = 0;
4226 4226
4227 if (png_get_sBIT(pp, pi, &sBIT) & PNG_INFO_sBIT) 4227 if (png_get_sBIT(pp, pi, &sBIT) & PNG_INFO_sBIT)
4228 { 4228 {
4229 int sBIT_invalid = 0; 4229 int sBIT_invalid = 0;
4230 4230
4231 if (sBIT == 0) 4231 if (sBIT == 0)
4232 png_error(pp, "validate: unexpected png_get_sBIT result"); 4232 png_error(pp, "validate: unexpected png_get_sBIT result");
4233 4233
4234 if (dp->colour_type & PNG_COLOR_MASK_COLOR) 4234 if (dp->colour_type & PNG_COLOR_MASK_COLOR)
4235 { 4235 {
4236 if (sBIT->red == 0 || sBIT->red > dp->bit_depth) 4236 if (sBIT->red == 0 || sBIT->red > dp->bit_depth)
4237 sBIT_invalid = 1; 4237 sBIT_invalid = 1;
4238 else 4238 else
4239 dp->red_sBIT = sBIT->red; 4239 dp->red_sBIT = sBIT->red;
4240 4240
4241 if (sBIT->green == 0 || sBIT->green > dp->bit_depth) 4241 if (sBIT->green == 0 || sBIT->green > dp->bit_depth)
4242 sBIT_invalid = 1; 4242 sBIT_invalid = 1;
4243 else 4243 else
4244 dp->green_sBIT = sBIT->green; 4244 dp->green_sBIT = sBIT->green;
4245 4245
4246 if (sBIT->blue == 0 || sBIT->blue > dp->bit_depth) 4246 if (sBIT->blue == 0 || sBIT->blue > dp->bit_depth)
4247 sBIT_invalid = 1; 4247 sBIT_invalid = 1;
4248 else 4248 else
4249 dp->blue_sBIT = sBIT->blue; 4249 dp->blue_sBIT = sBIT->blue;
4250 } 4250 }
4251 4251
4252 else /* !COLOR */ 4252 else /* !COLOR */
4253 { 4253 {
4254 if (sBIT->gray == 0 || sBIT->gray > dp->bit_depth) 4254 if (sBIT->gray == 0 || sBIT->gray > dp->bit_depth)
4255 sBIT_invalid = 1; 4255 sBIT_invalid = 1;
4256 else 4256 else
4257 dp->blue_sBIT = dp->green_sBIT = dp->red_sBIT = sBIT->gray; 4257 dp->blue_sBIT = dp->green_sBIT = dp->red_sBIT = sBIT->gray;
4258 } 4258 }
4259 4259
4260 /* All 8 bits in tRNS for a palette image are significant - see the 4260 /* All 8 bits in tRNS for a palette image are significant - see the
4261 * spec. 4261 * spec.
4262 */ 4262 */
4263 if (dp->colour_type & PNG_COLOR_MASK_ALPHA) 4263 if (dp->colour_type & PNG_COLOR_MASK_ALPHA)
4264 { 4264 {
4265 if (sBIT->alpha == 0 || sBIT->alpha > dp->bit_depth) 4265 if (sBIT->alpha == 0 || sBIT->alpha > dp->bit_depth)
4266 sBIT_invalid = 1; 4266 sBIT_invalid = 1;
4267 else 4267 else
4268 dp->alpha_sBIT = sBIT->alpha; 4268 dp->alpha_sBIT = sBIT->alpha;
4269 } 4269 }
4270 4270
4271 if (sBIT_invalid) 4271 if (sBIT_invalid)
4272 png_error(pp, "validate: sBIT value out of range"); 4272 png_error(pp, "validate: sBIT value out of range");
4273 } 4273 }
4274 } 4274 }
4275 4275
4276 /* Important: this is validating the value *before* any transforms have been 4276 /* Important: this is validating the value *before* any transforms have been
4277 * put in place. It doesn't matter for the standard tests, where there are 4277 * put in place. It doesn't matter for the standard tests, where there are
4278 * no transforms, but it does for other tests where rowbytes may change after 4278 * no transforms, but it does for other tests where rowbytes may change after
4279 * png_read_update_info. 4279 * png_read_update_info.
4280 */ 4280 */
4281 if (png_get_rowbytes(pp, pi) != standard_rowsize(pp, dp->id)) 4281 if (png_get_rowbytes(pp, pi) != standard_rowsize(pp, dp->id))
4282 png_error(pp, "validate: row size changed"); 4282 png_error(pp, "validate: row size changed");
4283 4283
4284 /* Validate the colour type 3 palette (this can be present on other color 4284 /* Validate the colour type 3 palette (this can be present on other color
4285 * types.) 4285 * types.)
4286 */ 4286 */
4287 standard_palette_validate(dp, pp, pi); 4287 standard_palette_validate(dp, pp, pi);
4288 4288
4289 /* In any case always check for a tranparent color (notice that the 4289 /* In any case always check for a tranparent color (notice that the
4290 * colour type 3 case must not give a successful return on the get_tRNS call 4290 * colour type 3 case must not give a successful return on the get_tRNS call
4291 * with these arguments!) 4291 * with these arguments!)
4292 */ 4292 */
4293 { 4293 {
4294 png_color_16p trans_color = 0; 4294 png_color_16p trans_color = 0;
4295 4295
4296 if (png_get_tRNS(pp, pi, 0, 0, &trans_color) & PNG_INFO_tRNS) 4296 if (png_get_tRNS(pp, pi, 0, 0, &trans_color) & PNG_INFO_tRNS)
4297 { 4297 {
4298 if (trans_color == 0) 4298 if (trans_color == 0)
4299 png_error(pp, "validate: unexpected png_get_tRNS (color) result"); 4299 png_error(pp, "validate: unexpected png_get_tRNS (color) result");
4300 4300
4301 switch (dp->colour_type) 4301 switch (dp->colour_type)
4302 { 4302 {
4303 case 0: 4303 case 0:
4304 dp->transparent.red = dp->transparent.green = dp->transparent.blue = 4304 dp->transparent.red = dp->transparent.green = dp->transparent.blue =
4305 trans_color->gray; 4305 trans_color->gray;
4306 dp->is_transparent = 1; 4306 dp->is_transparent = 1;
4307 break; 4307 break;
4308 4308
4309 case 2: 4309 case 2:
4310 dp->transparent.red = trans_color->red; 4310 dp->transparent.red = trans_color->red;
4311 dp->transparent.green = trans_color->green; 4311 dp->transparent.green = trans_color->green;
4312 dp->transparent.blue = trans_color->blue; 4312 dp->transparent.blue = trans_color->blue;
4313 dp->is_transparent = 1; 4313 dp->is_transparent = 1;
4314 break; 4314 break;
4315 4315
4316 case 3: 4316 case 3:
4317 /* Not expected because it should result in the array case 4317 /* Not expected because it should result in the array case
4318 * above. 4318 * above.
4319 */ 4319 */
4320 png_error(pp, "validate: unexpected png_get_tRNS result"); 4320 png_error(pp, "validate: unexpected png_get_tRNS result");
4321 break; 4321 break;
4322 4322
4323 default: 4323 default:
4324 png_error(pp, "validate: invalid tRNS chunk with alpha image"); 4324 png_error(pp, "validate: invalid tRNS chunk with alpha image");
4325 } 4325 }
4326 } 4326 }
4327 } 4327 }
4328 4328
4329 /* Read the number of passes - expected to match the value used when 4329 /* Read the number of passes - expected to match the value used when
4330 * creating the image (interlaced or not). This has the side effect of 4330 * creating the image (interlaced or not). This has the side effect of
4331 * turning on interlace handling (if do_interlace is not set.) 4331 * turning on interlace handling (if do_interlace is not set.)
4332 */ 4332 */
4333 dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type); 4333 dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type);
4334 if (!dp->do_interlace && dp->npasses != png_set_interlace_handling(pp)) 4334 if (!dp->do_interlace && dp->npasses != png_set_interlace_handling(pp))
4335 png_error(pp, "validate: file changed interlace type"); 4335 png_error(pp, "validate: file changed interlace type");
4336 4336
4337 /* Caller calls png_read_update_info or png_start_read_image now, then calls 4337 /* Caller calls png_read_update_info or png_start_read_image now, then calls
4338 * part2. 4338 * part2.
4339 */ 4339 */
4340} 4340}
4341 4341
4342/* This must be called *after* the png_read_update_info call to get the correct 4342/* This must be called *after* the png_read_update_info call to get the correct
4343 * 'rowbytes' value, otherwise png_get_rowbytes will refer to the untransformed 4343 * 'rowbytes' value, otherwise png_get_rowbytes will refer to the untransformed
4344 * image. 4344 * image.
4345 */ 4345 */
4346static void 4346static void
4347standard_info_part2(standard_display *dp, png_structp pp, png_infop pi, 4347standard_info_part2(standard_display *dp, png_structp pp, png_infop pi,
4348 int nImages) 4348 int nImages)
4349{ 4349{
4350 /* Record cbRow now that it can be found. */ 4350 /* Record cbRow now that it can be found. */
4351 dp->pixel_size = bit_size(pp, png_get_color_type(pp, pi), 4351 dp->pixel_size = bit_size(pp, png_get_color_type(pp, pi),
4352 png_get_bit_depth(pp, pi)); 4352 png_get_bit_depth(pp, pi));
4353 dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size; 4353 dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size;
4354 dp->cbRow = png_get_rowbytes(pp, pi); 4354 dp->cbRow = png_get_rowbytes(pp, pi);
4355 4355
4356 /* Validate the rowbytes here again. */ 4356 /* Validate the rowbytes here again. */
4357 if (dp->cbRow != (dp->bit_width+7)/8) 4357 if (dp->cbRow != (dp->bit_width+7)/8)
4358 png_error(pp, "bad png_get_rowbytes calculation"); 4358 png_error(pp, "bad png_get_rowbytes calculation");
4359 4359
4360 /* Then ensure there is enough space for the output image(s). */ 4360 /* Then ensure there is enough space for the output image(s). */
4361 store_ensure_image(dp->ps, pp, nImages, dp->cbRow, dp->h); 4361 store_ensure_image(dp->ps, pp, nImages, dp->cbRow, dp->h);
4362} 4362}
4363 4363
4364static void 4364static void
4365standard_info_imp(standard_display *dp, png_structp pp, png_infop pi, 4365standard_info_imp(standard_display *dp, png_structp pp, png_infop pi,
4366 int nImages) 4366 int nImages)
4367{ 4367{
4368 /* Note that the validation routine has the side effect of turning on 4368 /* Note that the validation routine has the side effect of turning on
4369 * interlace handling in the subsequent code. 4369 * interlace handling in the subsequent code.
4370 */ 4370 */
4371 standard_info_part1(dp, pp, pi); 4371 standard_info_part1(dp, pp, pi);
4372 4372
4373 /* And the info callback has to call this (or png_read_update_info - see 4373 /* And the info callback has to call this (or png_read_update_info - see
4374 * below in the png_modifier code for that variant. 4374 * below in the png_modifier code for that variant.
4375 */ 4375 */
4376 if (dp->use_update_info) 4376 if (dp->use_update_info)
4377 { 4377 {
4378 /* For debugging the effect of multiple calls: */ 4378 /* For debugging the effect of multiple calls: */
4379 int i = dp->use_update_info; 4379 int i = dp->use_update_info;
4380 while (i-- > 0) 4380 while (i-- > 0)
4381 png_read_update_info(pp, pi); 4381 png_read_update_info(pp, pi);
4382 } 4382 }
4383 4383
4384 else 4384 else
4385 png_start_read_image(pp); 4385 png_start_read_image(pp);
4386 4386
4387 /* Validate the height, width and rowbytes plus ensure that sufficient buffer 4387 /* Validate the height, width and rowbytes plus ensure that sufficient buffer
4388 * exists for decoding the image. 4388 * exists for decoding the image.
4389 */ 4389 */
4390 standard_info_part2(dp, pp, pi, nImages); 4390 standard_info_part2(dp, pp, pi, nImages);
4391} 4391}
4392 4392
4393static void 4393static void
4394standard_info(png_structp pp, png_infop pi) 4394standard_info(png_structp pp, png_infop pi)
4395{ 4395{
4396 standard_display *dp = voidcast(standard_display*, 4396 standard_display *dp = voidcast(standard_display*,
4397 png_get_progressive_ptr(pp)); 4397 png_get_progressive_ptr(pp));
4398 4398
4399 /* Call with nImages==1 because the progressive reader can only produce one 4399 /* Call with nImages==1 because the progressive reader can only produce one
4400 * image. 4400 * image.
4401 */ 4401 */
4402 standard_info_imp(dp, pp, pi, 1 /*only one image*/); 4402 standard_info_imp(dp, pp, pi, 1 /*only one image*/);
4403} 4403}
4404 4404
4405static void 4405static void
4406progressive_row(png_structp pp, png_bytep new_row, png_uint_32 y, int pass) 4406progressive_row(png_structp pp, png_bytep new_row, png_uint_32 y, int pass)
4407{ 4407{
4408 PNG_CONST standard_display *dp = voidcast(standard_display*, 4408 PNG_CONST standard_display *dp = voidcast(standard_display*,
4409 png_get_progressive_ptr(pp)); 4409 png_get_progressive_ptr(pp));
4410 4410
4411 /* When handling interlacing some rows will be absent in each pass, the 4411 /* When handling interlacing some rows will be absent in each pass, the
4412 * callback still gets called, but with a NULL pointer. This is checked 4412 * callback still gets called, but with a NULL pointer. This is checked
4413 * in the 'else' clause below. We need our own 'cbRow', but we can't call 4413 * in the 'else' clause below. We need our own 'cbRow', but we can't call
4414 * png_get_rowbytes because we got no info structure. 4414 * png_get_rowbytes because we got no info structure.
4415 */ 4415 */
4416 if (new_row != NULL) 4416 if (new_row != NULL)
4417 { 4417 {
4418 png_bytep row; 4418 png_bytep row;
4419 4419
4420 /* In the case where the reader doesn't do the interlace it gives 4420 /* In the case where the reader doesn't do the interlace it gives
4421 * us the y in the sub-image: 4421 * us the y in the sub-image:
4422 */ 4422 */
4423 if (dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7) 4423 if (dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7)
4424 { 4424 {
4425#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED 4425#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
4426 /* Use this opportunity to validate the png 'current' APIs: */ 4426 /* Use this opportunity to validate the png 'current' APIs: */
4427 if (y != png_get_current_row_number(pp)) 4427 if (y != png_get_current_row_number(pp))
4428 png_error(pp, "png_get_current_row_number is broken"); 4428 png_error(pp, "png_get_current_row_number is broken");
4429 4429
4430 if (pass != png_get_current_pass_number(pp)) 4430 if (pass != png_get_current_pass_number(pp))
4431 png_error(pp, "png_get_current_pass_number is broken"); 4431 png_error(pp, "png_get_current_pass_number is broken");
4432#endif 4432#endif
4433 4433
4434 y = PNG_ROW_FROM_PASS_ROW(y, pass); 4434 y = PNG_ROW_FROM_PASS_ROW(y, pass);
4435 } 4435 }
4436 4436
4437 /* Validate this just in case. */ 4437 /* Validate this just in case. */
4438 if (y >= dp->h) 4438 if (y >= dp->h)
4439 png_error(pp, "invalid y to progressive row callback"); 4439 png_error(pp, "invalid y to progressive row callback");
4440 4440
4441 row = store_image_row(dp->ps, pp, 0, y); 4441 row = store_image_row(dp->ps, pp, 0, y);
4442 4442
4443#ifdef PNG_READ_INTERLACING_SUPPORTED 4443#ifdef PNG_READ_INTERLACING_SUPPORTED
4444 /* Combine the new row into the old: */ 4444 /* Combine the new row into the old: */
4445 if (dp->do_interlace) 4445 if (dp->do_interlace)
4446 { 4446 {
4447 if (dp->interlace_type == PNG_INTERLACE_ADAM7) 4447 if (dp->interlace_type == PNG_INTERLACE_ADAM7)
4448 deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass); 4448 deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass);
4449 else 4449 else
4450 row_copy(row, new_row, dp->pixel_size * dp->w); 4450 row_copy(row, new_row, dp->pixel_size * dp->w);
4451 } 4451 }
4452 else 4452 else
4453 png_progressive_combine_row(pp, row, new_row); 4453 png_progressive_combine_row(pp, row, new_row);
4454 } else if (dp->interlace_type == PNG_INTERLACE_ADAM7 && 4454 } else if (dp->interlace_type == PNG_INTERLACE_ADAM7 &&
4455 PNG_ROW_IN_INTERLACE_PASS(y, pass) && 4455 PNG_ROW_IN_INTERLACE_PASS(y, pass) &&
4456 PNG_PASS_COLS(dp->w, pass) > 0) 4456 PNG_PASS_COLS(dp->w, pass) > 0)
4457 png_error(pp, "missing row in progressive de-interlacing"); 4457 png_error(pp, "missing row in progressive de-interlacing");
4458#endif /* PNG_READ_INTERLACING_SUPPORTED */ 4458#endif /* PNG_READ_INTERLACING_SUPPORTED */
4459} 4459}
4460 4460
4461static void 4461static void
4462sequential_row(standard_display *dp, png_structp pp, png_infop pi, 4462sequential_row(standard_display *dp, png_structp pp, png_infop pi,
4463 PNG_CONST int iImage, PNG_CONST int iDisplay) 4463 PNG_CONST int iImage, PNG_CONST int iDisplay)
4464{ 4464{
4465 PNG_CONST int npasses = dp->npasses; 4465 PNG_CONST int npasses = dp->npasses;
4466 PNG_CONST int do_interlace = dp->do_interlace && 4466 PNG_CONST int do_interlace = dp->do_interlace &&
4467 dp->interlace_type == PNG_INTERLACE_ADAM7; 4467 dp->interlace_type == PNG_INTERLACE_ADAM7;
4468 PNG_CONST png_uint_32 height = standard_height(pp, dp->id); 4468 PNG_CONST png_uint_32 height = standard_height(pp, dp->id);
4469 PNG_CONST png_uint_32 width = standard_width(pp, dp->id); 4469 PNG_CONST png_uint_32 width = standard_width(pp, dp->id);
4470 PNG_CONST png_store* ps = dp->ps; 4470 PNG_CONST png_store* ps = dp->ps;
4471 int pass; 4471 int pass;
4472 4472
4473 for (pass=0; pass<npasses; ++pass) 4473 for (pass=0; pass<npasses; ++pass)
4474 { 4474 {
4475 png_uint_32 y; 4475 png_uint_32 y;
4476 png_uint_32 wPass = PNG_PASS_COLS(width, pass); 4476 png_uint_32 wPass = PNG_PASS_COLS(width, pass);
4477 4477
4478 for (y=0; y<height; ++y) 4478 for (y=0; y<height; ++y)
4479 { 4479 {
4480 if (do_interlace) 4480 if (do_interlace)
4481 { 4481 {
4482 /* wPass may be zero or this row may not be in this pass. 4482 /* wPass may be zero or this row may not be in this pass.
4483 * png_read_row must not be called in either case. 4483 * png_read_row must not be called in either case.
4484 */ 4484 */
4485 if (wPass > 0 && PNG_ROW_IN_INTERLACE_PASS(y, pass)) 4485 if (wPass > 0 && PNG_ROW_IN_INTERLACE_PASS(y, pass))
4486 { 4486 {
4487 /* Read the row into a pair of temporary buffers, then do the 4487 /* Read the row into a pair of temporary buffers, then do the
4488 * merge here into the output rows. 4488 * merge here into the output rows.
4489 */ 4489 */
4490 png_byte row[STANDARD_ROWMAX], display[STANDARD_ROWMAX]; 4490 png_byte row[STANDARD_ROWMAX], display[STANDARD_ROWMAX];
4491 4491
4492 /* The following aids (to some extent) error detection - we can 4492 /* The following aids (to some extent) error detection - we can
4493 * see where png_read_row wrote. Use opposite values in row and 4493 * see where png_read_row wrote. Use opposite values in row and
4494 * display to make this easier. Don't use 0xff (which is used in 4494 * display to make this easier. Don't use 0xff (which is used in
4495 * the image write code to fill unused bits) or 0 (which is a 4495 * the image write code to fill unused bits) or 0 (which is a
4496 * likely value to overwrite unused bits with). 4496 * likely value to overwrite unused bits with).
4497 */ 4497 */
4498 memset(row, 0xc5, sizeof row); 4498 memset(row, 0xc5, sizeof row);
4499 memset(display, 0x5c, sizeof display); 4499 memset(display, 0x5c, sizeof display);
4500 4500
4501 png_read_row(pp, row, display); 4501 png_read_row(pp, row, display);
4502 4502
4503 if (iImage >= 0) 4503 if (iImage >= 0)
4504 deinterlace_row(store_image_row(ps, pp, iImage, y), row, 4504 deinterlace_row(store_image_row(ps, pp, iImage, y), row,
4505 dp->pixel_size, dp->w, pass); 4505 dp->pixel_size, dp->w, pass);
4506 4506
4507 if (iDisplay >= 0) 4507 if (iDisplay >= 0)
4508 deinterlace_row(store_image_row(ps, pp, iDisplay, y), display, 4508 deinterlace_row(store_image_row(ps, pp, iDisplay, y), display,
4509 dp->pixel_size, dp->w, pass); 4509 dp->pixel_size, dp->w, pass);
4510 } 4510 }
4511 } 4511 }
4512 else 4512 else
4513 png_read_row(pp, 4513 png_read_row(pp,
4514 iImage >= 0 ? store_image_row(ps, pp, iImage, y) : NULL, 4514 iImage >= 0 ? store_image_row(ps, pp, iImage, y) : NULL,
4515 iDisplay >= 0 ? store_image_row(ps, pp, iDisplay, y) : NULL); 4515 iDisplay >= 0 ? store_image_row(ps, pp, iDisplay, y) : NULL);
4516 } 4516 }
4517 } 4517 }
4518 4518
4519 /* And finish the read operation (only really necessary if the caller wants 4519 /* And finish the read operation (only really necessary if the caller wants
4520 * to find additional data in png_info from chunks after the last IDAT.) 4520 * to find additional data in png_info from chunks after the last IDAT.)
4521 */ 4521 */
4522 png_read_end(pp, pi); 4522 png_read_end(pp, pi);
4523} 4523}
4524 4524
4525static void 4525static void
4526standard_row_validate(standard_display *dp, png_structp pp, 4526standard_row_validate(standard_display *dp, png_structp pp,
4527 int iImage, int iDisplay, png_uint_32 y) 4527 int iImage, int iDisplay, png_uint_32 y)
4528{ 4528{
4529 int where; 4529 int where;
4530 png_byte std[STANDARD_ROWMAX]; 4530 png_byte std[STANDARD_ROWMAX];
4531 4531
4532 /* The row must be pre-initialized to the magic number here for the size 4532 /* The row must be pre-initialized to the magic number here for the size
4533 * tests to pass: 4533 * tests to pass:
4534 */ 4534 */
4535 memset(std, 178, sizeof std); 4535 memset(std, 178, sizeof std);
4536 standard_row(pp, std, dp->id, y); 4536 standard_row(pp, std, dp->id, y);
4537 4537
4538 /* At the end both the 'row' and 'display' arrays should end up identical. 4538 /* At the end both the 'row' and 'display' arrays should end up identical.
4539 * In earlier passes 'row' will be partially filled in, with only the pixels 4539 * In earlier passes 'row' will be partially filled in, with only the pixels
4540 * that have been read so far, but 'display' will have those pixels 4540 * that have been read so far, but 'display' will have those pixels
4541 * replicated to fill the unread pixels while reading an interlaced image. 4541 * replicated to fill the unread pixels while reading an interlaced image.
4542#if PNG_LIBPNG_VER < 10506 4542#if PNG_LIBPNG_VER < 10506
4543 * The side effect inside the libpng sequential reader is that the 'row' 4543 * The side effect inside the libpng sequential reader is that the 'row'
4544 * array retains the correct values for unwritten pixels within the row 4544 * array retains the correct values for unwritten pixels within the row
4545 * bytes, while the 'display' array gets bits off the end of the image (in 4545 * bytes, while the 'display' array gets bits off the end of the image (in
4546 * the last byte) trashed. Unfortunately in the progressive reader the 4546 * the last byte) trashed. Unfortunately in the progressive reader the
4547 * row bytes are always trashed, so we always do a pixel_cmp here even though 4547 * row bytes are always trashed, so we always do a pixel_cmp here even though
4548 * a memcmp of all cbRow bytes will succeed for the sequential reader. 4548 * a memcmp of all cbRow bytes will succeed for the sequential reader.
4549#endif 4549#endif
4550 */ 4550 */
4551 if (iImage >= 0 && 4551 if (iImage >= 0 &&
4552 (where = pixel_cmp(std, store_image_row(dp->ps, pp, iImage, y), 4552 (where = pixel_cmp(std, store_image_row(dp->ps, pp, iImage, y),
4553 dp->bit_width)) != 0) 4553 dp->bit_width)) != 0)
4554 { 4554 {
4555 char msg[64]; 4555 char msg[64];
4556 sprintf(msg, "PNG image row[%d][%d] changed from %.2x to %.2x", y, 4556 sprintf(msg, "PNG image row[%d][%d] changed from %.2x to %.2x", y,
4557 where-1, std[where-1], 4557 where-1, std[where-1],
4558 store_image_row(dp->ps, pp, iImage, y)[where-1]); 4558 store_image_row(dp->ps, pp, iImage, y)[where-1]);
4559 png_error(pp, msg); 4559 png_error(pp, msg);
4560 } 4560 }
4561 4561
4562#if PNG_LIBPNG_VER < 10506 4562#if PNG_LIBPNG_VER < 10506
4563 /* In this case use pixel_cmp because we need to compare a partial 4563 /* In this case use pixel_cmp because we need to compare a partial
4564 * byte at the end of the row if the row is not an exact multiple 4564 * byte at the end of the row if the row is not an exact multiple
4565 * of 8 bits wide. (This is fixed in libpng-1.5.6 and pixel_cmp is 4565 * of 8 bits wide. (This is fixed in libpng-1.5.6 and pixel_cmp is
4566 * changed to match!) 4566 * changed to match!)
4567 */ 4567 */
4568#endif 4568#endif
4569 if (iDisplay >= 0 && 4569 if (iDisplay >= 0 &&
4570 (where = pixel_cmp(std, store_image_row(dp->ps, pp, iDisplay, y), 4570 (where = pixel_cmp(std, store_image_row(dp->ps, pp, iDisplay, y),
4571 dp->bit_width)) != 0) 4571 dp->bit_width)) != 0)
4572 { 4572 {
4573 char msg[64]; 4573 char msg[64];
4574 sprintf(msg, "display row[%d][%d] changed from %.2x to %.2x", y, 4574 sprintf(msg, "display row[%d][%d] changed from %.2x to %.2x", y,
4575 where-1, std[where-1], 4575 where-1, std[where-1],
4576 store_image_row(dp->ps, pp, iDisplay, y)[where-1]); 4576 store_image_row(dp->ps, pp, iDisplay, y)[where-1]);
4577 png_error(pp, msg); 4577 png_error(pp, msg);
4578 } 4578 }
4579} 4579}
4580 4580
4581static void 4581static void
4582standard_image_validate(standard_display *dp, png_structp pp, int iImage, 4582standard_image_validate(standard_display *dp, png_structp pp, int iImage,
4583 int iDisplay) 4583 int iDisplay)
4584{ 4584{
4585 png_uint_32 y; 4585 png_uint_32 y;
4586 4586
4587 if (iImage >= 0) 4587 if (iImage >= 0)
4588 store_image_check(dp->ps, pp, iImage); 4588 store_image_check(dp->ps, pp, iImage);
4589 4589
4590 if (iDisplay >= 0) 4590 if (iDisplay >= 0)
4591 store_image_check(dp->ps, pp, iDisplay); 4591 store_image_check(dp->ps, pp, iDisplay);
4592 4592
4593 for (y=0; y<dp->h; ++y) 4593 for (y=0; y<dp->h; ++y)
4594 standard_row_validate(dp, pp, iImage, iDisplay, y); 4594 standard_row_validate(dp, pp, iImage, iDisplay, y);
4595 4595
4596 /* This avoids false positives if the validation code is never called! */ 4596 /* This avoids false positives if the validation code is never called! */
4597 dp->ps->validated = 1; 4597 dp->ps->validated = 1;
4598} 4598}
4599 4599
4600static void 4600static void
4601standard_end(png_structp pp, png_infop pi) 4601standard_end(png_structp pp, png_infop pi)
4602{ 4602{
4603 standard_display *dp = voidcast(standard_display*, 4603 standard_display *dp = voidcast(standard_display*,
4604 png_get_progressive_ptr(pp)); 4604 png_get_progressive_ptr(pp));
4605 4605
4606 UNUSED(pi) 4606 UNUSED(pi)
4607 4607
4608 /* Validate the image - progressive reading only produces one variant for 4608 /* Validate the image - progressive reading only produces one variant for
4609 * interlaced images. 4609 * interlaced images.
4610 */ 4610 */
4611 standard_image_validate(dp, pp, 0, -1); 4611 standard_image_validate(dp, pp, 0, -1);
4612} 4612}
4613 4613
4614/* A single test run checking the standard image to ensure it is not damaged. */ 4614/* A single test run checking the standard image to ensure it is not damaged. */
4615static void 4615static void
4616standard_test(png_store* PNG_CONST psIn, png_uint_32 PNG_CONST id, 4616standard_test(png_store* PNG_CONST psIn, png_uint_32 PNG_CONST id,
4617 int do_interlace, int use_update_info) 4617 int do_interlace, int use_update_info)
4618{ 4618{
4619 standard_display d; 4619 standard_display d;
4620 context(psIn, fault); 4620 context(psIn, fault);
4621 4621
4622 /* Set up the display (stack frame) variables from the arguments to the 4622 /* Set up the display (stack frame) variables from the arguments to the
4623 * function and initialize the locals that are filled in later. 4623 * function and initialize the locals that are filled in later.
4624 */ 4624 */
4625 standard_display_init(&d, psIn, id, do_interlace, use_update_info); 4625 standard_display_init(&d, psIn, id, do_interlace, use_update_info);
4626 4626
4627 /* Everything is protected by a Try/Catch. The functions called also 4627 /* Everything is protected by a Try/Catch. The functions called also
4628 * typically have local Try/Catch blocks. 4628 * typically have local Try/Catch blocks.
4629 */ 4629 */
4630 Try 4630 Try
4631 { 4631 {
4632 png_structp pp; 4632 png_structp pp;
4633 png_infop pi; 4633 png_infop pi;
4634 4634
4635 /* Get a png_struct for reading the image. This will throw an error if it 4635 /* Get a png_struct for reading the image. This will throw an error if it
4636 * fails, so we don't need to check the result. 4636 * fails, so we don't need to check the result.
4637 */ 4637 */
4638 pp = set_store_for_read(d.ps, &pi, d.id, 4638 pp = set_store_for_read(d.ps, &pi, d.id,
4639 d.do_interlace ? (d.ps->progressive ? 4639 d.do_interlace ? (d.ps->progressive ?
4640 "pngvalid progressive deinterlacer" : 4640 "pngvalid progressive deinterlacer" :
4641 "pngvalid sequential deinterlacer") : (d.ps->progressive ? 4641 "pngvalid sequential deinterlacer") : (d.ps->progressive ?
4642 "progressive reader" : "sequential reader")); 4642 "progressive reader" : "sequential reader"));
4643 4643
4644 /* Initialize the palette correctly from the png_store_file. */ 4644 /* Initialize the palette correctly from the png_store_file. */
4645 standard_palette_init(&d); 4645 standard_palette_init(&d);
4646 4646
4647 /* Introduce the correct read function. */ 4647 /* Introduce the correct read function. */
4648 if (d.ps->progressive) 4648 if (d.ps->progressive)
4649 { 4649 {
4650 png_set_progressive_read_fn(pp, &d, standard_info, progressive_row, 4650 png_set_progressive_read_fn(pp, &d, standard_info, progressive_row,
4651 standard_end); 4651 standard_end);
4652 4652
4653 /* Now feed data into the reader until we reach the end: */ 4653 /* Now feed data into the reader until we reach the end: */
4654 store_progressive_read(d.ps, pp, pi); 4654 store_progressive_read(d.ps, pp, pi);
4655 } 4655 }
4656 else 4656 else
4657 { 4657 {
4658 /* Note that this takes the store, not the display. */ 4658 /* Note that this takes the store, not the display. */
4659 png_set_read_fn(pp, d.ps, store_read); 4659 png_set_read_fn(pp, d.ps, store_read);
4660 4660
4661 /* Check the header values: */ 4661 /* Check the header values: */
4662 png_read_info(pp, pi); 4662 png_read_info(pp, pi);
4663 4663
4664 /* The code tests both versions of the images that the sequential 4664 /* The code tests both versions of the images that the sequential
4665 * reader can produce. 4665 * reader can produce.
4666 */ 4666 */
4667 standard_info_imp(&d, pp, pi, 2 /*images*/); 4667 standard_info_imp(&d, pp, pi, 2 /*images*/);
4668 4668
4669 /* Need the total bytes in the image below; we can't get to this point 4669 /* Need the total bytes in the image below; we can't get to this point
4670 * unless the PNG file values have been checked against the expected 4670 * unless the PNG file values have been checked against the expected
4671 * values. 4671 * values.
4672 */ 4672 */
4673 { 4673 {
4674 sequential_row(&d, pp, pi, 0, 1); 4674 sequential_row(&d, pp, pi, 0, 1);
4675 4675
4676 /* After the last pass loop over the rows again to check that the 4676 /* After the last pass loop over the rows again to check that the
4677 * image is correct. 4677 * image is correct.
4678 */ 4678 */
4679 if (!d.speed) 4679 if (!d.speed)
4680 standard_image_validate(&d, pp, 0, 1); 4680 standard_image_validate(&d, pp, 0, 1);
4681 else 4681 else
4682 d.ps->validated = 1; 4682 d.ps->validated = 1;
4683 } 4683 }
4684 } 4684 }
4685 4685
4686 /* Check for validation. */ 4686 /* Check for validation. */
4687 if (!d.ps->validated) 4687 if (!d.ps->validated)
4688 png_error(pp, "image read failed silently"); 4688 png_error(pp, "image read failed silently");
4689 4689
4690 /* Successful completion. */ 4690 /* Successful completion. */
4691 } 4691 }
4692 4692
4693 Catch(fault) 4693 Catch(fault)
4694 d.ps = fault; /* make sure this hasn't been clobbered. */ 4694 d.ps = fault; /* make sure this hasn't been clobbered. */
4695 4695
4696 /* In either case clean up the store. */ 4696 /* In either case clean up the store. */
4697 store_read_reset(d.ps); 4697 store_read_reset(d.ps);
4698} 4698}
4699 4699
4700static int 4700static int
4701test_standard(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, 4701test_standard(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
4702 int bdlo, int PNG_CONST bdhi) 4702 int bdlo, int PNG_CONST bdhi)
4703{ 4703{
4704 for (; bdlo <= bdhi; ++bdlo) 4704 for (; bdlo <= bdhi; ++bdlo)
4705 { 4705 {
4706 int interlace_type; 4706 int interlace_type;
4707 4707
4708 for (interlace_type = PNG_INTERLACE_NONE; 4708 for (interlace_type = PNG_INTERLACE_NONE;
4709 interlace_type < PNG_INTERLACE_LAST; ++interlace_type) 4709 interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
4710 { 4710 {
4711 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 4711 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
4712 interlace_type, 0, 0, 0), 0/*do_interlace*/, pm->use_update_info); 4712 interlace_type, 0, 0, 0), 0/*do_interlace*/, pm->use_update_info);
4713 4713
4714 if (fail(pm)) 4714 if (fail(pm))
4715 return 0; 4715 return 0;
4716 } 4716 }
4717 } 4717 }
4718 4718
4719 return 1; /* keep going */ 4719 return 1; /* keep going */
4720} 4720}
4721 4721
4722static void 4722static void
4723perform_standard_test(png_modifier *pm) 4723perform_standard_test(png_modifier *pm)
4724{ 4724{
4725 /* Test each colour type over the valid range of bit depths (expressed as 4725 /* Test each colour type over the valid range of bit depths (expressed as
4726 * log2(bit_depth) in turn, stop as soon as any error is detected. 4726 * log2(bit_depth) in turn, stop as soon as any error is detected.
4727 */ 4727 */
4728 if (!test_standard(pm, 0, 0, READ_BDHI)) 4728 if (!test_standard(pm, 0, 0, READ_BDHI))
4729 return; 4729 return;
4730 4730
4731 if (!test_standard(pm, 2, 3, READ_BDHI)) 4731 if (!test_standard(pm, 2, 3, READ_BDHI))
4732 return; 4732 return;
4733 4733
4734 if (!test_standard(pm, 3, 0, 3)) 4734 if (!test_standard(pm, 3, 0, 3))
4735 return; 4735 return;
4736 4736
4737 if (!test_standard(pm, 4, 3, READ_BDHI)) 4737 if (!test_standard(pm, 4, 3, READ_BDHI))
4738 return; 4738 return;
4739 4739
4740 if (!test_standard(pm, 6, 3, READ_BDHI)) 4740 if (!test_standard(pm, 6, 3, READ_BDHI))
4741 return; 4741 return;
4742} 4742}
4743 4743
4744 4744
4745/********************************** SIZE TESTS ********************************/ 4745/********************************** SIZE TESTS ********************************/
4746static int 4746static int
4747test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, 4747test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
4748 int bdlo, int PNG_CONST bdhi) 4748 int bdlo, int PNG_CONST bdhi)
4749{ 4749{
4750 /* Run the tests on each combination. 4750 /* Run the tests on each combination.
4751 * 4751 *
4752 * NOTE: on my 32 bit x86 each of the following blocks takes 4752 * NOTE: on my 32 bit x86 each of the following blocks takes
4753 * a total of 3.5 seconds if done across every combo of bit depth 4753 * a total of 3.5 seconds if done across every combo of bit depth
4754 * width and height. This is a waste of time in practice, hence the 4754 * width and height. This is a waste of time in practice, hence the
4755 * hinc and winc stuff: 4755 * hinc and winc stuff:
4756 */ 4756 */
4757 static PNG_CONST png_byte hinc[] = {1, 3, 11, 1, 5}; 4757 static PNG_CONST png_byte hinc[] = {1, 3, 11, 1, 5};
4758 static PNG_CONST png_byte winc[] = {1, 9, 5, 7, 1}; 4758 static PNG_CONST png_byte winc[] = {1, 9, 5, 7, 1};
4759 for (; bdlo <= bdhi; ++bdlo) 4759 for (; bdlo <= bdhi; ++bdlo)
4760 { 4760 {
4761 png_uint_32 h, w; 4761 png_uint_32 h, w;
4762 4762
4763 for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo]) 4763 for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])
4764 { 4764 {
4765 /* First test all the 'size' images against the sequential 4765 /* First test all the 'size' images against the sequential
4766 * reader using libpng to deinterlace (where required.) This 4766 * reader using libpng to deinterlace (where required.) This
4767 * validates the write side of libpng. There are four possibilities 4767 * validates the write side of libpng. There are four possibilities
4768 * to validate. 4768 * to validate.
4769 */ 4769 */
4770 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 4770 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
4771 PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/, 4771 PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/,
4772 pm->use_update_info); 4772 pm->use_update_info);
4773 4773
4774 if (fail(pm)) 4774 if (fail(pm))
4775 return 0; 4775 return 0;
4776 4776
4777 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 4777 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
4778 PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/, 4778 PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/,
4779 pm->use_update_info); 4779 pm->use_update_info);
4780 4780
4781 if (fail(pm)) 4781 if (fail(pm))
4782 return 0; 4782 return 0;
4783 4783
4784 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 4784 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
4785 PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/, 4785 PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/,
4786 pm->use_update_info); 4786 pm->use_update_info);
4787 4787
4788 if (fail(pm)) 4788 if (fail(pm))
4789 return 0; 4789 return 0;
4790 4790
4791 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 4791 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
4792 PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/, 4792 PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/,
4793 pm->use_update_info); 4793 pm->use_update_info);
4794 4794
4795 if (fail(pm)) 4795 if (fail(pm))
4796 return 0; 4796 return 0;
4797 4797
4798 /* Now validate the interlaced read side - do_interlace true, 4798 /* Now validate the interlaced read side - do_interlace true,
4799 * in the progressive case this does actually make a difference 4799 * in the progressive case this does actually make a difference
4800 * to the code used in the non-interlaced case too. 4800 * to the code used in the non-interlaced case too.
4801 */ 4801 */
4802 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 4802 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
4803 PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/, 4803 PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/,
4804 pm->use_update_info); 4804 pm->use_update_info);
4805 4805
4806 if (fail(pm)) 4806 if (fail(pm))
4807 return 0; 4807 return 0;
4808 4808
4809 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 4809 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
4810 PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/, 4810 PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/,
4811 pm->use_update_info); 4811 pm->use_update_info);
4812 4812
4813 if (fail(pm)) 4813 if (fail(pm))
4814 return 0; 4814 return 0;
4815 } 4815 }
4816 } 4816 }
4817 4817
4818 return 1; /* keep going */ 4818 return 1; /* keep going */
4819} 4819}
4820 4820
4821static void 4821static void
4822perform_size_test(png_modifier *pm) 4822perform_size_test(png_modifier *pm)
4823{ 4823{
4824 /* Test each colour type over the valid range of bit depths (expressed as 4824 /* Test each colour type over the valid range of bit depths (expressed as
4825 * log2(bit_depth) in turn, stop as soon as any error is detected. 4825 * log2(bit_depth) in turn, stop as soon as any error is detected.
4826 */ 4826 */
4827 if (!test_size(pm, 0, 0, READ_BDHI)) 4827 if (!test_size(pm, 0, 0, READ_BDHI))
4828 return; 4828 return;
4829 4829
4830 if (!test_size(pm, 2, 3, READ_BDHI)) 4830 if (!test_size(pm, 2, 3, READ_BDHI))
4831 return; 4831 return;
4832 4832
4833 /* For the moment don't do the palette test - it's a waste of time when 4833 /* For the moment don't do the palette test - it's a waste of time when
4834 * compared to the grayscale test. 4834 * compared to the grayscale test.
4835 */ 4835 */
4836#if 0 4836#if 0
4837 if (!test_size(pm, 3, 0, 3)) 4837 if (!test_size(pm, 3, 0, 3))
4838 return; 4838 return;
4839#endif 4839#endif
4840 4840
4841 if (!test_size(pm, 4, 3, READ_BDHI)) 4841 if (!test_size(pm, 4, 3, READ_BDHI))
4842 return; 4842 return;
4843 4843
4844 if (!test_size(pm, 6, 3, READ_BDHI)) 4844 if (!test_size(pm, 6, 3, READ_BDHI))
4845 return; 4845 return;
4846} 4846}
4847 4847
4848 4848
4849/******************************* TRANSFORM TESTS ******************************/ 4849/******************************* TRANSFORM TESTS ******************************/
4850#ifdef PNG_READ_TRANSFORMS_SUPPORTED 4850#ifdef PNG_READ_TRANSFORMS_SUPPORTED
4851/* A set of tests to validate libpng image transforms. The possibilities here 4851/* A set of tests to validate libpng image transforms. The possibilities here
4852 * are legion because the transforms can be combined in a combinatorial 4852 * are legion because the transforms can be combined in a combinatorial
4853 * fashion. To deal with this some measure of restraint is required, otherwise 4853 * fashion. To deal with this some measure of restraint is required, otherwise
4854 * the tests would take forever. 4854 * the tests would take forever.
4855 */ 4855 */
4856typedef struct image_pixel 4856typedef struct image_pixel
4857{ 4857{
4858 /* A local (pngvalid) representation of a PNG pixel, in all its 4858 /* A local (pngvalid) representation of a PNG pixel, in all its
4859 * various forms. 4859 * various forms.
4860 */ 4860 */
4861 unsigned int red, green, blue, alpha; /* For non-palette images. */ 4861 unsigned int red, green, blue, alpha; /* For non-palette images. */
4862 unsigned int palette_index; /* For a palette image. */ 4862 unsigned int palette_index; /* For a palette image. */
4863 png_byte colour_type; /* As in the spec. */ 4863 png_byte colour_type; /* As in the spec. */
4864 png_byte bit_depth; /* Defines bit size in row */ 4864 png_byte bit_depth; /* Defines bit size in row */
4865 png_byte sample_depth; /* Scale of samples */ 4865 png_byte sample_depth; /* Scale of samples */
4866 int have_tRNS; /* tRNS chunk may need processing */ 4866 int have_tRNS; /* tRNS chunk may need processing */
4867 4867
4868 /* For checking the code calculates double precision floating point values 4868 /* For checking the code calculates double precision floating point values
4869 * along with an error value, accumulated from the transforms. Because an 4869 * along with an error value, accumulated from the transforms. Because an
4870 * sBIT setting allows larger error bounds (indeed, by the spec, apparently 4870 * sBIT setting allows larger error bounds (indeed, by the spec, apparently
4871 * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each 4871 * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each
4872 * channel is stored. This sBIT value is folded in to the stored error value 4872 * channel is stored. This sBIT value is folded in to the stored error value
4873 * at the end of the application of the transforms to the pixel. 4873 * at the end of the application of the transforms to the pixel.
4874 */ 4874 */
4875 double redf, greenf, bluef, alphaf; 4875 double redf, greenf, bluef, alphaf;
4876 double rede, greene, bluee, alphae; 4876 double rede, greene, bluee, alphae;
4877 png_byte red_sBIT, green_sBIT, blue_sBIT, alpha_sBIT; 4877 png_byte red_sBIT, green_sBIT, blue_sBIT, alpha_sBIT;
4878} image_pixel; 4878} image_pixel;
4879 4879
4880/* Shared utility function, see below. */ 4880/* Shared utility function, see below. */
4881static void 4881static void
4882image_pixel_setf(image_pixel *this, unsigned int max) 4882image_pixel_setf(image_pixel *this, unsigned int max)
4883{ 4883{
4884 this->redf = this->red / (double)max; 4884 this->redf = this->red / (double)max;
4885 this->greenf = this->green / (double)max; 4885 this->greenf = this->green / (double)max;
4886 this->bluef = this->blue / (double)max; 4886 this->bluef = this->blue / (double)max;
4887 this->alphaf = this->alpha / (double)max; 4887 this->alphaf = this->alpha / (double)max;
4888 4888
4889 if (this->red < max) 4889 if (this->red < max)
4890 this->rede = this->redf * DBL_EPSILON; 4890 this->rede = this->redf * DBL_EPSILON;
4891 else 4891 else
4892 this->rede = 0; 4892 this->rede = 0;
4893 if (this->green < max) 4893 if (this->green < max)
4894 this->greene = this->greenf * DBL_EPSILON; 4894 this->greene = this->greenf * DBL_EPSILON;
4895 else 4895 else
4896 this->greene = 0; 4896 this->greene = 0;
4897 if (this->blue < max) 4897 if (this->blue < max)
4898 this->bluee = this->bluef * DBL_EPSILON; 4898 this->bluee = this->bluef * DBL_EPSILON;
4899 else 4899 else
4900 this->bluee = 0; 4900 this->bluee = 0;
4901 if (this->alpha < max) 4901 if (this->alpha < max)
4902 this->alphae = this->alphaf * DBL_EPSILON; 4902 this->alphae = this->alphaf * DBL_EPSILON;
4903 else 4903 else
4904 this->alphae = 0; 4904 this->alphae = 0;
4905} 4905}
4906 4906
4907/* Initialize the structure for the next pixel - call this before doing any 4907/* Initialize the structure for the next pixel - call this before doing any
4908 * transforms and call it for each pixel since all the fields may need to be 4908 * transforms and call it for each pixel since all the fields may need to be
4909 * reset. 4909 * reset.
4910 */ 4910 */
4911static void 4911static void
4912image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type, 4912image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type,
4913 png_byte bit_depth, png_uint_32 x, store_palette palette) 4913 png_byte bit_depth, png_uint_32 x, store_palette palette)
4914{ 4914{
4915 PNG_CONST png_byte sample_depth = (png_byte)(colour_type == 4915 PNG_CONST png_byte sample_depth = (png_byte)(colour_type ==
4916 PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth); 4916 PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth);
4917 PNG_CONST unsigned int max = (1U<<sample_depth)-1; 4917 PNG_CONST unsigned int max = (1U<<sample_depth)-1;
4918 4918
4919 /* Initially just set everything to the same number and the alpha to opaque. 4919 /* Initially just set everything to the same number and the alpha to opaque.
4920 * Note that this currently assumes a simple palette where entry x has colour 4920 * Note that this currently assumes a simple palette where entry x has colour
4921 * rgb(x,x,x)! 4921 * rgb(x,x,x)!
4922 */ 4922 */
4923 this->palette_index = this->red = this->green = this->blue = 4923 this->palette_index = this->red = this->green = this->blue =
4924 sample(row, colour_type, bit_depth, x, 0); 4924 sample(row, colour_type, bit_depth, x, 0);
4925 this->alpha = max; 4925 this->alpha = max;
4926 this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT = 4926 this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT =
4927 sample_depth; 4927 sample_depth;
4928 4928
4929 /* Then override as appropriate: */ 4929 /* Then override as appropriate: */
4930 if (colour_type == 3) /* palette */ 4930 if (colour_type == 3) /* palette */
4931 { 4931 {
4932 /* This permits the caller to default to the sample value. */ 4932 /* This permits the caller to default to the sample value. */
4933 if (palette != 0) 4933 if (palette != 0)
4934 { 4934 {
4935 PNG_CONST unsigned int i = this->palette_index; 4935 PNG_CONST unsigned int i = this->palette_index;
4936 4936
4937 this->red = palette[i].red; 4937 this->red = palette[i].red;
4938 this->green = palette[i].green; 4938 this->green = palette[i].green;
4939 this->blue = palette[i].blue; 4939 this->blue = palette[i].blue;
4940 this->alpha = palette[i].alpha; 4940 this->alpha = palette[i].alpha;
4941 } 4941 }
4942 } 4942 }
4943 4943
4944 else /* not palette */ 4944 else /* not palette */
4945 { 4945 {
4946 unsigned int i = 0; 4946 unsigned int i = 0;
4947 4947
4948 if (colour_type & 2) 4948 if (colour_type & 2)
4949 { 4949 {
4950 this->green = sample(row, colour_type, bit_depth, x, 1); 4950 this->green = sample(row, colour_type, bit_depth, x, 1);
4951 this->blue = sample(row, colour_type, bit_depth, x, 2); 4951 this->blue = sample(row, colour_type, bit_depth, x, 2);
4952 i = 2; 4952 i = 2;
4953 } 4953 }
4954 if (colour_type & 4) 4954 if (colour_type & 4)
4955 this->alpha = sample(row, colour_type, bit_depth, x, ++i); 4955 this->alpha = sample(row, colour_type, bit_depth, x, ++i);
4956 } 4956 }
4957 4957
4958 /* Calculate the scaled values, these are simply the values divided by 4958 /* Calculate the scaled values, these are simply the values divided by
4959 * 'max' and the error is initialized to the double precision epsilon value 4959 * 'max' and the error is initialized to the double precision epsilon value
4960 * from the header file. 4960 * from the header file.
4961 */ 4961 */
4962 image_pixel_setf(this, max); 4962 image_pixel_setf(this, max);
4963 4963
4964 /* Store the input information for use in the transforms - these will 4964 /* Store the input information for use in the transforms - these will
4965 * modify the information. 4965 * modify the information.
4966 */ 4966 */
4967 this->colour_type = colour_type; 4967 this->colour_type = colour_type;
4968 this->bit_depth = bit_depth; 4968 this->bit_depth = bit_depth;
4969 this->sample_depth = sample_depth; 4969 this->sample_depth = sample_depth;
4970 this->have_tRNS = 0; 4970 this->have_tRNS = 0;
4971} 4971}
4972 4972
4973/* Convert a palette image to an rgb image. This necessarily converts the tRNS 4973/* Convert a palette image to an rgb image. This necessarily converts the tRNS
4974 * chunk at the same time, because the tRNS will be in palette form. The way 4974 * chunk at the same time, because the tRNS will be in palette form. The way
4975 * palette validation works means that the original palette is never updated, 4975 * palette validation works means that the original palette is never updated,
4976 * instead the image_pixel value from the row contains the RGB of the 4976 * instead the image_pixel value from the row contains the RGB of the
4977 * corresponding palette entry and *this* is updated. Consequently this routine 4977 * corresponding palette entry and *this* is updated. Consequently this routine
4978 * only needs to change the colour type information. 4978 * only needs to change the colour type information.
4979 */ 4979 */
4980static void 4980static void
4981image_pixel_convert_PLTE(image_pixel *this) 4981image_pixel_convert_PLTE(image_pixel *this)
4982{ 4982{
4983 if (this->colour_type == PNG_COLOR_TYPE_PALETTE) 4983 if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
4984 { 4984 {
4985 if (this->have_tRNS) 4985 if (this->have_tRNS)
4986 { 4986 {
4987 this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; 4987 this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
4988 this->have_tRNS = 0; 4988 this->have_tRNS = 0;
4989 } 4989 }
4990 else 4990 else
4991 this->colour_type = PNG_COLOR_TYPE_RGB; 4991 this->colour_type = PNG_COLOR_TYPE_RGB;
4992 4992
4993 /* The bit depth of the row changes at this point too (notice that this is 4993 /* The bit depth of the row changes at this point too (notice that this is
4994 * the row format, not the sample depth, which is separate.) 4994 * the row format, not the sample depth, which is separate.)
4995 */ 4995 */
4996 this->bit_depth = 8; 4996 this->bit_depth = 8;
4997 } 4997 }
4998} 4998}
4999 4999
5000/* Add an alpha channel; this will import the tRNS information because tRNS is 5000/* Add an alpha channel; this will import the tRNS information because tRNS is
5001 * not valid in an alpha image. The bit depth will invariably be set to at 5001 * not valid in an alpha image. The bit depth will invariably be set to at
5002 * least 8. Palette images will be converted to alpha (using the above API). 5002 * least 8. Palette images will be converted to alpha (using the above API).
5003 */ 5003 */
5004static void 5004static void
5005image_pixel_add_alpha(image_pixel *this, PNG_CONST standard_display *display) 5005image_pixel_add_alpha(image_pixel *this, PNG_CONST standard_display *display)
5006{ 5006{
5007 if (this->colour_type == PNG_COLOR_TYPE_PALETTE) 5007 if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
5008 image_pixel_convert_PLTE(this); 5008 image_pixel_convert_PLTE(this);
5009 5009
5010 if ((this->colour_type & PNG_COLOR_MASK_ALPHA) == 0) 5010 if ((this->colour_type & PNG_COLOR_MASK_ALPHA) == 0)
5011 { 5011 {
5012 if (this->colour_type == PNG_COLOR_TYPE_GRAY) 5012 if (this->colour_type == PNG_COLOR_TYPE_GRAY)
5013 { 5013 {
5014 if (this->bit_depth < 8) 5014 if (this->bit_depth < 8)
5015 this->bit_depth = 8; 5015 this->bit_depth = 8;
5016 5016
5017 if (this->have_tRNS) 5017 if (this->have_tRNS)
5018 { 5018 {
5019 this->have_tRNS = 0; 5019 this->have_tRNS = 0;
5020 5020
5021 /* Check the input, original, channel value here against the 5021 /* Check the input, original, channel value here against the
5022 * original tRNS gray chunk valie. 5022 * original tRNS gray chunk valie.
5023 */ 5023 */
5024 if (this->red == display->transparent.red) 5024 if (this->red == display->transparent.red)
5025 this->alphaf = 0; 5025 this->alphaf = 0;
5026 else 5026 else
5027 this->alphaf = 1; 5027 this->alphaf = 1;
5028 } 5028 }
5029 else 5029 else
5030 this->alphaf = 1; 5030 this->alphaf = 1;
5031 5031
5032 this->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA; 5032 this->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
5033 } 5033 }
5034 5034
5035 else if (this->colour_type == PNG_COLOR_TYPE_RGB) 5035 else if (this->colour_type == PNG_COLOR_TYPE_RGB)
5036 { 5036 {
5037 if (this->have_tRNS) 5037 if (this->have_tRNS)
5038 { 5038 {
5039 this->have_tRNS = 0; 5039 this->have_tRNS = 0;
5040 5040
5041 /* Again, check the exact input values, not the current transformed 5041 /* Again, check the exact input values, not the current transformed
5042 * value! 5042 * value!
5043 */ 5043 */
5044 if (this->red == display->transparent.red && 5044 if (this->red == display->transparent.red &&
5045 this->green == display->transparent.green && 5045 this->green == display->transparent.green &&
5046 this->blue == display->transparent.blue) 5046 this->blue == display->transparent.blue)
5047 this->alphaf = 0; 5047 this->alphaf = 0;
5048 else 5048 else
5049 this->alphaf = 1; 5049 this->alphaf = 1;
5050 5050
5051 this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; 5051 this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
5052 } 5052 }
5053 } 5053 }
5054 5054
5055 /* The error in the alpha is zero and the sBIT value comes from the 5055 /* The error in the alpha is zero and the sBIT value comes from the
5056 * original sBIT data (actually it will always be the original bit depth). 5056 * original sBIT data (actually it will always be the original bit depth).
5057 */ 5057 */
5058 this->alphae = 0; 5058 this->alphae = 0;
5059 this->alpha_sBIT = display->alpha_sBIT; 5059 this->alpha_sBIT = display->alpha_sBIT;
5060 } 5060 }
5061} 5061}
5062 5062
5063struct transform_display; 5063struct transform_display;
5064typedef struct image_transform 5064typedef struct image_transform
5065{ 5065{
5066 /* The name of this transform: a string. */ 5066 /* The name of this transform: a string. */
5067 PNG_CONST char *name; 5067 PNG_CONST char *name;
5068 5068
5069 /* Each transform can be disabled from the command line: */ 5069 /* Each transform can be disabled from the command line: */
5070 int enable; 5070 int enable;
5071 5071
5072 /* The global list of transforms; read only. */ 5072 /* The global list of transforms; read only. */
5073 struct image_transform *PNG_CONST list; 5073 struct image_transform *PNG_CONST list;
5074 5074
5075 /* The global count of the number of times this transform has been set on an 5075 /* The global count of the number of times this transform has been set on an
5076 * image. 5076 * image.
5077 */ 5077 */
5078 unsigned int global_use; 5078 unsigned int global_use;
5079 5079
5080 /* The local count of the number of times this transform has been set. */ 5080 /* The local count of the number of times this transform has been set. */
5081 unsigned int local_use; 5081 unsigned int local_use;
5082 5082
5083 /* The next transform in the list, each transform must call its own next 5083 /* The next transform in the list, each transform must call its own next
5084 * transform after it has processed the pixel successfully. 5084 * transform after it has processed the pixel successfully.
5085 */ 5085 */
5086 PNG_CONST struct image_transform *next; 5086 PNG_CONST struct image_transform *next;
5087 5087
5088 /* A single transform for the image, expressed as a series of function 5088 /* A single transform for the image, expressed as a series of function
5089 * callbacks and some space for values. 5089 * callbacks and some space for values.
5090 * 5090 *
5091 * First a callback to add any required modifications to the png_modifier; 5091 * First a callback to add any required modifications to the png_modifier;
5092 * this gets called just before the modifier is set up for read. 5092 * this gets called just before the modifier is set up for read.
5093 */ 5093 */
5094 void (*ini)(PNG_CONST struct image_transform *this, 5094 void (*ini)(PNG_CONST struct image_transform *this,
5095 struct transform_display *that); 5095 struct transform_display *that);
5096 5096
5097 /* And a callback to set the transform on the current png_read_struct: 5097 /* And a callback to set the transform on the current png_read_struct:
5098 */ 5098 */
5099 void (*set)(PNG_CONST struct image_transform *this, 5099 void (*set)(PNG_CONST struct image_transform *this,
5100 struct transform_display *that, png_structp pp, png_infop pi); 5100 struct transform_display *that, png_structp pp, png_infop pi);
5101 5101
5102 /* Then a transform that takes an input pixel in one PNG format or another 5102 /* Then a transform that takes an input pixel in one PNG format or another
5103 * and modifies it by a pngvalid implementation of the transform (thus 5103 * and modifies it by a pngvalid implementation of the transform (thus
5104 * duplicating the libpng intent without, we hope, duplicating the bugs 5104 * duplicating the libpng intent without, we hope, duplicating the bugs
5105 * in the libpng implementation!) The png_structp is solely to allow error 5105 * in the libpng implementation!) The png_structp is solely to allow error
5106 * reporting via png_error and png_warning. 5106 * reporting via png_error and png_warning.
5107 */ 5107 */
5108 void (*mod)(PNG_CONST struct image_transform *this, image_pixel *that, 5108 void (*mod)(PNG_CONST struct image_transform *this, image_pixel *that,
5109 png_structp pp, PNG_CONST struct transform_display *display); 5109 png_structp pp, PNG_CONST struct transform_display *display);
5110 5110
5111 /* Add this transform to the list and return true if the transform is 5111 /* Add this transform to the list and return true if the transform is
5112 * meaningful for this colour type and bit depth - if false then the 5112 * meaningful for this colour type and bit depth - if false then the
5113 * transform should have no effect on the image so there's not a lot of 5113 * transform should have no effect on the image so there's not a lot of
5114 * point running it. 5114 * point running it.
5115 */ 5115 */
5116 int (*add)(struct image_transform *this, 5116 int (*add)(struct image_transform *this,
5117 PNG_CONST struct image_transform **that, png_byte colour_type, 5117 PNG_CONST struct image_transform **that, png_byte colour_type,
5118 png_byte bit_depth); 5118 png_byte bit_depth);
5119} image_transform; 5119} image_transform;
5120 5120
5121typedef struct transform_display 5121typedef struct transform_display
5122{ 5122{
5123 standard_display this; 5123 standard_display this;
5124 5124
5125 /* Parameters */ 5125 /* Parameters */
5126 png_modifier* pm; 5126 png_modifier* pm;
5127 PNG_CONST image_transform* transform_list; 5127 PNG_CONST image_transform* transform_list;
5128 5128
5129 /* Local variables */ 5129 /* Local variables */
5130 png_byte output_colour_type; 5130 png_byte output_colour_type;
5131 png_byte output_bit_depth; 5131 png_byte output_bit_depth;
5132 5132
5133 /* Modifications (not necessarily used.) */ 5133 /* Modifications (not necessarily used.) */
5134 gama_modification gama_mod; 5134 gama_modification gama_mod;
5135 chrm_modification chrm_mod; 5135 chrm_modification chrm_mod;
5136 srgb_modification srgb_mod; 5136 srgb_modification srgb_mod;
5137} transform_display; 5137} transform_display;
5138 5138
5139/* Set sRGB, cHRM and gAMA transforms as required by the current encoding. */ 5139/* Set sRGB, cHRM and gAMA transforms as required by the current encoding. */
5140static void 5140static void
5141transform_set_encoding(transform_display *this) 5141transform_set_encoding(transform_display *this)
5142{ 5142{
5143 /* Set up the png_modifier '_current' fields then use these to determine how 5143 /* Set up the png_modifier '_current' fields then use these to determine how
5144 * to add appropriate chunks. 5144 * to add appropriate chunks.
5145 */ 5145 */
5146 png_modifier *pm = this->pm; 5146 png_modifier *pm = this->pm;
5147 5147
5148 modifier_set_encoding(pm); 5148 modifier_set_encoding(pm);
5149 5149
5150 if (modifier_color_encoding_is_set(pm)) 5150 if (modifier_color_encoding_is_set(pm))
5151 { 5151 {
5152 if (modifier_color_encoding_is_sRGB(pm)) 5152 if (modifier_color_encoding_is_sRGB(pm))
5153 srgb_modification_init(&this->srgb_mod, pm, PNG_sRGB_INTENT_ABSOLUTE); 5153 srgb_modification_init(&this->srgb_mod, pm, PNG_sRGB_INTENT_ABSOLUTE);
5154 5154
5155 else 5155 else
5156 { 5156 {
5157 /* Set gAMA and cHRM separately. */ 5157 /* Set gAMA and cHRM separately. */
5158 gama_modification_init(&this->gama_mod, pm, pm->current_gamma); 5158 gama_modification_init(&this->gama_mod, pm, pm->current_gamma);
5159 5159
5160 if (pm->current_encoding != 0) 5160 if (pm->current_encoding != 0)
5161 chrm_modification_init(&this->chrm_mod, pm, pm->current_encoding); 5161 chrm_modification_init(&this->chrm_mod, pm, pm->current_encoding);
5162 } 5162 }
5163 } 5163 }
5164} 5164}
5165 5165
5166/* Three functions to end the list: */ 5166/* Three functions to end the list: */
5167static void 5167static void
5168image_transform_ini_end(PNG_CONST image_transform *this, 5168image_transform_ini_end(PNG_CONST image_transform *this,
5169 transform_display *that) 5169 transform_display *that)
5170{ 5170{
5171 UNUSED(this) 5171 UNUSED(this)
5172 UNUSED(that) 5172 UNUSED(that)
5173} 5173}
5174 5174
5175static void 5175static void
5176image_transform_set_end(PNG_CONST image_transform *this, 5176image_transform_set_end(PNG_CONST image_transform *this,
5177 transform_display *that, png_structp pp, png_infop pi) 5177 transform_display *that, png_structp pp, png_infop pi)
5178{ 5178{
5179 UNUSED(this) 5179 UNUSED(this)
5180 UNUSED(that) 5180 UNUSED(that)
5181 UNUSED(pp) 5181 UNUSED(pp)
5182 UNUSED(pi) 5182 UNUSED(pi)
5183} 5183}
5184 5184
5185/* At the end of the list recalculate the output image pixel value from the 5185/* At the end of the list recalculate the output image pixel value from the
5186 * double precision values set up by the preceding 'mod' calls: 5186 * double precision values set up by the preceding 'mod' calls:
5187 */ 5187 */
5188static unsigned int 5188static unsigned int
5189sample_scale(double sample_value, unsigned int scale) 5189sample_scale(double sample_value, unsigned int scale)
5190{ 5190{
5191 sample_value = floor(sample_value * scale + .5); 5191 sample_value = floor(sample_value * scale + .5);
5192 5192
5193 /* Return NaN as 0: */ 5193 /* Return NaN as 0: */
5194 if (!(sample_value > 0)) 5194 if (!(sample_value > 0))
5195 sample_value = 0; 5195 sample_value = 0;
5196 else if (sample_value > scale) 5196 else if (sample_value > scale)
5197 sample_value = scale; 5197 sample_value = scale;
5198 5198
5199 return (unsigned int)sample_value; 5199 return (unsigned int)sample_value;
5200} 5200}
5201 5201
5202static void 5202static void
5203image_transform_mod_end(PNG_CONST image_transform *this, image_pixel *that, 5203image_transform_mod_end(PNG_CONST image_transform *this, image_pixel *that,
5204 png_structp pp, PNG_CONST transform_display *display) 5204 png_structp pp, PNG_CONST transform_display *display)
5205{ 5205{
5206 PNG_CONST unsigned int scale = (1U<<that->sample_depth)-1; 5206 PNG_CONST unsigned int scale = (1U<<that->sample_depth)-1;
5207 5207
5208 UNUSED(this) 5208 UNUSED(this)
5209 UNUSED(pp) 5209 UNUSED(pp)
5210 UNUSED(display) 5210 UNUSED(display)
5211 5211
5212 /* At the end recalculate the digitized red green and blue values according 5212 /* At the end recalculate the digitized red green and blue values according
5213 * to the current sample_depth of the pixel. 5213 * to the current sample_depth of the pixel.
5214 * 5214 *
5215 * The sample value is simply scaled to the maximum, checking for over 5215 * The sample value is simply scaled to the maximum, checking for over
5216 * and underflow (which can both happen for some image transforms, 5216 * and underflow (which can both happen for some image transforms,
5217 * including simple size scaling, though libpng doesn't do that at present. 5217 * including simple size scaling, though libpng doesn't do that at present.
5218 */ 5218 */
5219 that->red = sample_scale(that->redf, scale); 5219 that->red = sample_scale(that->redf, scale);
5220 5220
5221 /* The error value is increased, at the end, according to the lowest sBIT 5221 /* The error value is increased, at the end, according to the lowest sBIT
5222 * value seen. Common sense tells us that the intermediate integer 5222 * value seen. Common sense tells us that the intermediate integer
5223 * representations are no more accurate than +/- 0.5 in the integral values, 5223 * representations are no more accurate than +/- 0.5 in the integral values,
5224 * the sBIT allows the implementation to be worse than this. In addition the 5224 * the sBIT allows the implementation to be worse than this. In addition the
5225 * PNG specification actually permits any error within the range (-1..+1), 5225 * PNG specification actually permits any error within the range (-1..+1),
5226 * but that is ignored here. Instead the final digitized value is compared, 5226 * but that is ignored here. Instead the final digitized value is compared,
5227 * below to the digitized value of the error limits - this has the net effect 5227 * below to the digitized value of the error limits - this has the net effect
5228 * of allowing (almost) +/-1 in the output value. It's difficult to see how 5228 * of allowing (almost) +/-1 in the output value. It's difficult to see how
5229 * any algorithm that digitizes intermediate results can be more accurate. 5229 * any algorithm that digitizes intermediate results can be more accurate.
5230 */ 5230 */
5231 that->rede += 1./(2*((1U<<that->red_sBIT)-1)); 5231 that->rede += 1./(2*((1U<<that->red_sBIT)-1));
5232 5232
5233 if (that->colour_type & PNG_COLOR_MASK_COLOR) 5233 if (that->colour_type & PNG_COLOR_MASK_COLOR)
5234 { 5234 {
5235 that->green = sample_scale(that->greenf, scale); 5235 that->green = sample_scale(that->greenf, scale);
5236 that->blue = sample_scale(that->bluef, scale); 5236 that->blue = sample_scale(that->bluef, scale);
5237 that->greene += 1./(2*((1U<<that->green_sBIT)-1)); 5237 that->greene += 1./(2*((1U<<that->green_sBIT)-1));
5238 that->bluee += 1./(2*((1U<<that->blue_sBIT)-1)); 5238 that->bluee += 1./(2*((1U<<that->blue_sBIT)-1));
5239 } 5239 }
5240 else 5240 else
5241 { 5241 {
5242 that->blue = that->green = that->red; 5242 that->blue = that->green = that->red;
5243 that->bluef = that->greenf = that->redf; 5243 that->bluef = that->greenf = that->redf;
5244 that->bluee = that->greene = that->rede; 5244 that->bluee = that->greene = that->rede;
5245 } 5245 }
5246 5246
5247 if ((that->colour_type & PNG_COLOR_MASK_ALPHA) || 5247 if ((that->colour_type & PNG_COLOR_MASK_ALPHA) ||
5248 that->colour_type == PNG_COLOR_TYPE_PALETTE) 5248 that->colour_type == PNG_COLOR_TYPE_PALETTE)
5249 { 5249 {
5250 that->alpha = sample_scale(that->alphaf, scale); 5250 that->alpha = sample_scale(that->alphaf, scale);
5251 that->alphae += 1./(2*((1U<<that->alpha_sBIT)-1)); 5251 that->alphae += 1./(2*((1U<<that->alpha_sBIT)-1));
5252 } 5252 }
5253 else 5253 else
5254 { 5254 {
5255 that->alpha = scale; /* opaque */ 5255 that->alpha = scale; /* opaque */
5256 that->alpha = 1; /* Override this. */ 5256 that->alpha = 1; /* Override this. */
5257 that->alphae = 0; /* It's exact ;-) */ 5257 that->alphae = 0; /* It's exact ;-) */
5258 } 5258 }
5259} 5259}
5260 5260
5261/* Static 'end' structure: */ 5261/* Static 'end' structure: */
5262static image_transform image_transform_end = 5262static image_transform image_transform_end =
5263{ 5263{
5264 "(end)", /* name */ 5264 "(end)", /* name */
5265 1, /* enable */ 5265 1, /* enable */
5266 0, /* list */ 5266 0, /* list */
5267 0, /* global_use */ 5267 0, /* global_use */
5268 0, /* local_use */ 5268 0, /* local_use */
5269 0, /* next */ 5269 0, /* next */
5270 image_transform_ini_end, 5270 image_transform_ini_end,
5271 image_transform_set_end, 5271 image_transform_set_end,
5272 image_transform_mod_end, 5272 image_transform_mod_end,
5273 0 /* never called, I want it to crash if it is! */ 5273 0 /* never called, I want it to crash if it is! */
5274}; 5274};
5275 5275
5276/* Reader callbacks and implementations, where they differ from the standard 5276/* Reader callbacks and implementations, where they differ from the standard
5277 * ones. 5277 * ones.
5278 */ 5278 */
5279static void 5279static void
5280transform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id, 5280transform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id,
5281 PNG_CONST image_transform *transform_list) 5281 PNG_CONST image_transform *transform_list)
5282{ 5282{
5283 memset(dp, 0, sizeof *dp); 5283 memset(dp, 0, sizeof *dp);
5284 5284
5285 /* Standard fields */ 5285 /* Standard fields */
5286 standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/, 5286 standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/,
5287 pm->use_update_info); 5287 pm->use_update_info);
5288 5288
5289 /* Parameter fields */ 5289 /* Parameter fields */
5290 dp->pm = pm; 5290 dp->pm = pm;
5291 dp->transform_list = transform_list; 5291 dp->transform_list = transform_list;
5292 5292
5293 /* Local variable fields */ 5293 /* Local variable fields */
5294 dp->output_colour_type = 255; /* invalid */ 5294 dp->output_colour_type = 255; /* invalid */
5295 dp->output_bit_depth = 255; /* invalid */ 5295 dp->output_bit_depth = 255; /* invalid */
5296} 5296}
5297 5297
5298static void 5298static void
5299transform_info_imp(transform_display *dp, png_structp pp, png_infop pi) 5299transform_info_imp(transform_display *dp, png_structp pp, png_infop pi)
5300{ 5300{
5301 /* Reuse the standard stuff as appropriate. */ 5301 /* Reuse the standard stuff as appropriate. */
5302 standard_info_part1(&dp->this, pp, pi); 5302 standard_info_part1(&dp->this, pp, pi);
5303 5303
5304 /* Now set the list of transforms. */ 5304 /* Now set the list of transforms. */
5305 dp->transform_list->set(dp->transform_list, dp, pp, pi); 5305 dp->transform_list->set(dp->transform_list, dp, pp, pi);
5306 5306
5307 /* Update the info structure for these transforms: */ 5307 /* Update the info structure for these transforms: */
5308 { 5308 {
5309 int i = dp->this.use_update_info; 5309 int i = dp->this.use_update_info;
5310 /* Always do one call, even if use_update_info is 0. */ 5310 /* Always do one call, even if use_update_info is 0. */
5311 do 5311 do
5312 png_read_update_info(pp, pi); 5312 png_read_update_info(pp, pi);
5313 while (--i > 0); 5313 while (--i > 0);
5314 } 5314 }
5315 5315
5316 /* And get the output information into the standard_display */ 5316 /* And get the output information into the standard_display */
5317 standard_info_part2(&dp->this, pp, pi, 1/*images*/); 5317 standard_info_part2(&dp->this, pp, pi, 1/*images*/);
5318 5318
5319 /* Plus the extra stuff we need for the transform tests: */ 5319 /* Plus the extra stuff we need for the transform tests: */
5320 dp->output_colour_type = png_get_color_type(pp, pi); 5320 dp->output_colour_type = png_get_color_type(pp, pi);
5321 dp->output_bit_depth = png_get_bit_depth(pp, pi); 5321 dp->output_bit_depth = png_get_bit_depth(pp, pi);
5322 5322
5323 /* Validate the combination of colour type and bit depth that we are getting 5323 /* Validate the combination of colour type and bit depth that we are getting
5324 * out of libpng; the semantics of something not in the PNG spec are, at 5324 * out of libpng; the semantics of something not in the PNG spec are, at
5325 * best, unclear. 5325 * best, unclear.
5326 */ 5326 */
5327 switch (dp->output_colour_type) 5327 switch (dp->output_colour_type)
5328 { 5328 {
5329 case PNG_COLOR_TYPE_PALETTE: 5329 case PNG_COLOR_TYPE_PALETTE:
5330 if (dp->output_bit_depth > 8) goto error; 5330 if (dp->output_bit_depth > 8) goto error;
5331 /*FALL THROUGH*/ 5331 /*FALL THROUGH*/
5332 case PNG_COLOR_TYPE_GRAY: 5332 case PNG_COLOR_TYPE_GRAY:
5333 if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 || 5333 if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 ||
5334 dp->output_bit_depth == 4) 5334 dp->output_bit_depth == 4)
5335 break; 5335 break;
5336 /*FALL THROUGH*/ 5336 /*FALL THROUGH*/
5337 default: 5337 default:
5338 if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16) 5338 if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16)
5339 break; 5339 break;
5340 /*FALL THROUGH*/ 5340 /*FALL THROUGH*/
5341 error: 5341 error:
5342 { 5342 {
5343 char message[128]; 5343 char message[128];
5344 size_t pos; 5344 size_t pos;
5345 5345
5346 pos = safecat(message, sizeof message, 0, 5346 pos = safecat(message, sizeof message, 0,
5347 "invalid final bit depth: colour type("); 5347 "invalid final bit depth: colour type(");
5348 pos = safecatn(message, sizeof message, pos, dp->output_colour_type); 5348 pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
5349 pos = safecat(message, sizeof message, pos, ") with bit depth: "); 5349 pos = safecat(message, sizeof message, pos, ") with bit depth: ");
5350 pos = safecatn(message, sizeof message, pos, dp->output_bit_depth); 5350 pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
5351 5351
5352 png_error(pp, message); 5352 png_error(pp, message);
5353 } 5353 }
5354 } 5354 }
5355 5355
5356 /* Use a test pixel to check that the output agrees with what we expect - 5356 /* Use a test pixel to check that the output agrees with what we expect -
5357 * this avoids running the whole test if the output is unexpected. 5357 * this avoids running the whole test if the output is unexpected.
5358 */ 5358 */
5359 { 5359 {
5360 image_pixel test_pixel; 5360 image_pixel test_pixel;
5361 5361
5362 memset(&test_pixel, 0, sizeof test_pixel); 5362 memset(&test_pixel, 0, sizeof test_pixel);
5363 test_pixel.colour_type = dp->this.colour_type; /* input */ 5363 test_pixel.colour_type = dp->this.colour_type; /* input */
5364 test_pixel.bit_depth = dp->this.bit_depth; 5364 test_pixel.bit_depth = dp->this.bit_depth;
5365 if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE) 5365 if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)
5366 test_pixel.sample_depth = 8; 5366 test_pixel.sample_depth = 8;
5367 else 5367 else
5368 test_pixel.sample_depth = test_pixel.bit_depth; 5368 test_pixel.sample_depth = test_pixel.bit_depth;
5369 /* Don't need sBIT here, but it must be set to non-zero to avoid 5369 /* Don't need sBIT here, but it must be set to non-zero to avoid
5370 * arithmetic overflows. 5370 * arithmetic overflows.
5371 */ 5371 */
5372 test_pixel.have_tRNS = dp->this.is_transparent; 5372 test_pixel.have_tRNS = dp->this.is_transparent;
5373 test_pixel.red_sBIT = test_pixel.green_sBIT = test_pixel.blue_sBIT = 5373 test_pixel.red_sBIT = test_pixel.green_sBIT = test_pixel.blue_sBIT =
5374 test_pixel.alpha_sBIT = test_pixel.sample_depth; 5374 test_pixel.alpha_sBIT = test_pixel.sample_depth;
5375 5375
5376 dp->transform_list->mod(dp->transform_list, &test_pixel, pp, dp); 5376 dp->transform_list->mod(dp->transform_list, &test_pixel, pp, dp);
5377 5377
5378 if (test_pixel.colour_type != dp->output_colour_type) 5378 if (test_pixel.colour_type != dp->output_colour_type)
5379 { 5379 {
5380 char message[128]; 5380 char message[128];
5381 size_t pos = safecat(message, sizeof message, 0, "colour type "); 5381 size_t pos = safecat(message, sizeof message, 0, "colour type ");
5382 5382
5383 pos = safecatn(message, sizeof message, pos, dp->output_colour_type); 5383 pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
5384 pos = safecat(message, sizeof message, pos, " expected "); 5384 pos = safecat(message, sizeof message, pos, " expected ");
5385 pos = safecatn(message, sizeof message, pos, test_pixel.colour_type); 5385 pos = safecatn(message, sizeof message, pos, test_pixel.colour_type);
5386 5386
5387 png_error(pp, message); 5387 png_error(pp, message);
5388 } 5388 }
5389 5389
5390 if (test_pixel.bit_depth != dp->output_bit_depth) 5390 if (test_pixel.bit_depth != dp->output_bit_depth)
5391 { 5391 {
5392 char message[128]; 5392 char message[128];
5393 size_t pos = safecat(message, sizeof message, 0, "bit depth "); 5393 size_t pos = safecat(message, sizeof message, 0, "bit depth ");
5394 5394
5395 pos = safecatn(message, sizeof message, pos, dp->output_bit_depth); 5395 pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
5396 pos = safecat(message, sizeof message, pos, " expected "); 5396 pos = safecat(message, sizeof message, pos, " expected ");
5397 pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth); 5397 pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
5398 5398
5399 png_error(pp, message); 5399 png_error(pp, message);
5400 } 5400 }
5401 5401
5402 /* If both bit depth and colour type are correct check the sample depth. 5402 /* If both bit depth and colour type are correct check the sample depth.
5403 * I believe these are both internal errors. 5403 * I believe these are both internal errors.
5404 */ 5404 */
5405 if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE) 5405 if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)
5406 { 5406 {
5407 if (test_pixel.sample_depth != 8) /* oops - internal error! */ 5407 if (test_pixel.sample_depth != 8) /* oops - internal error! */
5408 png_error(pp, "pngvalid: internal: palette sample depth not 8"); 5408 png_error(pp, "pngvalid: internal: palette sample depth not 8");
5409 } 5409 }
5410 else if (test_pixel.sample_depth != dp->output_bit_depth) 5410 else if (test_pixel.sample_depth != dp->output_bit_depth)
5411 { 5411 {
5412 char message[128]; 5412 char message[128];
5413 size_t pos = safecat(message, sizeof message, 0, 5413 size_t pos = safecat(message, sizeof message, 0,
5414 "internal: sample depth "); 5414 "internal: sample depth ");
5415 5415
5416 pos = safecatn(message, sizeof message, pos, dp->output_bit_depth); 5416 pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
5417 pos = safecat(message, sizeof message, pos, " expected "); 5417 pos = safecat(message, sizeof message, pos, " expected ");
5418 pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth); 5418 pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth);
5419 5419
5420 png_error(pp, message); 5420 png_error(pp, message);
5421 } 5421 }
5422 } 5422 }
5423} 5423}
5424 5424
5425static void 5425static void
5426transform_info(png_structp pp, png_infop pi) 5426transform_info(png_structp pp, png_infop pi)
5427{ 5427{
5428 transform_info_imp(voidcast(transform_display*, png_get_progressive_ptr(pp)), 5428 transform_info_imp(voidcast(transform_display*, png_get_progressive_ptr(pp)),
5429 pp, pi); 5429 pp, pi);
5430} 5430}
5431 5431
5432static void 5432static void
5433transform_range_check(png_structp pp, unsigned int r, unsigned int g, 5433transform_range_check(png_structp pp, unsigned int r, unsigned int g,
5434 unsigned int b, unsigned int a, unsigned int in_digitized, double in, 5434 unsigned int b, unsigned int a, unsigned int in_digitized, double in,
5435 unsigned int out, png_byte sample_depth, double err, double limit, 5435 unsigned int out, png_byte sample_depth, double err, double limit,
5436 PNG_CONST char *name, double digitization_error) 5436 PNG_CONST char *name, double digitization_error)
5437{ 5437{
5438 /* Compare the scaled, digitzed, values of our local calculation (in+-err) 5438 /* Compare the scaled, digitzed, values of our local calculation (in+-err)
5439 * with the digitized values libpng produced; 'sample_depth' is the actual 5439 * with the digitized values libpng produced; 'sample_depth' is the actual
5440 * digitization depth of the libpng output colors (the bit depth except for 5440 * digitization depth of the libpng output colors (the bit depth except for
5441 * palette images where it is always 8.) The check on 'err' is to detect 5441 * palette images where it is always 8.) The check on 'err' is to detect
5442 * internal errors in pngvalid itself. 5442 * internal errors in pngvalid itself.
5443 */ 5443 */
5444 unsigned int max = (1U<<sample_depth)-1; 5444 unsigned int max = (1U<<sample_depth)-1;
5445 double in_min = ceil((in-err)*max - digitization_error); 5445 double in_min = ceil((in-err)*max - digitization_error);
5446 double in_max = floor((in+err)*max + digitization_error); 5446 double in_max = floor((in+err)*max + digitization_error);
5447 if (err > limit || !(out >= in_min && out <= in_max)) 5447 if (err > limit || !(out >= in_min && out <= in_max))
5448 { 5448 {
5449 char message[256]; 5449 char message[256];
5450 size_t pos; 5450 size_t pos;
5451 5451
5452 pos = safecat(message, sizeof message, 0, name); 5452 pos = safecat(message, sizeof message, 0, name);
5453 pos = safecat(message, sizeof message, pos, " output value error: rgba("); 5453 pos = safecat(message, sizeof message, pos, " output value error: rgba(");
5454 pos = safecatn(message, sizeof message, pos, r); 5454 pos = safecatn(message, sizeof message, pos, r);
5455 pos = safecat(message, sizeof message, pos, ","); 5455 pos = safecat(message, sizeof message, pos, ",");
5456 pos = safecatn(message, sizeof message, pos, g); 5456 pos = safecatn(message, sizeof message, pos, g);
5457 pos = safecat(message, sizeof message, pos, ","); 5457 pos = safecat(message, sizeof message, pos, ",");
5458 pos = safecatn(message, sizeof message, pos, b); 5458 pos = safecatn(message, sizeof message, pos, b);
5459 pos = safecat(message, sizeof message, pos, ","); 5459 pos = safecat(message, sizeof message, pos, ",");
5460 pos = safecatn(message, sizeof message, pos, a); 5460 pos = safecatn(message, sizeof message, pos, a);
5461 pos = safecat(message, sizeof message, pos, "): "); 5461 pos = safecat(message, sizeof message, pos, "): ");
5462 pos = safecatn(message, sizeof message, pos, out); 5462 pos = safecatn(message, sizeof message, pos, out);
5463 pos = safecat(message, sizeof message, pos, " expected: "); 5463 pos = safecat(message, sizeof message, pos, " expected: ");
5464 pos = safecatn(message, sizeof message, pos, in_digitized); 5464 pos = safecatn(message, sizeof message, pos, in_digitized);
5465 pos = safecat(message, sizeof message, pos, " ("); 5465 pos = safecat(message, sizeof message, pos, " (");
5466 pos = safecatd(message, sizeof message, pos, (in-err)*max, 3); 5466 pos = safecatd(message, sizeof message, pos, (in-err)*max, 3);
5467 pos = safecat(message, sizeof message, pos, ".."); 5467 pos = safecat(message, sizeof message, pos, "..");
5468 pos = safecatd(message, sizeof message, pos, (in+err)*max, 3); 5468 pos = safecatd(message, sizeof message, pos, (in+err)*max, 3);
5469 pos = safecat(message, sizeof message, pos, ")"); 5469 pos = safecat(message, sizeof message, pos, ")");
5470 5470
5471 png_error(pp, message); 5471 png_error(pp, message);
5472 } 5472 }
5473} 5473}
5474 5474
5475static void 5475static void
5476transform_image_validate(transform_display *dp, png_structp pp, png_infop pi) 5476transform_image_validate(transform_display *dp, png_structp pp, png_infop pi)
5477{ 5477{
5478 /* Constants for the loop below: */ 5478 /* Constants for the loop below: */
5479 PNG_CONST png_store* PNG_CONST ps = dp->this.ps; 5479 PNG_CONST png_store* PNG_CONST ps = dp->this.ps;
5480 PNG_CONST png_byte in_ct = dp->this.colour_type; 5480 PNG_CONST png_byte in_ct = dp->this.colour_type;
5481 PNG_CONST png_byte in_bd = dp->this.bit_depth; 5481 PNG_CONST png_byte in_bd = dp->this.bit_depth;
5482 PNG_CONST png_uint_32 w = dp->this.w; 5482 PNG_CONST png_uint_32 w = dp->this.w;
5483 PNG_CONST png_uint_32 h = dp->this.h; 5483 PNG_CONST png_uint_32 h = dp->this.h;
5484 PNG_CONST png_byte out_ct = dp->output_colour_type; 5484 PNG_CONST png_byte out_ct = dp->output_colour_type;
5485 PNG_CONST png_byte out_bd = dp->output_bit_depth; 5485 PNG_CONST png_byte out_bd = dp->output_bit_depth;
5486 PNG_CONST png_byte sample_depth = (png_byte)(out_ct == 5486 PNG_CONST png_byte sample_depth = (png_byte)(out_ct ==
5487 PNG_COLOR_TYPE_PALETTE ? 8 : out_bd); 5487 PNG_COLOR_TYPE_PALETTE ? 8 : out_bd);
5488 PNG_CONST png_byte red_sBIT = dp->this.red_sBIT; 5488 PNG_CONST png_byte red_sBIT = dp->this.red_sBIT;
5489 PNG_CONST png_byte green_sBIT = dp->this.green_sBIT; 5489 PNG_CONST png_byte green_sBIT = dp->this.green_sBIT;
5490 PNG_CONST png_byte blue_sBIT = dp->this.blue_sBIT; 5490 PNG_CONST png_byte blue_sBIT = dp->this.blue_sBIT;
5491 PNG_CONST png_byte alpha_sBIT = dp->this.alpha_sBIT; 5491 PNG_CONST png_byte alpha_sBIT = dp->this.alpha_sBIT;
5492 PNG_CONST int have_tRNS = dp->this.is_transparent; 5492 PNG_CONST int have_tRNS = dp->this.is_transparent;
5493 double digitization_error; 5493 double digitization_error;
5494 5494
5495 store_palette out_palette; 5495 store_palette out_palette;
5496 png_uint_32 y; 5496 png_uint_32 y;
5497 5497
5498 UNUSED(pi) 5498 UNUSED(pi)
5499 5499
5500 /* Check for row overwrite errors */ 5500 /* Check for row overwrite errors */
5501 store_image_check(dp->this.ps, pp, 0); 5501 store_image_check(dp->this.ps, pp, 0);
5502 5502
5503 /* Read the palette corresponding to the output if the output colour type 5503 /* Read the palette corresponding to the output if the output colour type
5504 * indicates a palette, othewise set out_palette to garbage. 5504 * indicates a palette, othewise set out_palette to garbage.
5505 */ 5505 */
5506 if (out_ct == PNG_COLOR_TYPE_PALETTE) 5506 if (out_ct == PNG_COLOR_TYPE_PALETTE)
5507 { 5507 {
5508 /* Validate that the palette count itself has not changed - this is not 5508 /* Validate that the palette count itself has not changed - this is not
5509 * expected. 5509 * expected.
5510 */ 5510 */
5511 int npalette = (-1); 5511 int npalette = (-1);
5512 5512
5513 (void)read_palette(out_palette, &npalette, pp, pi); 5513 (void)read_palette(out_palette, &npalette, pp, pi);
5514 if (npalette != dp->this.npalette) 5514 if (npalette != dp->this.npalette)
5515 png_error(pp, "unexpected change in palette size"); 5515 png_error(pp, "unexpected change in palette size");
5516 5516
5517 digitization_error = .5; 5517 digitization_error = .5;
5518 } 5518 }
5519 else 5519 else
5520 { 5520 {
5521 png_byte in_sample_depth; 5521 png_byte in_sample_depth;
5522 5522
5523 memset(out_palette, 0x5e, sizeof out_palette); 5523 memset(out_palette, 0x5e, sizeof out_palette);
5524 5524
5525 /* assume-8-bit-calculations means assume that if the input has 8 bit 5525 /* assume-8-bit-calculations means assume that if the input has 8 bit
5526 * (or less) samples and the output has 16 bit samples the calculations 5526 * (or less) samples and the output has 16 bit samples the calculations
5527 * will be done with 8 bit precision, not 16. 5527 * will be done with 8 bit precision, not 16.
5528 * 5528 *
5529 * TODO: fix this in libpng; png_set_expand_16 should cause 16 bit 5529 * TODO: fix this in libpng; png_set_expand_16 should cause 16 bit
5530 * calculations to be used throughout. 5530 * calculations to be used throughout.
5531 */ 5531 */
5532 if (in_ct == PNG_COLOR_TYPE_PALETTE || in_bd < 16) 5532 if (in_ct == PNG_COLOR_TYPE_PALETTE || in_bd < 16)
5533 in_sample_depth = 8; 5533 in_sample_depth = 8;
5534 else 5534 else
5535 in_sample_depth = in_bd; 5535 in_sample_depth = in_bd;
5536 5536
5537 if (sample_depth != 16 || in_sample_depth > 8 || 5537 if (sample_depth != 16 || in_sample_depth > 8 ||
5538 !dp->pm->calculations_use_input_precision) 5538 !dp->pm->calculations_use_input_precision)
5539 digitization_error = .5; 5539 digitization_error = .5;
5540 5540
5541 /* Else errors are at 8 bit precision, scale .5 in 8 bits to the 16 bits: 5541 /* Else errors are at 8 bit precision, scale .5 in 8 bits to the 16 bits:
5542 */ 5542 */
5543 else 5543 else
5544 digitization_error = .5 * 257; 5544 digitization_error = .5 * 257;
5545 } 5545 }
5546 5546
5547 for (y=0; y<h; ++y) 5547 for (y=0; y<h; ++y)
5548 { 5548 {
5549 png_const_bytep PNG_CONST pRow = store_image_row(ps, pp, 0, y); 5549 png_const_bytep PNG_CONST pRow = store_image_row(ps, pp, 0, y);
5550 png_uint_32 x; 5550 png_uint_32 x;
5551 5551
5552 /* The original, standard, row pre-transforms. */ 5552 /* The original, standard, row pre-transforms. */
5553 png_byte std[STANDARD_ROWMAX]; 5553 png_byte std[STANDARD_ROWMAX];
5554 5554
5555 transform_row(pp, std, in_ct, in_bd, y); 5555 transform_row(pp, std, in_ct, in_bd, y);
5556 5556
5557 /* Go through each original pixel transforming it and comparing with what 5557 /* Go through each original pixel transforming it and comparing with what
5558 * libpng did to the same pixel. 5558 * libpng did to the same pixel.
5559 */ 5559 */
5560 for (x=0; x<w; ++x) 5560 for (x=0; x<w; ++x)
5561 { 5561 {
5562 image_pixel in_pixel, out_pixel; 5562 image_pixel in_pixel, out_pixel;
5563 unsigned int r, g, b, a; 5563 unsigned int r, g, b, a;
5564 5564
5565 /* Find out what we think the pixel should be: */ 5565 /* Find out what we think the pixel should be: */
5566 image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette); 5566 image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette);
5567 5567
5568 in_pixel.red_sBIT = red_sBIT; 5568 in_pixel.red_sBIT = red_sBIT;
5569 in_pixel.green_sBIT = green_sBIT; 5569 in_pixel.green_sBIT = green_sBIT;
5570 in_pixel.blue_sBIT = blue_sBIT; 5570 in_pixel.blue_sBIT = blue_sBIT;
5571 in_pixel.alpha_sBIT = alpha_sBIT; 5571 in_pixel.alpha_sBIT = alpha_sBIT;
5572 in_pixel.have_tRNS = have_tRNS; 5572 in_pixel.have_tRNS = have_tRNS;
5573 5573
5574 /* For error detection, below. */ 5574 /* For error detection, below. */
5575 r = in_pixel.red; 5575 r = in_pixel.red;
5576 g = in_pixel.green; 5576 g = in_pixel.green;
5577 b = in_pixel.blue; 5577 b = in_pixel.blue;
5578 a = in_pixel.alpha; 5578 a = in_pixel.alpha;
5579 5579
5580 dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp); 5580 dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp);
5581 5581
5582 /* Read the output pixel and compare it to what we got, we don't 5582 /* Read the output pixel and compare it to what we got, we don't
5583 * use the error field here, so no need to update sBIT. 5583 * use the error field here, so no need to update sBIT.
5584 */ 5584 */
5585 image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette); 5585 image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette);
5586 5586
5587 /* We don't expect changes to the index here even if the bit depth is 5587 /* We don't expect changes to the index here even if the bit depth is
5588 * changed. 5588 * changed.
5589 */ 5589 */
5590 if (in_ct == PNG_COLOR_TYPE_PALETTE && 5590 if (in_ct == PNG_COLOR_TYPE_PALETTE &&
5591 out_ct == PNG_COLOR_TYPE_PALETTE) 5591 out_ct == PNG_COLOR_TYPE_PALETTE)
5592 { 5592 {
5593 if (in_pixel.palette_index != out_pixel.palette_index) 5593 if (in_pixel.palette_index != out_pixel.palette_index)
5594 png_error(pp, "unexpected transformed palette index"); 5594 png_error(pp, "unexpected transformed palette index");
5595 } 5595 }
5596 5596
5597 /* Check the colours for palette images too - in fact the palette could 5597 /* Check the colours for palette images too - in fact the palette could
5598 * be separately verified itself in most cases. 5598 * be separately verified itself in most cases.
5599 */ 5599 */
5600 if (in_pixel.red != out_pixel.red) 5600 if (in_pixel.red != out_pixel.red)
5601 transform_range_check(pp, r, g, b, a, in_pixel.red, in_pixel.redf, 5601 transform_range_check(pp, r, g, b, a, in_pixel.red, in_pixel.redf,
5602 out_pixel.red, sample_depth, in_pixel.rede, 5602 out_pixel.red, sample_depth, in_pixel.rede,
5603 dp->pm->limit + 1./(2*((1U<<in_pixel.red_sBIT)-1)), "red/gray", 5603 dp->pm->limit + 1./(2*((1U<<in_pixel.red_sBIT)-1)), "red/gray",
5604 digitization_error); 5604 digitization_error);
5605 5605
5606 if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 && 5606 if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
5607 in_pixel.green != out_pixel.green) 5607 in_pixel.green != out_pixel.green)
5608 transform_range_check(pp, r, g, b, a, in_pixel.green, 5608 transform_range_check(pp, r, g, b, a, in_pixel.green,
5609 in_pixel.greenf, out_pixel.green, sample_depth, in_pixel.greene, 5609 in_pixel.greenf, out_pixel.green, sample_depth, in_pixel.greene,
5610 dp->pm->limit + 1./(2*((1U<<in_pixel.green_sBIT)-1)), "green", 5610 dp->pm->limit + 1./(2*((1U<<in_pixel.green_sBIT)-1)), "green",
5611 digitization_error); 5611 digitization_error);
5612 5612
5613 if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 && 5613 if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
5614 in_pixel.blue != out_pixel.blue) 5614 in_pixel.blue != out_pixel.blue)
5615 transform_range_check(pp, r, g, b, a, in_pixel.blue, in_pixel.bluef, 5615 transform_range_check(pp, r, g, b, a, in_pixel.blue, in_pixel.bluef,
5616 out_pixel.blue, sample_depth, in_pixel.bluee, 5616 out_pixel.blue, sample_depth, in_pixel.bluee,
5617 dp->pm->limit + 1./(2*((1U<<in_pixel.blue_sBIT)-1)), "blue", 5617 dp->pm->limit + 1./(2*((1U<<in_pixel.blue_sBIT)-1)), "blue",
5618 digitization_error); 5618 digitization_error);
5619 5619
5620 if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0 && 5620 if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0 &&
5621 in_pixel.alpha != out_pixel.alpha) 5621 in_pixel.alpha != out_pixel.alpha)
5622 transform_range_check(pp, r, g, b, a, in_pixel.alpha, 5622 transform_range_check(pp, r, g, b, a, in_pixel.alpha,
5623 in_pixel.alphaf, out_pixel.alpha, sample_depth, in_pixel.alphae, 5623 in_pixel.alphaf, out_pixel.alpha, sample_depth, in_pixel.alphae,
5624 dp->pm->limit + 1./(2*((1U<<in_pixel.alpha_sBIT)-1)), "alpha", 5624 dp->pm->limit + 1./(2*((1U<<in_pixel.alpha_sBIT)-1)), "alpha",
5625 digitization_error); 5625 digitization_error);
5626 } /* pixel (x) loop */ 5626 } /* pixel (x) loop */
5627 } /* row (y) loop */ 5627 } /* row (y) loop */
5628 5628
5629 /* Record that something was actually checked to avoid a false positive. */ 5629 /* Record that something was actually checked to avoid a false positive. */
5630 dp->this.ps->validated = 1; 5630 dp->this.ps->validated = 1;
5631} 5631}
5632 5632
5633static void 5633static void
5634transform_end(png_structp pp, png_infop pi) 5634transform_end(png_structp pp, png_infop pi)
5635{ 5635{
5636 transform_display *dp = voidcast(transform_display*, 5636 transform_display *dp = voidcast(transform_display*,
5637 png_get_progressive_ptr(pp)); 5637 png_get_progressive_ptr(pp));
5638 5638
5639 if (!dp->this.speed) 5639 if (!dp->this.speed)
5640 transform_image_validate(dp, pp, pi); 5640 transform_image_validate(dp, pp, pi);
5641 else 5641 else
5642 dp->this.ps->validated = 1; 5642 dp->this.ps->validated = 1;
5643} 5643}
5644 5644
5645/* A single test run. */ 5645/* A single test run. */
5646static void 5646static void
5647transform_test(png_modifier *pmIn, PNG_CONST png_uint_32 idIn, 5647transform_test(png_modifier *pmIn, PNG_CONST png_uint_32 idIn,
5648 PNG_CONST image_transform* transform_listIn, PNG_CONST char * volatile name) 5648 PNG_CONST image_transform* transform_listIn, PNG_CONST char * volatile name)
5649{ 5649{
5650 transform_display d; 5650 transform_display d;
5651 context(&pmIn->this, fault); 5651 context(&pmIn->this, fault);
5652 5652
5653 transform_display_init(&d, pmIn, idIn, transform_listIn); 5653 transform_display_init(&d, pmIn, idIn, transform_listIn);
5654 5654
5655 Try 5655 Try
5656 { 5656 {
5657 size_t pos = 0; 5657 size_t pos = 0;
5658 png_structp pp; 5658 png_structp pp;
5659 png_infop pi; 5659 png_infop pi;
5660 char full_name[256]; 5660 char full_name[256];
5661 5661
5662 /* Make sure the encoding fields are correct and enter the required 5662 /* Make sure the encoding fields are correct and enter the required
5663 * modifications. 5663 * modifications.
5664 */ 5664 */
5665 transform_set_encoding(&d); 5665 transform_set_encoding(&d);
5666 5666
5667 /* Add any modifications required by the transform list. */ 5667 /* Add any modifications required by the transform list. */
5668 d.transform_list->ini(d.transform_list, &d); 5668 d.transform_list->ini(d.transform_list, &d);
5669 5669
5670 /* Add the color space information, if any, to the name. */ 5670 /* Add the color space information, if any, to the name. */
5671 pos = safecat(full_name, sizeof full_name, pos, name); 5671 pos = safecat(full_name, sizeof full_name, pos, name);
5672 pos = safecat_current_encoding(full_name, sizeof full_name, pos, d.pm); 5672 pos = safecat_current_encoding(full_name, sizeof full_name, pos, d.pm);
5673 5673
5674 /* Get a png_struct for reading the image. */ 5674 /* Get a png_struct for reading the image. */
5675 pp = set_modifier_for_read(d.pm, &pi, d.this.id, full_name); 5675 pp = set_modifier_for_read(d.pm, &pi, d.this.id, full_name);
5676 standard_palette_init(&d.this); 5676 standard_palette_init(&d.this);
5677 5677
5678# if 0 5678# if 0
5679 /* Logging (debugging only) */ 5679 /* Logging (debugging only) */
5680 { 5680 {
5681 char buffer[256]; 5681 char buffer[256];
5682 5682
5683 (void)store_message(&d.pm->this, pp, buffer, sizeof buffer, 0, 5683 (void)store_message(&d.pm->this, pp, buffer, sizeof buffer, 0,
5684 "running test"); 5684 "running test");
5685 5685
5686 fprintf(stderr, "%s\n", buffer); 5686 fprintf(stderr, "%s\n", buffer);
5687 } 5687 }
5688# endif 5688# endif
5689 5689
5690 /* Introduce the correct read function. */ 5690 /* Introduce the correct read function. */
5691 if (d.pm->this.progressive) 5691 if (d.pm->this.progressive)
5692 { 5692 {
5693 /* Share the row function with the standard implementation. */ 5693 /* Share the row function with the standard implementation. */
5694 png_set_progressive_read_fn(pp, &d, transform_info, progressive_row, 5694 png_set_progressive_read_fn(pp, &d, transform_info, progressive_row,
5695 transform_end); 5695 transform_end);
5696 5696
5697 /* Now feed data into the reader until we reach the end: */ 5697 /* Now feed data into the reader until we reach the end: */
5698 modifier_progressive_read(d.pm, pp, pi); 5698 modifier_progressive_read(d.pm, pp, pi);
5699 } 5699 }
5700 else 5700 else
5701 { 5701 {
5702 /* modifier_read expects a png_modifier* */ 5702 /* modifier_read expects a png_modifier* */
5703 png_set_read_fn(pp, d.pm, modifier_read); 5703 png_set_read_fn(pp, d.pm, modifier_read);
5704 5704
5705 /* Check the header values: */ 5705 /* Check the header values: */
5706 png_read_info(pp, pi); 5706 png_read_info(pp, pi);
5707 5707
5708 /* Process the 'info' requirements. Only one image is generated */ 5708 /* Process the 'info' requirements. Only one image is generated */
5709 transform_info_imp(&d, pp, pi); 5709 transform_info_imp(&d, pp, pi);
5710 5710
5711 sequential_row(&d.this, pp, pi, -1, 0); 5711 sequential_row(&d.this, pp, pi, -1, 0);
5712 5712
5713 if (!d.this.speed) 5713 if (!d.this.speed)
5714 transform_image_validate(&d, pp, pi); 5714 transform_image_validate(&d, pp, pi);
5715 else 5715 else
5716 d.this.ps->validated = 1; 5716 d.this.ps->validated = 1;
5717 } 5717 }
5718 5718
5719 modifier_reset(d.pm); 5719 modifier_reset(d.pm);
5720 } 5720 }
5721 5721
5722 Catch(fault) 5722 Catch(fault)
5723 { 5723 {
5724 modifier_reset((png_modifier*)fault); 5724 modifier_reset((png_modifier*)fault);
5725 } 5725 }
5726} 5726}
5727 5727
5728/* The transforms: */ 5728/* The transforms: */
5729#define ITSTRUCT(name) image_transform_##name 5729#define ITSTRUCT(name) image_transform_##name
5730#define ITDATA(name) image_transform_data_##name 5730#define ITDATA(name) image_transform_data_##name
5731#define image_transform_ini image_transform_default_ini 5731#define image_transform_ini image_transform_default_ini
5732#define IT(name)\ 5732#define IT(name)\
5733static image_transform ITSTRUCT(name) =\ 5733static image_transform ITSTRUCT(name) =\
5734{\ 5734{\
5735 #name,\ 5735 #name,\
5736 1, /*enable*/\ 5736 1, /*enable*/\
5737 &PT, /*list*/\ 5737 &PT, /*list*/\
5738 0, /*global_use*/\ 5738 0, /*global_use*/\
5739 0, /*local_use*/\ 5739 0, /*local_use*/\
5740 0, /*next*/\ 5740 0, /*next*/\
5741 image_transform_ini,\ 5741 image_transform_ini,\
5742 image_transform_png_set_##name##_set,\ 5742 image_transform_png_set_##name##_set,\
5743 image_transform_png_set_##name##_mod,\ 5743 image_transform_png_set_##name##_mod,\
5744 image_transform_png_set_##name##_add\ 5744 image_transform_png_set_##name##_add\
5745} 5745}
5746#define PT ITSTRUCT(end) /* stores the previous transform */ 5746#define PT ITSTRUCT(end) /* stores the previous transform */
5747 5747
5748/* To save code: */ 5748/* To save code: */
5749static void 5749static void
5750image_transform_default_ini(PNG_CONST image_transform *this, 5750image_transform_default_ini(PNG_CONST image_transform *this,
5751 transform_display *that) 5751 transform_display *that)
5752{ 5752{
5753 this->next->ini(this->next, that); 5753 this->next->ini(this->next, that);
5754} 5754}
5755 5755
5756static int 5756static int
5757image_transform_default_add(image_transform *this, 5757image_transform_default_add(image_transform *this,
5758 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 5758 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
5759{ 5759{
5760 UNUSED(colour_type) 5760 UNUSED(colour_type)
5761 UNUSED(bit_depth) 5761 UNUSED(bit_depth)
5762 5762
5763 this->next = *that; 5763 this->next = *that;
5764 *that = this; 5764 *that = this;
5765 5765
5766 return 1; 5766 return 1;
5767} 5767}
5768 5768
5769#ifdef PNG_READ_EXPAND_SUPPORTED 5769#ifdef PNG_READ_EXPAND_SUPPORTED
5770/* png_set_palette_to_rgb */ 5770/* png_set_palette_to_rgb */
5771static void 5771static void
5772image_transform_png_set_palette_to_rgb_set(PNG_CONST image_transform *this, 5772image_transform_png_set_palette_to_rgb_set(PNG_CONST image_transform *this,
5773 transform_display *that, png_structp pp, png_infop pi) 5773 transform_display *that, png_structp pp, png_infop pi)
5774{ 5774{
5775 png_set_palette_to_rgb(pp); 5775 png_set_palette_to_rgb(pp);
5776 this->next->set(this->next, that, pp, pi); 5776 this->next->set(this->next, that, pp, pi);
5777} 5777}
5778 5778
5779static void 5779static void
5780image_transform_png_set_palette_to_rgb_mod(PNG_CONST image_transform *this, 5780image_transform_png_set_palette_to_rgb_mod(PNG_CONST image_transform *this,
5781 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 5781 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
5782{ 5782{
5783 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 5783 if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
5784 image_pixel_convert_PLTE(that); 5784 image_pixel_convert_PLTE(that);
5785 5785
5786 this->next->mod(this->next, that, pp, display); 5786 this->next->mod(this->next, that, pp, display);
5787} 5787}
5788 5788
5789static int 5789static int
5790image_transform_png_set_palette_to_rgb_add(image_transform *this, 5790image_transform_png_set_palette_to_rgb_add(image_transform *this,
5791 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 5791 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
5792{ 5792{
5793 UNUSED(bit_depth) 5793 UNUSED(bit_depth)
5794 5794
5795 this->next = *that; 5795 this->next = *that;
5796 *that = this; 5796 *that = this;
5797 5797
5798 return colour_type == PNG_COLOR_TYPE_PALETTE; 5798 return colour_type == PNG_COLOR_TYPE_PALETTE;
5799} 5799}
5800 5800
5801IT(palette_to_rgb); 5801IT(palette_to_rgb);
5802#undef PT 5802#undef PT
5803#define PT ITSTRUCT(palette_to_rgb) 5803#define PT ITSTRUCT(palette_to_rgb)
5804#endif /* PNG_READ_EXPAND_SUPPORTED */ 5804#endif /* PNG_READ_EXPAND_SUPPORTED */
5805 5805
5806#ifdef PNG_READ_EXPAND_SUPPORTED 5806#ifdef PNG_READ_EXPAND_SUPPORTED
5807/* png_set_tRNS_to_alpha */ 5807/* png_set_tRNS_to_alpha */
5808static void 5808static void
5809image_transform_png_set_tRNS_to_alpha_set(PNG_CONST image_transform *this, 5809image_transform_png_set_tRNS_to_alpha_set(PNG_CONST image_transform *this,
5810 transform_display *that, png_structp pp, png_infop pi) 5810 transform_display *that, png_structp pp, png_infop pi)
5811{ 5811{
5812 png_set_tRNS_to_alpha(pp); 5812 png_set_tRNS_to_alpha(pp);
5813 this->next->set(this->next, that, pp, pi); 5813 this->next->set(this->next, that, pp, pi);
5814} 5814}
5815 5815
5816static void 5816static void
5817image_transform_png_set_tRNS_to_alpha_mod(PNG_CONST image_transform *this, 5817image_transform_png_set_tRNS_to_alpha_mod(PNG_CONST image_transform *this,
5818 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 5818 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
5819{ 5819{
5820 /* LIBPNG BUG: this always forces palette images to RGB. */ 5820 /* LIBPNG BUG: this always forces palette images to RGB. */
5821 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 5821 if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
5822 image_pixel_convert_PLTE(that); 5822 image_pixel_convert_PLTE(that);
5823 5823
5824 /* This effectively does an 'expand' only if there is some transparency to 5824 /* This effectively does an 'expand' only if there is some transparency to
5825 * convert to an alpha channel. 5825 * convert to an alpha channel.
5826 */ 5826 */
5827 if (that->have_tRNS) 5827 if (that->have_tRNS)
5828 image_pixel_add_alpha(that, &display->this); 5828 image_pixel_add_alpha(that, &display->this);
5829 5829
5830 /* LIBPNG BUG: otherwise libpng still expands to 8 bits! */ 5830 /* LIBPNG BUG: otherwise libpng still expands to 8 bits! */
5831 else 5831 else
5832 { 5832 {
5833 if (that->bit_depth < 8) 5833 if (that->bit_depth < 8)
5834 that->bit_depth =8; 5834 that->bit_depth =8;
5835 if (that->sample_depth < 8) 5835 if (that->sample_depth < 8)
5836 that->sample_depth = 8; 5836 that->sample_depth = 8;
5837 } 5837 }
5838 5838
5839 this->next->mod(this->next, that, pp, display); 5839 this->next->mod(this->next, that, pp, display);
5840} 5840}
5841 5841
5842static int 5842static int
5843image_transform_png_set_tRNS_to_alpha_add(image_transform *this, 5843image_transform_png_set_tRNS_to_alpha_add(image_transform *this,
5844 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 5844 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
5845{ 5845{
5846 UNUSED(bit_depth) 5846 UNUSED(bit_depth)
5847 5847
5848 this->next = *that; 5848 this->next = *that;
5849 *that = this; 5849 *that = this;
5850 5850
5851 /* We don't know yet whether there will be a tRNS chunk, but we know that 5851 /* We don't know yet whether there will be a tRNS chunk, but we know that
5852 * this transformation should do nothing if there already is an alpha 5852 * this transformation should do nothing if there already is an alpha
5853 * channel. 5853 * channel.
5854 */ 5854 */
5855 return (colour_type & PNG_COLOR_MASK_ALPHA) == 0; 5855 return (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
5856} 5856}
5857 5857
5858IT(tRNS_to_alpha); 5858IT(tRNS_to_alpha);
5859#undef PT 5859#undef PT
5860#define PT ITSTRUCT(tRNS_to_alpha) 5860#define PT ITSTRUCT(tRNS_to_alpha)
5861#endif /* PNG_READ_EXPAND_SUPPORTED */ 5861#endif /* PNG_READ_EXPAND_SUPPORTED */
5862 5862
5863#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 5863#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
5864/* png_set_gray_to_rgb */ 5864/* png_set_gray_to_rgb */
5865static void 5865static void
5866image_transform_png_set_gray_to_rgb_set(PNG_CONST image_transform *this, 5866image_transform_png_set_gray_to_rgb_set(PNG_CONST image_transform *this,
5867 transform_display *that, png_structp pp, png_infop pi) 5867 transform_display *that, png_structp pp, png_infop pi)
5868{ 5868{
5869 png_set_gray_to_rgb(pp); 5869 png_set_gray_to_rgb(pp);
5870 this->next->set(this->next, that, pp, pi); 5870 this->next->set(this->next, that, pp, pi);
5871} 5871}
5872 5872
5873static void 5873static void
5874image_transform_png_set_gray_to_rgb_mod(PNG_CONST image_transform *this, 5874image_transform_png_set_gray_to_rgb_mod(PNG_CONST image_transform *this,
5875 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 5875 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
5876{ 5876{
5877 /* NOTE: we can actually pend the tRNS processing at this point because we 5877 /* NOTE: we can actually pend the tRNS processing at this point because we
5878 * can correctly recognize the original pixel value even though we have 5878 * can correctly recognize the original pixel value even though we have
5879 * mapped the one gray channel to the three RGB ones, but in fact libpng 5879 * mapped the one gray channel to the three RGB ones, but in fact libpng
5880 * doesn't do this, so we don't either. 5880 * doesn't do this, so we don't either.
5881 */ 5881 */
5882 if ((that->colour_type & PNG_COLOR_MASK_COLOR) == 0 && that->have_tRNS) 5882 if ((that->colour_type & PNG_COLOR_MASK_COLOR) == 0 && that->have_tRNS)
5883 image_pixel_add_alpha(that, &display->this); 5883 image_pixel_add_alpha(that, &display->this);
5884 5884
5885 /* Simply expand the bit depth and alter the colour type as required. */ 5885 /* Simply expand the bit depth and alter the colour type as required. */
5886 if (that->colour_type == PNG_COLOR_TYPE_GRAY) 5886 if (that->colour_type == PNG_COLOR_TYPE_GRAY)
5887 { 5887 {
5888 /* RGB images have a bit depth at least equal to '8' */ 5888 /* RGB images have a bit depth at least equal to '8' */
5889 if (that->bit_depth < 8) 5889 if (that->bit_depth < 8)
5890 that->sample_depth = that->bit_depth = 8; 5890 that->sample_depth = that->bit_depth = 8;
5891 5891
5892 /* And just changing the colour type works here because the green and blue 5892 /* And just changing the colour type works here because the green and blue
5893 * channels are being maintained in lock-step with the red/gray: 5893 * channels are being maintained in lock-step with the red/gray:
5894 */ 5894 */
5895 that->colour_type = PNG_COLOR_TYPE_RGB; 5895 that->colour_type = PNG_COLOR_TYPE_RGB;
5896 } 5896 }
5897 5897
5898 else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) 5898 else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
5899 that->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; 5899 that->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
5900 5900
5901 this->next->mod(this->next, that, pp, display); 5901 this->next->mod(this->next, that, pp, display);
5902} 5902}
5903 5903
5904static int 5904static int
5905image_transform_png_set_gray_to_rgb_add(image_transform *this, 5905image_transform_png_set_gray_to_rgb_add(image_transform *this,
5906 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 5906 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
5907{ 5907{
5908 UNUSED(bit_depth) 5908 UNUSED(bit_depth)
5909 5909
5910 this->next = *that; 5910 this->next = *that;
5911 *that = this; 5911 *that = this;
5912 5912
5913 return (colour_type & PNG_COLOR_MASK_COLOR) == 0; 5913 return (colour_type & PNG_COLOR_MASK_COLOR) == 0;
5914} 5914}
5915 5915
5916IT(gray_to_rgb); 5916IT(gray_to_rgb);
5917#undef PT 5917#undef PT
5918#define PT ITSTRUCT(gray_to_rgb) 5918#define PT ITSTRUCT(gray_to_rgb)
5919#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */ 5919#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
5920 5920
5921#ifdef PNG_READ_EXPAND_SUPPORTED 5921#ifdef PNG_READ_EXPAND_SUPPORTED
5922/* png_set_expand */ 5922/* png_set_expand */
5923static void 5923static void
5924image_transform_png_set_expand_set(PNG_CONST image_transform *this, 5924image_transform_png_set_expand_set(PNG_CONST image_transform *this,
5925 transform_display *that, png_structp pp, png_infop pi) 5925 transform_display *that, png_structp pp, png_infop pi)
5926{ 5926{
5927 png_set_expand(pp); 5927 png_set_expand(pp);
5928 this->next->set(this->next, that, pp, pi); 5928 this->next->set(this->next, that, pp, pi);
5929} 5929}
5930 5930
5931static void 5931static void
5932image_transform_png_set_expand_mod(PNG_CONST image_transform *this, 5932image_transform_png_set_expand_mod(PNG_CONST image_transform *this,
5933 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 5933 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
5934{ 5934{
5935 /* The general expand case depends on what the colour type is: */ 5935 /* The general expand case depends on what the colour type is: */
5936 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 5936 if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
5937 image_pixel_convert_PLTE(that); 5937 image_pixel_convert_PLTE(that);
5938 else if (that->bit_depth < 8) /* grayscale */ 5938 else if (that->bit_depth < 8) /* grayscale */
5939 that->sample_depth = that->bit_depth = 8; 5939 that->sample_depth = that->bit_depth = 8;
5940 5940
5941 if (that->have_tRNS) 5941 if (that->have_tRNS)
5942 image_pixel_add_alpha(that, &display->this); 5942 image_pixel_add_alpha(that, &display->this);
5943 5943
5944 this->next->mod(this->next, that, pp, display); 5944 this->next->mod(this->next, that, pp, display);
5945} 5945}
5946 5946
5947static int 5947static int
5948image_transform_png_set_expand_add(image_transform *this, 5948image_transform_png_set_expand_add(image_transform *this,
5949 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 5949 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
5950{ 5950{
5951 UNUSED(bit_depth) 5951 UNUSED(bit_depth)
5952 5952
5953 this->next = *that; 5953 this->next = *that;
5954 *that = this; 5954 *that = this;
5955 5955
5956 /* 'expand' should do nothing for RGBA or GA input - no tRNS and the bit 5956 /* 'expand' should do nothing for RGBA or GA input - no tRNS and the bit
5957 * depth is at least 8 already. 5957 * depth is at least 8 already.
5958 */ 5958 */
5959 return (colour_type & PNG_COLOR_MASK_ALPHA) == 0; 5959 return (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
5960} 5960}
5961 5961
5962IT(expand); 5962IT(expand);
5963#undef PT 5963#undef PT
5964#define PT ITSTRUCT(expand) 5964#define PT ITSTRUCT(expand)
5965#endif /* PNG_READ_EXPAND_SUPPORTED */ 5965#endif /* PNG_READ_EXPAND_SUPPORTED */
5966 5966
5967#ifdef PNG_READ_EXPAND_SUPPORTED 5967#ifdef PNG_READ_EXPAND_SUPPORTED
5968/* png_set_expand_gray_1_2_4_to_8 5968/* png_set_expand_gray_1_2_4_to_8
5969 * LIBPNG BUG: this just does an 'expand' 5969 * LIBPNG BUG: this just does an 'expand'
5970 */ 5970 */
5971static void 5971static void
5972image_transform_png_set_expand_gray_1_2_4_to_8_set( 5972image_transform_png_set_expand_gray_1_2_4_to_8_set(
5973 PNG_CONST image_transform *this, transform_display *that, png_structp pp, 5973 PNG_CONST image_transform *this, transform_display *that, png_structp pp,
5974 png_infop pi) 5974 png_infop pi)
5975{ 5975{
5976 png_set_expand_gray_1_2_4_to_8(pp); 5976 png_set_expand_gray_1_2_4_to_8(pp);
5977 this->next->set(this->next, that, pp, pi); 5977 this->next->set(this->next, that, pp, pi);
5978} 5978}
5979 5979
5980static void 5980static void
5981image_transform_png_set_expand_gray_1_2_4_to_8_mod( 5981image_transform_png_set_expand_gray_1_2_4_to_8_mod(
5982 PNG_CONST image_transform *this, image_pixel *that, png_structp pp, 5982 PNG_CONST image_transform *this, image_pixel *that, png_structp pp,
5983 PNG_CONST transform_display *display) 5983 PNG_CONST transform_display *display)
5984{ 5984{
5985 image_transform_png_set_expand_mod(this, that, pp, display); 5985 image_transform_png_set_expand_mod(this, that, pp, display);
5986} 5986}
5987 5987
5988static int 5988static int
5989image_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this, 5989image_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this,
5990 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 5990 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
5991{ 5991{
5992 return image_transform_png_set_expand_add(this, that, colour_type, 5992 return image_transform_png_set_expand_add(this, that, colour_type,
5993 bit_depth); 5993 bit_depth);
5994} 5994}
5995 5995
5996IT(expand_gray_1_2_4_to_8); 5996IT(expand_gray_1_2_4_to_8);
5997#undef PT 5997#undef PT
5998#define PT ITSTRUCT(expand_gray_1_2_4_to_8) 5998#define PT ITSTRUCT(expand_gray_1_2_4_to_8)
5999#endif /* PNG_READ_EXPAND_SUPPORTED */ 5999#endif /* PNG_READ_EXPAND_SUPPORTED */
6000 6000
6001#ifdef PNG_READ_EXPAND_16_SUPPORTED 6001#ifdef PNG_READ_EXPAND_16_SUPPORTED
6002/* png_set_expand_16 */ 6002/* png_set_expand_16 */
6003static void 6003static void
6004image_transform_png_set_expand_16_set(PNG_CONST image_transform *this, 6004image_transform_png_set_expand_16_set(PNG_CONST image_transform *this,
6005 transform_display *that, png_structp pp, png_infop pi) 6005 transform_display *that, png_structp pp, png_infop pi)
6006{ 6006{
6007 png_set_expand_16(pp); 6007 png_set_expand_16(pp);
6008 this->next->set(this->next, that, pp, pi); 6008 this->next->set(this->next, that, pp, pi);
6009} 6009}
6010 6010
6011static void 6011static void
6012image_transform_png_set_expand_16_mod(PNG_CONST image_transform *this, 6012image_transform_png_set_expand_16_mod(PNG_CONST image_transform *this,
6013 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 6013 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
6014{ 6014{
6015 /* Expect expand_16 to expand everything to 16 bits as a result of also 6015 /* Expect expand_16 to expand everything to 16 bits as a result of also
6016 * causing 'expand' to happen. 6016 * causing 'expand' to happen.
6017 */ 6017 */
6018 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 6018 if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
6019 image_pixel_convert_PLTE(that); 6019 image_pixel_convert_PLTE(that);
6020 6020
6021 if (that->have_tRNS) 6021 if (that->have_tRNS)
6022 image_pixel_add_alpha(that, &display->this); 6022 image_pixel_add_alpha(that, &display->this);
6023 6023
6024 if (that->bit_depth < 16) 6024 if (that->bit_depth < 16)
6025 that->sample_depth = that->bit_depth = 16; 6025 that->sample_depth = that->bit_depth = 16;
6026 6026
6027 this->next->mod(this->next, that, pp, display); 6027 this->next->mod(this->next, that, pp, display);
6028} 6028}
6029 6029
6030static int 6030static int
6031image_transform_png_set_expand_16_add(image_transform *this, 6031image_transform_png_set_expand_16_add(image_transform *this,
6032 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 6032 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
6033{ 6033{
6034 UNUSED(colour_type) 6034 UNUSED(colour_type)
6035 6035
6036 this->next = *that; 6036 this->next = *that;
6037 *that = this; 6037 *that = this;
6038 6038
6039 /* expand_16 does something unless the bit depth is already 16. */ 6039 /* expand_16 does something unless the bit depth is already 16. */
6040 return bit_depth < 16; 6040 return bit_depth < 16;
6041} 6041}
6042 6042
6043IT(expand_16); 6043IT(expand_16);
6044#undef PT 6044#undef PT
6045#define PT ITSTRUCT(expand_16) 6045#define PT ITSTRUCT(expand_16)
6046#endif /* PNG_READ_EXPAND_16_SUPPORTED */ 6046#endif /* PNG_READ_EXPAND_16_SUPPORTED */
6047 6047
6048#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED /* API added in 1.5.4 */ 6048#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED /* API added in 1.5.4 */
6049/* png_set_scale_16 */ 6049/* png_set_scale_16 */
6050static void 6050static void
6051image_transform_png_set_scale_16_set(PNG_CONST image_transform *this, 6051image_transform_png_set_scale_16_set(PNG_CONST image_transform *this,
6052 transform_display *that, png_structp pp, png_infop pi) 6052 transform_display *that, png_structp pp, png_infop pi)
6053{ 6053{
6054 png_set_scale_16(pp); 6054 png_set_scale_16(pp);
6055 this->next->set(this->next, that, pp, pi); 6055 this->next->set(this->next, that, pp, pi);
6056} 6056}
6057 6057
6058static void 6058static void
6059image_transform_png_set_scale_16_mod(PNG_CONST image_transform *this, 6059image_transform_png_set_scale_16_mod(PNG_CONST image_transform *this,
6060 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 6060 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
6061{ 6061{
6062 if (that->bit_depth == 16) 6062 if (that->bit_depth == 16)
6063 { 6063 {
6064 that->sample_depth = that->bit_depth = 8; 6064 that->sample_depth = that->bit_depth = 8;
6065 if (that->red_sBIT > 8) that->red_sBIT = 8; 6065 if (that->red_sBIT > 8) that->red_sBIT = 8;
6066 if (that->green_sBIT > 8) that->green_sBIT = 8; 6066 if (that->green_sBIT > 8) that->green_sBIT = 8;
6067 if (that->blue_sBIT > 8) that->blue_sBIT = 8; 6067 if (that->blue_sBIT > 8) that->blue_sBIT = 8;
6068 if (that->alpha_sBIT > 8) that->alpha_sBIT = 8; 6068 if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;
6069 } 6069 }
6070 6070
6071 this->next->mod(this->next, that, pp, display); 6071 this->next->mod(this->next, that, pp, display);
6072} 6072}
6073 6073
6074static int 6074static int
6075image_transform_png_set_scale_16_add(image_transform *this, 6075image_transform_png_set_scale_16_add(image_transform *this,
6076 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 6076 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
6077{ 6077{
6078 UNUSED(colour_type) 6078 UNUSED(colour_type)
6079 6079
6080 this->next = *that; 6080 this->next = *that;
6081 *that = this; 6081 *that = this;
6082 6082
6083 return bit_depth > 8; 6083 return bit_depth > 8;
6084} 6084}
6085 6085
6086IT(scale_16); 6086IT(scale_16);
6087#undef PT 6087#undef PT
6088#define PT ITSTRUCT(scale_16) 6088#define PT ITSTRUCT(scale_16)
6089#endif /* PNG_READ_SCALE_16_TO_8_SUPPORTED (1.5.4 on) */ 6089#endif /* PNG_READ_SCALE_16_TO_8_SUPPORTED (1.5.4 on) */
6090 6090
6091#ifdef PNG_READ_16_TO_8_SUPPORTED /* the default before 1.5.4 */ 6091#ifdef PNG_READ_16_TO_8_SUPPORTED /* the default before 1.5.4 */
6092/* png_set_strip_16 */ 6092/* png_set_strip_16 */
6093static void 6093static void
6094image_transform_png_set_strip_16_set(PNG_CONST image_transform *this, 6094image_transform_png_set_strip_16_set(PNG_CONST image_transform *this,
6095 transform_display *that, png_structp pp, png_infop pi) 6095 transform_display *that, png_structp pp, png_infop pi)
6096{ 6096{
6097 png_set_strip_16(pp); 6097 png_set_strip_16(pp);
6098 this->next->set(this->next, that, pp, pi); 6098 this->next->set(this->next, that, pp, pi);
6099} 6099}
6100 6100
6101static void 6101static void
6102image_transform_png_set_strip_16_mod(PNG_CONST image_transform *this, 6102image_transform_png_set_strip_16_mod(PNG_CONST image_transform *this,
6103 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 6103 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
6104{ 6104{
6105 if (that->bit_depth == 16) 6105 if (that->bit_depth == 16)
6106 { 6106 {
6107 that->sample_depth = that->bit_depth = 8; 6107 that->sample_depth = that->bit_depth = 8;
6108 if (that->red_sBIT > 8) that->red_sBIT = 8; 6108 if (that->red_sBIT > 8) that->red_sBIT = 8;
6109 if (that->green_sBIT > 8) that->green_sBIT = 8; 6109 if (that->green_sBIT > 8) that->green_sBIT = 8;
6110 if (that->blue_sBIT > 8) that->blue_sBIT = 8; 6110 if (that->blue_sBIT > 8) that->blue_sBIT = 8;
6111 if (that->alpha_sBIT > 8) that->alpha_sBIT = 8; 6111 if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;
6112 6112
6113 /* Prior to 1.5.4 png_set_strip_16 would use an 'accurate' method if this 6113 /* Prior to 1.5.4 png_set_strip_16 would use an 'accurate' method if this
6114 * configuration option is set. From 1.5.4 the flag is never set and the 6114 * configuration option is set. From 1.5.4 the flag is never set and the
6115 * 'scale' API (above) must be used. 6115 * 'scale' API (above) must be used.
6116 */ 6116 */
6117# ifdef PNG_READ_ACCURATE_SCALE_SUPPORTED 6117# ifdef PNG_READ_ACCURATE_SCALE_SUPPORTED
6118# if PNG_LIBPNG_VER >= 10504 6118# if PNG_LIBPNG_VER >= 10504
6119# error PNG_READ_ACCURATE_SCALE should not be set 6119# error PNG_READ_ACCURATE_SCALE should not be set
6120# endif 6120# endif
6121 6121
6122 /* The strip 16 algorithm drops the low 8 bits rather than calculating 6122 /* The strip 16 algorithm drops the low 8 bits rather than calculating
6123 * 1/257, so we need to adjust the permitted errors appropriately: 6123 * 1/257, so we need to adjust the permitted errors appropriately:
6124 * Notice that this is only relevant prior to the addition of the 6124 * Notice that this is only relevant prior to the addition of the
6125 * png_set_scale_16 API in 1.5.4 (but 1.5.4+ always defines the above!) 6125 * png_set_scale_16 API in 1.5.4 (but 1.5.4+ always defines the above!)
6126 */ 6126 */
6127 { 6127 {
6128 PNG_CONST double d = (255-128.5)/65535; 6128 PNG_CONST double d = (255-128.5)/65535;
6129 that->rede += d; 6129 that->rede += d;
6130 that->greene += d; 6130 that->greene += d;
6131 that->bluee += d; 6131 that->bluee += d;
6132 that->alphae += d; 6132 that->alphae += d;
6133 } 6133 }
6134# endif 6134# endif
6135 } 6135 }
6136 6136
6137 this->next->mod(this->next, that, pp, display); 6137 this->next->mod(this->next, that, pp, display);
6138} 6138}
6139 6139
6140static int 6140static int
6141image_transform_png_set_strip_16_add(image_transform *this, 6141image_transform_png_set_strip_16_add(image_transform *this,
6142 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 6142 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
6143{ 6143{
6144 UNUSED(colour_type) 6144 UNUSED(colour_type)
6145 6145
6146 this->next = *that; 6146 this->next = *that;
6147 *that = this; 6147 *that = this;
6148 6148
6149 return bit_depth > 8; 6149 return bit_depth > 8;
6150} 6150}
6151 6151
6152IT(strip_16); 6152IT(strip_16);
6153#undef PT 6153#undef PT
6154#define PT ITSTRUCT(strip_16) 6154#define PT ITSTRUCT(strip_16)
6155#endif /* PNG_READ_16_TO_8_SUPPORTED */ 6155#endif /* PNG_READ_16_TO_8_SUPPORTED */
6156 6156
6157#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 6157#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
6158/* png_set_strip_alpha */ 6158/* png_set_strip_alpha */
6159static void 6159static void
6160image_transform_png_set_strip_alpha_set(PNG_CONST image_transform *this, 6160image_transform_png_set_strip_alpha_set(PNG_CONST image_transform *this,
6161 transform_display *that, png_structp pp, png_infop pi) 6161 transform_display *that, png_structp pp, png_infop pi)
6162{ 6162{
6163 png_set_strip_alpha(pp); 6163 png_set_strip_alpha(pp);
6164 this->next->set(this->next, that, pp, pi); 6164 this->next->set(this->next, that, pp, pi);
6165} 6165}
6166 6166
6167static void 6167static void
6168image_transform_png_set_strip_alpha_mod(PNG_CONST image_transform *this, 6168image_transform_png_set_strip_alpha_mod(PNG_CONST image_transform *this,
6169 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 6169 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
6170{ 6170{
6171 if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) 6171 if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
6172 that->colour_type = PNG_COLOR_TYPE_GRAY; 6172 that->colour_type = PNG_COLOR_TYPE_GRAY;
6173 else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA) 6173 else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
6174 that->colour_type = PNG_COLOR_TYPE_RGB; 6174 that->colour_type = PNG_COLOR_TYPE_RGB;
6175 6175
6176 that->have_tRNS = 0; 6176 that->have_tRNS = 0;
6177 that->alphaf = 1; 6177 that->alphaf = 1;
6178 6178
6179 this->next->mod(this->next, that, pp, display); 6179 this->next->mod(this->next, that, pp, display);
6180} 6180}
6181 6181
6182static int 6182static int
6183image_transform_png_set_strip_alpha_add(image_transform *this, 6183image_transform_png_set_strip_alpha_add(image_transform *this,
6184 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 6184 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
6185{ 6185{
6186 UNUSED(bit_depth) 6186 UNUSED(bit_depth)
6187 6187
6188 this->next = *that; 6188 this->next = *that;
6189 *that = this; 6189 *that = this;
6190 6190
6191 return (colour_type & PNG_COLOR_MASK_ALPHA) != 0; 6191 return (colour_type & PNG_COLOR_MASK_ALPHA) != 0;
6192} 6192}
6193 6193
6194IT(strip_alpha); 6194IT(strip_alpha);
6195#undef PT 6195#undef PT
6196#define PT ITSTRUCT(strip_alpha) 6196#define PT ITSTRUCT(strip_alpha)
6197#endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */ 6197#endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */
6198 6198
6199#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 6199#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
6200/* png_set_rgb_to_gray(png_structp, int err_action, double red, double green) 6200/* png_set_rgb_to_gray(png_structp, int err_action, double red, double green)
6201 * png_set_rgb_to_gray_fixed(png_structp, int err_action, png_fixed_point red, 6201 * png_set_rgb_to_gray_fixed(png_structp, int err_action, png_fixed_point red,
6202 * png_fixed_point green) 6202 * png_fixed_point green)
6203 * png_get_rgb_to_gray_status 6203 * png_get_rgb_to_gray_status
6204 * 6204 *
6205 * The 'default' test here uses values known to be used inside libpng: 6205 * The 'default' test here uses values known to be used inside libpng:
6206 * 6206 *
6207 * red: 6968 6207 * red: 6968
6208 * green: 23434 6208 * green: 23434
6209 * blue: 2366 6209 * blue: 2366
6210 * 6210 *
6211 * These values are being retained for compatibility, along with the somewhat 6211 * These values are being retained for compatibility, along with the somewhat
6212 * broken truncation calculation in the fast-and-inaccurate code path. Older 6212 * broken truncation calculation in the fast-and-inaccurate code path. Older
6213 * versions of libpng will fail the accuracy tests below because they use the 6213 * versions of libpng will fail the accuracy tests below because they use the
6214 * truncation algorithm everywhere. 6214 * truncation algorithm everywhere.
6215 */ 6215 */
6216#define data ITDATA(rgb_to_gray) 6216#define data ITDATA(rgb_to_gray)
6217static struct 6217static struct
6218{ 6218{
6219 double gamma; /* File gamma to use in processing */ 6219 double gamma; /* File gamma to use in processing */
6220 6220
6221 /* The following are the parameters for png_set_rgb_to_gray: */ 6221 /* The following are the parameters for png_set_rgb_to_gray: */
6222# ifdef PNG_FLOATING_POINT_SUPPORTED 6222# ifdef PNG_FLOATING_POINT_SUPPORTED
6223 double red_to_set; 6223 double red_to_set;
6224 double green_to_set; 6224 double green_to_set;
6225# else 6225# else
6226 png_fixed_point red_to_set; 6226 png_fixed_point red_to_set;
6227 png_fixed_point green_to_set; 6227 png_fixed_point green_to_set;
6228# endif 6228# endif
6229 6229
6230 /* The actual coefficients: */ 6230 /* The actual coefficients: */
6231 double red_coefficient; 6231 double red_coefficient;
6232 double green_coefficient; 6232 double green_coefficient;
6233 double blue_coefficient; 6233 double blue_coefficient;
6234 6234
6235 /* Set if the coeefficients have been overridden. */ 6235 /* Set if the coeefficients have been overridden. */
6236 int coefficients_overridden; 6236 int coefficients_overridden;
6237} data; 6237} data;
6238 6238
6239#undef image_transform_ini 6239#undef image_transform_ini
6240#define image_transform_ini image_transform_png_set_rgb_to_gray_ini 6240#define image_transform_ini image_transform_png_set_rgb_to_gray_ini
6241static void 6241static void
6242image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this, 6242image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this,
6243 transform_display *that) 6243 transform_display *that)
6244{ 6244{
6245 png_modifier *pm = that->pm; 6245 png_modifier *pm = that->pm;
6246 PNG_CONST color_encoding *e = pm->current_encoding; 6246 PNG_CONST color_encoding *e = pm->current_encoding;
6247 6247
6248 UNUSED(this) 6248 UNUSED(this)
6249 6249
6250 /* Since we check the encoding this flag must be set: */ 6250 /* Since we check the encoding this flag must be set: */
6251 pm->test_uses_encoding = 1; 6251 pm->test_uses_encoding = 1;
6252 6252
6253 /* If 'e' is not NULL chromaticity information is present and either a cHRM 6253 /* If 'e' is not NULL chromaticity information is present and either a cHRM
6254 * or an sRGB chunk will be inserted. 6254 * or an sRGB chunk will be inserted.
6255 */ 6255 */
6256 if (e != 0) 6256 if (e != 0)
6257 { 6257 {
6258 /* Coefficients come from the encoding, but may need to be normalized to a 6258 /* Coefficients come from the encoding, but may need to be normalized to a
6259 * white point Y of 1.0 6259 * white point Y of 1.0
6260 */ 6260 */
6261 PNG_CONST double whiteY = e->red.Y + e->green.Y + e->blue.Y; 6261 PNG_CONST double whiteY = e->red.Y + e->green.Y + e->blue.Y;
6262 6262
6263 data.red_coefficient = e->red.Y; 6263 data.red_coefficient = e->red.Y;
6264 data.green_coefficient = e->green.Y; 6264 data.green_coefficient = e->green.Y;
6265 data.blue_coefficient = e->blue.Y; 6265 data.blue_coefficient = e->blue.Y;
6266 6266
6267 if (whiteY != 1) 6267 if (whiteY != 1)
6268 { 6268 {
6269 data.red_coefficient /= whiteY; 6269 data.red_coefficient /= whiteY;
6270 data.green_coefficient /= whiteY; 6270 data.green_coefficient /= whiteY;
6271 data.blue_coefficient /= whiteY; 6271 data.blue_coefficient /= whiteY;
6272 } 6272 }
6273 } 6273 }
6274 6274
6275 else 6275 else
6276 { 6276 {
6277 /* The default (built in) coeffcients, as above: */ 6277 /* The default (built in) coeffcients, as above: */
6278 data.red_coefficient = 6968 / 32768.; 6278 data.red_coefficient = 6968 / 32768.;
6279 data.green_coefficient = 23434 / 32768.; 6279 data.green_coefficient = 23434 / 32768.;
6280 data.blue_coefficient = 2366 / 32768.; 6280 data.blue_coefficient = 2366 / 32768.;
6281 } 6281 }
6282 6282
6283 data.gamma = pm->current_gamma; 6283 data.gamma = pm->current_gamma;
6284 6284
6285 /* If not set then the calculations assume linear encoding (implicitly): */ 6285 /* If not set then the calculations assume linear encoding (implicitly): */
6286 if (data.gamma == 0) 6286 if (data.gamma == 0)
6287 data.gamma = 1; 6287 data.gamma = 1;
6288 6288
6289 /* The arguments to png_set_rgb_to_gray can override the coefficients implied 6289 /* The arguments to png_set_rgb_to_gray can override the coefficients implied
6290 * by the color space encoding. If doing exhaustive checks do the override 6290 * by the color space encoding. If doing exhaustive checks do the override
6291 * in each case, otherwise do it randomly. 6291 * in each case, otherwise do it randomly.
6292 */ 6292 */
6293 if (pm->test_exhaustive) 6293 if (pm->test_exhaustive)
6294 { 6294 {
6295 /* First time in coefficients_overridden is 0, the following sets it to 1, 6295 /* First time in coefficients_overridden is 0, the following sets it to 1,
6296 * so repeat if it is set. If a test fails this may mean we subsequently 6296 * so repeat if it is set. If a test fails this may mean we subsequently
6297 * skip a non-override test, ignore that. 6297 * skip a non-override test, ignore that.
6298 */ 6298 */
6299 data.coefficients_overridden = !data.coefficients_overridden; 6299 data.coefficients_overridden = !data.coefficients_overridden;
6300 pm->repeat = data.coefficients_overridden != 0; 6300 pm->repeat = data.coefficients_overridden != 0;
6301 } 6301 }
6302 6302
6303 else 6303 else
6304 data.coefficients_overridden = random_choice(); 6304 data.coefficients_overridden = random_choice();
6305 6305
6306 if (data.coefficients_overridden) 6306 if (data.coefficients_overridden)
6307 { 6307 {
6308 /* These values override the color encoding defaults, simply use random 6308 /* These values override the color encoding defaults, simply use random
6309 * numbers. 6309 * numbers.
6310 */ 6310 */
6311 png_uint_32 ru; 6311 png_uint_32 ru;
6312 double total; 6312 double total;
6313 6313
6314 RANDOMIZE(ru); 6314 RANDOMIZE(ru);
6315 data.green_coefficient = total = (ru & 0xffff) / 65535.; 6315 data.green_coefficient = total = (ru & 0xffff) / 65535.;
6316 ru >>= 16; 6316 ru >>= 16;
6317 data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.; 6317 data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.;
6318 total += data.red_coefficient; 6318 total += data.red_coefficient;
6319 data.blue_coefficient = 1 - total; 6319 data.blue_coefficient = 1 - total;
6320 6320
6321# ifdef PNG_FLOATING_POINT_SUPPORTED 6321# ifdef PNG_FLOATING_POINT_SUPPORTED
6322 data.red_to_set = data.red_coefficient; 6322 data.red_to_set = data.red_coefficient;
6323 data.green_to_set = data.green_coefficient; 6323 data.green_to_set = data.green_coefficient;
6324# else 6324# else
6325 data.red_to_set = fix(data.red_coefficient); 6325 data.red_to_set = fix(data.red_coefficient);
6326 data.green_to_set = fix(data.green_coefficient); 6326 data.green_to_set = fix(data.green_coefficient);
6327# endif 6327# endif
6328 6328
6329 /* The following just changes the error messages: */ 6329 /* The following just changes the error messages: */
6330 pm->encoding_ignored = 1; 6330 pm->encoding_ignored = 1;
6331 } 6331 }
6332 6332
6333 else 6333 else
6334 { 6334 {
6335 data.red_to_set = -1; 6335 data.red_to_set = -1;
6336 data.green_to_set = -1; 6336 data.green_to_set = -1;
6337 } 6337 }
6338 6338
6339 /* Adjust the error limit in the png_modifier because of the larger errors 6339 /* Adjust the error limit in the png_modifier because of the larger errors
6340 * produced in the digitization during the gamma handling. 6340 * produced in the digitization during the gamma handling.
6341 */ 6341 */
6342 if (data.gamma != 1) /* Use gamma tables */ 6342 if (data.gamma != 1) /* Use gamma tables */
6343 { 6343 {
6344 if (that->this.bit_depth == 16 || pm->assume_16_bit_calculations) 6344 if (that->this.bit_depth == 16 || pm->assume_16_bit_calculations)
6345 { 6345 {
6346 /* The 16 bit case ends up producing a maximum error of about 6346 /* The 16 bit case ends up producing a maximum error of about
6347 * +/-5 in 65535, allow for +/-8 with the given gamma. 6347 * +/-5 in 65535, allow for +/-8 with the given gamma.
6348 */ 6348 */
6349 that->pm->limit += pow(8./65535, data.gamma); 6349 that->pm->limit += pow(8./65535, data.gamma);
6350 } 6350 }
6351 6351
6352 else 6352 else
6353 { 6353 {
6354 /* Rounding to 8 bits in the linear space causes massive errors which 6354 /* Rounding to 8 bits in the linear space causes massive errors which
6355 * will trigger the error check in transform_range_check. Fix that 6355 * will trigger the error check in transform_range_check. Fix that
6356 * here by taking the gamma encoding into account. 6356 * here by taking the gamma encoding into account.
6357 */ 6357 */
6358 that->pm->limit += pow(1./255, data.gamma); 6358 that->pm->limit += pow(1./255, data.gamma);
6359 } 6359 }
6360 } 6360 }
6361 6361
6362 else 6362 else
6363 { 6363 {
6364 /* With no gamma correction a large error comes from the truncation of the 6364 /* With no gamma correction a large error comes from the truncation of the
6365 * calculation in the 8 bit case, allow for that here. 6365 * calculation in the 8 bit case, allow for that here.
6366 */ 6366 */
6367 if (that->this.bit_depth != 16) 6367 if (that->this.bit_depth != 16)
6368 that->pm->limit += 4E-3; 6368 that->pm->limit += 4E-3;
6369 } 6369 }
6370} 6370}
6371 6371
6372static void 6372static void
6373image_transform_png_set_rgb_to_gray_set(PNG_CONST image_transform *this, 6373image_transform_png_set_rgb_to_gray_set(PNG_CONST image_transform *this,
6374 transform_display *that, png_structp pp, png_infop pi) 6374 transform_display *that, png_structp pp, png_infop pi)
6375{ 6375{
6376 PNG_CONST int error_action = 1; /* no error, no defines in png.h */ 6376 PNG_CONST int error_action = 1; /* no error, no defines in png.h */
6377 6377
6378# ifdef PNG_FLOATING_POINT_SUPPORTED 6378# ifdef PNG_FLOATING_POINT_SUPPORTED
6379 png_set_rgb_to_gray(pp, error_action, data.red_to_set, data.green_to_set); 6379 png_set_rgb_to_gray(pp, error_action, data.red_to_set, data.green_to_set);
6380# else 6380# else
6381 png_set_rgb_to_gray_fixed(pp, error_action, data.red_to_set, 6381 png_set_rgb_to_gray_fixed(pp, error_action, data.red_to_set,
6382 data.green_to_set); 6382 data.green_to_set);
6383# endif 6383# endif
6384 6384
6385# ifdef PNG_READ_cHRM_SUPPORTED 6385# ifdef PNG_READ_cHRM_SUPPORTED
6386 if (that->pm->current_encoding != 0) 6386 if (that->pm->current_encoding != 0)
6387 { 6387 {
6388 /* We have an encoding so a cHRM chunk may have been set; if so then 6388 /* We have an encoding so a cHRM chunk may have been set; if so then
6389 * check that the libpng APIs give the correct (X,Y,Z) values within 6389 * check that the libpng APIs give the correct (X,Y,Z) values within
6390 * some margin of error for the round trip through the chromaticity 6390 * some margin of error for the round trip through the chromaticity
6391 * form. 6391 * form.
6392 */ 6392 */
6393# ifdef PNG_FLOATING_POINT_SUPPORTED 6393# ifdef PNG_FLOATING_POINT_SUPPORTED
6394# define API_function png_get_cHRM_XYZ 6394# define API_function png_get_cHRM_XYZ
6395# define API_form "FP" 6395# define API_form "FP"
6396# define API_type double 6396# define API_type double
6397# define API_cvt(x) (x) 6397# define API_cvt(x) (x)
6398# else 6398# else
6399# define API_function png_get_cHRM_XYZ_fixed 6399# define API_function png_get_cHRM_XYZ_fixed
6400# define API_form "fixed" 6400# define API_form "fixed"
6401# define API_type png_fixed_point 6401# define API_type png_fixed_point
6402# define API_cvt(x) ((double)(x)/PNG_FP_1) 6402# define API_cvt(x) ((double)(x)/PNG_FP_1)
6403# endif 6403# endif
6404 6404
6405 API_type rX, gX, bX; 6405 API_type rX, gX, bX;
6406 API_type rY, gY, bY; 6406 API_type rY, gY, bY;
6407 API_type rZ, gZ, bZ; 6407 API_type rZ, gZ, bZ;
6408 6408
6409 if ((API_function(pp, pi, &rX, &rY, &rZ, &gX, &gY, &gZ, &bX, &bY, &bZ) 6409 if ((API_function(pp, pi, &rX, &rY, &rZ, &gX, &gY, &gZ, &bX, &bY, &bZ)
6410 & PNG_INFO_cHRM) != 0) 6410 & PNG_INFO_cHRM) != 0)
6411 { 6411 {
6412 double maxe; 6412 double maxe;
6413 PNG_CONST char *el; 6413 PNG_CONST char *el;
6414 color_encoding e, o; 6414 color_encoding e, o;
6415 6415
6416 /* Expect libpng to return a normalized result, but the original 6416 /* Expect libpng to return a normalized result, but the original
6417 * color space encoding may not be normalized. 6417 * color space encoding may not be normalized.
6418 */ 6418 */
6419 modifier_current_encoding(that->pm, &o); 6419 modifier_current_encoding(that->pm, &o);
6420 normalize_color_encoding(&o); 6420 normalize_color_encoding(&o);
6421 6421
6422 /* Sanity check the pngvalid code - the coefficients should match 6422 /* Sanity check the pngvalid code - the coefficients should match
6423 * the normalized Y values of the encoding unless they were 6423 * the normalized Y values of the encoding unless they were
6424 * overridden. 6424 * overridden.
6425 */ 6425 */
6426 if (data.red_to_set == -1 && data.green_to_set == -1 && 6426 if (data.red_to_set == -1 && data.green_to_set == -1 &&
6427 (fabs(o.red.Y - data.red_coefficient) > DBL_EPSILON || 6427 (fabs(o.red.Y - data.red_coefficient) > DBL_EPSILON ||
6428 fabs(o.green.Y - data.green_coefficient) > DBL_EPSILON || 6428 fabs(o.green.Y - data.green_coefficient) > DBL_EPSILON ||
6429 fabs(o.blue.Y - data.blue_coefficient) > DBL_EPSILON)) 6429 fabs(o.blue.Y - data.blue_coefficient) > DBL_EPSILON))
6430 png_error(pp, "internal pngvalid cHRM coefficient error"); 6430 png_error(pp, "internal pngvalid cHRM coefficient error");
6431 6431
6432 /* Generate a colour space encoding. */ 6432 /* Generate a colour space encoding. */
6433 e.gamma = o.gamma; /* not used */ 6433 e.gamma = o.gamma; /* not used */
6434 e.red.X = API_cvt(rX); 6434 e.red.X = API_cvt(rX);
6435 e.red.Y = API_cvt(rY); 6435 e.red.Y = API_cvt(rY);
6436 e.red.Z = API_cvt(rZ); 6436 e.red.Z = API_cvt(rZ);
6437 e.green.X = API_cvt(gX); 6437 e.green.X = API_cvt(gX);
6438 e.green.Y = API_cvt(gY); 6438 e.green.Y = API_cvt(gY);
6439 e.green.Z = API_cvt(gZ); 6439 e.green.Z = API_cvt(gZ);
6440 e.blue.X = API_cvt(bX); 6440 e.blue.X = API_cvt(bX);
6441 e.blue.Y = API_cvt(bY); 6441 e.blue.Y = API_cvt(bY);
6442 e.blue.Z = API_cvt(bZ); 6442 e.blue.Z = API_cvt(bZ);
6443 6443
6444 /* This should match the original one from the png_modifier, within 6444 /* This should match the original one from the png_modifier, within
6445 * the range permitted by the libpng fixed point representation. 6445 * the range permitted by the libpng fixed point representation.
6446 */ 6446 */
6447 maxe = 0; 6447 maxe = 0;
6448 el = "-"; /* Set to element name with error */ 6448 el = "-"; /* Set to element name with error */
6449 6449
6450# define CHECK(col,x)\ 6450# define CHECK(col,x)\
6451 {\ 6451 {\
6452 double err = fabs(o.col.x - e.col.x);\ 6452 double err = fabs(o.col.x - e.col.x);\
6453 if (err > maxe)\ 6453 if (err > maxe)\
6454 {\ 6454 {\
6455 maxe = err;\ 6455 maxe = err;\
6456 el = #col "(" #x ")";\ 6456 el = #col "(" #x ")";\
6457 }\ 6457 }\
6458 } 6458 }
6459 6459
6460 CHECK(red,X) 6460 CHECK(red,X)
6461 CHECK(red,Y) 6461 CHECK(red,Y)
6462 CHECK(red,Z) 6462 CHECK(red,Z)
6463 CHECK(green,X) 6463 CHECK(green,X)
6464 CHECK(green,Y) 6464 CHECK(green,Y)
6465 CHECK(green,Z) 6465 CHECK(green,Z)
6466 CHECK(blue,X) 6466 CHECK(blue,X)
6467 CHECK(blue,Y) 6467 CHECK(blue,Y)
6468 CHECK(blue,Z) 6468 CHECK(blue,Z)
6469 6469
6470 /* Here in both fixed and floating cases to check the values read 6470 /* Here in both fixed and floating cases to check the values read
6471 * from the cHRm chunk. PNG uses fixed point in the cHRM chunk, so 6471 * from the cHRm chunk. PNG uses fixed point in the cHRM chunk, so
6472 * we can't expect better than +/-.5E-5 on the result, allow 1E-5. 6472 * we can't expect better than +/-.5E-5 on the result, allow 1E-5.
6473 */ 6473 */
6474 if (maxe >= 1E-5) 6474 if (maxe >= 1E-5)
6475 { 6475 {
6476 size_t pos = 0; 6476 size_t pos = 0;
6477 char buffer[256]; 6477 char buffer[256];
6478 6478
6479 pos = safecat(buffer, sizeof buffer, pos, API_form); 6479 pos = safecat(buffer, sizeof buffer, pos, API_form);
6480 pos = safecat(buffer, sizeof buffer, pos, " cHRM "); 6480 pos = safecat(buffer, sizeof buffer, pos, " cHRM ");
6481 pos = safecat(buffer, sizeof buffer, pos, el); 6481 pos = safecat(buffer, sizeof buffer, pos, el);
6482 pos = safecat(buffer, sizeof buffer, pos, " error: "); 6482 pos = safecat(buffer, sizeof buffer, pos, " error: ");
6483 pos = safecatd(buffer, sizeof buffer, pos, maxe, 7); 6483 pos = safecatd(buffer, sizeof buffer, pos, maxe, 7);
6484 pos = safecat(buffer, sizeof buffer, pos, " "); 6484 pos = safecat(buffer, sizeof buffer, pos, " ");
6485 /* Print the color space without the gamma value: */ 6485 /* Print the color space without the gamma value: */
6486 pos = safecat_color_encoding(buffer, sizeof buffer, pos, &o, 0); 6486 pos = safecat_color_encoding(buffer, sizeof buffer, pos, &o, 0);
6487 pos = safecat(buffer, sizeof buffer, pos, " -> "); 6487 pos = safecat(buffer, sizeof buffer, pos, " -> ");
6488 pos = safecat_color_encoding(buffer, sizeof buffer, pos, &e, 0); 6488 pos = safecat_color_encoding(buffer, sizeof buffer, pos, &e, 0);
6489 6489
6490 png_error(pp, buffer); 6490 png_error(pp, buffer);
6491 } 6491 }
6492 } 6492 }
6493 } 6493 }
6494# endif /* READ_cHRM */ 6494# endif /* READ_cHRM */
6495 6495
6496 this->next->set(this->next, that, pp, pi); 6496 this->next->set(this->next, that, pp, pi);
6497} 6497}
6498 6498
6499static void 6499static void
6500image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, 6500image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
6501 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 6501 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
6502{ 6502{
6503 if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0) 6503 if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0)
6504 { 6504 {
6505 double gray, err; 6505 double gray, err;
6506 6506
6507 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 6507 if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
6508 image_pixel_convert_PLTE(that); 6508 image_pixel_convert_PLTE(that);
6509 6509
6510 /* Image now has RGB channels... */ 6510 /* Image now has RGB channels... */
6511 { 6511 {
6512 PNG_CONST png_modifier *pm = display->pm; 6512 PNG_CONST png_modifier *pm = display->pm;
6513 PNG_CONST unsigned int sample_depth = that->sample_depth; 6513 PNG_CONST unsigned int sample_depth = that->sample_depth;
6514 int isgray; 6514 int isgray;
6515 double r, g, b; 6515 double r, g, b;
6516 double rlo, rhi, glo, ghi, blo, bhi, graylo, grayhi; 6516 double rlo, rhi, glo, ghi, blo, bhi, graylo, grayhi;
6517 6517
6518 /* Do this using interval arithmetic, otherwise it is too difficult to 6518 /* Do this using interval arithmetic, otherwise it is too difficult to
6519 * handle the errors correctly. 6519 * handle the errors correctly.
6520 * 6520 *
6521 * To handle the gamma correction work out the upper and lower bounds 6521 * To handle the gamma correction work out the upper and lower bounds
6522 * of the digitized value. Assume rounding here - normally the values 6522 * of the digitized value. Assume rounding here - normally the values
6523 * will be identical after this operation if there is only one 6523 * will be identical after this operation if there is only one
6524 * transform, feel free to delete the png_error checks on this below in 6524 * transform, feel free to delete the png_error checks on this below in
6525 * the future (this is just me trying to ensure it works!) 6525 * the future (this is just me trying to ensure it works!)
6526 */ 6526 */
6527 r = rlo = rhi = that->redf; 6527 r = rlo = rhi = that->redf;
6528 rlo -= that->rede; 6528 rlo -= that->rede;
6529 rlo = digitize(pm, rlo, sample_depth, 1/*round*/); 6529 rlo = digitize(pm, rlo, sample_depth, 1/*round*/);
6530 rhi += that->rede; 6530 rhi += that->rede;
6531 rhi = digitize(pm, rhi, sample_depth, 1/*round*/); 6531 rhi = digitize(pm, rhi, sample_depth, 1/*round*/);
6532 6532
6533 g = glo = ghi = that->greenf; 6533 g = glo = ghi = that->greenf;
6534 glo -= that->greene; 6534 glo -= that->greene;
6535 glo = digitize(pm, glo, sample_depth, 1/*round*/); 6535 glo = digitize(pm, glo, sample_depth, 1/*round*/);
6536 ghi += that->greene; 6536 ghi += that->greene;
6537 ghi = digitize(pm, ghi, sample_depth, 1/*round*/); 6537 ghi = digitize(pm, ghi, sample_depth, 1/*round*/);
6538 6538
6539 b = blo = bhi = that->bluef; 6539 b = blo = bhi = that->bluef;
6540 blo -= that->bluee; 6540 blo -= that->bluee;
6541 blo = digitize(pm, blo, sample_depth, 1/*round*/); 6541 blo = digitize(pm, blo, sample_depth, 1/*round*/);
6542 bhi += that->greene; 6542 bhi += that->greene;
6543 bhi = digitize(pm, bhi, sample_depth, 1/*round*/); 6543 bhi = digitize(pm, bhi, sample_depth, 1/*round*/);
6544 6544
6545 isgray = r==g && g==b; 6545 isgray = r==g && g==b;
6546 6546
6547 if (data.gamma != 1) 6547 if (data.gamma != 1)
6548 { 6548 {
6549 PNG_CONST double power = 1/data.gamma; 6549 PNG_CONST double power = 1/data.gamma;
6550 PNG_CONST double abse = abserr(pm, sample_depth, sample_depth); 6550 PNG_CONST double abse = abserr(pm, sample_depth, sample_depth);
6551 6551
6552 /* 'abse' is the absolute error permitted in linear calculations. It 6552 /* 'abse' is the absolute error permitted in linear calculations. It
6553 * is used here to capture the error permitted in the handling 6553 * is used here to capture the error permitted in the handling
6554 * (undoing) of the gamma encoding. Once again digitization occurs 6554 * (undoing) of the gamma encoding. Once again digitization occurs
6555 * to handle the upper and lower bounds of the values. This is 6555 * to handle the upper and lower bounds of the values. This is
6556 * where the real errors are introduced. 6556 * where the real errors are introduced.
6557 */ 6557 */
6558 r = pow(r, power); 6558 r = pow(r, power);
6559 rlo = digitize(pm, pow(rlo, power)-abse, sample_depth, 1); 6559 rlo = digitize(pm, pow(rlo, power)-abse, sample_depth, 1);
6560 rhi = digitize(pm, pow(rhi, power)+abse, sample_depth, 1); 6560 rhi = digitize(pm, pow(rhi, power)+abse, sample_depth, 1);
6561 6561
6562 g = pow(g, power); 6562 g = pow(g, power);
6563 glo = digitize(pm, pow(glo, power)-abse, sample_depth, 1); 6563 glo = digitize(pm, pow(glo, power)-abse, sample_depth, 1);
6564 ghi = digitize(pm, pow(ghi, power)+abse, sample_depth, 1); 6564 ghi = digitize(pm, pow(ghi, power)+abse, sample_depth, 1);
6565 6565
6566 b = pow(b, power); 6566 b = pow(b, power);
6567 blo = digitize(pm, pow(blo, power)-abse, sample_depth, 1); 6567 blo = digitize(pm, pow(blo, power)-abse, sample_depth, 1);
6568 bhi = digitize(pm, pow(bhi, power)+abse, sample_depth, 1); 6568 bhi = digitize(pm, pow(bhi, power)+abse, sample_depth, 1);
6569 } 6569 }
6570 6570
6571 /* Now calculate the actual gray values. Although the error in the 6571 /* Now calculate the actual gray values. Although the error in the
6572 * coefficients depends on whether they were specified on the command 6572 * coefficients depends on whether they were specified on the command
6573 * line (in which case truncation to 15 bits happened) or not (rounding 6573 * line (in which case truncation to 15 bits happened) or not (rounding
6574 * was used) the maxium error in an individual coefficient is always 6574 * was used) the maxium error in an individual coefficient is always
6575 * 1/32768, because even in the rounding case the requirement that 6575 * 1/32768, because even in the rounding case the requirement that
6576 * coefficients add up to 32768 can cause a larger rounding error. 6576 * coefficients add up to 32768 can cause a larger rounding error.
6577 * 6577 *
6578 * The only time when rounding doesn't occur in 1.5.5 and later is when 6578 * The only time when rounding doesn't occur in 1.5.5 and later is when
6579 * the non-gamma code path is used for less than 16 bit data. 6579 * the non-gamma code path is used for less than 16 bit data.
6580 */ 6580 */
6581 gray = r * data.red_coefficient + g * data.green_coefficient + 6581 gray = r * data.red_coefficient + g * data.green_coefficient +
6582 b * data.blue_coefficient; 6582 b * data.blue_coefficient;
6583 6583
6584 { 6584 {
6585 PNG_CONST int do_round = data.gamma != 1 || sample_depth == 16; 6585 PNG_CONST int do_round = data.gamma != 1 || sample_depth == 16;
6586 PNG_CONST double ce = 1. / 32768; 6586 PNG_CONST double ce = 1. / 32768;
6587 6587
6588 graylo = digitize(pm, rlo * (data.red_coefficient-ce) + 6588 graylo = digitize(pm, rlo * (data.red_coefficient-ce) +
6589 glo * (data.green_coefficient-ce) + 6589 glo * (data.green_coefficient-ce) +
6590 blo * (data.blue_coefficient-ce), sample_depth, do_round); 6590 blo * (data.blue_coefficient-ce), sample_depth, do_round);
6591 if (graylo <= 0) 6591 if (graylo <= 0)
6592 graylo = 0; 6592 graylo = 0;
6593 6593
6594 grayhi = digitize(pm, rhi * (data.red_coefficient+ce) + 6594 grayhi = digitize(pm, rhi * (data.red_coefficient+ce) +
6595 ghi * (data.green_coefficient+ce) + 6595 ghi * (data.green_coefficient+ce) +
6596 bhi * (data.blue_coefficient+ce), sample_depth, do_round); 6596 bhi * (data.blue_coefficient+ce), sample_depth, do_round);
6597 if (grayhi >= 1) 6597 if (grayhi >= 1)
6598 grayhi = 1; 6598 grayhi = 1;
6599 } 6599 }
6600 6600
6601 /* And invert the gamma. */ 6601 /* And invert the gamma. */
6602 if (data.gamma != 1) 6602 if (data.gamma != 1)
6603 { 6603 {
6604 PNG_CONST double power = data.gamma; 6604 PNG_CONST double power = data.gamma;
6605 6605
6606 gray = pow(gray, power); 6606 gray = pow(gray, power);
6607 graylo = digitize(pm, pow(graylo, power), sample_depth, 1); 6607 graylo = digitize(pm, pow(graylo, power), sample_depth, 1);
6608 grayhi = digitize(pm, pow(grayhi, power), sample_depth, 1); 6608 grayhi = digitize(pm, pow(grayhi, power), sample_depth, 1);
6609 } 6609 }
6610 6610
6611 /* Now the error can be calculated. 6611 /* Now the error can be calculated.
6612 * 6612 *
6613 * If r==g==b because there is no overall gamma correction libpng 6613 * If r==g==b because there is no overall gamma correction libpng
6614 * currently preserves the original value. 6614 * currently preserves the original value.
6615 */ 6615 */
6616 if (isgray) 6616 if (isgray)
6617 err = (that->rede + that->greene + that->bluee)/3; 6617 err = (that->rede + that->greene + that->bluee)/3;
6618 6618
6619 else 6619 else
6620 { 6620 {
6621 err = fabs(grayhi-gray); 6621 err = fabs(grayhi-gray);
6622 if (fabs(gray - graylo) > err) 6622 if (fabs(gray - graylo) > err)
6623 err = fabs(graylo-gray); 6623 err = fabs(graylo-gray);
6624 6624
6625 /* Check that this worked: */ 6625 /* Check that this worked: */
6626 if (err > display->pm->limit) 6626 if (err > display->pm->limit)
6627 { 6627 {
6628 size_t pos = 0; 6628 size_t pos = 0;
6629 char buffer[128]; 6629 char buffer[128];
6630 6630
6631 pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error "); 6631 pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error ");
6632 pos = safecatd(buffer, sizeof buffer, pos, err, 6); 6632 pos = safecatd(buffer, sizeof buffer, pos, err, 6);
6633 pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); 6633 pos = safecat(buffer, sizeof buffer, pos, " exceeds limit ");
6634 pos = safecatd(buffer, sizeof buffer, pos, 6634 pos = safecatd(buffer, sizeof buffer, pos,
6635 display->pm->limit, 6); 6635 display->pm->limit, 6);
6636 png_error(pp, buffer); 6636 png_error(pp, buffer);
6637 } 6637 }
6638 } 6638 }
6639 } 6639 }
6640 6640
6641 that->bluef = that->greenf = that->redf = gray; 6641 that->bluef = that->greenf = that->redf = gray;
6642 that->bluee = that->greene = that->rede = err; 6642 that->bluee = that->greene = that->rede = err;
6643 6643
6644 /* The sBIT is the minium of the three colour channel sBITs. */ 6644 /* The sBIT is the minium of the three colour channel sBITs. */
6645 if (that->red_sBIT > that->green_sBIT) 6645 if (that->red_sBIT > that->green_sBIT)
6646 that->red_sBIT = that->green_sBIT; 6646 that->red_sBIT = that->green_sBIT;
6647 if (that->red_sBIT > that->blue_sBIT) 6647 if (that->red_sBIT > that->blue_sBIT)
6648 that->red_sBIT = that->blue_sBIT; 6648 that->red_sBIT = that->blue_sBIT;
6649 that->blue_sBIT = that->green_sBIT = that->red_sBIT; 6649 that->blue_sBIT = that->green_sBIT = that->red_sBIT;
6650 6650
6651 /* And remove the colour bit in the type: */ 6651 /* And remove the colour bit in the type: */
6652 if (that->colour_type == PNG_COLOR_TYPE_RGB) 6652 if (that->colour_type == PNG_COLOR_TYPE_RGB)
6653 that->colour_type = PNG_COLOR_TYPE_GRAY; 6653 that->colour_type = PNG_COLOR_TYPE_GRAY;
6654 else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA) 6654 else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
6655 that->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA; 6655 that->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
6656 } 6656 }
6657 6657
6658 this->next->mod(this->next, that, pp, display); 6658 this->next->mod(this->next, that, pp, display);
6659} 6659}
6660 6660
6661static int 6661static int
6662image_transform_png_set_rgb_to_gray_add(image_transform *this, 6662image_transform_png_set_rgb_to_gray_add(image_transform *this,
6663 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) 6663 PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
6664{ 6664{
6665 UNUSED(bit_depth) 6665 UNUSED(bit_depth)
6666 6666
6667 this->next = *that; 6667 this->next = *that;
6668 *that = this; 6668 *that = this;
6669 6669
6670 return (colour_type & PNG_COLOR_MASK_COLOR) != 0; 6670 return (colour_type & PNG_COLOR_MASK_COLOR) != 0;
6671} 6671}
6672 6672
6673#undef data 6673#undef data
6674IT(rgb_to_gray); 6674IT(rgb_to_gray);
6675#undef PT 6675#undef PT
6676#define PT ITSTRUCT(rgb_to_gray) 6676#define PT ITSTRUCT(rgb_to_gray)
6677#undef image_transform_ini 6677#undef image_transform_ini
6678#define image_transform_ini image_transform_default_ini 6678#define image_transform_ini image_transform_default_ini
6679#endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */ 6679#endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */
6680 6680
6681#ifdef PNG_READ_BACKGROUND_SUPPORTED 6681#ifdef PNG_READ_BACKGROUND_SUPPORTED
6682/* png_set_background(png_structp, png_const_color_16p background_color, 6682/* png_set_background(png_structp, png_const_color_16p background_color,
6683 * int background_gamma_code, int need_expand, double background_gamma) 6683 * int background_gamma_code, int need_expand, double background_gamma)
6684 * png_set_background_fixed(png_structp, png_const_color_16p background_color, 6684 * png_set_background_fixed(png_structp, png_const_color_16p background_color,
6685 * int background_gamma_code, int need_expand, 6685 * int background_gamma_code, int need_expand,
6686 * png_fixed_point background_gamma) 6686 * png_fixed_point background_gamma)
6687 * 6687 *
6688 * As with rgb_to_gray this ignores the gamma (at present.) 6688 * As with rgb_to_gray this ignores the gamma (at present.)
6689*/ 6689*/
6690#define data ITDATA(background) 6690#define data ITDATA(background)
6691static image_pixel data; 6691static image_pixel data;
6692 6692
6693static void 6693static void
6694image_transform_png_set_background_set(PNG_CONST image_transform *this, 6694image_transform_png_set_background_set(PNG_CONST image_transform *this,
6695 transform_display *that, png_structp pp, png_infop pi) 6695 transform_display *that, png_structp pp, png_infop pi)
6696{ 6696{
6697 png_byte colour_type, bit_depth; 6697 png_byte colour_type, bit_depth;
6698 png_byte random_bytes[8]; /* 8 bytes - 64 bits - the biggest pixel */ 6698 png_byte random_bytes[8]; /* 8 bytes - 64 bits - the biggest pixel */
6699 png_color_16 back; 6699 png_color_16 back;
6700 6700
6701 /* We need a background colour, because we don't know exactly what transforms 6701 /* We need a background colour, because we don't know exactly what transforms
6702 * have been set we have to supply the colour in the original file format and 6702 * have been set we have to supply the colour in the original file format and
6703 * so we need to know what that is! The background colour is stored in the 6703 * so we need to know what that is! The background colour is stored in the
6704 * transform_display. 6704 * transform_display.
6705 */ 6705 */
6706 RANDOMIZE(random_bytes); 6706 RANDOMIZE(random_bytes);
6707 6707
6708 /* Read the random value, for colour type 3 the background colour is actually 6708 /* Read the random value, for colour type 3 the background colour is actually
6709 * expressed as a 24bit rgb, not an index. 6709 * expressed as a 24bit rgb, not an index.
6710 */ 6710 */
6711 colour_type = that->this.colour_type; 6711 colour_type = that->this.colour_type;
6712 if (colour_type == 3) 6712 if (colour_type == 3)
6713 { 6713 {
6714 colour_type = PNG_COLOR_TYPE_RGB; 6714 colour_type = PNG_COLOR_TYPE_RGB;
6715 bit_depth = 8; 6715 bit_depth = 8;
6716 } 6716 }
6717 6717
6718 else 6718 else
6719 bit_depth = that->this.bit_depth; 6719 bit_depth = that->this.bit_depth;
6720 6720
6721 image_pixel_init(&data, random_bytes, colour_type, 6721 image_pixel_init(&data, random_bytes, colour_type,
6722 bit_depth, 0/*x*/, 0/*unused: palette*/); 6722 bit_depth, 0/*x*/, 0/*unused: palette*/);
6723 6723
6724 /* Extract the background colour from this image_pixel, but make sure the 6724 /* Extract the background colour from this image_pixel, but make sure the
6725 * unused fields of 'back' are garbage. 6725 * unused fields of 'back' are garbage.
6726 */ 6726 */
6727 RANDOMIZE(back); 6727 RANDOMIZE(back);
6728 6728
6729 if (colour_type & PNG_COLOR_MASK_COLOR) 6729 if (colour_type & PNG_COLOR_MASK_COLOR)
6730 { 6730 {
6731 back.red = (png_uint_16)data.red; 6731 back.red = (png_uint_16)data.red;
6732 back.green = (png_uint_16)data.green; 6732 back.green = (png_uint_16)data.green;
6733 back.blue = (png_uint_16)data.blue; 6733 back.blue = (png_uint_16)data.blue;
6734 } 6734 }
6735 6735
6736 else 6736 else
6737 back.gray = (png_uint_16)data.red; 6737 back.gray = (png_uint_16)data.red;
6738 6738
6739# ifdef PNG_FLOATING_POINT_SUPPORTED 6739# ifdef PNG_FLOATING_POINT_SUPPORTED
6740 png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, 1/*need expand*/, 6740 png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, 1/*need expand*/,
6741 0); 6741 0);
6742# else 6742# else
6743 png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, 6743 png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE,
6744 1/*need expand*/, 0); 6744 1/*need expand*/, 0);
6745# endif 6745# endif
6746 6746
6747 this->next->set(this->next, that, pp, pi); 6747 this->next->set(this->next, that, pp, pi);
6748} 6748}
6749 6749
6750static void 6750static void
6751image_transform_png_set_background_mod(PNG_CONST image_transform *this, 6751image_transform_png_set_background_mod(PNG_CONST image_transform *this,
6752 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 6752 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
6753{ 6753{
6754 /* Check for tRNS first: */ 6754 /* Check for tRNS first: */
6755 if (that->have_tRNS && that->colour_type != PNG_COLOR_TYPE_PALETTE) 6755 if (that->have_tRNS && that->colour_type != PNG_COLOR_TYPE_PALETTE)
6756 image_pixel_add_alpha(that, &display->this); 6756 image_pixel_add_alpha(that, &display->this);
6757 6757
6758 /* This is only necessary if the alpha value is less than 1. */ 6758 /* This is only necessary if the alpha value is less than 1. */
6759 if (that->alphaf < 1) 6759 if (that->alphaf < 1)
6760 { 6760 {
6761 /* Now we do the background calculation without any gamma correction. */ 6761 /* Now we do the background calculation without any gamma correction. */
6762 if (that->alphaf <= 0) 6762 if (that->alphaf <= 0)
6763 { 6763 {
6764 that->redf = data.redf; 6764 that->redf = data.redf;
6765 that->greenf = data.greenf; 6765 that->greenf = data.greenf;
6766 that->bluef = data.bluef; 6766 that->bluef = data.bluef;
6767 6767
6768 that->rede = data.rede; 6768 that->rede = data.rede;
6769 that->greene = data.greene; 6769 that->greene = data.greene;
6770 that->bluee = data.bluee; 6770 that->bluee = data.bluee;
6771 6771
6772 that->red_sBIT= data.red_sBIT; 6772 that->red_sBIT= data.red_sBIT;
6773 that->green_sBIT= data.green_sBIT; 6773 that->green_sBIT= data.green_sBIT;
6774 that->blue_sBIT= data.blue_sBIT; 6774 that->blue_sBIT= data.blue_sBIT;
6775 } 6775 }
6776 6776
6777 else /* 0 < alpha < 1 */ 6777 else /* 0 < alpha < 1 */
6778 { 6778 {
6779 double alf = 1 - that->alphaf; 6779 double alf = 1 - that->alphaf;
6780 6780
6781 that->redf = that->redf * that->alphaf + data.redf * alf; 6781 that->redf = that->redf * that->alphaf + data.redf * alf;
6782 that->rede = that->rede * that->alphaf + data.rede * alf + 6782 that->rede = that->rede * that->alphaf + data.rede * alf +
6783 DBL_EPSILON; 6783 DBL_EPSILON;
6784 that->greenf = that->greenf * that->alphaf + data.greenf * alf; 6784 that->greenf = that->greenf * that->alphaf + data.greenf * alf;
6785 that->greene = that->greene * that->alphaf + data.greene * alf + 6785 that->greene = that->greene * that->alphaf + data.greene * alf +
6786 DBL_EPSILON; 6786 DBL_EPSILON;
6787 that->bluef = that->bluef * that->alphaf + data.bluef * alf; 6787 that->bluef = that->bluef * that->alphaf + data.bluef * alf;
6788 that->bluee = that->bluee * that->alphaf + data.bluee * alf + 6788 that->bluee = that->bluee * that->alphaf + data.bluee * alf +
6789 DBL_EPSILON; 6789 DBL_EPSILON;
6790 } 6790 }
6791 6791
6792 /* Remove the alpha type and set the alpha (not in that order.) */ 6792 /* Remove the alpha type and set the alpha (not in that order.) */
6793 that->alphaf = 1; 6793 that->alphaf = 1;
6794 that->alphae = 0; 6794 that->alphae = 0;
6795 6795
6796 if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA) 6796 if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
6797 that->colour_type = PNG_COLOR_TYPE_RGB; 6797 that->colour_type = PNG_COLOR_TYPE_RGB;
6798 else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) 6798 else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
6799 that->colour_type = PNG_COLOR_TYPE_GRAY; 6799 that->colour_type = PNG_COLOR_TYPE_GRAY;
6800 /* PNG_COLOR_TYPE_PALETTE is not changed */ 6800 /* PNG_COLOR_TYPE_PALETTE is not changed */
6801 } 6801 }
6802 6802
6803 this->next->mod(this->next, that, pp, display); 6803 this->next->mod(this->next, that, pp, display);
6804} 6804}
6805 6805
6806#define image_transform_png_set_background_add image_transform_default_add 6806#define image_transform_png_set_background_add image_transform_default_add
6807 6807
6808#undef data 6808#undef data
6809IT(background); 6809IT(background);
6810#undef PT 6810#undef PT
6811#define PT ITSTRUCT(background) 6811#define PT ITSTRUCT(background)
6812#endif /* PNG_READ_BACKGROUND_SUPPORTED */ 6812#endif /* PNG_READ_BACKGROUND_SUPPORTED */
6813 6813
6814/* This may just be 'end' if all the transforms are disabled! */ 6814/* This may just be 'end' if all the transforms are disabled! */
6815static image_transform *PNG_CONST image_transform_first = &PT; 6815static image_transform *PNG_CONST image_transform_first = &PT;
6816 6816
6817static void 6817static void
6818transform_enable(PNG_CONST char *name) 6818transform_enable(PNG_CONST char *name)
6819{ 6819{
6820 /* Everything starts out enabled, so if we see an 'enable' disabled 6820 /* Everything starts out enabled, so if we see an 'enable' disabled
6821 * everything else the first time round. 6821 * everything else the first time round.
6822 */ 6822 */
6823 static int all_disabled = 0; 6823 static int all_disabled = 0;
6824 int found_it = 0; 6824 int found_it = 0;
6825 image_transform *list = image_transform_first; 6825 image_transform *list = image_transform_first;
6826 6826
6827 while (list != &image_transform_end) 6827 while (list != &image_transform_end)
6828 { 6828 {
6829 if (strcmp(list->name, name) == 0) 6829 if (strcmp(list->name, name) == 0)
6830 { 6830 {
6831 list->enable = 1; 6831 list->enable = 1;
6832 found_it = 1; 6832 found_it = 1;
6833 } 6833 }
6834 else if (!all_disabled) 6834 else if (!all_disabled)
6835 list->enable = 0; 6835 list->enable = 0;
6836 6836
6837 list = list->list; 6837 list = list->list;
6838 } 6838 }
6839 6839
6840 all_disabled = 1; 6840 all_disabled = 1;
6841 6841
6842 if (!found_it) 6842 if (!found_it)
6843 { 6843 {
6844 fprintf(stderr, "pngvalid: --transform-enable=%s: unknown transform\n", 6844 fprintf(stderr, "pngvalid: --transform-enable=%s: unknown transform\n",
6845 name); 6845 name);
6846 exit(1); 6846 exit(1);
6847 } 6847 }
6848} 6848}
6849 6849
6850static void 6850static void
6851transform_disable(PNG_CONST char *name) 6851transform_disable(PNG_CONST char *name)
6852{ 6852{
6853 image_transform *list = image_transform_first; 6853 image_transform *list = image_transform_first;
6854 6854
6855 while (list != &image_transform_end) 6855 while (list != &image_transform_end)
6856 { 6856 {
6857 if (strcmp(list->name, name) == 0) 6857 if (strcmp(list->name, name) == 0)
6858 { 6858 {
6859 list->enable = 0; 6859 list->enable = 0;
6860 return; 6860 return;
6861 } 6861 }
6862 6862
6863 list = list->list; 6863 list = list->list;
6864 } 6864 }
6865 6865
6866 fprintf(stderr, "pngvalid: --transform-disable=%s: unknown transform\n", 6866 fprintf(stderr, "pngvalid: --transform-disable=%s: unknown transform\n",
6867 name); 6867 name);
6868 exit(1); 6868 exit(1);
6869} 6869}
6870 6870
6871static void 6871static void
6872image_transform_reset_count(void) 6872image_transform_reset_count(void)
6873{ 6873{
6874 image_transform *next = image_transform_first; 6874 image_transform *next = image_transform_first;
6875 int count = 0; 6875 int count = 0;
6876 6876
6877 while (next != &image_transform_end) 6877 while (next != &image_transform_end)
6878 { 6878 {
6879 next->local_use = 0; 6879 next->local_use = 0;
6880 next->next = 0; 6880 next->next = 0;
6881 next = next->list; 6881 next = next->list;
6882 ++count; 6882 ++count;
6883 } 6883 }
6884 6884
6885 /* This can only happen if we every have more than 32 transforms (excluding 6885 /* This can only happen if we every have more than 32 transforms (excluding
6886 * the end) in the list. 6886 * the end) in the list.
6887 */ 6887 */
6888 if (count > 32) abort(); 6888 if (count > 32) abort();
6889} 6889}
6890 6890
6891static int 6891static int
6892image_transform_test_counter(png_uint_32 counter, unsigned int max) 6892image_transform_test_counter(png_uint_32 counter, unsigned int max)
6893{ 6893{
6894 /* Test the list to see if there is any point contining, given a current 6894 /* Test the list to see if there is any point contining, given a current
6895 * counter and a 'max' value. 6895 * counter and a 'max' value.
6896 */ 6896 */
6897 image_transform *next = image_transform_first; 6897 image_transform *next = image_transform_first;
6898 6898
6899 while (next != &image_transform_end) 6899 while (next != &image_transform_end)
6900 { 6900 {
6901 /* For max 0 or 1 continue until the counter overflows: */ 6901 /* For max 0 or 1 continue until the counter overflows: */
6902 counter >>= 1; 6902 counter >>= 1;
6903 6903
6904 /* Continue if any entry hasn't reacked the max. */ 6904 /* Continue if any entry hasn't reacked the max. */
6905 if (max > 1 && next->local_use < max) 6905 if (max > 1 && next->local_use < max)
6906 return 1; 6906 return 1;
6907 next = next->list; 6907 next = next->list;
6908 } 6908 }
6909 6909
6910 return max <= 1 && counter == 0; 6910 return max <= 1 && counter == 0;
6911} 6911}
6912 6912
6913static png_uint_32 6913static png_uint_32
6914image_transform_add(PNG_CONST image_transform **this, unsigned int max, 6914image_transform_add(PNG_CONST image_transform **this, unsigned int max,
6915 png_uint_32 counter, char *name, size_t sizeof_name, size_t *pos, 6915 png_uint_32 counter, char *name, size_t sizeof_name, size_t *pos,
6916 png_byte colour_type, png_byte bit_depth) 6916 png_byte colour_type, png_byte bit_depth)
6917{ 6917{
6918 for (;;) /* until we manage to add something */ 6918 for (;;) /* until we manage to add something */
6919 { 6919 {
6920 png_uint_32 mask; 6920 png_uint_32 mask;
6921 image_transform *list; 6921 image_transform *list;
6922 6922
6923 /* Find the next counter value, if the counter is zero this is the start 6923 /* Find the next counter value, if the counter is zero this is the start
6924 * of the list. This routine always returns the current counter (not the 6924 * of the list. This routine always returns the current counter (not the
6925 * next) so it returns 0 at the end and expects 0 at the beginning. 6925 * next) so it returns 0 at the end and expects 0 at the beginning.
6926 */ 6926 */
6927 if (counter == 0) /* first time */ 6927 if (counter == 0) /* first time */
6928 { 6928 {
6929 image_transform_reset_count(); 6929 image_transform_reset_count();
6930 if (max <= 1) 6930 if (max <= 1)
6931 counter = 1; 6931 counter = 1;
6932 else 6932 else
6933 counter = random_32(); 6933 counter = random_32();
6934 } 6934 }
6935 else /* advance the counter */ 6935 else /* advance the counter */
6936 { 6936 {
6937 switch (max) 6937 switch (max)
6938 { 6938 {
6939 case 0: ++counter; break; 6939 case 0: ++counter; break;
6940 case 1: counter <<= 1; break; 6940 case 1: counter <<= 1; break;
6941 default: counter = random_32(); break; 6941 default: counter = random_32(); break;
6942 } 6942 }
6943 } 6943 }
6944 6944
6945 /* Now add all these items, if possible */ 6945 /* Now add all these items, if possible */
6946 *this = &image_transform_end; 6946 *this = &image_transform_end;
6947 list = image_transform_first; 6947 list = image_transform_first;
6948 mask = 1; 6948 mask = 1;
6949 6949
6950 /* Go through the whole list adding anything that the counter selects: */ 6950 /* Go through the whole list adding anything that the counter selects: */
6951 while (list != &image_transform_end) 6951 while (list != &image_transform_end)
6952 { 6952 {
6953 if ((counter & mask) != 0 && list->enable && 6953 if ((counter & mask) != 0 && list->enable &&
6954 (max == 0 || list->local_use < max)) 6954 (max == 0 || list->local_use < max))
6955 { 6955 {
6956 /* Candidate to add: */ 6956 /* Candidate to add: */
6957 if (list->add(list, this, colour_type, bit_depth) || max == 0) 6957 if (list->add(list, this, colour_type, bit_depth) || max == 0)
6958 { 6958 {
6959 /* Added, so add to the name too. */ 6959 /* Added, so add to the name too. */
6960 *pos = safecat(name, sizeof_name, *pos, " +"); 6960 *pos = safecat(name, sizeof_name, *pos, " +");
6961 *pos = safecat(name, sizeof_name, *pos, list->name); 6961 *pos = safecat(name, sizeof_name, *pos, list->name);
6962 } 6962 }
6963 6963
6964 else 6964 else
6965 { 6965 {
6966 /* Not useful and max>0, so remove it from *this: */ 6966 /* Not useful and max>0, so remove it from *this: */
6967 *this = list->next; 6967 *this = list->next;
6968 list->next = 0; 6968 list->next = 0;
6969 6969
6970 /* And, since we know it isn't useful, stop it being added again 6970 /* And, since we know it isn't useful, stop it being added again
6971 * in this run: 6971 * in this run:
6972 */ 6972 */
6973 list->local_use = max; 6973 list->local_use = max;
6974 } 6974 }
6975 } 6975 }
6976 6976
6977 mask <<= 1; 6977 mask <<= 1;
6978 list = list->list; 6978 list = list->list;
6979 } 6979 }
6980 6980
6981 /* Now if anything was added we have something to do. */ 6981 /* Now if anything was added we have something to do. */
6982 if (*this != &image_transform_end) 6982 if (*this != &image_transform_end)
6983 return counter; 6983 return counter;
6984 6984
6985 /* Nothing added, but was there anything in there to add? */ 6985 /* Nothing added, but was there anything in there to add? */
6986 if (!image_transform_test_counter(counter, max)) 6986 if (!image_transform_test_counter(counter, max))
6987 return 0; 6987 return 0;
6988 } 6988 }
6989} 6989}
6990 6990
6991#ifdef THIS_IS_THE_PROFORMA 6991#ifdef THIS_IS_THE_PROFORMA
6992static void 6992static void
6993image_transform_png_set_@_set(PNG_CONST image_transform *this, 6993image_transform_png_set_@_set(PNG_CONST image_transform *this,
6994 transform_display *that, png_structp pp, png_infop pi) 6994 transform_display *that, png_structp pp, png_infop pi)
6995{ 6995{
6996 png_set_@(pp); 6996 png_set_@(pp);
6997 this->next->set(this->next, that, pp, pi); 6997 this->next->set(this->next, that, pp, pi);
6998} 6998}
6999 6999
7000static void 7000static void
7001image_transform_png_set_@_mod(PNG_CONST image_transform *this, 7001image_transform_png_set_@_mod(PNG_CONST image_transform *this,
7002 image_pixel *that, png_structp pp, PNG_CONST transform_display *display) 7002 image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
7003{ 7003{
7004 this->next->mod(this->next, that, pp, display); 7004 this->next->mod(this->next, that, pp, display);
7005} 7005}
7006 7006
7007static int 7007static int
7008image_transform_png_set_@_add(image_transform *this, 7008image_transform_png_set_@_add(image_transform *this,
7009 PNG_CONST image_transform **that, char *name, size_t sizeof_name, 7009 PNG_CONST image_transform **that, char *name, size_t sizeof_name,
7010 size_t *pos, png_byte colour_type, png_byte bit_depth) 7010 size_t *pos, png_byte colour_type, png_byte bit_depth)
7011{ 7011{
7012 this->next = *that; 7012 this->next = *that;
7013 *that = this; 7013 *that = this;
7014 7014
7015 *pos = safecat(name, sizeof_name, *pos, " +@"); 7015 *pos = safecat(name, sizeof_name, *pos, " +@");
7016 7016
7017 return 1; 7017 return 1;
7018} 7018}
7019 7019
7020IT(@); 7020IT(@);
7021#endif 7021#endif
7022 7022
7023/* png_set_quantize(png_structp, png_colorp palette, int num_palette, 7023/* png_set_quantize(png_structp, png_colorp palette, int num_palette,
7024 * int maximum_colors, png_const_uint_16p histogram, int full_quantize) 7024 * int maximum_colors, png_const_uint_16p histogram, int full_quantize)
7025 * 7025 *
7026 * Very difficult to validate this! 7026 * Very difficult to validate this!
7027 */ 7027 */
7028/*NOTE: TBD NYI */ 7028/*NOTE: TBD NYI */
7029 7029
7030/* The data layout transforms are handled by swapping our own channel data, 7030/* The data layout transforms are handled by swapping our own channel data,
7031 * necessarily these need to happen at the end of the transform list because the 7031 * necessarily these need to happen at the end of the transform list because the
7032 * semantic of the channels changes after these are executed. Some of these, 7032 * semantic of the channels changes after these are executed. Some of these,
7033 * like set_shift and set_packing, can't be done at present because they change 7033 * like set_shift and set_packing, can't be done at present because they change
7034 * the layout of the data at the sub-sample level so sample() won't get the 7034 * the layout of the data at the sub-sample level so sample() won't get the
7035 * right answer. 7035 * right answer.
7036 */ 7036 */
7037/* png_set_invert_alpha */ 7037/* png_set_invert_alpha */
7038/*NOTE: TBD NYI */ 7038/*NOTE: TBD NYI */
7039 7039
7040/* png_set_bgr */ 7040/* png_set_bgr */
7041/*NOTE: TBD NYI */ 7041/*NOTE: TBD NYI */
7042 7042
7043/* png_set_swap_alpha */ 7043/* png_set_swap_alpha */
7044/*NOTE: TBD NYI */ 7044/*NOTE: TBD NYI */
7045 7045
7046/* png_set_swap */ 7046/* png_set_swap */
7047/*NOTE: TBD NYI */ 7047/*NOTE: TBD NYI */
7048 7048
7049/* png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags)); */ 7049/* png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags)); */
7050/*NOTE: TBD NYI */ 7050/*NOTE: TBD NYI */
7051 7051
7052/* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */ 7052/* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */
7053/*NOTE: TBD NYI */ 7053/*NOTE: TBD NYI */
7054 7054
7055/* png_set_packing */ 7055/* png_set_packing */
7056/*NOTE: TBD NYI */ 7056/*NOTE: TBD NYI */
7057 7057
7058/* png_set_packswap */ 7058/* png_set_packswap */
7059/*NOTE: TBD NYI */ 7059/*NOTE: TBD NYI */
7060 7060
7061/* png_set_invert_mono */ 7061/* png_set_invert_mono */
7062/*NOTE: TBD NYI */ 7062/*NOTE: TBD NYI */
7063 7063
7064/* png_set_shift(png_structp, png_const_color_8p true_bits) */ 7064/* png_set_shift(png_structp, png_const_color_8p true_bits) */
7065/*NOTE: TBD NYI */ 7065/*NOTE: TBD NYI */
7066 7066
7067static void 7067static void
7068perform_transform_test(png_modifier *pm) 7068perform_transform_test(png_modifier *pm)
7069{ 7069{
7070 png_byte colour_type = 0; 7070 png_byte colour_type = 0;
7071 png_byte bit_depth = 0; 7071 png_byte bit_depth = 0;
7072 int palette_number = 0; 7072 int palette_number = 0;
7073 7073
7074 while (next_format(&colour_type, &bit_depth, &palette_number)) 7074 while (next_format(&colour_type, &bit_depth, &palette_number))
7075 { 7075 {
7076 png_uint_32 counter = 0; 7076 png_uint_32 counter = 0;
7077 size_t base_pos; 7077 size_t base_pos;
7078 char name[64]; 7078 char name[64];
7079 7079
7080 base_pos = safecat(name, sizeof name, 0, "transform:"); 7080 base_pos = safecat(name, sizeof name, 0, "transform:");
7081 7081
7082 for (;;) 7082 for (;;)
7083 { 7083 {
7084 size_t pos = base_pos; 7084 size_t pos = base_pos;
7085 PNG_CONST image_transform *list = 0; 7085 PNG_CONST image_transform *list = 0;
7086 7086
7087 /* 'max' is currently hardwired to '1'; this should be settable on the 7087 /* 'max' is currently hardwired to '1'; this should be settable on the
7088 * command line. 7088 * command line.
7089 */ 7089 */
7090 counter = image_transform_add(&list, 1/*max*/, counter, 7090 counter = image_transform_add(&list, 1/*max*/, counter,
7091 name, sizeof name, &pos, colour_type, bit_depth); 7091 name, sizeof name, &pos, colour_type, bit_depth);
7092 7092
7093 if (counter == 0) 7093 if (counter == 0)
7094 break; 7094 break;
7095 7095
7096 /* The command line can change this to checking interlaced images. */ 7096 /* The command line can change this to checking interlaced images. */
7097 do 7097 do
7098 { 7098 {
7099 pm->repeat = 0; 7099 pm->repeat = 0;
7100 transform_test(pm, FILEID(colour_type, bit_depth, palette_number, 7100 transform_test(pm, FILEID(colour_type, bit_depth, palette_number,
7101 pm->interlace_type, 0, 0, 0), list, name); 7101 pm->interlace_type, 0, 0, 0), list, name);
7102 7102
7103 if (fail(pm)) 7103 if (fail(pm))
7104 return; 7104 return;
7105 } 7105 }
7106 while (pm->repeat); 7106 while (pm->repeat);
7107 } 7107 }
7108 } 7108 }
7109} 7109}
7110#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 7110#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
7111 7111
7112/********************************* GAMMA TESTS ********************************/ 7112/********************************* GAMMA TESTS ********************************/
7113#ifdef PNG_READ_GAMMA_SUPPORTED 7113#ifdef PNG_READ_GAMMA_SUPPORTED
7114/* Reader callbacks and implementations, where they differ from the standard 7114/* Reader callbacks and implementations, where they differ from the standard
7115 * ones. 7115 * ones.
7116 */ 7116 */
7117typedef struct gamma_display 7117typedef struct gamma_display
7118{ 7118{
7119 standard_display this; 7119 standard_display this;
7120 7120
7121 /* Parameters */ 7121 /* Parameters */
7122 png_modifier* pm; 7122 png_modifier* pm;
7123 double file_gamma; 7123 double file_gamma;
7124 double screen_gamma; 7124 double screen_gamma;
7125 double background_gamma; 7125 double background_gamma;
7126 png_byte sbit; 7126 png_byte sbit;
7127 int threshold_test; 7127 int threshold_test;
7128 int use_input_precision; 7128 int use_input_precision;
7129 int scale16; 7129 int scale16;
7130 int expand16; 7130 int expand16;
7131 int do_background; 7131 int do_background;
7132 png_color_16 background_color; 7132 png_color_16 background_color;
7133 7133
7134 /* Local variables */ 7134 /* Local variables */
7135 double maxerrout; 7135 double maxerrout;
7136 double maxerrpc; 7136 double maxerrpc;
7137 double maxerrabs; 7137 double maxerrabs;
7138} gamma_display; 7138} gamma_display;
7139 7139
7140#define ALPHA_MODE_OFFSET 4 7140#define ALPHA_MODE_OFFSET 4
7141 7141
7142static void 7142static void
7143gamma_display_init(gamma_display *dp, png_modifier *pm, png_uint_32 id, 7143gamma_display_init(gamma_display *dp, png_modifier *pm, png_uint_32 id,
7144 double file_gamma, double screen_gamma, png_byte sbit, int threshold_test, 7144 double file_gamma, double screen_gamma, png_byte sbit, int threshold_test,
7145 int use_input_precision, int scale16, int expand16, 7145 int use_input_precision, int scale16, int expand16,
7146 int do_background, PNG_CONST png_color_16 *pointer_to_the_background_color, 7146 int do_background, PNG_CONST png_color_16 *pointer_to_the_background_color,
7147 double background_gamma) 7147 double background_gamma)
7148{ 7148{
7149 /* Standard fields */ 7149 /* Standard fields */
7150 standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/, 7150 standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/,
7151 pm->use_update_info); 7151 pm->use_update_info);
7152 7152
7153 /* Parameter fields */ 7153 /* Parameter fields */
7154 dp->pm = pm; 7154 dp->pm = pm;
7155 dp->file_gamma = file_gamma; 7155 dp->file_gamma = file_gamma;
7156 dp->screen_gamma = screen_gamma; 7156 dp->screen_gamma = screen_gamma;
7157 dp->background_gamma = background_gamma; 7157 dp->background_gamma = background_gamma;
7158 dp->sbit = sbit; 7158 dp->sbit = sbit;
7159 dp->threshold_test = threshold_test; 7159 dp->threshold_test = threshold_test;
7160 dp->use_input_precision = use_input_precision; 7160 dp->use_input_precision = use_input_precision;
7161 dp->scale16 = scale16; 7161 dp->scale16 = scale16;
7162 dp->expand16 = expand16; 7162 dp->expand16 = expand16;
7163 dp->do_background = do_background; 7163 dp->do_background = do_background;
7164 if (do_background && pointer_to_the_background_color != 0) 7164 if (do_background && pointer_to_the_background_color != 0)
7165 dp->background_color = *pointer_to_the_background_color; 7165 dp->background_color = *pointer_to_the_background_color;
7166 else 7166 else
7167 memset(&dp->background_color, 0, sizeof dp->background_color); 7167 memset(&dp->background_color, 0, sizeof dp->background_color);
7168 7168
7169 /* Local variable fields */ 7169 /* Local variable fields */
7170 dp->maxerrout = dp->maxerrpc = dp->maxerrabs = 0; 7170 dp->maxerrout = dp->maxerrpc = dp->maxerrabs = 0;
7171} 7171}
7172 7172
7173static void 7173static void
7174gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi) 7174gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi)
7175{ 7175{
7176 /* Reuse the standard stuff as appropriate. */ 7176 /* Reuse the standard stuff as appropriate. */
7177 standard_info_part1(&dp->this, pp, pi); 7177 standard_info_part1(&dp->this, pp, pi);
7178 7178
7179 /* If requested strip 16 to 8 bits - this is handled automagically below 7179 /* If requested strip 16 to 8 bits - this is handled automagically below
7180 * because the output bit depth is read from the library. Note that there 7180 * because the output bit depth is read from the library. Note that there
7181 * are interactions with sBIT but, internally, libpng makes sbit at most 7181 * are interactions with sBIT but, internally, libpng makes sbit at most
7182 * PNG_MAX_GAMMA_8 when doing the following. 7182 * PNG_MAX_GAMMA_8 when doing the following.
7183 */ 7183 */
7184 if (dp->scale16) 7184 if (dp->scale16)
7185# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 7185# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
7186 png_set_scale_16(pp); 7186 png_set_scale_16(pp);
7187# else 7187# else
7188 /* The following works both in 1.5.4 and earlier versions: */ 7188 /* The following works both in 1.5.4 and earlier versions: */
7189# ifdef PNG_READ_16_TO_8_SUPPORTED 7189# ifdef PNG_READ_16_TO_8_SUPPORTED
7190 png_set_strip_16(pp); 7190 png_set_strip_16(pp);
7191# else 7191# else
7192 png_error(pp, "scale16 (16 to 8 bit conversion) not supported"); 7192 png_error(pp, "scale16 (16 to 8 bit conversion) not supported");
7193# endif 7193# endif
7194# endif 7194# endif
7195 7195
7196 if (dp->expand16) 7196 if (dp->expand16)
7197# ifdef PNG_READ_EXPAND_16_SUPPORTED 7197# ifdef PNG_READ_EXPAND_16_SUPPORTED
7198 png_set_expand_16(pp); 7198 png_set_expand_16(pp);
7199# else 7199# else
7200 png_error(pp, "expand16 (8 to 16 bit conversion) not supported"); 7200 png_error(pp, "expand16 (8 to 16 bit conversion) not supported");
7201# endif 7201# endif
7202 7202
7203 if (dp->do_background >= ALPHA_MODE_OFFSET) 7203 if (dp->do_background >= ALPHA_MODE_OFFSET)
7204 { 7204 {
7205# ifdef PNG_READ_ALPHA_MODE_SUPPORTED 7205# ifdef PNG_READ_ALPHA_MODE_SUPPORTED
7206 { 7206 {
7207 /* This tests the alpha mode handling, if supported. */ 7207 /* This tests the alpha mode handling, if supported. */
7208 int mode = dp->do_background - ALPHA_MODE_OFFSET; 7208 int mode = dp->do_background - ALPHA_MODE_OFFSET;
7209 7209
7210 /* The gamma value is the output gamma, and is in the standard, 7210 /* The gamma value is the output gamma, and is in the standard,
7211 * non-inverted, represenation. It provides a default for the PNG file 7211 * non-inverted, represenation. It provides a default for the PNG file
7212 * gamma, but since the file has a gAMA chunk this does not matter. 7212 * gamma, but since the file has a gAMA chunk this does not matter.
7213 */ 7213 */
7214 PNG_CONST double sg = dp->screen_gamma; 7214 PNG_CONST double sg = dp->screen_gamma;
7215# ifndef PNG_FLOATING_POINT_SUPPORTED 7215# ifndef PNG_FLOATING_POINT_SUPPORTED
7216 PNG_CONST png_fixed_point g = fix(sg); 7216 PNG_CONST png_fixed_point g = fix(sg);
7217# endif 7217# endif
7218 7218
7219# ifdef PNG_FLOATING_POINT_SUPPORTED 7219# ifdef PNG_FLOATING_POINT_SUPPORTED
7220 png_set_alpha_mode(pp, mode, sg); 7220 png_set_alpha_mode(pp, mode, sg);
7221# else 7221# else
7222 png_set_alpha_mode_fixed(pp, mode, g); 7222 png_set_alpha_mode_fixed(pp, mode, g);
7223# endif 7223# endif
7224 7224
7225 /* However, for the standard Porter-Duff algorithm the output defaults 7225 /* However, for the standard Porter-Duff algorithm the output defaults
7226 * to be linear, so if the test requires non-linear output it must be 7226 * to be linear, so if the test requires non-linear output it must be
7227 * corrected here. 7227 * corrected here.
7228 */ 7228 */
7229 if (mode == PNG_ALPHA_STANDARD && sg != 1) 7229 if (mode == PNG_ALPHA_STANDARD && sg != 1)
7230 { 7230 {
7231# ifdef PNG_FLOATING_POINT_SUPPORTED 7231# ifdef PNG_FLOATING_POINT_SUPPORTED
7232 png_set_gamma(pp, sg, dp->file_gamma); 7232 png_set_gamma(pp, sg, dp->file_gamma);
7233# else 7233# else
7234 png_fixed_point f = fix(dp->file_gamma); 7234 png_fixed_point f = fix(dp->file_gamma);
7235 png_set_gamma_fixed(pp, g, f); 7235 png_set_gamma_fixed(pp, g, f);
7236# endif 7236# endif
7237 } 7237 }
7238 } 7238 }
7239# else 7239# else
7240 png_error(pp, "alpha mode handling not supported"); 7240 png_error(pp, "alpha mode handling not supported");
7241# endif 7241# endif
7242 } 7242 }
7243 7243
7244 else 7244 else
7245 { 7245 {
7246 /* Set up gamma processing. */ 7246 /* Set up gamma processing. */
7247# ifdef PNG_FLOATING_POINT_SUPPORTED 7247# ifdef PNG_FLOATING_POINT_SUPPORTED
7248 png_set_gamma(pp, dp->screen_gamma, dp->file_gamma); 7248 png_set_gamma(pp, dp->screen_gamma, dp->file_gamma);
7249# else 7249# else
7250 { 7250 {
7251 png_fixed_point s = fix(dp->screen_gamma); 7251 png_fixed_point s = fix(dp->screen_gamma);
7252 png_fixed_point f = fix(dp->file_gamma); 7252 png_fixed_point f = fix(dp->file_gamma);
7253 png_set_gamma_fixed(pp, s, f); 7253 png_set_gamma_fixed(pp, s, f);
7254 } 7254 }
7255# endif 7255# endif
7256 7256
7257 if (dp->do_background) 7257 if (dp->do_background)
7258 { 7258 {
7259# ifdef PNG_READ_BACKGROUND_SUPPORTED 7259# ifdef PNG_READ_BACKGROUND_SUPPORTED
7260 /* NOTE: this assumes the caller provided the correct background gamma! 7260 /* NOTE: this assumes the caller provided the correct background gamma!
7261 */ 7261 */
7262 PNG_CONST double bg = dp->background_gamma; 7262 PNG_CONST double bg = dp->background_gamma;
7263# ifndef PNG_FLOATING_POINT_SUPPORTED 7263# ifndef PNG_FLOATING_POINT_SUPPORTED
7264 PNG_CONST png_fixed_point g = fix(bg); 7264 PNG_CONST png_fixed_point g = fix(bg);
7265# endif 7265# endif
7266 7266
7267# ifdef PNG_FLOATING_POINT_SUPPORTED 7267# ifdef PNG_FLOATING_POINT_SUPPORTED
7268 png_set_background(pp, &dp->background_color, dp->do_background, 7268 png_set_background(pp, &dp->background_color, dp->do_background,
7269 0/*need_expand*/, bg); 7269 0/*need_expand*/, bg);
7270# else 7270# else
7271 png_set_background_fixed(pp, &dp->background_color, 7271 png_set_background_fixed(pp, &dp->background_color,
7272 dp->do_background, 0/*need_expand*/, g); 7272 dp->do_background, 0/*need_expand*/, g);
7273# endif 7273# endif
7274# else 7274# else
7275 png_error(pp, "png_set_background not supported"); 7275 png_error(pp, "png_set_background not supported");
7276# endif 7276# endif
7277 } 7277 }
7278 } 7278 }
7279 7279
7280 { 7280 {
7281 int i = dp->this.use_update_info; 7281 int i = dp->this.use_update_info;
7282 /* Always do one call, even if use_update_info is 0. */ 7282 /* Always do one call, even if use_update_info is 0. */
7283 do 7283 do
7284 png_read_update_info(pp, pi); 7284 png_read_update_info(pp, pi);
7285 while (--i > 0); 7285 while (--i > 0);
7286 } 7286 }
7287 7287
7288 /* Now we may get a different cbRow: */ 7288 /* Now we may get a different cbRow: */
7289 standard_info_part2(&dp->this, pp, pi, 1 /*images*/); 7289 standard_info_part2(&dp->this, pp, pi, 1 /*images*/);
7290} 7290}
7291 7291
7292static void 7292static void
7293gamma_info(png_structp pp, png_infop pi) 7293gamma_info(png_structp pp, png_infop pi)
7294{ 7294{
7295 gamma_info_imp(voidcast(gamma_display*, png_get_progressive_ptr(pp)), pp, 7295 gamma_info_imp(voidcast(gamma_display*, png_get_progressive_ptr(pp)), pp,
7296 pi); 7296 pi);
7297} 7297}
7298 7298
7299/* Validate a single component value - the routine gets the input and output 7299/* Validate a single component value - the routine gets the input and output
7300 * sample values as unscaled PNG component values along with a cache of all the 7300 * sample values as unscaled PNG component values along with a cache of all the
7301 * information required to validate the values. 7301 * information required to validate the values.
7302 */ 7302 */
7303typedef struct validate_info 7303typedef struct validate_info
7304{ 7304{
7305 png_structp pp; 7305 png_structp pp;
7306 gamma_display *dp; 7306 gamma_display *dp;
7307 png_byte sbit; 7307 png_byte sbit;
7308 int use_input_precision; 7308 int use_input_precision;
7309 int do_background; 7309 int do_background;
7310 int scale16; 7310 int scale16;
7311 unsigned int sbit_max; 7311 unsigned int sbit_max;
7312 unsigned int isbit_shift; 7312 unsigned int isbit_shift;
7313 unsigned int outmax; 7313 unsigned int outmax;
7314 7314
7315 double gamma_correction; /* Overall correction required. */ 7315 double gamma_correction; /* Overall correction required. */
7316 double file_inverse; /* Inverse of file gamma. */ 7316 double file_inverse; /* Inverse of file gamma. */
7317 double screen_gamma; 7317 double screen_gamma;
7318 double screen_inverse; /* Inverse of screen gamma. */ 7318 double screen_inverse; /* Inverse of screen gamma. */
7319 7319
7320 double background_red; /* Linear background value, red or gray. */ 7320 double background_red; /* Linear background value, red or gray. */
7321 double background_green; 7321 double background_green;
7322 double background_blue; 7322 double background_blue;
7323 7323
7324 double maxabs; 7324 double maxabs;
7325 double maxpc; 7325 double maxpc;
7326 double maxcalc; 7326 double maxcalc;
7327 double maxout; 7327 double maxout;
7328 double maxout_total; /* Total including quantization error */ 7328 double maxout_total; /* Total including quantization error */
7329 double outlog; 7329 double outlog;
7330 int outquant; 7330 int outquant;
7331} 7331}
7332validate_info; 7332validate_info;
7333 7333
7334static void 7334static void
7335init_validate_info(validate_info *vi, gamma_display *dp, png_struct *pp, 7335init_validate_info(validate_info *vi, gamma_display *dp, png_struct *pp,
7336 int in_depth, int out_depth) 7336 int in_depth, int out_depth)
7337{ 7337{
7338 PNG_CONST unsigned int outmax = (1U<<out_depth)-1; 7338 PNG_CONST unsigned int outmax = (1U<<out_depth)-1;
7339 7339
7340 vi->pp = pp; 7340 vi->pp = pp;
7341 vi->dp = dp; 7341 vi->dp = dp;
7342 7342
7343 if (dp->sbit > 0 && dp->sbit < in_depth) 7343 if (dp->sbit > 0 && dp->sbit < in_depth)
7344 { 7344 {
7345 vi->sbit = dp->sbit; 7345 vi->sbit = dp->sbit;
7346 vi->isbit_shift = in_depth - dp->sbit; 7346 vi->isbit_shift = in_depth - dp->sbit;
7347 } 7347 }
7348 7348
7349 else 7349 else
7350 { 7350 {
7351 vi->sbit = (png_byte)in_depth; 7351 vi->sbit = (png_byte)in_depth;
7352 vi->isbit_shift = 0; 7352 vi->isbit_shift = 0;
7353 } 7353 }
7354 7354
7355 vi->sbit_max = (1U << vi->sbit)-1; 7355 vi->sbit_max = (1U << vi->sbit)-1;
7356 7356
7357 /* This mimics the libpng threshold test, '0' is used to prevent gamma 7357 /* This mimics the libpng threshold test, '0' is used to prevent gamma
7358 * correction in the validation test. 7358 * correction in the validation test.
7359 */ 7359 */
7360 vi->screen_gamma = dp->screen_gamma; 7360 vi->screen_gamma = dp->screen_gamma;
7361 if (fabs(vi->screen_gamma-1) < PNG_GAMMA_THRESHOLD) 7361 if (fabs(vi->screen_gamma-1) < PNG_GAMMA_THRESHOLD)
7362 vi->screen_gamma = vi->screen_inverse = 0; 7362 vi->screen_gamma = vi->screen_inverse = 0;
7363 else 7363 else
7364 vi->screen_inverse = 1/vi->screen_gamma; 7364 vi->screen_inverse = 1/vi->screen_gamma;
7365 7365
7366 vi->use_input_precision = dp->use_input_precision; 7366 vi->use_input_precision = dp->use_input_precision;
7367 vi->outmax = outmax; 7367 vi->outmax = outmax;
7368 vi->maxabs = abserr(dp->pm, in_depth, out_depth); 7368 vi->maxabs = abserr(dp->pm, in_depth, out_depth);
7369 vi->maxpc = pcerr(dp->pm, in_depth, out_depth); 7369 vi->maxpc = pcerr(dp->pm, in_depth, out_depth);
7370 vi->maxcalc = calcerr(dp->pm, in_depth, out_depth); 7370 vi->maxcalc = calcerr(dp->pm, in_depth, out_depth);
7371 vi->maxout = outerr(dp->pm, in_depth, out_depth); 7371 vi->maxout = outerr(dp->pm, in_depth, out_depth);
7372 vi->outquant = output_quantization_factor(dp->pm, in_depth, out_depth); 7372 vi->outquant = output_quantization_factor(dp->pm, in_depth, out_depth);
7373 vi->maxout_total = vi->maxout + vi->outquant * .5; 7373 vi->maxout_total = vi->maxout + vi->outquant * .5;
7374 vi->outlog = outlog(dp->pm, in_depth, out_depth); 7374 vi->outlog = outlog(dp->pm, in_depth, out_depth);
7375 7375
7376 if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 || 7376 if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 ||
7377 (dp->this.colour_type == 3 && dp->this.is_transparent)) 7377 (dp->this.colour_type == 3 && dp->this.is_transparent))
7378 { 7378 {
7379 vi->do_background = dp->do_background; 7379 vi->do_background = dp->do_background;
7380 7380
7381 if (vi->do_background != 0) 7381 if (vi->do_background != 0)
7382 { 7382 {
7383 PNG_CONST double bg_inverse = 1/dp->background_gamma; 7383 PNG_CONST double bg_inverse = 1/dp->background_gamma;
7384 double r, g, b; 7384 double r, g, b;
7385 7385
7386 /* Caller must at least put the gray value into the red channel */ 7386 /* Caller must at least put the gray value into the red channel */
7387 r = dp->background_color.red; r /= outmax; 7387 r = dp->background_color.red; r /= outmax;
7388 g = dp->background_color.green; g /= outmax; 7388 g = dp->background_color.green; g /= outmax;
7389 b = dp->background_color.blue; b /= outmax; 7389 b = dp->background_color.blue; b /= outmax;
7390 7390
7391# if 0 7391# if 0
7392 /* libpng doesn't do this optimization, if we do pngvalid will fail. 7392 /* libpng doesn't do this optimization, if we do pngvalid will fail.
7393 */ 7393 */
7394 if (fabs(bg_inverse-1) >= PNG_GAMMA_THRESHOLD) 7394 if (fabs(bg_inverse-1) >= PNG_GAMMA_THRESHOLD)
7395# endif 7395# endif
7396 { 7396 {
7397 r = pow(r, bg_inverse); 7397 r = pow(r, bg_inverse);
7398 g = pow(g, bg_inverse); 7398 g = pow(g, bg_inverse);
7399 b = pow(b, bg_inverse); 7399 b = pow(b, bg_inverse);
7400 } 7400 }
7401 7401
7402 vi->background_red = r; 7402 vi->background_red = r;
7403 vi->background_green = g; 7403 vi->background_green = g;
7404 vi->background_blue = b; 7404 vi->background_blue = b;
7405 } 7405 }
7406 } 7406 }
7407 else 7407 else
7408 vi->do_background = 0; 7408 vi->do_background = 0;
7409 7409
7410 if (vi->do_background == 0) 7410 if (vi->do_background == 0)
7411 vi->background_red = vi->background_green = vi->background_blue = 0; 7411 vi->background_red = vi->background_green = vi->background_blue = 0;
7412 7412
7413 vi->gamma_correction = 1/(dp->file_gamma*dp->screen_gamma); 7413 vi->gamma_correction = 1/(dp->file_gamma*dp->screen_gamma);
7414 if (fabs(vi->gamma_correction-1) < PNG_GAMMA_THRESHOLD) 7414 if (fabs(vi->gamma_correction-1) < PNG_GAMMA_THRESHOLD)
7415 vi->gamma_correction = 0; 7415 vi->gamma_correction = 0;
7416 7416
7417 vi->file_inverse = 1/dp->file_gamma; 7417 vi->file_inverse = 1/dp->file_gamma;
7418 if (fabs(vi->file_inverse-1) < PNG_GAMMA_THRESHOLD) 7418 if (fabs(vi->file_inverse-1) < PNG_GAMMA_THRESHOLD)
7419 vi->file_inverse = 0; 7419 vi->file_inverse = 0;
7420 7420
7421 vi->scale16 = dp->scale16; 7421 vi->scale16 = dp->scale16;
7422} 7422}
7423 7423
7424/* This function handles composition of a single non-alpha component. The 7424/* This function handles composition of a single non-alpha component. The
7425 * argument is the input sample value, in the range 0..1, and the alpha value. 7425 * argument is the input sample value, in the range 0..1, and the alpha value.
7426 * The result is the composed, linear, input sample. If alpha is less than zero 7426 * The result is the composed, linear, input sample. If alpha is less than zero
7427 * this is the alpha component and the function should not be called! 7427 * this is the alpha component and the function should not be called!
7428 */ 7428 */
7429static double 7429static double
7430gamma_component_compose(int do_background, double input_sample, double alpha, 7430gamma_component_compose(int do_background, double input_sample, double alpha,
7431 double background, int *compose) 7431 double background, int *compose)
7432{ 7432{
7433 switch (do_background) 7433 switch (do_background)
7434 { 7434 {
7435 case PNG_BACKGROUND_GAMMA_SCREEN: 7435 case PNG_BACKGROUND_GAMMA_SCREEN:
7436 case PNG_BACKGROUND_GAMMA_FILE: 7436 case PNG_BACKGROUND_GAMMA_FILE:
7437 case PNG_BACKGROUND_GAMMA_UNIQUE: 7437 case PNG_BACKGROUND_GAMMA_UNIQUE:
7438 /* Standard PNG background processing. */ 7438 /* Standard PNG background processing. */
7439 if (alpha < 1) 7439 if (alpha < 1)
7440 { 7440 {
7441 if (alpha > 0) 7441 if (alpha > 0)
7442 { 7442 {
7443 input_sample = input_sample * alpha + background * (1-alpha); 7443 input_sample = input_sample * alpha + background * (1-alpha);
7444 if (compose != NULL) 7444 if (compose != NULL)
7445 *compose = 1; 7445 *compose = 1;
7446 } 7446 }
7447 7447
7448 else 7448 else
7449 input_sample = background; 7449 input_sample = background;
7450 } 7450 }
7451 break; 7451 break;
7452 7452
7453#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 7453#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
7454 case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: 7454 case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
7455 case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: 7455 case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
7456 /* The components are premultiplied in either case and the output is 7456 /* The components are premultiplied in either case and the output is
7457 * gamma encoded (to get standard Porter-Duff we expect the output 7457 * gamma encoded (to get standard Porter-Duff we expect the output
7458 * gamma to be set to 1.0!) 7458 * gamma to be set to 1.0!)
7459 */ 7459 */
7460 case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: 7460 case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
7461 /* The optimization is that the partial-alpha entries are linear 7461 /* The optimization is that the partial-alpha entries are linear
7462 * while the opaque pixels are gamma encoded, but this only affects the 7462 * while the opaque pixels are gamma encoded, but this only affects the
7463 * output encoding. 7463 * output encoding.
7464 */ 7464 */
7465 if (alpha < 1) 7465 if (alpha < 1)
7466 { 7466 {
7467 if (alpha > 0) 7467 if (alpha > 0)
7468 { 7468 {
7469 input_sample *= alpha; 7469 input_sample *= alpha;
7470 if (compose != NULL) 7470 if (compose != NULL)
7471 *compose = 1; 7471 *compose = 1;
7472 } 7472 }
7473 7473
7474 else 7474 else
7475 input_sample = 0; 7475 input_sample = 0;
7476 } 7476 }
7477 break; 7477 break;
7478#endif 7478#endif
7479 7479
7480 default: 7480 default:
7481 /* Standard cases where no compositing is done (so the component 7481 /* Standard cases where no compositing is done (so the component
7482 * value is already correct.) 7482 * value is already correct.)
7483 */ 7483 */
7484 break; 7484 break;
7485 } 7485 }
7486 7486
7487 return input_sample; 7487 return input_sample;
7488} 7488}
7489 7489
7490/* This API returns the encoded *input* component, in the range 0..1 */ 7490/* This API returns the encoded *input* component, in the range 0..1 */
7491static double 7491static double
7492gamma_component_validate(PNG_CONST char *name, PNG_CONST validate_info *vi, 7492gamma_component_validate(PNG_CONST char *name, PNG_CONST validate_info *vi,
7493 PNG_CONST unsigned int id, PNG_CONST unsigned int od, 7493 PNG_CONST unsigned int id, PNG_CONST unsigned int od,
7494 PNG_CONST double alpha /* <0 for the alpha channel itself */, 7494 PNG_CONST double alpha /* <0 for the alpha channel itself */,
7495 PNG_CONST double background /* component background value */) 7495 PNG_CONST double background /* component background value */)
7496{ 7496{
7497 PNG_CONST unsigned int isbit = id >> vi->isbit_shift; 7497 PNG_CONST unsigned int isbit = id >> vi->isbit_shift;
7498 PNG_CONST unsigned int sbit_max = vi->sbit_max; 7498 PNG_CONST unsigned int sbit_max = vi->sbit_max;
7499 PNG_CONST unsigned int outmax = vi->outmax; 7499 PNG_CONST unsigned int outmax = vi->outmax;
7500 PNG_CONST int do_background = vi->do_background; 7500 PNG_CONST int do_background = vi->do_background;
7501 7501
7502 double i; 7502 double i;
7503 7503
7504 /* First check on the 'perfect' result obtained from the digitized input 7504 /* First check on the 'perfect' result obtained from the digitized input
7505 * value, id, and compare this against the actual digitized result, 'od'. 7505 * value, id, and compare this against the actual digitized result, 'od'.
7506 * 'i' is the input result in the range 0..1: 7506 * 'i' is the input result in the range 0..1:
7507 */ 7507 */
7508 i = isbit; i /= sbit_max; 7508 i = isbit; i /= sbit_max;
7509 7509
7510 /* Check for the fast route: if we don't do any background composition or if 7510 /* Check for the fast route: if we don't do any background composition or if
7511 * this is the alpha channel ('alpha' < 0) or if the pixel is opaque then 7511 * this is the alpha channel ('alpha' < 0) or if the pixel is opaque then
7512 * just use the gamma_correction field to correct to the final output gamma. 7512 * just use the gamma_correction field to correct to the final output gamma.
7513 */ 7513 */
7514 if (alpha == 1 /* opaque pixel component */ || !do_background 7514 if (alpha == 1 /* opaque pixel component */ || !do_background
7515#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 7515#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
7516 || do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_PNG 7516 || do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_PNG
7517#endif 7517#endif
7518 || (alpha < 0 /* alpha channel */ 7518 || (alpha < 0 /* alpha channel */
7519#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 7519#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
7520 && do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN 7520 && do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN
7521#endif 7521#endif
7522 )) 7522 ))
7523 { 7523 {
7524 /* Then get the gamma corrected version of 'i' and compare to 'od', any 7524 /* Then get the gamma corrected version of 'i' and compare to 'od', any
7525 * error less than .5 is insignificant - just quantization of the output 7525 * error less than .5 is insignificant - just quantization of the output
7526 * value to the nearest digital value (nevertheless the error is still 7526 * value to the nearest digital value (nevertheless the error is still
7527 * recorded - it's interesting ;-) 7527 * recorded - it's interesting ;-)
7528 */ 7528 */
7529 double encoded_sample = i; 7529 double encoded_sample = i;
7530 double encoded_error; 7530 double encoded_error;
7531 7531
7532 /* alpha less than 0 indicates the alpha channel, which is always linear 7532 /* alpha less than 0 indicates the alpha channel, which is always linear
7533 */ 7533 */
7534 if (alpha >= 0 && vi->gamma_correction > 0) 7534 if (alpha >= 0 && vi->gamma_correction > 0)
7535 encoded_sample = pow(encoded_sample, vi->gamma_correction); 7535 encoded_sample = pow(encoded_sample, vi->gamma_correction);
7536 encoded_sample *= outmax; 7536 encoded_sample *= outmax;
7537 7537
7538 encoded_error = fabs(od-encoded_sample); 7538 encoded_error = fabs(od-encoded_sample);
7539 7539
7540 if (encoded_error > vi->dp->maxerrout) 7540 if (encoded_error > vi->dp->maxerrout)
7541 vi->dp->maxerrout = encoded_error; 7541 vi->dp->maxerrout = encoded_error;
7542 7542
7543 if (encoded_error < vi->maxout_total && encoded_error < vi->outlog) 7543 if (encoded_error < vi->maxout_total && encoded_error < vi->outlog)
7544 return i; 7544 return i;
7545 } 7545 }
7546 7546
7547 /* The slow route - attempt to do linear calculations. */ 7547 /* The slow route - attempt to do linear calculations. */
7548 /* There may be an error, or background processing is required, so calculate 7548 /* There may be an error, or background processing is required, so calculate
7549 * the actual sample values - unencoded light intensity values. Note that in 7549 * the actual sample values - unencoded light intensity values. Note that in
7550 * practice these are not completely unencoded because they include a 7550 * practice these are not completely unencoded because they include a
7551 * 'viewing correction' to decrease or (normally) increase the perceptual 7551 * 'viewing correction' to decrease or (normally) increase the perceptual
7552 * contrast of the image. There's nothing we can do about this - we don't 7552 * contrast of the image. There's nothing we can do about this - we don't
7553 * know what it is - so assume the unencoded value is perceptually linear. 7553 * know what it is - so assume the unencoded value is perceptually linear.
7554 */ 7554 */
7555 { 7555 {
7556 double input_sample = i; /* In range 0..1 */ 7556 double input_sample = i; /* In range 0..1 */
7557 double output, error, encoded_sample, encoded_error; 7557 double output, error, encoded_sample, encoded_error;
7558 double es_lo, es_hi; 7558 double es_lo, es_hi;
7559 int compose = 0; /* Set to one if composition done */ 7559 int compose = 0; /* Set to one if composition done */
7560 int output_is_encoded; /* Set if encoded to screen gamma */ 7560 int output_is_encoded; /* Set if encoded to screen gamma */
7561 int log_max_error = 1; /* Check maximum error values */ 7561 int log_max_error = 1; /* Check maximum error values */
7562 png_const_charp pass = 0; /* Reason test passes (or 0 for fail) */ 7562 png_const_charp pass = 0; /* Reason test passes (or 0 for fail) */
7563 7563
7564 /* Convert to linear light (with the above caveat.) The alpha channel is 7564 /* Convert to linear light (with the above caveat.) The alpha channel is
7565 * already linear. 7565 * already linear.
7566 */ 7566 */
7567 if (alpha >= 0) 7567 if (alpha >= 0)
7568 { 7568 {
7569 int tcompose; 7569 int tcompose;
7570 7570
7571 if (vi->file_inverse > 0) 7571 if (vi->file_inverse > 0)
7572 input_sample = pow(input_sample, vi->file_inverse); 7572 input_sample = pow(input_sample, vi->file_inverse);
7573 7573
7574 /* Handle the compose processing: */ 7574 /* Handle the compose processing: */
7575 tcompose = 0; 7575 tcompose = 0;
7576 input_sample = gamma_component_compose(do_background, input_sample, 7576 input_sample = gamma_component_compose(do_background, input_sample,
7577 alpha, background, &tcompose); 7577 alpha, background, &tcompose);
7578 7578
7579 if (tcompose) 7579 if (tcompose)
7580 compose = 1; 7580 compose = 1;
7581 } 7581 }
7582 7582
7583 /* And similarly for the output value, but we need to check the background 7583 /* And similarly for the output value, but we need to check the background
7584 * handling to linearize it correctly. 7584 * handling to linearize it correctly.
7585 */ 7585 */
7586 output = od; 7586 output = od;
7587 output /= outmax; 7587 output /= outmax;
7588 7588
7589 output_is_encoded = vi->screen_gamma > 0; 7589 output_is_encoded = vi->screen_gamma > 0;
7590 7590
7591 if (alpha < 0) /* The alpha channel */ 7591 if (alpha < 0) /* The alpha channel */
7592 { 7592 {
7593#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 7593#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
7594 if (do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN) 7594 if (do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN)
7595#endif 7595#endif
7596 { 7596 {
7597 /* In all other cases the output alpha channel is linear already, 7597 /* In all other cases the output alpha channel is linear already,
7598 * don't log errors here, they are much larger in linear data. 7598 * don't log errors here, they are much larger in linear data.
7599 */ 7599 */
7600 output_is_encoded = 0; 7600 output_is_encoded = 0;
7601 log_max_error = 0; 7601 log_max_error = 0;
7602 } 7602 }
7603 } 7603 }
7604 7604
7605#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 7605#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
7606 else /* A component */ 7606 else /* A component */
7607 { 7607 {
7608 if (do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED && 7608 if (do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED &&
7609 alpha < 1) /* the optimized case - linear output */ 7609 alpha < 1) /* the optimized case - linear output */
7610 { 7610 {
7611 if (alpha > 0) log_max_error = 0; 7611 if (alpha > 0) log_max_error = 0;
7612 output_is_encoded = 0; 7612 output_is_encoded = 0;
7613 } 7613 }
7614 } 7614 }
7615#endif 7615#endif
7616 7616
7617 if (output_is_encoded) 7617 if (output_is_encoded)
7618 output = pow(output, vi->screen_gamma); 7618 output = pow(output, vi->screen_gamma);
7619 7619
7620 /* Calculate (or recalculate) the encoded_sample value and repeat the 7620 /* Calculate (or recalculate) the encoded_sample value and repeat the
7621 * check above (unnecessary if we took the fast route, but harmless.) 7621 * check above (unnecessary if we took the fast route, but harmless.)
7622 */ 7622 */
7623 encoded_sample = input_sample; 7623 encoded_sample = input_sample;
7624 if (output_is_encoded) 7624 if (output_is_encoded)
7625 encoded_sample = pow(encoded_sample, vi->screen_inverse); 7625 encoded_sample = pow(encoded_sample, vi->screen_inverse);
7626 encoded_sample *= outmax; 7626 encoded_sample *= outmax;
7627 7627
7628 encoded_error = fabs(od-encoded_sample); 7628 encoded_error = fabs(od-encoded_sample);
7629 7629
7630 /* Don't log errors in the alpha channel, or the 'optimized' case, 7630 /* Don't log errors in the alpha channel, or the 'optimized' case,
7631 * neither are significant to the overall perception. 7631 * neither are significant to the overall perception.
7632 */ 7632 */
7633 if (log_max_error && encoded_error > vi->dp->maxerrout) 7633 if (log_max_error && encoded_error > vi->dp->maxerrout)
7634 vi->dp->maxerrout = encoded_error; 7634 vi->dp->maxerrout = encoded_error;
7635 7635
7636 if (encoded_error < vi->maxout_total) 7636 if (encoded_error < vi->maxout_total)
7637 { 7637 {
7638 if (encoded_error < vi->outlog) 7638 if (encoded_error < vi->outlog)
7639 return i; 7639 return i;
7640 7640
7641 /* Test passed but error is bigger than the log limit, record why the 7641 /* Test passed but error is bigger than the log limit, record why the
7642 * test passed: 7642 * test passed:
7643 */ 7643 */
7644 pass = "less than maxout:\n"; 7644 pass = "less than maxout:\n";
7645 } 7645 }
7646 7646
7647 /* i: the original input value in the range 0..1 7647 /* i: the original input value in the range 0..1
7648 * 7648 *
7649 * pngvalid calculations: 7649 * pngvalid calculations:
7650 * input_sample: linear result; i linearized and composed, range 0..1 7650 * input_sample: linear result; i linearized and composed, range 0..1
7651 * encoded_sample: encoded result; input_sample scaled to ouput bit depth 7651 * encoded_sample: encoded result; input_sample scaled to ouput bit depth
7652 * 7652 *
7653 * libpng calculations: 7653 * libpng calculations:
7654 * output: linear result; od scaled to 0..1 and linearized 7654 * output: linear result; od scaled to 0..1 and linearized
7655 * od: encoded result from libpng 7655 * od: encoded result from libpng
7656 */ 7656 */
7657 7657
7658 /* Now we have the numbers for real errors, both absolute values as as a 7658 /* Now we have the numbers for real errors, both absolute values as as a
7659 * percentage of the correct value (output): 7659 * percentage of the correct value (output):
7660 */ 7660 */
7661 error = fabs(input_sample-output); 7661 error = fabs(input_sample-output);
7662 7662
7663 if (log_max_error && error > vi->dp->maxerrabs) 7663 if (log_max_error && error > vi->dp->maxerrabs)
7664 vi->dp->maxerrabs = error; 7664 vi->dp->maxerrabs = error;
7665 7665
7666 /* The following is an attempt to ignore the tendency of quantization to 7666 /* The following is an attempt to ignore the tendency of quantization to
7667 * dominate the percentage errors for lower result values: 7667 * dominate the percentage errors for lower result values:
7668 */ 7668 */
7669 if (log_max_error && input_sample > .5) 7669 if (log_max_error && input_sample > .5)
7670 { 7670 {
7671 double percentage_error = error/input_sample; 7671 double percentage_error = error/input_sample;
7672 if (percentage_error > vi->dp->maxerrpc) 7672 if (percentage_error > vi->dp->maxerrpc)
7673 vi->dp->maxerrpc = percentage_error; 7673 vi->dp->maxerrpc = percentage_error;
7674 } 7674 }
7675 7675
7676 /* Now calculate the digitization limits for 'encoded_sample' using the 7676 /* Now calculate the digitization limits for 'encoded_sample' using the
7677 * 'max' values. Note that maxout is in the encoded space but maxpc and 7677 * 'max' values. Note that maxout is in the encoded space but maxpc and
7678 * maxabs are in linear light space. 7678 * maxabs are in linear light space.
7679 * 7679 *
7680 * First find the maximum error in linear light space, range 0..1: 7680 * First find the maximum error in linear light space, range 0..1:
7681 */ 7681 */
7682 { 7682 {
7683 double tmp = input_sample * vi->maxpc; 7683 double tmp = input_sample * vi->maxpc;
7684 if (tmp < vi->maxabs) tmp = vi->maxabs; 7684 if (tmp < vi->maxabs) tmp = vi->maxabs;
7685 /* If 'compose' is true the composition was done in linear space using 7685 /* If 'compose' is true the composition was done in linear space using
7686 * integer arithmetic. This introduces an extra error of +/- 0.5 (at 7686 * integer arithmetic. This introduces an extra error of +/- 0.5 (at
7687 * least) in the integer space used. 'maxcalc' records this, taking 7687 * least) in the integer space used. 'maxcalc' records this, taking
7688 * into account the possibility that even for 16 bit output 8 bit space 7688 * into account the possibility that even for 16 bit output 8 bit space
7689 * may have been used. 7689 * may have been used.
7690 */ 7690 */
7691 if (compose && tmp < vi->maxcalc) tmp = vi->maxcalc; 7691 if (compose && tmp < vi->maxcalc) tmp = vi->maxcalc;
7692 7692
7693 /* The 'maxout' value refers to the encoded result, to compare with 7693 /* The 'maxout' value refers to the encoded result, to compare with
7694 * this encode input_sample adjusted by the maximum error (tmp) above. 7694 * this encode input_sample adjusted by the maximum error (tmp) above.
7695 */ 7695 */
7696 es_lo = encoded_sample - vi->maxout; 7696 es_lo = encoded_sample - vi->maxout;
7697 7697
7698 if (es_lo > 0 && input_sample-tmp > 0) 7698 if (es_lo > 0 && input_sample-tmp > 0)
7699 { 7699 {
7700 double low_value = input_sample-tmp; 7700 double low_value = input_sample-tmp;
7701 if (output_is_encoded) 7701 if (output_is_encoded)
7702 low_value = pow(low_value, vi->screen_inverse); 7702 low_value = pow(low_value, vi->screen_inverse);
7703 low_value *= outmax; 7703 low_value *= outmax;
7704 if (low_value < es_lo) es_lo = low_value; 7704 if (low_value < es_lo) es_lo = low_value;
7705 7705
7706 /* Quantize this appropriately: */ 7706 /* Quantize this appropriately: */
7707 es_lo = ceil(es_lo / vi->outquant - .5) * vi->outquant; 7707 es_lo = ceil(es_lo / vi->outquant - .5) * vi->outquant;
7708 } 7708 }
7709 7709
7710 else 7710 else
7711 es_lo = 0; 7711 es_lo = 0;
7712 7712
7713 es_hi = encoded_sample + vi->maxout; 7713 es_hi = encoded_sample + vi->maxout;
7714 7714
7715 if (es_hi < outmax && input_sample+tmp < 1) 7715 if (es_hi < outmax && input_sample+tmp < 1)
7716 { 7716 {
7717 double high_value = input_sample+tmp; 7717 double high_value = input_sample+tmp;
7718 if (output_is_encoded) 7718 if (output_is_encoded)
7719 high_value = pow(high_value, vi->screen_inverse); 7719 high_value = pow(high_value, vi->screen_inverse);
7720 high_value *= outmax; 7720 high_value *= outmax;
7721 if (high_value > es_hi) es_hi = high_value; 7721 if (high_value > es_hi) es_hi = high_value;
7722 7722
7723 es_hi = floor(es_hi / vi->outquant + .5) * vi->outquant; 7723 es_hi = floor(es_hi / vi->outquant + .5) * vi->outquant;
7724 } 7724 }
7725 7725
7726 else 7726 else
7727 es_hi = outmax; 7727 es_hi = outmax;
7728 } 7728 }
7729 7729
7730 /* The primary test is that the final encoded value returned by the 7730 /* The primary test is that the final encoded value returned by the
7731 * library should be between the two limits (inclusive) that were 7731 * library should be between the two limits (inclusive) that were
7732 * calculated above. 7732 * calculated above.
7733 */ 7733 */
7734 if (od >= es_lo && od <= es_hi) 7734 if (od >= es_lo && od <= es_hi)
7735 { 7735 {
7736 /* The value passes, but we may need to log the information anyway. */ 7736 /* The value passes, but we may need to log the information anyway. */
7737 if (encoded_error < vi->outlog) 7737 if (encoded_error < vi->outlog)
7738 return i; 7738 return i;
7739 7739
7740 if (pass == 0) 7740 if (pass == 0)
7741 pass = "within digitization limits:\n"; 7741 pass = "within digitization limits:\n";
7742 } 7742 }
7743 7743
7744 { 7744 {
7745 /* There has been an error in processing, or we need to log this 7745 /* There has been an error in processing, or we need to log this
7746 * value. 7746 * value.
7747 */ 7747 */
7748 double is_lo, is_hi; 7748 double is_lo, is_hi;
7749 7749
7750 /* pass is set at this point if either of the tests above would have 7750 /* pass is set at this point if either of the tests above would have
7751 * passed. Don't do these additional tests here - just log the 7751 * passed. Don't do these additional tests here - just log the
7752 * original [es_lo..es_hi] values. 7752 * original [es_lo..es_hi] values.
7753 */ 7753 */
7754 if (pass == 0 && vi->use_input_precision) 7754 if (pass == 0 && vi->use_input_precision)
7755 { 7755 {
7756 /* Ok, something is wrong - this actually happens in current libpng 7756 /* Ok, something is wrong - this actually happens in current libpng
7757 * 16-to-8 processing. Assume that the input value (id, adjusted 7757 * 16-to-8 processing. Assume that the input value (id, adjusted
7758 * for sbit) can be anywhere between value-.5 and value+.5 - quite a 7758 * for sbit) can be anywhere between value-.5 and value+.5 - quite a
7759 * large range if sbit is low. 7759 * large range if sbit is low.
7760 */ 7760 */
7761 double tmp = (isbit - .5)/sbit_max; 7761 double tmp = (isbit - .5)/sbit_max;
7762 7762
7763 if (tmp <= 0) 7763 if (tmp <= 0)
7764 tmp = 0; 7764 tmp = 0;
7765 7765
7766 else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1) 7766 else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1)
7767 tmp = pow(tmp, vi->file_inverse); 7767 tmp = pow(tmp, vi->file_inverse);
7768 7768
7769 tmp = gamma_component_compose(do_background, tmp, alpha, background, 7769 tmp = gamma_component_compose(do_background, tmp, alpha, background,
7770 NULL); 7770 NULL);
7771 7771
7772 if (output_is_encoded && tmp > 0 && tmp < 1) 7772 if (output_is_encoded && tmp > 0 && tmp < 1)
7773 tmp = pow(tmp, vi->screen_inverse); 7773 tmp = pow(tmp, vi->screen_inverse);
7774 7774
7775 is_lo = ceil(outmax * tmp - vi->maxout_total); 7775 is_lo = ceil(outmax * tmp - vi->maxout_total);
7776 7776
7777 if (is_lo < 0) 7777 if (is_lo < 0)
7778 is_lo = 0; 7778 is_lo = 0;
7779 7779
7780 tmp = (isbit + .5)/sbit_max; 7780 tmp = (isbit + .5)/sbit_max;
7781 7781
7782 if (tmp <= 0) 7782 if (tmp <= 0)
7783 tmp = 0; 7783 tmp = 0;
7784 7784
7785 else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1) 7785 else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1)
7786 tmp = pow(tmp, vi->file_inverse); 7786 tmp = pow(tmp, vi->file_inverse);
7787 7787
7788 tmp = gamma_component_compose(do_background, tmp, alpha, background, 7788 tmp = gamma_component_compose(do_background, tmp, alpha, background,
7789 NULL); 7789 NULL);
7790 7790
7791 if (output_is_encoded && tmp > 0 && tmp < 1) 7791 if (output_is_encoded && tmp > 0 && tmp < 1)
7792 tmp = pow(tmp, vi->screen_inverse); 7792 tmp = pow(tmp, vi->screen_inverse);
7793 7793
7794 is_hi = floor(outmax * tmp + vi->maxout_total); 7794 is_hi = floor(outmax * tmp + vi->maxout_total);
7795 7795
7796 if (is_hi > outmax) 7796 if (is_hi > outmax)
7797 is_hi = outmax; 7797 is_hi = outmax;
7798 7798
7799 if (!(od < is_lo || od > is_hi)) 7799 if (!(od < is_lo || od > is_hi))
7800 { 7800 {
7801 if (encoded_error < vi->outlog) 7801 if (encoded_error < vi->outlog)
7802 return i; 7802 return i;
7803 7803
7804 pass = "within input precision limits:\n"; 7804 pass = "within input precision limits:\n";
7805 } 7805 }
7806 7806
7807 /* One last chance. If this is an alpha channel and the 16to8 7807 /* One last chance. If this is an alpha channel and the 16to8
7808 * option has been used and 'inaccurate' scaling is used then the 7808 * option has been used and 'inaccurate' scaling is used then the
7809 * bit reduction is obtained by simply using the top 8 bits of the 7809 * bit reduction is obtained by simply using the top 8 bits of the
7810 * value. 7810 * value.
7811 * 7811 *
7812 * This is only done for older libpng versions when the 'inaccurate' 7812 * This is only done for older libpng versions when the 'inaccurate'
7813 * (chop) method of scaling was used. 7813 * (chop) method of scaling was used.
7814 */ 7814 */
7815# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED 7815# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
7816# if PNG_LIBPNG_VER < 10504 7816# if PNG_LIBPNG_VER < 10504
7817 /* This may be required for other components in the future, 7817 /* This may be required for other components in the future,
7818 * but at present the presence of gamma correction effectively 7818 * but at present the presence of gamma correction effectively
7819 * prevents the errors in the component scaling (I don't quite 7819 * prevents the errors in the component scaling (I don't quite
7820 * understand why, but since it's better this way I care not 7820 * understand why, but since it's better this way I care not
7821 * to ask, JB 20110419.) 7821 * to ask, JB 20110419.)
7822 */ 7822 */
7823 if (pass == 0 && alpha < 0 && vi->scale16 && vi->sbit > 8 && 7823 if (pass == 0 && alpha < 0 && vi->scale16 && vi->sbit > 8 &&
7824 vi->sbit + vi->isbit_shift == 16) 7824 vi->sbit + vi->isbit_shift == 16)
7825 { 7825 {
7826 tmp = ((id >> 8) - .5)/255; 7826 tmp = ((id >> 8) - .5)/255;
7827 7827
7828 if (tmp > 0) 7828 if (tmp > 0)
7829 { 7829 {
7830 is_lo = ceil(outmax * tmp - vi->maxout_total); 7830 is_lo = ceil(outmax * tmp - vi->maxout_total);
7831 if (is_lo < 0) is_lo = 0; 7831 if (is_lo < 0) is_lo = 0;
7832 } 7832 }
7833 7833
7834 else 7834 else
7835 is_lo = 0; 7835 is_lo = 0;
7836 7836
7837 tmp = ((id >> 8) + .5)/255; 7837 tmp = ((id >> 8) + .5)/255;
7838 7838
7839 if (tmp < 1) 7839 if (tmp < 1)
7840 { 7840 {
7841 is_hi = floor(outmax * tmp + vi->maxout_total); 7841 is_hi = floor(outmax * tmp + vi->maxout_total);
7842 if (is_hi > outmax) is_hi = outmax; 7842 if (is_hi > outmax) is_hi = outmax;
7843 } 7843 }
7844 7844
7845 else 7845 else
7846 is_hi = outmax; 7846 is_hi = outmax;
7847 7847
7848 if (!(od < is_lo || od > is_hi)) 7848 if (!(od < is_lo || od > is_hi))
7849 { 7849 {
7850 if (encoded_error < vi->outlog) 7850 if (encoded_error < vi->outlog)
7851 return i; 7851 return i;
7852 7852
7853 pass = "within 8 bit limits:\n"; 7853 pass = "within 8 bit limits:\n";
7854 } 7854 }
7855 } 7855 }
7856# endif 7856# endif
7857# endif 7857# endif
7858 } 7858 }
7859 else /* !use_input_precision */ 7859 else /* !use_input_precision */
7860 is_lo = es_lo, is_hi = es_hi; 7860 is_lo = es_lo, is_hi = es_hi;
7861 7861
7862 /* Attempt to output a meaningful error/warning message: the message 7862 /* Attempt to output a meaningful error/warning message: the message
7863 * output depends on the background/composite operation being performed 7863 * output depends on the background/composite operation being performed
7864 * because this changes what parameters were actually used above. 7864 * because this changes what parameters were actually used above.
7865 */ 7865 */
7866 { 7866 {
7867 size_t pos = 0; 7867 size_t pos = 0;
7868 /* Need either 1/255 or 1/65535 precision here; 3 or 6 decimal 7868 /* Need either 1/255 or 1/65535 precision here; 3 or 6 decimal
7869 * places. Just use outmax to work out which. 7869 * places. Just use outmax to work out which.
7870 */ 7870 */
7871 int precision = (outmax >= 1000 ? 6 : 3); 7871 int precision = (outmax >= 1000 ? 6 : 3);
7872 int use_input=1, use_background=0, do_compose=0; 7872 int use_input=1, use_background=0, do_compose=0;
7873 char msg[256]; 7873 char msg[256];
7874 7874
7875 if (pass != 0) 7875 if (pass != 0)
7876 pos = safecat(msg, sizeof msg, pos, "\n\t"); 7876 pos = safecat(msg, sizeof msg, pos, "\n\t");
7877 7877
7878 /* Set up the various flags, the output_is_encoded flag above 7878 /* Set up the various flags, the output_is_encoded flag above
7879 * is also used below. do_compose is just a double check. 7879 * is also used below. do_compose is just a double check.
7880 */ 7880 */
7881 switch (do_background) 7881 switch (do_background)
7882 { 7882 {
7883 case PNG_BACKGROUND_GAMMA_SCREEN: 7883 case PNG_BACKGROUND_GAMMA_SCREEN:
7884 case PNG_BACKGROUND_GAMMA_FILE: 7884 case PNG_BACKGROUND_GAMMA_FILE:
7885 case PNG_BACKGROUND_GAMMA_UNIQUE: 7885 case PNG_BACKGROUND_GAMMA_UNIQUE:
7886 use_background = (alpha >= 0 && alpha < 1); 7886 use_background = (alpha >= 0 && alpha < 1);
7887 /*FALL THROUGH*/ 7887 /*FALL THROUGH*/
7888# ifdef PNG_READ_ALPHA_MODE_SUPPORTED 7888# ifdef PNG_READ_ALPHA_MODE_SUPPORTED
7889 case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: 7889 case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
7890 case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: 7890 case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
7891 case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: 7891 case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
7892# endif /* ALPHA_MODE_SUPPORTED */ 7892# endif /* ALPHA_MODE_SUPPORTED */
7893 do_compose = (alpha > 0 && alpha < 1); 7893 do_compose = (alpha > 0 && alpha < 1);
7894 use_input = (alpha != 0); 7894 use_input = (alpha != 0);
7895 break; 7895 break;
7896 7896
7897 default: 7897 default:
7898 break; 7898 break;
7899 } 7899 }
7900 7900
7901 /* Check the 'compose' flag */ 7901 /* Check the 'compose' flag */
7902 if (compose != do_compose) 7902 if (compose != do_compose)
7903 png_error(vi->pp, "internal error (compose)"); 7903 png_error(vi->pp, "internal error (compose)");
7904 7904
7905 /* 'name' is the component name */ 7905 /* 'name' is the component name */
7906 pos = safecat(msg, sizeof msg, pos, name); 7906 pos = safecat(msg, sizeof msg, pos, name);
7907 pos = safecat(msg, sizeof msg, pos, "("); 7907 pos = safecat(msg, sizeof msg, pos, "(");
7908 pos = safecatn(msg, sizeof msg, pos, id); 7908 pos = safecatn(msg, sizeof msg, pos, id);
7909 if (use_input || pass != 0/*logging*/) 7909 if (use_input || pass != 0/*logging*/)
7910 { 7910 {
7911 if (isbit != id) 7911 if (isbit != id)
7912 { 7912 {
7913 /* sBIT has reduced the precision of the input: */ 7913 /* sBIT has reduced the precision of the input: */
7914 pos = safecat(msg, sizeof msg, pos, ", sbit("); 7914 pos = safecat(msg, sizeof msg, pos, ", sbit(");
7915 pos = safecatn(msg, sizeof msg, pos, vi->sbit); 7915 pos = safecatn(msg, sizeof msg, pos, vi->sbit);
7916 pos = safecat(msg, sizeof msg, pos, "): "); 7916 pos = safecat(msg, sizeof msg, pos, "): ");
7917 pos = safecatn(msg, sizeof msg, pos, isbit); 7917 pos = safecatn(msg, sizeof msg, pos, isbit);
7918 } 7918 }
7919 pos = safecat(msg, sizeof msg, pos, "/"); 7919 pos = safecat(msg, sizeof msg, pos, "/");
7920 /* The output is either "id/max" or "id sbit(sbit): isbit/max" */ 7920 /* The output is either "id/max" or "id sbit(sbit): isbit/max" */
7921 pos = safecatn(msg, sizeof msg, pos, vi->sbit_max); 7921 pos = safecatn(msg, sizeof msg, pos, vi->sbit_max);
7922 } 7922 }
7923 pos = safecat(msg, sizeof msg, pos, ")"); 7923 pos = safecat(msg, sizeof msg, pos, ")");
7924 7924
7925 /* A component may have been multiplied (in linear space) by the 7925 /* A component may have been multiplied (in linear space) by the
7926 * alpha value, 'compose' says whether this is relevant. 7926 * alpha value, 'compose' says whether this is relevant.
7927 */ 7927 */
7928 if (compose || pass != 0) 7928 if (compose || pass != 0)
7929 { 7929 {
7930 /* If any form of composition is being done report our 7930 /* If any form of composition is being done report our
7931 * calculated linear value here (the code above doesn't record 7931 * calculated linear value here (the code above doesn't record
7932 * the input value before composition is performed, so what 7932 * the input value before composition is performed, so what
7933 * gets reported is the value after composition.) 7933 * gets reported is the value after composition.)
7934 */ 7934 */
7935 if (use_input || pass != 0) 7935 if (use_input || pass != 0)
7936 { 7936 {
7937 if (vi->file_inverse > 0) 7937 if (vi->file_inverse > 0)
7938 { 7938 {
7939 pos = safecat(msg, sizeof msg, pos, "^"); 7939 pos = safecat(msg, sizeof msg, pos, "^");
7940 pos = safecatd(msg, sizeof msg, pos, vi->file_inverse, 2); 7940 pos = safecatd(msg, sizeof msg, pos, vi->file_inverse, 2);
7941 } 7941 }
7942 7942
7943 else 7943 else
7944 pos = safecat(msg, sizeof msg, pos, "[linear]"); 7944 pos = safecat(msg, sizeof msg, pos, "[linear]");
7945 7945
7946 pos = safecat(msg, sizeof msg, pos, "*(alpha)"); 7946 pos = safecat(msg, sizeof msg, pos, "*(alpha)");
7947 pos = safecatd(msg, sizeof msg, pos, alpha, precision); 7947 pos = safecatd(msg, sizeof msg, pos, alpha, precision);
7948 } 7948 }
7949 7949
7950 /* Now record the *linear* background value if it was used 7950 /* Now record the *linear* background value if it was used
7951 * (this function is not passed the original, non-linear, 7951 * (this function is not passed the original, non-linear,
7952 * value but it is contained in the test name.) 7952 * value but it is contained in the test name.)
7953 */ 7953 */
7954 if (use_background) 7954 if (use_background)
7955 { 7955 {
7956 pos = safecat(msg, sizeof msg, pos, use_input ? "+" : " "); 7956 pos = safecat(msg, sizeof msg, pos, use_input ? "+" : " ");
7957 pos = safecat(msg, sizeof msg, pos, "(background)"); 7957 pos = safecat(msg, sizeof msg, pos, "(background)");
7958 pos = safecatd(msg, sizeof msg, pos, background, precision); 7958 pos = safecatd(msg, sizeof msg, pos, background, precision);
7959 pos = safecat(msg, sizeof msg, pos, "*"); 7959 pos = safecat(msg, sizeof msg, pos, "*");
7960 pos = safecatd(msg, sizeof msg, pos, 1-alpha, precision); 7960 pos = safecatd(msg, sizeof msg, pos, 1-alpha, precision);
7961 } 7961 }
7962 } 7962 }
7963 7963
7964 /* Report the calculated value (input_sample) and the linearized 7964 /* Report the calculated value (input_sample) and the linearized
7965 * libpng value (output) unless this is just a component gamma 7965 * libpng value (output) unless this is just a component gamma
7966 * correction. 7966 * correction.
7967 */ 7967 */
7968 if (compose || alpha < 0 || pass != 0) 7968 if (compose || alpha < 0 || pass != 0)
7969 { 7969 {
7970 pos = safecat(msg, sizeof msg, pos, 7970 pos = safecat(msg, sizeof msg, pos,
7971 pass != 0 ? " =\n\t" : " = "); 7971 pass != 0 ? " =\n\t" : " = ");
7972 pos = safecatd(msg, sizeof msg, pos, input_sample, precision); 7972 pos = safecatd(msg, sizeof msg, pos, input_sample, precision);
7973 pos = safecat(msg, sizeof msg, pos, " (libpng: "); 7973 pos = safecat(msg, sizeof msg, pos, " (libpng: ");
7974 pos = safecatd(msg, sizeof msg, pos, output, precision); 7974 pos = safecatd(msg, sizeof msg, pos, output, precision);
7975 pos = safecat(msg, sizeof msg, pos, ")"); 7975 pos = safecat(msg, sizeof msg, pos, ")");
7976 7976
7977 /* Finally report the output gamma encoding, if any. */ 7977 /* Finally report the output gamma encoding, if any. */
7978 if (output_is_encoded) 7978 if (output_is_encoded)
7979 { 7979 {
7980 pos = safecat(msg, sizeof msg, pos, " ^"); 7980 pos = safecat(msg, sizeof msg, pos, " ^");
7981 pos = safecatd(msg, sizeof msg, pos, vi->screen_inverse, 2); 7981 pos = safecatd(msg, sizeof msg, pos, vi->screen_inverse, 2);
7982 pos = safecat(msg, sizeof msg, pos, "(to screen) ="); 7982 pos = safecat(msg, sizeof msg, pos, "(to screen) =");
7983 } 7983 }
7984 7984
7985 else 7985 else
7986 pos = safecat(msg, sizeof msg, pos, " [screen is linear] ="); 7986 pos = safecat(msg, sizeof msg, pos, " [screen is linear] =");
7987 } 7987 }
7988 7988
7989 if ((!compose && alpha >= 0) || pass != 0) 7989 if ((!compose && alpha >= 0) || pass != 0)
7990 { 7990 {
7991 if (pass != 0) /* logging */ 7991 if (pass != 0) /* logging */
7992 pos = safecat(msg, sizeof msg, pos, "\n\t[overall:"); 7992 pos = safecat(msg, sizeof msg, pos, "\n\t[overall:");
7993 7993
7994 /* This is the non-composition case, the internal linear 7994 /* This is the non-composition case, the internal linear
7995 * values are irrelevant (though the log below will reveal 7995 * values are irrelevant (though the log below will reveal
7996 * them.) Output a much shorter warning/error message and report 7996 * them.) Output a much shorter warning/error message and report
7997 * the overall gamma correction. 7997 * the overall gamma correction.
7998 */ 7998 */
7999 if (vi->gamma_correction > 0) 7999 if (vi->gamma_correction > 0)
8000 { 8000 {
8001 pos = safecat(msg, sizeof msg, pos, " ^"); 8001 pos = safecat(msg, sizeof msg, pos, " ^");
8002 pos = safecatd(msg, sizeof msg, pos, vi->gamma_correction, 2); 8002 pos = safecatd(msg, sizeof msg, pos, vi->gamma_correction, 2);
8003 pos = safecat(msg, sizeof msg, pos, "(gamma correction) ="); 8003 pos = safecat(msg, sizeof msg, pos, "(gamma correction) =");
8004 } 8004 }
8005 8005
8006 else 8006 else
8007 pos = safecat(msg, sizeof msg, pos, 8007 pos = safecat(msg, sizeof msg, pos,
8008 " [no gamma correction] ="); 8008 " [no gamma correction] =");
8009 8009
8010 if (pass != 0) 8010 if (pass != 0)
8011 pos = safecat(msg, sizeof msg, pos, "]"); 8011 pos = safecat(msg, sizeof msg, pos, "]");
8012 } 8012 }
8013 8013
8014 /* This is our calculated encoded_sample which should (but does 8014 /* This is our calculated encoded_sample which should (but does
8015 * not) match od: 8015 * not) match od:
8016 */ 8016 */
8017 pos = safecat(msg, sizeof msg, pos, pass != 0 ? "\n\t" : " "); 8017 pos = safecat(msg, sizeof msg, pos, pass != 0 ? "\n\t" : " ");
8018 pos = safecatd(msg, sizeof msg, pos, is_lo, 1); 8018 pos = safecatd(msg, sizeof msg, pos, is_lo, 1);
8019 pos = safecat(msg, sizeof msg, pos, " < "); 8019 pos = safecat(msg, sizeof msg, pos, " < ");
8020 pos = safecatd(msg, sizeof msg, pos, encoded_sample, 1); 8020 pos = safecatd(msg, sizeof msg, pos, encoded_sample, 1);
8021 pos = safecat(msg, sizeof msg, pos, " (libpng: "); 8021 pos = safecat(msg, sizeof msg, pos, " (libpng: ");
8022 pos = safecatn(msg, sizeof msg, pos, od); 8022 pos = safecatn(msg, sizeof msg, pos, od);
8023 pos = safecat(msg, sizeof msg, pos, ")"); 8023 pos = safecat(msg, sizeof msg, pos, ")");
8024 pos = safecat(msg, sizeof msg, pos, "/"); 8024 pos = safecat(msg, sizeof msg, pos, "/");
8025 pos = safecatn(msg, sizeof msg, pos, outmax); 8025 pos = safecatn(msg, sizeof msg, pos, outmax);
8026 pos = safecat(msg, sizeof msg, pos, " < "); 8026 pos = safecat(msg, sizeof msg, pos, " < ");
8027 pos = safecatd(msg, sizeof msg, pos, is_hi, 1); 8027 pos = safecatd(msg, sizeof msg, pos, is_hi, 1);
8028 8028
8029 if (pass == 0) /* The error condition */ 8029 if (pass == 0) /* The error condition */
8030 { 8030 {
8031# ifdef PNG_WARNINGS_SUPPORTED 8031# ifdef PNG_WARNINGS_SUPPORTED
8032 png_warning(vi->pp, msg); 8032 png_warning(vi->pp, msg);
8033# else 8033# else
8034 store_warning(vi->pp, msg); 8034 store_warning(vi->pp, msg);
8035# endif 8035# endif
8036 } 8036 }
8037 8037
8038 else /* logging this value */ 8038 else /* logging this value */
8039 store_verbose(&vi->dp->pm->this, vi->pp, pass, msg); 8039 store_verbose(&vi->dp->pm->this, vi->pp, pass, msg);
8040 } 8040 }
8041 } 8041 }
8042 } 8042 }
8043 8043
8044 return i; 8044 return i;
8045} 8045}
8046 8046
8047static void 8047static void
8048gamma_image_validate(gamma_display *dp, png_structp pp, png_infop pi) 8048gamma_image_validate(gamma_display *dp, png_structp pp, png_infop pi)
8049{ 8049{
8050 /* Get some constants derived from the input and output file formats: */ 8050 /* Get some constants derived from the input and output file formats: */
8051 PNG_CONST png_store* PNG_CONST ps = dp->this.ps; 8051 PNG_CONST png_store* PNG_CONST ps = dp->this.ps;
8052 PNG_CONST png_byte in_ct = dp->this.colour_type; 8052 PNG_CONST png_byte in_ct = dp->this.colour_type;
8053 PNG_CONST png_byte in_bd = dp->this.bit_depth; 8053 PNG_CONST png_byte in_bd = dp->this.bit_depth;
8054 PNG_CONST png_uint_32 w = dp->this.w; 8054 PNG_CONST png_uint_32 w = dp->this.w;
8055 PNG_CONST png_uint_32 h = dp->this.h; 8055 PNG_CONST png_uint_32 h = dp->this.h;
8056 PNG_CONST size_t cbRow = dp->this.cbRow; 8056 PNG_CONST size_t cbRow = dp->this.cbRow;
8057 PNG_CONST png_byte out_ct = png_get_color_type(pp, pi); 8057 PNG_CONST png_byte out_ct = png_get_color_type(pp, pi);
8058 PNG_CONST png_byte out_bd = png_get_bit_depth(pp, pi); 8058 PNG_CONST png_byte out_bd = png_get_bit_depth(pp, pi);
8059 8059
8060 /* There are three sources of error, firstly the quantization in the 8060 /* There are three sources of error, firstly the quantization in the
8061 * file encoding, determined by sbit and/or the file depth, secondly 8061 * file encoding, determined by sbit and/or the file depth, secondly
8062 * the output (screen) gamma and thirdly the output file encoding. 8062 * the output (screen) gamma and thirdly the output file encoding.
8063 * 8063 *
8064 * Since this API receives the screen and file gamma in double 8064 * Since this API receives the screen and file gamma in double
8065 * precision it is possible to calculate an exact answer given an input 8065 * precision it is possible to calculate an exact answer given an input
8066 * pixel value. Therefore we assume that the *input* value is exact - 8066 * pixel value. Therefore we assume that the *input* value is exact -
8067 * sample/maxsample - calculate the corresponding gamma corrected 8067 * sample/maxsample - calculate the corresponding gamma corrected
8068 * output to the limits of double precision arithmetic and compare with 8068 * output to the limits of double precision arithmetic and compare with
8069 * what libpng returns. 8069 * what libpng returns.
8070 * 8070 *
8071 * Since the library must quantize the output to 8 or 16 bits there is 8071 * Since the library must quantize the output to 8 or 16 bits there is
8072 * a fundamental limit on the accuracy of the output of +/-.5 - this 8072 * a fundamental limit on the accuracy of the output of +/-.5 - this
8073 * quantization limit is included in addition to the other limits 8073 * quantization limit is included in addition to the other limits
8074 * specified by the paramaters to the API. (Effectively, add .5 8074 * specified by the paramaters to the API. (Effectively, add .5
8075 * everywhere.) 8075 * everywhere.)
8076 * 8076 *
8077 * The behavior of the 'sbit' paramter is defined by section 12.5 8077 * The behavior of the 'sbit' paramter is defined by section 12.5
8078 * (sample depth scaling) of the PNG spec. That section forces the 8078 * (sample depth scaling) of the PNG spec. That section forces the
8079 * decoder to assume that the PNG values have been scaled if sBIT is 8079 * decoder to assume that the PNG values have been scaled if sBIT is
8080 * present: 8080 * present:
8081 * 8081 *
8082 * png-sample = floor( input-sample * (max-out/max-in) + .5); 8082 * png-sample = floor( input-sample * (max-out/max-in) + .5);
8083 * 8083 *
8084 * This means that only a subset of the possible PNG values should 8084 * This means that only a subset of the possible PNG values should
8085 * appear in the input. However, the spec allows the encoder to use a 8085 * appear in the input. However, the spec allows the encoder to use a
8086 * variety of approximations to the above and doesn't require any 8086 * variety of approximations to the above and doesn't require any
8087 * restriction of the values produced. 8087 * restriction of the values produced.
8088 * 8088 *
8089 * Nevertheless the spec requires that the upper 'sBIT' bits of the 8089 * Nevertheless the spec requires that the upper 'sBIT' bits of the
8090 * value stored in a PNG file be the original sample bits. 8090 * value stored in a PNG file be the original sample bits.
8091 * Consequently the code below simply scales the top sbit bits by 8091 * Consequently the code below simply scales the top sbit bits by
8092 * (1<<sbit)-1 to obtain an original sample value. 8092 * (1<<sbit)-1 to obtain an original sample value.
8093 * 8093 *
8094 * Because there is limited precision in the input it is arguable that 8094 * Because there is limited precision in the input it is arguable that
8095 * an acceptable result is any valid result from input-.5 to input+.5. 8095 * an acceptable result is any valid result from input-.5 to input+.5.
8096 * The basic tests below do not do this, however if 'use_input_precision' 8096 * The basic tests below do not do this, however if 'use_input_precision'
8097 * is set a subsequent test is performed below. 8097 * is set a subsequent test is performed below.
8098 */ 8098 */
8099 PNG_CONST unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U; 8099 PNG_CONST unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U;
8100 int processing; 8100 int processing;
8101 png_uint_32 y; 8101 png_uint_32 y;
8102 PNG_CONST store_palette_entry *in_palette = dp->this.palette; 8102 PNG_CONST store_palette_entry *in_palette = dp->this.palette;
8103 PNG_CONST int in_is_transparent = dp->this.is_transparent; 8103 PNG_CONST int in_is_transparent = dp->this.is_transparent;
8104 int out_npalette = -1; 8104 int out_npalette = -1;
8105 int out_is_transparent = 0; /* Just refers to the palette case */ 8105 int out_is_transparent = 0; /* Just refers to the palette case */
8106 store_palette out_palette; 8106 store_palette out_palette;
8107 validate_info vi; 8107 validate_info vi;
8108 8108
8109 /* Check for row overwrite errors */ 8109 /* Check for row overwrite errors */
8110 store_image_check(dp->this.ps, pp, 0); 8110 store_image_check(dp->this.ps, pp, 0);
8111 8111
8112 /* Supply the input and output sample depths here - 8 for an indexed image, 8112 /* Supply the input and output sample depths here - 8 for an indexed image,
8113 * otherwise the bit depth. 8113 * otherwise the bit depth.
8114 */ 8114 */
8115 init_validate_info(&vi, dp, pp, in_ct==3?8:in_bd, out_ct==3?8:out_bd); 8115 init_validate_info(&vi, dp, pp, in_ct==3?8:in_bd, out_ct==3?8:out_bd);
8116 8116
8117 processing = (vi.gamma_correction > 0 && !dp->threshold_test) 8117 processing = (vi.gamma_correction > 0 && !dp->threshold_test)
8118 || in_bd != out_bd || in_ct != out_ct || vi.do_background; 8118 || in_bd != out_bd || in_ct != out_ct || vi.do_background;
8119 8119
8120 /* TODO: FIX THIS: MAJOR BUG! If the transformations all happen inside 8120 /* TODO: FIX THIS: MAJOR BUG! If the transformations all happen inside
8121 * the palette there is no way of finding out, because libpng fails to 8121 * the palette there is no way of finding out, because libpng fails to
8122 * update the palette on png_read_update_info. Indeed, libpng doesn't 8122 * update the palette on png_read_update_info. Indeed, libpng doesn't
8123 * even do the required work until much later, when it doesn't have any 8123 * even do the required work until much later, when it doesn't have any
8124 * info pointer. Oops. For the moment 'processing' is turned off if 8124 * info pointer. Oops. For the moment 'processing' is turned off if
8125 * out_ct is palette. 8125 * out_ct is palette.
8126 */ 8126 */
8127 if (in_ct == 3 && out_ct == 3) 8127 if (in_ct == 3 && out_ct == 3)
8128 processing = 0; 8128 processing = 0;
8129 8129
8130 if (processing && out_ct == 3) 8130 if (processing && out_ct == 3)
8131 out_is_transparent = read_palette(out_palette, &out_npalette, pp, pi); 8131 out_is_transparent = read_palette(out_palette, &out_npalette, pp, pi);
8132 8132
8133 for (y=0; y<h; ++y) 8133 for (y=0; y<h; ++y)
8134 { 8134 {
8135 png_const_bytep pRow = store_image_row(ps, pp, 0, y); 8135 png_const_bytep pRow = store_image_row(ps, pp, 0, y);
8136 png_byte std[STANDARD_ROWMAX]; 8136 png_byte std[STANDARD_ROWMAX];
8137 8137
8138 transform_row(pp, std, in_ct, in_bd, y); 8138 transform_row(pp, std, in_ct, in_bd, y);
8139 8139
8140 if (processing) 8140 if (processing)
8141 { 8141 {
8142 unsigned int x; 8142 unsigned int x;
8143 8143
8144 for (x=0; x<w; ++x) 8144 for (x=0; x<w; ++x)
8145 { 8145 {
8146 double alpha = 1; /* serves as a flag value */ 8146 double alpha = 1; /* serves as a flag value */
8147 8147
8148 /* Record the palette index for index images. */ 8148 /* Record the palette index for index images. */
8149 PNG_CONST unsigned int in_index = 8149 PNG_CONST unsigned int in_index =
8150 in_ct == 3 ? sample(std, 3, in_bd, x, 0) : 256; 8150 in_ct == 3 ? sample(std, 3, in_bd, x, 0) : 256;
8151 PNG_CONST unsigned int out_index = 8151 PNG_CONST unsigned int out_index =
8152 out_ct == 3 ? sample(std, 3, out_bd, x, 0) : 256; 8152 out_ct == 3 ? sample(std, 3, out_bd, x, 0) : 256;
8153 8153
8154 /* Handle input alpha - png_set_background will cause the output 8154 /* Handle input alpha - png_set_background will cause the output
8155 * alpha to disappear so there is nothing to check. 8155 * alpha to disappear so there is nothing to check.
8156 */ 8156 */
8157 if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 || (in_ct == 3 && 8157 if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 || (in_ct == 3 &&
8158 in_is_transparent)) 8158 in_is_transparent))
8159 { 8159 {
8160 PNG_CONST unsigned int input_alpha = in_ct == 3 ? 8160 PNG_CONST unsigned int input_alpha = in_ct == 3 ?
8161 dp->this.palette[in_index].alpha : 8161 dp->this.palette[in_index].alpha :
8162 sample(std, in_ct, in_bd, x, samples_per_pixel); 8162 sample(std, in_ct, in_bd, x, samples_per_pixel);
8163 8163
8164 unsigned int output_alpha = 65536 /* as a flag value */; 8164 unsigned int output_alpha = 65536 /* as a flag value */;
8165 8165
8166 if (out_ct == 3) 8166 if (out_ct == 3)
8167 { 8167 {
8168 if (out_is_transparent) 8168 if (out_is_transparent)
8169 output_alpha = out_palette[out_index].alpha; 8169 output_alpha = out_palette[out_index].alpha;
8170 } 8170 }
8171 8171
8172 else if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0) 8172 else if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0)
8173 output_alpha = sample(pRow, out_ct, out_bd, x, 8173 output_alpha = sample(pRow, out_ct, out_bd, x,
8174 samples_per_pixel); 8174 samples_per_pixel);
8175 8175
8176 if (output_alpha != 65536) 8176 if (output_alpha != 65536)
8177 alpha = gamma_component_validate("alpha", &vi, input_alpha, 8177 alpha = gamma_component_validate("alpha", &vi, input_alpha,
8178 output_alpha, -1/*alpha*/, 0/*background*/); 8178 output_alpha, -1/*alpha*/, 0/*background*/);
8179 8179
8180 else /* no alpha in output */ 8180 else /* no alpha in output */
8181 { 8181 {
8182 /* This is a copy of the calculation of 'i' above in order to 8182 /* This is a copy of the calculation of 'i' above in order to
8183 * have the alpha value to use in the background calculation. 8183 * have the alpha value to use in the background calculation.
8184 */ 8184 */
8185 alpha = input_alpha >> vi.isbit_shift; 8185 alpha = input_alpha >> vi.isbit_shift;
8186 alpha /= vi.sbit_max; 8186 alpha /= vi.sbit_max;
8187 } 8187 }
8188 } 8188 }
8189 8189
8190 /* Handle grayscale or RGB components. */ 8190 /* Handle grayscale or RGB components. */
8191 if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */ 8191 if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */
8192 (void)gamma_component_validate("gray", &vi, 8192 (void)gamma_component_validate("gray", &vi,
8193 sample(std, in_ct, in_bd, x, 0), 8193 sample(std, in_ct, in_bd, x, 0),
8194 sample(pRow, out_ct, out_bd, x, 0), alpha/*component*/, 8194 sample(pRow, out_ct, out_bd, x, 0), alpha/*component*/,
8195 vi.background_red); 8195 vi.background_red);
8196 else /* RGB or palette */ 8196 else /* RGB or palette */
8197 { 8197 {
8198 (void)gamma_component_validate("red", &vi, 8198 (void)gamma_component_validate("red", &vi,
8199 in_ct == 3 ? in_palette[in_index].red : 8199 in_ct == 3 ? in_palette[in_index].red :
8200 sample(std, in_ct, in_bd, x, 0), 8200 sample(std, in_ct, in_bd, x, 0),
8201 out_ct == 3 ? out_palette[out_index].red : 8201 out_ct == 3 ? out_palette[out_index].red :
8202 sample(pRow, out_ct, out_bd, x, 0), 8202 sample(pRow, out_ct, out_bd, x, 0),
8203 alpha/*component*/, vi.background_red); 8203 alpha/*component*/, vi.background_red);
8204 8204
8205 (void)gamma_component_validate("green", &vi, 8205 (void)gamma_component_validate("green", &vi,
8206 in_ct == 3 ? in_palette[in_index].green : 8206 in_ct == 3 ? in_palette[in_index].green :
8207 sample(std, in_ct, in_bd, x, 1), 8207 sample(std, in_ct, in_bd, x, 1),
8208 out_ct == 3 ? out_palette[out_index].green : 8208 out_ct == 3 ? out_palette[out_index].green :
8209 sample(pRow, out_ct, out_bd, x, 1), 8209 sample(pRow, out_ct, out_bd, x, 1),
8210 alpha/*component*/, vi.background_green); 8210 alpha/*component*/, vi.background_green);
8211 8211
8212 (void)gamma_component_validate("blue", &vi, 8212 (void)gamma_component_validate("blue", &vi,
8213 in_ct == 3 ? in_palette[in_index].blue : 8213 in_ct == 3 ? in_palette[in_index].blue :
8214 sample(std, in_ct, in_bd, x, 2), 8214 sample(std, in_ct, in_bd, x, 2),
8215 out_ct == 3 ? out_palette[out_index].blue : 8215 out_ct == 3 ? out_palette[out_index].blue :
8216 sample(pRow, out_ct, out_bd, x, 2), 8216 sample(pRow, out_ct, out_bd, x, 2),
8217 alpha/*component*/, vi.background_blue); 8217 alpha/*component*/, vi.background_blue);
8218 } 8218 }
8219 } 8219 }
8220 } 8220 }
8221 8221
8222 else if (memcmp(std, pRow, cbRow) != 0) 8222 else if (memcmp(std, pRow, cbRow) != 0)
8223 { 8223 {
8224 char msg[64]; 8224 char msg[64];
8225 8225
8226 /* No transform is expected on the threshold tests. */ 8226 /* No transform is expected on the threshold tests. */
8227 sprintf(msg, "gamma: below threshold row %d changed", y); 8227 sprintf(msg, "gamma: below threshold row %d changed", y);
8228 8228
8229 png_error(pp, msg); 8229 png_error(pp, msg);
8230 } 8230 }
8231 } /* row (y) loop */ 8231 } /* row (y) loop */
8232 8232
8233 dp->this.ps->validated = 1; 8233 dp->this.ps->validated = 1;
8234} 8234}
8235 8235
8236static void 8236static void
8237gamma_end(png_structp pp, png_infop pi) 8237gamma_end(png_structp pp, png_infop pi)
8238{ 8238{
8239 gamma_display *dp = voidcast(gamma_display*, png_get_progressive_ptr(pp)); 8239 gamma_display *dp = voidcast(gamma_display*, png_get_progressive_ptr(pp));
8240 8240
8241 if (!dp->this.speed) 8241 if (!dp->this.speed)
8242 gamma_image_validate(dp, pp, pi); 8242 gamma_image_validate(dp, pp, pi);
8243 else 8243 else
8244 dp->this.ps->validated = 1; 8244 dp->this.ps->validated = 1;
8245} 8245}
8246 8246
8247/* A single test run checking a gamma transformation. 8247/* A single test run checking a gamma transformation.
8248 * 8248 *
8249 * maxabs: maximum absolute error as a fraction 8249 * maxabs: maximum absolute error as a fraction
8250 * maxout: maximum output error in the output units 8250 * maxout: maximum output error in the output units
8251 * maxpc: maximum percentage error (as a percentage) 8251 * maxpc: maximum percentage error (as a percentage)
8252 */ 8252 */
8253static void 8253static void
8254gamma_test(png_modifier *pmIn, PNG_CONST png_byte colour_typeIn, 8254gamma_test(png_modifier *pmIn, PNG_CONST png_byte colour_typeIn,
8255 PNG_CONST png_byte bit_depthIn, PNG_CONST int palette_numberIn, 8255 PNG_CONST png_byte bit_depthIn, PNG_CONST int palette_numberIn,
8256 PNG_CONST int interlace_typeIn, 8256 PNG_CONST int interlace_typeIn,
8257 PNG_CONST double file_gammaIn, PNG_CONST double screen_gammaIn, 8257 PNG_CONST double file_gammaIn, PNG_CONST double screen_gammaIn,
8258 PNG_CONST png_byte sbitIn, PNG_CONST int threshold_testIn, 8258 PNG_CONST png_byte sbitIn, PNG_CONST int threshold_testIn,
8259 PNG_CONST char *name, 8259 PNG_CONST char *name,
8260 PNG_CONST int use_input_precisionIn, PNG_CONST int scale16In, 8260 PNG_CONST int use_input_precisionIn, PNG_CONST int scale16In,
8261 PNG_CONST int expand16In, PNG_CONST int do_backgroundIn, 8261 PNG_CONST int expand16In, PNG_CONST int do_backgroundIn,
8262 PNG_CONST png_color_16 *bkgd_colorIn, double bkgd_gammaIn) 8262 PNG_CONST png_color_16 *bkgd_colorIn, double bkgd_gammaIn)
8263{ 8263{
8264 gamma_display d; 8264 gamma_display d;
8265 context(&pmIn->this, fault); 8265 context(&pmIn->this, fault);
8266 8266
8267 gamma_display_init(&d, pmIn, FILEID(colour_typeIn, bit_depthIn, 8267 gamma_display_init(&d, pmIn, FILEID(colour_typeIn, bit_depthIn,
8268 palette_numberIn, interlace_typeIn, 0, 0, 0), 8268 palette_numberIn, interlace_typeIn, 0, 0, 0),
8269 file_gammaIn, screen_gammaIn, sbitIn, 8269 file_gammaIn, screen_gammaIn, sbitIn,
8270 threshold_testIn, use_input_precisionIn, scale16In, 8270 threshold_testIn, use_input_precisionIn, scale16In,
8271 expand16In, do_backgroundIn, bkgd_colorIn, bkgd_gammaIn); 8271 expand16In, do_backgroundIn, bkgd_colorIn, bkgd_gammaIn);
8272 8272
8273 Try 8273 Try
8274 { 8274 {
8275 png_structp pp; 8275 png_structp pp;
8276 png_infop pi; 8276 png_infop pi;
8277 gama_modification gama_mod; 8277 gama_modification gama_mod;
8278 srgb_modification srgb_mod; 8278 srgb_modification srgb_mod;
8279 sbit_modification sbit_mod; 8279 sbit_modification sbit_mod;
8280 8280
8281 /* For the moment don't use the png_modifier support here. */ 8281 /* For the moment don't use the png_modifier support here. */
8282 d.pm->encoding_counter = 0; 8282 d.pm->encoding_counter = 0;
8283 modifier_set_encoding(d.pm); /* Just resets everything */ 8283 modifier_set_encoding(d.pm); /* Just resets everything */
8284 d.pm->current_gamma = d.file_gamma; 8284 d.pm->current_gamma = d.file_gamma;
8285 8285
8286 /* Make an appropriate modifier to set the PNG file gamma to the 8286 /* Make an appropriate modifier to set the PNG file gamma to the
8287 * given gamma value and the sBIT chunk to the given precision. 8287 * given gamma value and the sBIT chunk to the given precision.
8288 */ 8288 */
8289 d.pm->modifications = NULL; 8289 d.pm->modifications = NULL;
8290 gama_modification_init(&gama_mod, d.pm, d.file_gamma); 8290 gama_modification_init(&gama_mod, d.pm, d.file_gamma);
8291 srgb_modification_init(&srgb_mod, d.pm, 127 /*delete*/); 8291 srgb_modification_init(&srgb_mod, d.pm, 127 /*delete*/);
8292 if (d.sbit > 0) 8292 if (d.sbit > 0)
8293 sbit_modification_init(&sbit_mod, d.pm, d.sbit); 8293 sbit_modification_init(&sbit_mod, d.pm, d.sbit);
8294 8294
8295 modification_reset(d.pm->modifications); 8295 modification_reset(d.pm->modifications);
8296 8296
8297 /* Get a png_struct for writing the image. */ 8297 /* Get a png_struct for writing the image. */
8298 pp = set_modifier_for_read(d.pm, &pi, d.this.id, name); 8298 pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
8299 standard_palette_init(&d.this); 8299 standard_palette_init(&d.this);
8300 8300
8301 /* Introduce the correct read function. */ 8301 /* Introduce the correct read function. */
8302 if (d.pm->this.progressive) 8302 if (d.pm->this.progressive)
8303 { 8303 {
8304 /* Share the row function with the standard implementation. */ 8304 /* Share the row function with the standard implementation. */
8305 png_set_progressive_read_fn(pp, &d, gamma_info, progressive_row, 8305 png_set_progressive_read_fn(pp, &d, gamma_info, progressive_row,
8306 gamma_end); 8306 gamma_end);
8307 8307
8308 /* Now feed data into the reader until we reach the end: */ 8308 /* Now feed data into the reader until we reach the end: */
8309 modifier_progressive_read(d.pm, pp, pi); 8309 modifier_progressive_read(d.pm, pp, pi);
8310 } 8310 }
8311 else 8311 else
8312 { 8312 {
8313 /* modifier_read expects a png_modifier* */ 8313 /* modifier_read expects a png_modifier* */
8314 png_set_read_fn(pp, d.pm, modifier_read); 8314 png_set_read_fn(pp, d.pm, modifier_read);
8315 8315
8316 /* Check the header values: */ 8316 /* Check the header values: */
8317 png_read_info(pp, pi); 8317 png_read_info(pp, pi);
8318 8318
8319 /* Process the 'info' requirements. Only one image is generated */ 8319 /* Process the 'info' requirements. Only one image is generated */
8320 gamma_info_imp(&d, pp, pi); 8320 gamma_info_imp(&d, pp, pi);
8321 8321
8322 sequential_row(&d.this, pp, pi, -1, 0); 8322 sequential_row(&d.this, pp, pi, -1, 0);
8323 8323
8324 if (!d.this.speed) 8324 if (!d.this.speed)
8325 gamma_image_validate(&d, pp, pi); 8325 gamma_image_validate(&d, pp, pi);
8326 else 8326 else
8327 d.this.ps->validated = 1; 8327 d.this.ps->validated = 1;
8328 } 8328 }
8329 8329
8330 modifier_reset(d.pm); 8330 modifier_reset(d.pm);
8331 8331
8332 if (d.pm->log && !d.threshold_test && !d.this.speed) 8332 if (d.pm->log && !d.threshold_test && !d.this.speed)
8333 fprintf(stderr, "%d bit %s %s: max error %f (%.2g, %2g%%)\n", 8333 fprintf(stderr, "%d bit %s %s: max error %f (%.2g, %2g%%)\n",
8334 d.this.bit_depth, colour_types[d.this.colour_type], name, 8334 d.this.bit_depth, colour_types[d.this.colour_type], name,
8335 d.maxerrout, d.maxerrabs, 100*d.maxerrpc); 8335 d.maxerrout, d.maxerrabs, 100*d.maxerrpc);
8336 8336
8337 /* Log the summary values too. */ 8337 /* Log the summary values too. */
8338 if (d.this.colour_type == 0 || d.this.colour_type == 4) 8338 if (d.this.colour_type == 0 || d.this.colour_type == 4)
8339 { 8339 {
8340 switch (d.this.bit_depth) 8340 switch (d.this.bit_depth)
8341 { 8341 {
8342 case 1: 8342 case 1:
8343 break; 8343 break;
8344 8344
8345 case 2: 8345 case 2:
8346 if (d.maxerrout > d.pm->error_gray_2) 8346 if (d.maxerrout > d.pm->error_gray_2)
8347 d.pm->error_gray_2 = d.maxerrout; 8347 d.pm->error_gray_2 = d.maxerrout;
8348 8348
8349 break; 8349 break;
8350 8350
8351 case 4: 8351 case 4:
8352 if (d.maxerrout > d.pm->error_gray_4) 8352 if (d.maxerrout > d.pm->error_gray_4)
8353 d.pm->error_gray_4 = d.maxerrout; 8353 d.pm->error_gray_4 = d.maxerrout;
8354 8354
8355 break; 8355 break;
8356 8356
8357 case 8: 8357 case 8:
8358 if (d.maxerrout > d.pm->error_gray_8) 8358 if (d.maxerrout > d.pm->error_gray_8)
8359 d.pm->error_gray_8 = d.maxerrout; 8359 d.pm->error_gray_8 = d.maxerrout;
8360 8360
8361 break; 8361 break;
8362 8362
8363 case 16: 8363 case 16:
8364 if (d.maxerrout > d.pm->error_gray_16) 8364 if (d.maxerrout > d.pm->error_gray_16)
8365 d.pm->error_gray_16 = d.maxerrout; 8365 d.pm->error_gray_16 = d.maxerrout;
8366 8366
8367 break; 8367 break;
8368 8368
8369 default: 8369 default:
8370 png_error(pp, "bad bit depth (internal: 1)"); 8370 png_error(pp, "bad bit depth (internal: 1)");
8371 } 8371 }
8372 } 8372 }
8373 8373
8374 else if (d.this.colour_type == 2 || d.this.colour_type == 6) 8374 else if (d.this.colour_type == 2 || d.this.colour_type == 6)
8375 { 8375 {
8376 switch (d.this.bit_depth) 8376 switch (d.this.bit_depth)
8377 { 8377 {
8378 case 8: 8378 case 8:
8379 8379
8380 if (d.maxerrout > d.pm->error_color_8) 8380 if (d.maxerrout > d.pm->error_color_8)
8381 d.pm->error_color_8 = d.maxerrout; 8381 d.pm->error_color_8 = d.maxerrout;
8382 8382
8383 break; 8383 break;
8384 8384
8385 case 16: 8385 case 16:
8386 8386
8387 if (d.maxerrout > d.pm->error_color_16) 8387 if (d.maxerrout > d.pm->error_color_16)
8388 d.pm->error_color_16 = d.maxerrout; 8388 d.pm->error_color_16 = d.maxerrout;
8389 8389
8390 break; 8390 break;
8391 8391
8392 default: 8392 default:
8393 png_error(pp, "bad bit depth (internal: 2)"); 8393 png_error(pp, "bad bit depth (internal: 2)");
8394 } 8394 }
8395 } 8395 }
8396 8396
8397 else if (d.this.colour_type == 3) 8397 else if (d.this.colour_type == 3)
8398 { 8398 {
8399 if (d.maxerrout > d.pm->error_indexed) 8399 if (d.maxerrout > d.pm->error_indexed)
8400 d.pm->error_indexed = d.maxerrout; 8400 d.pm->error_indexed = d.maxerrout;
8401 } 8401 }
8402 } 8402 }
8403 8403
8404 Catch(fault) 8404 Catch(fault)
8405 modifier_reset((png_modifier*)fault); 8405 modifier_reset((png_modifier*)fault);
8406} 8406}
8407 8407
8408static void gamma_threshold_test(png_modifier *pm, png_byte colour_type, 8408static void gamma_threshold_test(png_modifier *pm, png_byte colour_type,
8409 png_byte bit_depth, int interlace_type, double file_gamma, 8409 png_byte bit_depth, int interlace_type, double file_gamma,
8410 double screen_gamma) 8410 double screen_gamma)
8411{ 8411{
8412 size_t pos = 0; 8412 size_t pos = 0;
8413 char name[64]; 8413 char name[64];
8414 pos = safecat(name, sizeof name, pos, "threshold "); 8414 pos = safecat(name, sizeof name, pos, "threshold ");
8415 pos = safecatd(name, sizeof name, pos, file_gamma, 3); 8415 pos = safecatd(name, sizeof name, pos, file_gamma, 3);
8416 pos = safecat(name, sizeof name, pos, "/"); 8416 pos = safecat(name, sizeof name, pos, "/");
8417 pos = safecatd(name, sizeof name, pos, screen_gamma, 3); 8417 pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
8418 8418
8419 (void)gamma_test(pm, colour_type, bit_depth, 0/*palette*/, interlace_type, 8419 (void)gamma_test(pm, colour_type, bit_depth, 0/*palette*/, interlace_type,
8420 file_gamma, screen_gamma, 0/*sBIT*/, 1/*threshold test*/, name, 8420 file_gamma, screen_gamma, 0/*sBIT*/, 1/*threshold test*/, name,
8421 0 /*no input precision*/, 8421 0 /*no input precision*/,
8422 0 /*no scale16*/, 0 /*no expand16*/, 0 /*no background*/, 0 /*hence*/, 8422 0 /*no scale16*/, 0 /*no expand16*/, 0 /*no background*/, 0 /*hence*/,
8423 0 /*no background gamma*/); 8423 0 /*no background gamma*/);
8424} 8424}
8425 8425
8426static void 8426static void
8427perform_gamma_threshold_tests(png_modifier *pm) 8427perform_gamma_threshold_tests(png_modifier *pm)
8428{ 8428{
8429 png_byte colour_type = 0; 8429 png_byte colour_type = 0;
8430 png_byte bit_depth = 0; 8430 png_byte bit_depth = 0;
8431 int palette_number = 0; 8431 int palette_number = 0;
8432 8432
8433 /* Don't test more than one instance of each palette - it's pointless, in 8433 /* Don't test more than one instance of each palette - it's pointless, in
8434 * fact this test is somewhat excessive since libpng doesn't make this 8434 * fact this test is somewhat excessive since libpng doesn't make this
8435 * decision based on colour type or bit depth! 8435 * decision based on colour type or bit depth!
8436 */ 8436 */
8437 while (next_format(&colour_type, &bit_depth, &palette_number)) 8437 while (next_format(&colour_type, &bit_depth, &palette_number))
8438 if (palette_number == 0) 8438 if (palette_number == 0)
8439 { 8439 {
8440 double test_gamma = 1.0; 8440 double test_gamma = 1.0;
8441 while (test_gamma >= .4) 8441 while (test_gamma >= .4)
8442 { 8442 {
8443 /* There's little point testing the interlacing vs non-interlacing, 8443 /* There's little point testing the interlacing vs non-interlacing,
8444 * but this can be set from the command line. 8444 * but this can be set from the command line.
8445 */ 8445 */
8446 gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type, 8446 gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
8447 test_gamma, 1/test_gamma); 8447 test_gamma, 1/test_gamma);
8448 test_gamma *= .95; 8448 test_gamma *= .95;
8449 } 8449 }
8450 8450
8451 /* And a special test for sRGB */ 8451 /* And a special test for sRGB */
8452 gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type, 8452 gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
8453 .45455, 2.2); 8453 .45455, 2.2);
8454 8454
8455 if (fail(pm)) 8455 if (fail(pm))
8456 return; 8456 return;
8457 } 8457 }
8458} 8458}
8459 8459
8460static void gamma_transform_test(png_modifier *pm, 8460static void gamma_transform_test(png_modifier *pm,
8461 PNG_CONST png_byte colour_type, PNG_CONST png_byte bit_depth, 8461 PNG_CONST png_byte colour_type, PNG_CONST png_byte bit_depth,
8462 PNG_CONST int palette_number, 8462 PNG_CONST int palette_number,
8463 PNG_CONST int interlace_type, PNG_CONST double file_gamma, 8463 PNG_CONST int interlace_type, PNG_CONST double file_gamma,
8464 PNG_CONST double screen_gamma, PNG_CONST png_byte sbit, 8464 PNG_CONST double screen_gamma, PNG_CONST png_byte sbit,
8465 PNG_CONST int use_input_precision, PNG_CONST int scale16) 8465 PNG_CONST int use_input_precision, PNG_CONST int scale16)
8466{ 8466{
8467 size_t pos = 0; 8467 size_t pos = 0;
8468 char name[64]; 8468 char name[64];
8469 8469
8470 if (sbit != bit_depth && sbit != 0) 8470 if (sbit != bit_depth && sbit != 0)
8471 { 8471 {
8472 pos = safecat(name, sizeof name, pos, "sbit("); 8472 pos = safecat(name, sizeof name, pos, "sbit(");
8473 pos = safecatn(name, sizeof name, pos, sbit); 8473 pos = safecatn(name, sizeof name, pos, sbit);
8474 pos = safecat(name, sizeof name, pos, ") "); 8474 pos = safecat(name, sizeof name, pos, ") ");
8475 } 8475 }
8476 8476
8477 else 8477 else
8478 pos = safecat(name, sizeof name, pos, "gamma "); 8478 pos = safecat(name, sizeof name, pos, "gamma ");
8479 8479
8480 if (scale16) 8480 if (scale16)
8481 pos = safecat(name, sizeof name, pos, "16to8 "); 8481 pos = safecat(name, sizeof name, pos, "16to8 ");
8482 8482
8483 pos = safecatd(name, sizeof name, pos, file_gamma, 3); 8483 pos = safecatd(name, sizeof name, pos, file_gamma, 3);
8484 pos = safecat(name, sizeof name, pos, "->"); 8484 pos = safecat(name, sizeof name, pos, "->");
8485 pos = safecatd(name, sizeof name, pos, screen_gamma, 3); 8485 pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
8486 8486
8487 gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type, 8487 gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type,
8488 file_gamma, screen_gamma, sbit, 0, name, use_input_precision, 8488 file_gamma, screen_gamma, sbit, 0, name, use_input_precision,
8489 scale16, pm->test_gamma_expand16, 0 , 0, 0); 8489 scale16, pm->test_gamma_expand16, 0 , 0, 0);
8490} 8490}
8491 8491
8492static void perform_gamma_transform_tests(png_modifier *pm) 8492static void perform_gamma_transform_tests(png_modifier *pm)
8493{ 8493{
8494 png_byte colour_type = 0; 8494 png_byte colour_type = 0;
8495 png_byte bit_depth = 0; 8495 png_byte bit_depth = 0;
8496 int palette_number = 0; 8496 int palette_number = 0;
8497 8497
8498 while (next_format(&colour_type, &bit_depth, &palette_number)) 8498 while (next_format(&colour_type, &bit_depth, &palette_number))
8499 { 8499 {
8500 unsigned int i, j; 8500 unsigned int i, j;
8501 8501
8502 for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j) 8502 for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)
8503 if (i != j) 8503 if (i != j)
8504 { 8504 {
8505 gamma_transform_test(pm, colour_type, bit_depth, palette_number, 8505 gamma_transform_test(pm, colour_type, bit_depth, palette_number,
8506 pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 0/*sBIT*/, 8506 pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 0/*sBIT*/,
8507 pm->use_input_precision, 0 /*do not scale16*/); 8507 pm->use_input_precision, 0 /*do not scale16*/);
8508 8508
8509 if (fail(pm)) 8509 if (fail(pm))
8510 return; 8510 return;
8511 } 8511 }
8512 } 8512 }
8513} 8513}
8514 8514
8515static void perform_gamma_sbit_tests(png_modifier *pm) 8515static void perform_gamma_sbit_tests(png_modifier *pm)
8516{ 8516{
8517 png_byte sbit; 8517 png_byte sbit;
8518 8518
8519 /* The only interesting cases are colour and grayscale, alpha is ignored here 8519 /* The only interesting cases are colour and grayscale, alpha is ignored here
8520 * for overall speed. Only bit depths where sbit is less than the bit depth 8520 * for overall speed. Only bit depths where sbit is less than the bit depth
8521 * are tested. 8521 * are tested.
8522 */ 8522 */
8523 for (sbit=pm->sbitlow; sbit<(1<<READ_BDHI); ++sbit) 8523 for (sbit=pm->sbitlow; sbit<(1<<READ_BDHI); ++sbit)
8524 { 8524 {
8525 png_byte colour_type, bit_depth; 8525 png_byte colour_type, bit_depth;
8526 int npalette; 8526 int npalette;
8527 8527
8528 colour_type = bit_depth = 0; 8528 colour_type = bit_depth = 0;
8529 npalette = 0; 8529 npalette = 0;
8530 8530
8531 while (next_format(&colour_type, &bit_depth, &npalette)) 8531 while (next_format(&colour_type, &bit_depth, &npalette))
8532 if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 && 8532 if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 &&
8533 ((colour_type == 3 && sbit < 8) || 8533 ((colour_type == 3 && sbit < 8) ||
8534 (colour_type != 3 && sbit < bit_depth))) 8534 (colour_type != 3 && sbit < bit_depth)))
8535 { 8535 {
8536 unsigned int i; 8536 unsigned int i;
8537 8537
8538 for (i=0; i<pm->ngamma_tests; ++i) 8538 for (i=0; i<pm->ngamma_tests; ++i)
8539 { 8539 {
8540 unsigned int j; 8540 unsigned int j;
8541 8541
8542 for (j=0; j<pm->ngamma_tests; ++j) if (i != j) 8542 for (j=0; j<pm->ngamma_tests; ++j) if (i != j)
8543 { 8543 {
8544 gamma_transform_test(pm, colour_type, bit_depth, npalette, 8544 gamma_transform_test(pm, colour_type, bit_depth, npalette,
8545 pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 8545 pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
8546 sbit, pm->use_input_precision_sbit, 0 /*scale16*/); 8546 sbit, pm->use_input_precision_sbit, 0 /*scale16*/);
8547 8547
8548 if (fail(pm)) 8548 if (fail(pm))
8549 return; 8549 return;
8550 } 8550 }
8551 } 8551 }
8552 } 8552 }
8553 } 8553 }
8554} 8554}
8555 8555
8556/* Note that this requires a 16 bit source image but produces 8 bit output, so 8556/* Note that this requires a 16 bit source image but produces 8 bit output, so
8557 * we only need the 16bit write support, but the 16 bit images are only 8557 * we only need the 16bit write support, but the 16 bit images are only
8558 * generated if DO_16BIT is defined. 8558 * generated if DO_16BIT is defined.
8559 */ 8559 */
8560#ifdef DO_16BIT 8560#ifdef DO_16BIT
8561static void perform_gamma_scale16_tests(png_modifier *pm) 8561static void perform_gamma_scale16_tests(png_modifier *pm)
8562{ 8562{
8563# ifndef PNG_MAX_GAMMA_8 8563# ifndef PNG_MAX_GAMMA_8
8564# define PNG_MAX_GAMMA_8 11 8564# define PNG_MAX_GAMMA_8 11
8565# endif 8565# endif
8566 /* Include the alpha cases here. Note that sbit matches the internal value 8566 /* Include the alpha cases here. Note that sbit matches the internal value
8567 * used by the library - otherwise we will get spurious errors from the 8567 * used by the library - otherwise we will get spurious errors from the
8568 * internal sbit style approximation. 8568 * internal sbit style approximation.
8569 * 8569 *
8570 * The threshold test is here because otherwise the 16 to 8 conversion will 8570 * The threshold test is here because otherwise the 16 to 8 conversion will
8571 * proceed *without* gamma correction, and the tests above will fail (but not 8571 * proceed *without* gamma correction, and the tests above will fail (but not
8572 * by much) - this could be fixed, it only appears with the -g option. 8572 * by much) - this could be fixed, it only appears with the -g option.
8573 */ 8573 */
8574 unsigned int i, j; 8574 unsigned int i, j;
8575 for (i=0; i<pm->ngamma_tests; ++i) 8575 for (i=0; i<pm->ngamma_tests; ++i)
8576 { 8576 {
8577 for (j=0; j<pm->ngamma_tests; ++j) 8577 for (j=0; j<pm->ngamma_tests; ++j)
8578 { 8578 {
8579 if (i != j && 8579 if (i != j &&
8580 fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD) 8580 fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD)
8581 { 8581 {
8582 gamma_transform_test(pm, 0, 16, 0, pm->interlace_type, 8582 gamma_transform_test(pm, 0, 16, 0, pm->interlace_type,
8583 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8, 8583 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8,
8584 pm->use_input_precision_16to8, 1 /*scale16*/); 8584 pm->use_input_precision_16to8, 1 /*scale16*/);
8585 8585
8586 if (fail(pm)) 8586 if (fail(pm))
8587 return; 8587 return;
8588 8588
8589 gamma_transform_test(pm, 2, 16, 0, pm->interlace_type, 8589 gamma_transform_test(pm, 2, 16, 0, pm->interlace_type,
8590 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8, 8590 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8,
8591 pm->use_input_precision_16to8, 1 /*scale16*/); 8591 pm->use_input_precision_16to8, 1 /*scale16*/);
8592 8592
8593 if (fail(pm)) 8593 if (fail(pm))
8594 return; 8594 return;
8595 8595
8596 gamma_transform_test(pm, 4, 16, 0, pm->interlace_type, 8596 gamma_transform_test(pm, 4, 16, 0, pm->interlace_type,
8597 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8, 8597 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8,
8598 pm->use_input_precision_16to8, 1 /*scale16*/); 8598 pm->use_input_precision_16to8, 1 /*scale16*/);
8599 8599
8600 if (fail(pm)) 8600 if (fail(pm))
8601 return; 8601 return;
8602 8602
8603 gamma_transform_test(pm, 6, 16, 0, pm->interlace_type, 8603 gamma_transform_test(pm, 6, 16, 0, pm->interlace_type,
8604 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8, 8604 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8,
8605 pm->use_input_precision_16to8, 1 /*scale16*/); 8605 pm->use_input_precision_16to8, 1 /*scale16*/);
8606 8606
8607 if (fail(pm)) 8607 if (fail(pm))
8608 return; 8608 return;
8609 } 8609 }
8610 } 8610 }
8611 } 8611 }
8612} 8612}
8613#endif /* 16 to 8 bit conversion */ 8613#endif /* 16 to 8 bit conversion */
8614 8614
8615#if defined PNG_READ_BACKGROUND_SUPPORTED ||\ 8615#if defined PNG_READ_BACKGROUND_SUPPORTED ||\
8616 defined PNG_READ_ALPHA_MODE_SUPPORTED 8616 defined PNG_READ_ALPHA_MODE_SUPPORTED
8617static void gamma_composition_test(png_modifier *pm, 8617static void gamma_composition_test(png_modifier *pm,
8618 PNG_CONST png_byte colour_type, PNG_CONST png_byte bit_depth, 8618 PNG_CONST png_byte colour_type, PNG_CONST png_byte bit_depth,
8619 PNG_CONST int palette_number, 8619 PNG_CONST int palette_number,
8620 PNG_CONST int interlace_type, PNG_CONST double file_gamma, 8620 PNG_CONST int interlace_type, PNG_CONST double file_gamma,
8621 PNG_CONST double screen_gamma, 8621 PNG_CONST double screen_gamma,
8622 PNG_CONST int use_input_precision, PNG_CONST int do_background, 8622 PNG_CONST int use_input_precision, PNG_CONST int do_background,
8623 PNG_CONST int expand_16) 8623 PNG_CONST int expand_16)
8624{ 8624{
8625 size_t pos = 0; 8625 size_t pos = 0;
8626 png_const_charp base; 8626 png_const_charp base;
8627 double bg; 8627 double bg;
8628 char name[128]; 8628 char name[128];
8629 png_color_16 background; 8629 png_color_16 background;
8630 8630
8631 /* Make up a name and get an appropriate background gamma value. */ 8631 /* Make up a name and get an appropriate background gamma value. */
8632 switch (do_background) 8632 switch (do_background)
8633 { 8633 {
8634 default: 8634 default:
8635 base = ""; 8635 base = "";
8636 bg = 4; /* should not be used */ 8636 bg = 4; /* should not be used */
8637 break; 8637 break;
8638 case PNG_BACKGROUND_GAMMA_SCREEN: 8638 case PNG_BACKGROUND_GAMMA_SCREEN:
8639 base = " bckg(Screen):"; 8639 base = " bckg(Screen):";
8640 bg = 1/screen_gamma; 8640 bg = 1/screen_gamma;
8641 break; 8641 break;
8642 case PNG_BACKGROUND_GAMMA_FILE: 8642 case PNG_BACKGROUND_GAMMA_FILE:
8643 base = " bckg(File):"; 8643 base = " bckg(File):";
8644 bg = file_gamma; 8644 bg = file_gamma;
8645 break; 8645 break;
8646 case PNG_BACKGROUND_GAMMA_UNIQUE: 8646 case PNG_BACKGROUND_GAMMA_UNIQUE:
8647 base = " bckg(Unique):"; 8647 base = " bckg(Unique):";
8648 /* This tests the handling of a unique value, the math is such that the 8648 /* This tests the handling of a unique value, the math is such that the
8649 * value tends to be <1, but is neither screen nor file (even if they 8649 * value tends to be <1, but is neither screen nor file (even if they
8650 * match!) 8650 * match!)
8651 */ 8651 */
8652 bg = (file_gamma + screen_gamma) / 3; 8652 bg = (file_gamma + screen_gamma) / 3;
8653 break; 8653 break;
8654#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 8654#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
8655 case ALPHA_MODE_OFFSET + PNG_ALPHA_PNG: 8655 case ALPHA_MODE_OFFSET + PNG_ALPHA_PNG:
8656 base = " alpha(PNG)"; 8656 base = " alpha(PNG)";
8657 bg = 4; /* should not be used */ 8657 bg = 4; /* should not be used */
8658 break; 8658 break;
8659 case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: 8659 case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
8660 base = " alpha(Porter-Duff)"; 8660 base = " alpha(Porter-Duff)";
8661 bg = 4; /* should not be used */ 8661 bg = 4; /* should not be used */
8662 break; 8662 break;
8663 case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: 8663 case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
8664 base = " alpha(Optimized)"; 8664 base = " alpha(Optimized)";
8665 bg = 4; /* should not be used */ 8665 bg = 4; /* should not be used */
8666 break; 8666 break;
8667 case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: 8667 case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
8668 base = " alpha(Broken)"; 8668 base = " alpha(Broken)";
8669 bg = 4; /* should not be used */ 8669 bg = 4; /* should not be used */
8670 break; 8670 break;
8671#endif 8671#endif
8672 } 8672 }
8673 8673
8674 /* Use random background values - the background is always presented in the 8674 /* Use random background values - the background is always presented in the
8675 * output space (8 or 16 bit components). 8675 * output space (8 or 16 bit components).
8676 */ 8676 */
8677 if (expand_16 || bit_depth == 16) 8677 if (expand_16 || bit_depth == 16)
8678 { 8678 {
8679 png_uint_32 r = random_32(); 8679 png_uint_32 r = random_32();
8680 8680
8681 background.red = (png_uint_16)r; 8681 background.red = (png_uint_16)r;
8682 background.green = (png_uint_16)(r >> 16); 8682 background.green = (png_uint_16)(r >> 16);
8683 r = random_32(); 8683 r = random_32();
8684 background.blue = (png_uint_16)r; 8684 background.blue = (png_uint_16)r;
8685 background.gray = (png_uint_16)(r >> 16); 8685 background.gray = (png_uint_16)(r >> 16);
8686 } 8686 }
8687 8687
8688 else /* 8 bit colors */ 8688 else /* 8 bit colors */
8689 { 8689 {
8690 png_uint_32 r = random_32(); 8690 png_uint_32 r = random_32();
8691 8691
8692 background.red = (png_byte)r; 8692 background.red = (png_byte)r;
8693 background.green = (png_byte)(r >> 8); 8693 background.green = (png_byte)(r >> 8);
8694 background.blue = (png_byte)(r >> 16); 8694 background.blue = (png_byte)(r >> 16);
8695 background.gray = (png_byte)(r >> 24); 8695 background.gray = (png_byte)(r >> 24);
8696 } 8696 }
8697 8697
8698 background.index = 193; /* rgb(193,193,193) to detect errors */ 8698 background.index = 193; /* rgb(193,193,193) to detect errors */
8699 if (!(colour_type & PNG_COLOR_MASK_COLOR)) 8699 if (!(colour_type & PNG_COLOR_MASK_COLOR))
8700 { 8700 {
8701 /* Grayscale input, we do not convert to RGB (TBD), so we must set the 8701 /* Grayscale input, we do not convert to RGB (TBD), so we must set the
8702 * background to gray - else libpng seems to fail. 8702 * background to gray - else libpng seems to fail.
8703 */ 8703 */
8704 background.red = background.green = background.blue = background.gray; 8704 background.red = background.green = background.blue = background.gray;
8705 } 8705 }
8706 8706
8707 pos = safecat(name, sizeof name, pos, "gamma "); 8707 pos = safecat(name, sizeof name, pos, "gamma ");
8708 pos = safecatd(name, sizeof name, pos, file_gamma, 3); 8708 pos = safecatd(name, sizeof name, pos, file_gamma, 3);
8709 pos = safecat(name, sizeof name, pos, "->"); 8709 pos = safecat(name, sizeof name, pos, "->");
8710 pos = safecatd(name, sizeof name, pos, screen_gamma, 3); 8710 pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
8711 8711
8712 pos = safecat(name, sizeof name, pos, base); 8712 pos = safecat(name, sizeof name, pos, base);
8713 if (do_background < ALPHA_MODE_OFFSET) 8713 if (do_background < ALPHA_MODE_OFFSET)
8714 { 8714 {
8715 /* Include the background color and gamma in the name: */ 8715 /* Include the background color and gamma in the name: */
8716 pos = safecat(name, sizeof name, pos, "("); 8716 pos = safecat(name, sizeof name, pos, "(");
8717 /* This assumes no expand gray->rgb - the current code won't handle that! 8717 /* This assumes no expand gray->rgb - the current code won't handle that!
8718 */ 8718 */
8719 if (colour_type & PNG_COLOR_MASK_COLOR) 8719 if (colour_type & PNG_COLOR_MASK_COLOR)
8720 { 8720 {
8721 pos = safecatn(name, sizeof name, pos, background.red); 8721 pos = safecatn(name, sizeof name, pos, background.red);
8722 pos = safecat(name, sizeof name, pos, ","); 8722 pos = safecat(name, sizeof name, pos, ",");
8723 pos = safecatn(name, sizeof name, pos, background.green); 8723 pos = safecatn(name, sizeof name, pos, background.green);
8724 pos = safecat(name, sizeof name, pos, ","); 8724 pos = safecat(name, sizeof name, pos, ",");
8725 pos = safecatn(name, sizeof name, pos, background.blue); 8725 pos = safecatn(name, sizeof name, pos, background.blue);
8726 } 8726 }
8727 else 8727 else
8728 pos = safecatn(name, sizeof name, pos, background.gray); 8728 pos = safecatn(name, sizeof name, pos, background.gray);
8729 pos = safecat(name, sizeof name, pos, ")^"); 8729 pos = safecat(name, sizeof name, pos, ")^");
8730 pos = safecatd(name, sizeof name, pos, bg, 3); 8730 pos = safecatd(name, sizeof name, pos, bg, 3);
8731 } 8731 }
8732 8732
8733 gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type, 8733 gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type,
8734 file_gamma, screen_gamma, 0/*sBIT*/, 0, name, use_input_precision, 8734 file_gamma, screen_gamma, 0/*sBIT*/, 0, name, use_input_precision,
8735 0/*strip 16*/, expand_16, do_background, &background, bg); 8735 0/*strip 16*/, expand_16, do_background, &background, bg);
8736} 8736}
8737 8737
8738 8738
8739static void 8739static void
8740perform_gamma_composition_tests(png_modifier *pm, int do_background, 8740perform_gamma_composition_tests(png_modifier *pm, int do_background,
8741 int expand_16) 8741 int expand_16)
8742{ 8742{
8743 png_byte colour_type = 0; 8743 png_byte colour_type = 0;
8744 png_byte bit_depth = 0; 8744 png_byte bit_depth = 0;
8745 int palette_number = 0; 8745 int palette_number = 0;
8746 8746
8747 /* Skip the non-alpha cases - there is no setting of a transparency colour at 8747 /* Skip the non-alpha cases - there is no setting of a transparency colour at
8748 * present. 8748 * present.
8749 */ 8749 */
8750 while (next_format(&colour_type, &bit_depth, &palette_number)) 8750 while (next_format(&colour_type, &bit_depth, &palette_number))
8751 if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0) 8751 if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0)
8752 { 8752 {
8753 unsigned int i, j; 8753 unsigned int i, j;
8754 8754
8755 /* Don't skip the i==j case here - it's relevant. */ 8755 /* Don't skip the i==j case here - it's relevant. */
8756 for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j) 8756 for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)
8757 { 8757 {
8758 gamma_composition_test(pm, colour_type, bit_depth, palette_number, 8758 gamma_composition_test(pm, colour_type, bit_depth, palette_number,
8759 pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 8759 pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
8760 pm->use_input_precision, do_background, expand_16); 8760 pm->use_input_precision, do_background, expand_16);
8761 8761
8762 if (fail(pm)) 8762 if (fail(pm))
8763 return; 8763 return;
8764 } 8764 }
8765 } 8765 }
8766} 8766}
8767#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ 8767#endif /* READ_BACKGROUND || READ_ALPHA_MODE */
8768 8768
8769static void 8769static void
8770init_gamma_errors(png_modifier *pm) 8770init_gamma_errors(png_modifier *pm)
8771{ 8771{
8772 pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0; 8772 pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;
8773 pm->error_color_8 = 0; 8773 pm->error_color_8 = 0;
8774 pm->error_indexed = 0; 8774 pm->error_indexed = 0;
8775 pm->error_gray_16 = pm->error_color_16 = 0; 8775 pm->error_gray_16 = pm->error_color_16 = 0;
8776} 8776}
8777 8777
8778static void 8778static void
8779summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth) 8779summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth)
8780{ 8780{
8781 if (who) 8781 if (who)
8782 printf("Gamma correction with %s:\n", who); 8782 printf("Gamma correction with %s:\n", who);
8783 8783
8784 if (low_bit_depth) 8784 if (low_bit_depth)
8785 { 8785 {
8786 printf(" 2 bit gray: %.5f\n", pm->error_gray_2); 8786 printf(" 2 bit gray: %.5f\n", pm->error_gray_2);
8787 printf(" 4 bit gray: %.5f\n", pm->error_gray_4); 8787 printf(" 4 bit gray: %.5f\n", pm->error_gray_4);
8788 printf(" 8 bit gray: %.5f\n", pm->error_gray_8); 8788 printf(" 8 bit gray: %.5f\n", pm->error_gray_8);
8789 printf(" 8 bit color: %.5f\n", pm->error_color_8); 8789 printf(" 8 bit color: %.5f\n", pm->error_color_8);
8790 printf(" indexed: %.5f\n", pm->error_indexed); 8790 printf(" indexed: %.5f\n", pm->error_indexed);
8791 } 8791 }
8792 8792
8793#ifdef DO_16BIT 8793#ifdef DO_16BIT
8794 printf(" 16 bit gray: %.5f\n", pm->error_gray_16); 8794 printf(" 16 bit gray: %.5f\n", pm->error_gray_16);
8795 printf(" 16 bit color: %.5f\n", pm->error_color_16); 8795 printf(" 16 bit color: %.5f\n", pm->error_color_16);
8796#endif 8796#endif
8797} 8797}
8798 8798
8799static void 8799static void
8800perform_gamma_test(png_modifier *pm, int summary) 8800perform_gamma_test(png_modifier *pm, int summary)
8801{ 8801{
8802 /*TODO: remove this*/ 8802 /*TODO: remove this*/
8803 /* Save certain values for the temporary overrides below. */ 8803 /* Save certain values for the temporary overrides below. */
8804 unsigned int calculations_use_input_precision = 8804 unsigned int calculations_use_input_precision =
8805 pm->calculations_use_input_precision; 8805 pm->calculations_use_input_precision;
8806 double maxout8 = pm->maxout8; 8806 double maxout8 = pm->maxout8;
8807 8807
8808 /* First some arbitrary no-transform tests: */ 8808 /* First some arbitrary no-transform tests: */
8809 if (!pm->this.speed && pm->test_gamma_threshold) 8809 if (!pm->this.speed && pm->test_gamma_threshold)
8810 { 8810 {
8811 perform_gamma_threshold_tests(pm); 8811 perform_gamma_threshold_tests(pm);
8812 8812
8813 if (fail(pm)) 8813 if (fail(pm))
8814 return; 8814 return;
8815 } 8815 }
8816 8816
8817 /* Now some real transforms. */ 8817 /* Now some real transforms. */
8818 if (pm->test_gamma_transform) 8818 if (pm->test_gamma_transform)
8819 { 8819 {
8820 init_gamma_errors(pm); 8820 init_gamma_errors(pm);
8821 /*TODO: remove this. Necessary because the current libpng 8821 /*TODO: remove this. Necessary because the current libpng
8822 * implementation works in 8 bits: 8822 * implementation works in 8 bits:
8823 */ 8823 */
8824 if (pm->test_gamma_expand16) 8824 if (pm->test_gamma_expand16)
8825 pm->calculations_use_input_precision = 1; 8825 pm->calculations_use_input_precision = 1;
8826 perform_gamma_transform_tests(pm); 8826 perform_gamma_transform_tests(pm);
8827 if (!calculations_use_input_precision) 8827 if (!calculations_use_input_precision)
8828 pm->calculations_use_input_precision = 0; 8828 pm->calculations_use_input_precision = 0;
8829 8829
8830 if (summary) 8830 if (summary)
8831 { 8831 {
8832 printf("Gamma correction error summary\n\n"); 8832 printf("Gamma correction error summary\n\n");
8833 printf("The printed value is the maximum error in the pixel values\n"); 8833 printf("The printed value is the maximum error in the pixel values\n");
8834 printf("calculated by the libpng gamma correction code. The error\n"); 8834 printf("calculated by the libpng gamma correction code. The error\n");
8835 printf("is calculated as the difference between the output pixel\n"); 8835 printf("is calculated as the difference between the output pixel\n");
8836 printf("value (always an integer) and the ideal value from the\n"); 8836 printf("value (always an integer) and the ideal value from the\n");
8837 printf("libpng specification (typically not an integer).\n\n"); 8837 printf("libpng specification (typically not an integer).\n\n");
8838 8838
8839 printf("Expect this value to be less than .5 for 8 bit formats,\n"); 8839 printf("Expect this value to be less than .5 for 8 bit formats,\n");
8840 printf("less than 1 for formats with fewer than 8 bits and a small\n"); 8840 printf("less than 1 for formats with fewer than 8 bits and a small\n");
8841 printf("number (typically less than 5) for the 16 bit formats.\n"); 8841 printf("number (typically less than 5) for the 16 bit formats.\n");
8842 printf("For performance reasons the value for 16 bit formats\n"); 8842 printf("For performance reasons the value for 16 bit formats\n");
8843 printf("increases when the image file includes an sBIT chunk.\n\n"); 8843 printf("increases when the image file includes an sBIT chunk.\n\n");
8844 8844
8845 summarize_gamma_errors(pm, 0/*who*/, 1); 8845 summarize_gamma_errors(pm, 0/*who*/, 1);
8846 } 8846 }
8847 } 8847 }
8848 8848
8849 /* The sbit tests produce much larger errors: */ 8849 /* The sbit tests produce much larger errors: */
8850 if (pm->test_gamma_sbit) 8850 if (pm->test_gamma_sbit)
8851 { 8851 {
8852 init_gamma_errors(pm); 8852 init_gamma_errors(pm);
8853 perform_gamma_sbit_tests(pm); 8853 perform_gamma_sbit_tests(pm);
8854 8854
8855 if (summary) 8855 if (summary)
8856 summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U); 8856 summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U);
8857 } 8857 }
8858 8858
8859#ifdef DO_16BIT /* Should be READ_16BIT_SUPPORTED */ 8859#ifdef DO_16BIT /* Should be READ_16BIT_SUPPORTED */
8860 if (pm->test_gamma_scale16) 8860 if (pm->test_gamma_scale16)
8861 { 8861 {
8862 /* The 16 to 8 bit strip operations: */ 8862 /* The 16 to 8 bit strip operations: */
8863 init_gamma_errors(pm); 8863 init_gamma_errors(pm);
8864 perform_gamma_scale16_tests(pm); 8864 perform_gamma_scale16_tests(pm);
8865 8865
8866 if (summary) 8866 if (summary)
8867 { 8867 {
8868 printf("Gamma correction with 16 to 8 bit reduction:\n"); 8868 printf("Gamma correction with 16 to 8 bit reduction:\n");
8869 printf(" 16 bit gray: %.5f\n", pm->error_gray_16); 8869 printf(" 16 bit gray: %.5f\n", pm->error_gray_16);
8870 printf(" 16 bit color: %.5f\n", pm->error_color_16); 8870 printf(" 16 bit color: %.5f\n", pm->error_color_16);
8871 } 8871 }
8872 } 8872 }
8873#endif 8873#endif
8874 8874
8875#ifdef PNG_READ_BACKGROUND_SUPPORTED 8875#ifdef PNG_READ_BACKGROUND_SUPPORTED
8876 if (pm->test_gamma_background) 8876 if (pm->test_gamma_background)
8877 { 8877 {
8878 init_gamma_errors(pm); 8878 init_gamma_errors(pm);
8879 8879
8880 /*TODO: remove this. Necessary because the current libpng 8880 /*TODO: remove this. Necessary because the current libpng
8881 * implementation works in 8 bits: 8881 * implementation works in 8 bits:
8882 */ 8882 */
8883 if (pm->test_gamma_expand16) 8883 if (pm->test_gamma_expand16)
8884 { 8884 {
8885 pm->calculations_use_input_precision = 1; 8885 pm->calculations_use_input_precision = 1;
8886 pm->maxout8 = .499; /* because the 16 bit background is smashed */ 8886 pm->maxout8 = .499; /* because the 16 bit background is smashed */
8887 } 8887 }
8888 perform_gamma_composition_tests(pm, PNG_BACKGROUND_GAMMA_UNIQUE, 8888 perform_gamma_composition_tests(pm, PNG_BACKGROUND_GAMMA_UNIQUE,
8889 pm->test_gamma_expand16); 8889 pm->test_gamma_expand16);
8890 if (!calculations_use_input_precision) 8890 if (!calculations_use_input_precision)
8891 pm->calculations_use_input_precision = 0; 8891 pm->calculations_use_input_precision = 0;
8892 pm->maxout8 = maxout8; 8892 pm->maxout8 = maxout8;
8893 8893
8894 if (summary) 8894 if (summary)
8895 summarize_gamma_errors(pm, "background", 1); 8895 summarize_gamma_errors(pm, "background", 1);
8896 } 8896 }
8897#endif 8897#endif
8898 8898
8899#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 8899#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
8900 if (pm->test_gamma_alpha_mode) 8900 if (pm->test_gamma_alpha_mode)
8901 { 8901 {
8902 int do_background; 8902 int do_background;
8903 8903
8904 init_gamma_errors(pm); 8904 init_gamma_errors(pm);
8905 8905
8906 /*TODO: remove this. Necessary because the current libpng 8906 /*TODO: remove this. Necessary because the current libpng
8907 * implementation works in 8 bits: 8907 * implementation works in 8 bits:
8908 */ 8908 */
8909 if (pm->test_gamma_expand16) 8909 if (pm->test_gamma_expand16)
8910 pm->calculations_use_input_precision = 1; 8910 pm->calculations_use_input_precision = 1;
8911 for (do_background = ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD; 8911 for (do_background = ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD;
8912 do_background <= ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN && !fail(pm); 8912 do_background <= ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN && !fail(pm);
8913 ++do_background) 8913 ++do_background)
8914 perform_gamma_composition_tests(pm, do_background, 8914 perform_gamma_composition_tests(pm, do_background,
8915 pm->test_gamma_expand16); 8915 pm->test_gamma_expand16);
8916 if (!calculations_use_input_precision) 8916 if (!calculations_use_input_precision)
8917 pm->calculations_use_input_precision = 0; 8917 pm->calculations_use_input_precision = 0;
8918 8918
8919 if (summary) 8919 if (summary)
8920 summarize_gamma_errors(pm, "alpha mode", 1); 8920 summarize_gamma_errors(pm, "alpha mode", 1);
8921 } 8921 }
8922#endif 8922#endif
8923} 8923}
8924#endif /* PNG_READ_GAMMA_SUPPORTED */ 8924#endif /* PNG_READ_GAMMA_SUPPORTED */
8925 8925
8926/* INTERLACE MACRO VALIDATION */ 8926/* INTERLACE MACRO VALIDATION */
8927/* This is copied verbatim from the specification, it is simply the pass 8927/* This is copied verbatim from the specification, it is simply the pass
8928 * number in which each pixel in each 8x8 tile appears. The array must 8928 * number in which each pixel in each 8x8 tile appears. The array must
8929 * be indexed adam7[y][x] and notice that the pass numbers are based at 8929 * be indexed adam7[y][x] and notice that the pass numbers are based at
8930 * 1, not 0 - the base libpng uses. 8930 * 1, not 0 - the base libpng uses.
8931 */ 8931 */
8932static PNG_CONST 8932static PNG_CONST
8933png_byte adam7[8][8] = 8933png_byte adam7[8][8] =
8934{ 8934{
8935 { 1,6,4,6,2,6,4,6 }, 8935 { 1,6,4,6,2,6,4,6 },
8936 { 7,7,7,7,7,7,7,7 }, 8936 { 7,7,7,7,7,7,7,7 },
8937 { 5,6,5,6,5,6,5,6 }, 8937 { 5,6,5,6,5,6,5,6 },
8938 { 7,7,7,7,7,7,7,7 }, 8938 { 7,7,7,7,7,7,7,7 },
8939 { 3,6,4,6,3,6,4,6 }, 8939 { 3,6,4,6,3,6,4,6 },
8940 { 7,7,7,7,7,7,7,7 }, 8940 { 7,7,7,7,7,7,7,7 },
8941 { 5,6,5,6,5,6,5,6 }, 8941 { 5,6,5,6,5,6,5,6 },
8942 { 7,7,7,7,7,7,7,7 } 8942 { 7,7,7,7,7,7,7,7 }
8943}; 8943};
8944 8944
8945/* This routine validates all the interlace support macros in png.h for 8945/* This routine validates all the interlace support macros in png.h for
8946 * a variety of valid PNG widths and heights. It uses a number of similarly 8946 * a variety of valid PNG widths and heights. It uses a number of similarly
8947 * named internal routines that feed off the above array. 8947 * named internal routines that feed off the above array.
8948 */ 8948 */
8949static png_uint_32 8949static png_uint_32
8950png_pass_start_row(int pass) 8950png_pass_start_row(int pass)
8951{ 8951{
8952 int x, y; 8952 int x, y;
8953 ++pass; 8953 ++pass;
8954 for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) 8954 for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
8955 return y; 8955 return y;
8956 return 0xf; 8956 return 0xf;
8957} 8957}
8958 8958
8959static png_uint_32 8959static png_uint_32
8960png_pass_start_col(int pass) 8960png_pass_start_col(int pass)
8961{ 8961{
8962 int x, y; 8962 int x, y;
8963 ++pass; 8963 ++pass;
8964 for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) 8964 for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
8965 return x; 8965 return x;
8966 return 0xf; 8966 return 0xf;
8967} 8967}
8968 8968
8969static int 8969static int
8970png_pass_row_shift(int pass) 8970png_pass_row_shift(int pass)
8971{ 8971{
8972 int x, y, base=(-1), inc=8; 8972 int x, y, base=(-1), inc=8;
8973 ++pass; 8973 ++pass;
8974 for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) 8974 for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
8975 { 8975 {
8976 if (base == (-1)) 8976 if (base == (-1))
8977 base = y; 8977 base = y;
8978 else if (base == y) 8978 else if (base == y)
8979 {} 8979 {}
8980 else if (inc == y-base) 8980 else if (inc == y-base)
8981 base=y; 8981 base=y;
8982 else if (inc == 8) 8982 else if (inc == 8)
8983 inc = y-base, base=y; 8983 inc = y-base, base=y;
8984 else if (inc != y-base) 8984 else if (inc != y-base)
8985 return 0xff; /* error - more than one 'inc' value! */ 8985 return 0xff; /* error - more than one 'inc' value! */
8986 } 8986 }
8987 8987
8988 if (base == (-1)) return 0xfe; /* error - no row in pass! */ 8988 if (base == (-1)) return 0xfe; /* error - no row in pass! */
8989 8989
8990 /* The shift is always 1, 2 or 3 - no pass has all the rows! */ 8990 /* The shift is always 1, 2 or 3 - no pass has all the rows! */
8991 switch (inc) 8991 switch (inc)
8992 { 8992 {
8993case 2: return 1; 8993case 2: return 1;
8994case 4: return 2; 8994case 4: return 2;
8995case 8: return 3; 8995case 8: return 3;
8996default: break; 8996default: break;
8997 } 8997 }
8998 8998
8999 /* error - unrecognized 'inc' */ 8999 /* error - unrecognized 'inc' */
9000 return (inc << 8) + 0xfd; 9000 return (inc << 8) + 0xfd;
9001} 9001}
9002 9002
9003static int 9003static int
9004png_pass_col_shift(int pass) 9004png_pass_col_shift(int pass)
9005{ 9005{
9006 int x, y, base=(-1), inc=8; 9006 int x, y, base=(-1), inc=8;
9007 ++pass; 9007 ++pass;
9008 for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) 9008 for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
9009 { 9009 {
9010 if (base == (-1)) 9010 if (base == (-1))
9011 base = x; 9011 base = x;
9012 else if (base == x) 9012 else if (base == x)
9013 {} 9013 {}
9014 else if (inc == x-base) 9014 else if (inc == x-base)
9015 base=x; 9015 base=x;
9016 else if (inc == 8) 9016 else if (inc == 8)
9017 inc = x-base, base=x; 9017 inc = x-base, base=x;
9018 else if (inc != x-base) 9018 else if (inc != x-base)
9019 return 0xff; /* error - more than one 'inc' value! */ 9019 return 0xff; /* error - more than one 'inc' value! */
9020 } 9020 }
9021 9021
9022 if (base == (-1)) return 0xfe; /* error - no row in pass! */ 9022 if (base == (-1)) return 0xfe; /* error - no row in pass! */
9023 9023
9024 /* The shift is always 1, 2 or 3 - no pass has all the rows! */ 9024 /* The shift is always 1, 2 or 3 - no pass has all the rows! */
9025 switch (inc) 9025 switch (inc)
9026 { 9026 {
9027case 1: return 0; /* pass 7 has all the columns */ 9027case 1: return 0; /* pass 7 has all the columns */
9028case 2: return 1; 9028case 2: return 1;
9029case 4: return 2; 9029case 4: return 2;
9030case 8: return 3; 9030case 8: return 3;
9031default: break; 9031default: break;
9032 } 9032 }
9033 9033
9034 /* error - unrecognized 'inc' */ 9034 /* error - unrecognized 'inc' */
9035 return (inc << 8) + 0xfd; 9035 return (inc << 8) + 0xfd;
9036} 9036}
9037 9037
9038static png_uint_32 9038static png_uint_32
9039png_row_from_pass_row(png_uint_32 yIn, int pass) 9039png_row_from_pass_row(png_uint_32 yIn, int pass)
9040{ 9040{
9041 /* By examination of the array: */ 9041 /* By examination of the array: */
9042 switch (pass) 9042 switch (pass)
9043 { 9043 {
9044case 0: return yIn * 8; 9044case 0: return yIn * 8;
9045case 1: return yIn * 8; 9045case 1: return yIn * 8;
9046case 2: return yIn * 8 + 4; 9046case 2: return yIn * 8 + 4;
9047case 3: return yIn * 4; 9047case 3: return yIn * 4;
9048case 4: return yIn * 4 + 2; 9048case 4: return yIn * 4 + 2;
9049case 5: return yIn * 2; 9049case 5: return yIn * 2;
9050case 6: return yIn * 2 + 1; 9050case 6: return yIn * 2 + 1;
9051default: break; 9051default: break;
9052 } 9052 }
9053 9053
9054 return 0xff; /* bad pass number */ 9054 return 0xff; /* bad pass number */
9055} 9055}
9056 9056
9057static png_uint_32 9057static png_uint_32
9058png_col_from_pass_col(png_uint_32 xIn, int pass) 9058png_col_from_pass_col(png_uint_32 xIn, int pass)
9059{ 9059{
9060 /* By examination of the array: */ 9060 /* By examination of the array: */
9061 switch (pass) 9061 switch (pass)
9062 { 9062 {
9063case 0: return xIn * 8; 9063case 0: return xIn * 8;
9064case 1: return xIn * 8 + 4; 9064case 1: return xIn * 8 + 4;
9065case 2: return xIn * 4; 9065case 2: return xIn * 4;
9066case 3: return xIn * 4 + 2; 9066case 3: return xIn * 4 + 2;
9067case 4: return xIn * 2; 9067case 4: return xIn * 2;
9068case 5: return xIn * 2 + 1; 9068case 5: return xIn * 2 + 1;
9069case 6: return xIn; 9069case 6: return xIn;
9070default: break; 9070default: break;
9071 } 9071 }
9072 9072
9073 return 0xff; /* bad pass number */ 9073 return 0xff; /* bad pass number */
9074} 9074}
9075 9075
9076static int 9076static int
9077png_row_in_interlace_pass(png_uint_32 y, int pass) 9077png_row_in_interlace_pass(png_uint_32 y, int pass)
9078{ 9078{
9079 /* Is row 'y' in pass 'pass'? */ 9079 /* Is row 'y' in pass 'pass'? */
9080 int x; 9080 int x;
9081 y &= 7; 9081 y &= 7;
9082 ++pass; 9082 ++pass;
9083 for (x=0; x<8; ++x) if (adam7[y][x] == pass) 9083 for (x=0; x<8; ++x) if (adam7[y][x] == pass)
9084 return 1; 9084 return 1;
9085 9085
9086 return 0; 9086 return 0;
9087} 9087}
9088 9088
9089static int 9089static int
9090png_col_in_interlace_pass(png_uint_32 x, int pass) 9090png_col_in_interlace_pass(png_uint_32 x, int pass)
9091{ 9091{
9092 /* Is column 'x' in pass 'pass'? */ 9092 /* Is column 'x' in pass 'pass'? */
9093 int y; 9093 int y;
9094 x &= 7; 9094 x &= 7;
9095 ++pass; 9095 ++pass;
9096 for (y=0; y<8; ++y) if (adam7[y][x] == pass) 9096 for (y=0; y<8; ++y) if (adam7[y][x] == pass)
9097 return 1; 9097 return 1;
9098 9098
9099 return 0; 9099 return 0;
9100} 9100}
9101 9101
9102static png_uint_32 9102static png_uint_32
9103png_pass_rows(png_uint_32 height, int pass) 9103png_pass_rows(png_uint_32 height, int pass)
9104{ 9104{
9105 png_uint_32 tiles = height>>3; 9105 png_uint_32 tiles = height>>3;
9106 png_uint_32 rows = 0; 9106 png_uint_32 rows = 0;
9107 unsigned int x, y; 9107 unsigned int x, y;
9108 9108
9109 height &= 7; 9109 height &= 7;
9110 ++pass; 9110 ++pass;
9111 for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) 9111 for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
9112 { 9112 {
9113 rows += tiles; 9113 rows += tiles;
9114 if (y < height) ++rows; 9114 if (y < height) ++rows;
9115 break; /* i.e. break the 'x', column, loop. */ 9115 break; /* i.e. break the 'x', column, loop. */
9116 } 9116 }
9117 9117
9118 return rows; 9118 return rows;
9119} 9119}
9120 9120
9121static png_uint_32 9121static png_uint_32
9122png_pass_cols(png_uint_32 width, int pass) 9122png_pass_cols(png_uint_32 width, int pass)
9123{ 9123{
9124 png_uint_32 tiles = width>>3; 9124 png_uint_32 tiles = width>>3;
9125 png_uint_32 cols = 0; 9125 png_uint_32 cols = 0;
9126 unsigned int x, y; 9126 unsigned int x, y;
9127 9127
9128 width &= 7; 9128 width &= 7;
9129 ++pass; 9129 ++pass;
9130 for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) 9130 for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
9131 { 9131 {
9132 cols += tiles; 9132 cols += tiles;
9133 if (x < width) ++cols; 9133 if (x < width) ++cols;
9134 break; /* i.e. break the 'y', row, loop. */ 9134 break; /* i.e. break the 'y', row, loop. */
9135 } 9135 }
9136 9136
9137 return cols; 9137 return cols;
9138} 9138}
9139 9139
9140static void 9140static void
9141perform_interlace_macro_validation(void) 9141perform_interlace_macro_validation(void)
9142{ 9142{
9143 /* The macros to validate, first those that depend only on pass: 9143 /* The macros to validate, first those that depend only on pass:
9144 * 9144 *
9145 * PNG_PASS_START_ROW(pass) 9145 * PNG_PASS_START_ROW(pass)
9146 * PNG_PASS_START_COL(pass) 9146 * PNG_PASS_START_COL(pass)
9147 * PNG_PASS_ROW_SHIFT(pass) 9147 * PNG_PASS_ROW_SHIFT(pass)
9148 * PNG_PASS_COL_SHIFT(pass) 9148 * PNG_PASS_COL_SHIFT(pass)
9149 */ 9149 */
9150 int pass; 9150 int pass;
9151 9151
9152 for (pass=0; pass<7; ++pass) 9152 for (pass=0; pass<7; ++pass)
9153 { 9153 {
9154 png_uint_32 m, f, v; 9154 png_uint_32 m, f, v;
9155 9155
9156 m = PNG_PASS_START_ROW(pass); 9156 m = PNG_PASS_START_ROW(pass);
9157 f = png_pass_start_row(pass); 9157 f = png_pass_start_row(pass);
9158 if (m != f) 9158 if (m != f)
9159 { 9159 {
9160 fprintf(stderr, "PNG_PASS_START_ROW(%d) = %u != %x\n", pass, m, f); 9160 fprintf(stderr, "PNG_PASS_START_ROW(%d) = %u != %x\n", pass, m, f);
9161 exit(1); 9161 exit(1);
9162 } 9162 }
9163 9163
9164 m = PNG_PASS_START_COL(pass); 9164 m = PNG_PASS_START_COL(pass);
9165 f = png_pass_start_col(pass); 9165 f = png_pass_start_col(pass);
9166 if (m != f) 9166 if (m != f)
9167 { 9167 {
9168 fprintf(stderr, "PNG_PASS_START_COL(%d) = %u != %x\n", pass, m, f); 9168 fprintf(stderr, "PNG_PASS_START_COL(%d) = %u != %x\n", pass, m, f);
9169 exit(1); 9169 exit(1);
9170 } 9170 }
9171 9171
9172 m = PNG_PASS_ROW_SHIFT(pass); 9172 m = PNG_PASS_ROW_SHIFT(pass);
9173 f = png_pass_row_shift(pass); 9173 f = png_pass_row_shift(pass);
9174 if (m != f) 9174 if (m != f)
9175 { 9175 {
9176 fprintf(stderr, "PNG_PASS_ROW_SHIFT(%d) = %u != %x\n", pass, m, f); 9176 fprintf(stderr, "PNG_PASS_ROW_SHIFT(%d) = %u != %x\n", pass, m, f);
9177 exit(1); 9177 exit(1);
9178 } 9178 }
9179 9179
9180 m = PNG_PASS_COL_SHIFT(pass); 9180 m = PNG_PASS_COL_SHIFT(pass);
9181 f = png_pass_col_shift(pass); 9181 f = png_pass_col_shift(pass);
9182 if (m != f) 9182 if (m != f)
9183 { 9183 {
9184 fprintf(stderr, "PNG_PASS_COL_SHIFT(%d) = %u != %x\n", pass, m, f); 9184 fprintf(stderr, "PNG_PASS_COL_SHIFT(%d) = %u != %x\n", pass, m, f);
9185 exit(1); 9185 exit(1);
9186 } 9186 }
9187 9187
9188 /* Macros that depend on the image or sub-image height too: 9188 /* Macros that depend on the image or sub-image height too:
9189 * 9189 *
9190 * PNG_PASS_ROWS(height, pass) 9190 * PNG_PASS_ROWS(height, pass)
9191 * PNG_PASS_COLS(width, pass) 9191 * PNG_PASS_COLS(width, pass)
9192 * PNG_ROW_FROM_PASS_ROW(yIn, pass) 9192 * PNG_ROW_FROM_PASS_ROW(yIn, pass)
9193 * PNG_COL_FROM_PASS_COL(xIn, pass) 9193 * PNG_COL_FROM_PASS_COL(xIn, pass)
9194 * PNG_ROW_IN_INTERLACE_PASS(y, pass) 9194 * PNG_ROW_IN_INTERLACE_PASS(y, pass)
9195 * PNG_COL_IN_INTERLACE_PASS(x, pass) 9195 * PNG_COL_IN_INTERLACE_PASS(x, pass)
9196 */ 9196 */
9197 for (v=0;;) 9197 for (v=0;;)
9198 { 9198 {
9199 /* First the base 0 stuff: */ 9199 /* First the base 0 stuff: */
9200 m = PNG_ROW_FROM_PASS_ROW(v, pass); 9200 m = PNG_ROW_FROM_PASS_ROW(v, pass);
9201 f = png_row_from_pass_row(v, pass); 9201 f = png_row_from_pass_row(v, pass);
9202 if (m != f) 9202 if (m != f)
9203 { 9203 {
9204 fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n", 9204 fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n",
9205 v, pass, m, f); 9205 v, pass, m, f);
9206 exit(1); 9206 exit(1);
9207 } 9207 }
9208 9208
9209 m = PNG_COL_FROM_PASS_COL(v, pass); 9209 m = PNG_COL_FROM_PASS_COL(v, pass);
9210 f = png_col_from_pass_col(v, pass); 9210 f = png_col_from_pass_col(v, pass);
9211 if (m != f) 9211 if (m != f)
9212 { 9212 {
9213 fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n", 9213 fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n",
9214 v, pass, m, f); 9214 v, pass, m, f);
9215 exit(1); 9215 exit(1);
9216 } 9216 }
9217 9217
9218 m = PNG_ROW_IN_INTERLACE_PASS(v, pass); 9218 m = PNG_ROW_IN_INTERLACE_PASS(v, pass);
9219 f = png_row_in_interlace_pass(v, pass); 9219 f = png_row_in_interlace_pass(v, pass);
9220 if (m != f) 9220 if (m != f)
9221 { 9221 {
9222 fprintf(stderr, "PNG_ROW_IN_INTERLACE_PASS(%u, %d) = %u != %x\n", 9222 fprintf(stderr, "PNG_ROW_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
9223 v, pass, m, f); 9223 v, pass, m, f);
9224 exit(1); 9224 exit(1);
9225 } 9225 }
9226 9226
9227 m = PNG_COL_IN_INTERLACE_PASS(v, pass); 9227 m = PNG_COL_IN_INTERLACE_PASS(v, pass);
9228 f = png_col_in_interlace_pass(v, pass); 9228 f = png_col_in_interlace_pass(v, pass);
9229 if (m != f) 9229 if (m != f)
9230 { 9230 {
9231 fprintf(stderr, "PNG_COL_IN_INTERLACE_PASS(%u, %d) = %u != %x\n", 9231 fprintf(stderr, "PNG_COL_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
9232 v, pass, m, f); 9232 v, pass, m, f);
9233 exit(1); 9233 exit(1);
9234 } 9234 }
9235 9235
9236 /* Then the base 1 stuff: */ 9236 /* Then the base 1 stuff: */
9237 ++v; 9237 ++v;
9238 m = PNG_PASS_ROWS(v, pass); 9238 m = PNG_PASS_ROWS(v, pass);
9239 f = png_pass_rows(v, pass); 9239 f = png_pass_rows(v, pass);
9240 if (m != f) 9240 if (m != f)
9241 { 9241 {
9242 fprintf(stderr, "PNG_PASS_ROWS(%u, %d) = %u != %x\n", 9242 fprintf(stderr, "PNG_PASS_ROWS(%u, %d) = %u != %x\n",
9243 v, pass, m, f); 9243 v, pass, m, f);
9244 exit(1); 9244 exit(1);
9245 } 9245 }
9246 9246
9247 m = PNG_PASS_COLS(v, pass); 9247 m = PNG_PASS_COLS(v, pass);
9248 f = png_pass_cols(v, pass); 9248 f = png_pass_cols(v, pass);
9249 if (m != f) 9249 if (m != f)
9250 { 9250 {
9251 fprintf(stderr, "PNG_PASS_COLS(%u, %d) = %u != %x\n", 9251 fprintf(stderr, "PNG_PASS_COLS(%u, %d) = %u != %x\n",
9252 v, pass, m, f); 9252 v, pass, m, f);
9253 exit(1); 9253 exit(1);
9254 } 9254 }
9255 9255
9256 /* Move to the next v - the stepping algorithm starts skipping 9256 /* Move to the next v - the stepping algorithm starts skipping
9257 * values above 1024. 9257 * values above 1024.
9258 */ 9258 */
9259 if (v > 1024) 9259 if (v > 1024)
9260 { 9260 {
9261 if (v == PNG_UINT_31_MAX) 9261 if (v == PNG_UINT_31_MAX)
9262 break; 9262 break;
9263 9263
9264 v = (v << 1) ^ v; 9264 v = (v << 1) ^ v;
9265 if (v >= PNG_UINT_31_MAX) 9265 if (v >= PNG_UINT_31_MAX)
9266 v = PNG_UINT_31_MAX-1; 9266 v = PNG_UINT_31_MAX-1;
9267 } 9267 }
9268 } 9268 }
9269 } 9269 }
9270} 9270}
9271 9271
9272/* Test color encodings. These values are back-calculated from the published 9272/* Test color encodings. These values are back-calculated from the published
9273 * chromaticities. The values are accurate to about 14 decimal places; 15 are 9273 * chromaticities. The values are accurate to about 14 decimal places; 15 are
9274 * given. These values are much more accurate than the ones given in the spec, 9274 * given. These values are much more accurate than the ones given in the spec,
9275 * which typically don't exceed 4 decimal places. This allows testing of the 9275 * which typically don't exceed 4 decimal places. This allows testing of the
9276 * libpng code to its theoretical accuracy of 4 decimal places. (If pngvalid 9276 * libpng code to its theoretical accuracy of 4 decimal places. (If pngvalid
9277 * used the published errors the 'slack' permitted would have to be +/-.5E-4 or 9277 * used the published errors the 'slack' permitted would have to be +/-.5E-4 or
9278 * more.) 9278 * more.)
9279 * 9279 *
9280 * The png_modifier code assumes that encodings[0] is sRGB and treats it 9280 * The png_modifier code assumes that encodings[0] is sRGB and treats it
9281 * specially: do not change the first entry in this list! 9281 * specially: do not change the first entry in this list!
9282 */ 9282 */
9283static PNG_CONST color_encoding test_encodings[] = 9283static PNG_CONST color_encoding test_encodings[] =
9284{ 9284{
9285/* sRGB: must be first in this list! */ 9285/* sRGB: must be first in this list! */
9286/*gamma:*/ { 1/2.2, 9286/*gamma:*/ { 1/2.2,
9287/*red: */ { 0.412390799265959, 0.212639005871510, 0.019330818715592 }, 9287/*red: */ { 0.412390799265959, 0.212639005871510, 0.019330818715592 },
9288/*green:*/ { 0.357584339383878, 0.715168678767756, 0.119194779794626 }, 9288/*green:*/ { 0.357584339383878, 0.715168678767756, 0.119194779794626 },
9289/*blue: */ { 0.180480788401834, 0.072192315360734, 0.950532152249660} }, 9289/*blue: */ { 0.180480788401834, 0.072192315360734, 0.950532152249660} },
9290/* Kodak ProPhoto (wide gamut) */ 9290/* Kodak ProPhoto (wide gamut) */
9291/*gamma:*/ { 1/1.6 /*approximate: uses 1.8 power law compared to sRGB 2.4*/, 9291/*gamma:*/ { 1/1.6 /*approximate: uses 1.8 power law compared to sRGB 2.4*/,
9292/*red: */ { 0.797760489672303, 0.288071128229293, 0.000000000000000 }, 9292/*red: */ { 0.797760489672303, 0.288071128229293, 0.000000000000000 },
9293/*green:*/ { 0.135185837175740, 0.711843217810102, 0.000000000000000 }, 9293/*green:*/ { 0.135185837175740, 0.711843217810102, 0.000000000000000 },
9294/*blue: */ { 0.031349349581525, 0.000085653960605, 0.825104602510460} }, 9294/*blue: */ { 0.031349349581525, 0.000085653960605, 0.825104602510460} },
9295/* Adobe RGB (1998) */ 9295/* Adobe RGB (1998) */
9296/*gamma:*/ { 1/(2+51./256), 9296/*gamma:*/ { 1/(2+51./256),
9297/*red: */ { 0.576669042910131, 0.297344975250536, 0.027031361386412 }, 9297/*red: */ { 0.576669042910131, 0.297344975250536, 0.027031361386412 },
9298/*green:*/ { 0.185558237906546, 0.627363566255466, 0.070688852535827 }, 9298/*green:*/ { 0.185558237906546, 0.627363566255466, 0.070688852535827 },
9299/*blue: */ { 0.188228646234995, 0.075291458493998, 0.991337536837639} }, 9299/*blue: */ { 0.188228646234995, 0.075291458493998, 0.991337536837639} },
9300/* Adobe Wide Gamut RGB */ 9300/* Adobe Wide Gamut RGB */
9301/*gamma:*/ { 1/(2+51./256), 9301/*gamma:*/ { 1/(2+51./256),
9302/*red: */ { 0.716500716779386, 0.258728243040113, 0.000000000000000 }, 9302/*red: */ { 0.716500716779386, 0.258728243040113, 0.000000000000000 },
9303/*green:*/ { 0.101020574397477, 0.724682314948566, 0.051211818965388 }, 9303/*green:*/ { 0.101020574397477, 0.724682314948566, 0.051211818965388 },
9304/*blue: */ { 0.146774385252705, 0.016589442011321, 0.773892783545073} }, 9304/*blue: */ { 0.146774385252705, 0.016589442011321, 0.773892783545073} },
9305}; 9305};
9306 9306
9307/* signal handler 9307/* signal handler
9308 * 9308 *
9309 * This attempts to trap signals and escape without crashing. It needs a 9309 * This attempts to trap signals and escape without crashing. It needs a
9310 * context pointer so that it can throw an exception (call longjmp) to recover 9310 * context pointer so that it can throw an exception (call longjmp) to recover
9311 * from the condition; this is handled by making the png_modifier used by 'main' 9311 * from the condition; this is handled by making the png_modifier used by 'main'
9312 * into a global variable. 9312 * into a global variable.
9313 */ 9313 */
9314static png_modifier pm; 9314static png_modifier pm;
9315 9315
9316static void signal_handler(int signum) 9316static void signal_handler(int signum)
9317{ 9317{
9318 9318
9319 size_t pos = 0; 9319 size_t pos = 0;
9320 char msg[64]; 9320 char msg[64];
9321 9321
9322 pos = safecat(msg, sizeof msg, pos, "caught signal: "); 9322 pos = safecat(msg, sizeof msg, pos, "caught signal: ");
9323 9323
9324 switch (signum) 9324 switch (signum)
9325 { 9325 {
9326 case SIGABRT: 9326 case SIGABRT:
9327 pos = safecat(msg, sizeof msg, pos, "abort"); 9327 pos = safecat(msg, sizeof msg, pos, "abort");
9328 break; 9328 break;
9329 9329
9330 case SIGFPE: 9330 case SIGFPE:
9331 pos = safecat(msg, sizeof msg, pos, "floating point exception"); 9331 pos = safecat(msg, sizeof msg, pos, "floating point exception");
9332 break; 9332 break;
9333 9333
9334 case SIGILL: 9334 case SIGILL:
9335 pos = safecat(msg, sizeof msg, pos, "illegal instruction"); 9335 pos = safecat(msg, sizeof msg, pos, "illegal instruction");
9336 break; 9336 break;
9337 9337
9338 case SIGINT: 9338 case SIGINT:
9339 pos = safecat(msg, sizeof msg, pos, "interrupt"); 9339 pos = safecat(msg, sizeof msg, pos, "interrupt");
9340 break; 9340 break;
9341 9341
9342 case SIGSEGV: 9342 case SIGSEGV:
9343 pos = safecat(msg, sizeof msg, pos, "invalid memory access"); 9343 pos = safecat(msg, sizeof msg, pos, "invalid memory access");
9344 break; 9344 break;
9345 9345
9346 case SIGTERM: 9346 case SIGTERM:
9347 pos = safecat(msg, sizeof msg, pos, "termination request"); 9347 pos = safecat(msg, sizeof msg, pos, "termination request");
9348 break; 9348 break;
9349 9349
9350 default: 9350 default:
9351 pos = safecat(msg, sizeof msg, pos, "unknown "); 9351 pos = safecat(msg, sizeof msg, pos, "unknown ");
9352 pos = safecatn(msg, sizeof msg, pos, signum); 9352 pos = safecatn(msg, sizeof msg, pos, signum);
9353 break; 9353 break;
9354 } 9354 }
9355 9355
9356 store_log(&pm.this, NULL/*png_structp*/, msg, 1/*error*/); 9356 store_log(&pm.this, NULL/*png_structp*/, msg, 1/*error*/);
9357 9357
9358 /* And finally throw an exception so we can keep going, unless this is 9358 /* And finally throw an exception so we can keep going, unless this is
9359 * SIGTERM in which case stop now. 9359 * SIGTERM in which case stop now.
9360 */ 9360 */
9361 if (signum != SIGTERM) 9361 if (signum != SIGTERM)
9362 { 9362 {
9363 struct exception_context *the_exception_context = 9363 struct exception_context *the_exception_context =
9364 &pm.this.exception_context; 9364 &pm.this.exception_context;
9365 9365
9366 Throw &pm.this; 9366 Throw &pm.this;
9367 } 9367 }
9368 9368
9369 else 9369 else
9370 exit(1); 9370 exit(1);
9371} 9371}
9372 9372
9373/* main program */ 9373/* main program */
9374int main(int argc, PNG_CONST char **argv) 9374int main(int argc, PNG_CONST char **argv)
9375{ 9375{
9376 volatile int summary = 1; /* Print the error summary at the end */ 9376 volatile int summary = 1; /* Print the error summary at the end */
9377 volatile int memstats = 0; /* Print memory statistics at the end */ 9377 volatile int memstats = 0; /* Print memory statistics at the end */
9378 9378
9379 /* Create the given output file on success: */ 9379 /* Create the given output file on success: */
9380 PNG_CONST char *volatile touch = NULL; 9380 PNG_CONST char *volatile touch = NULL;
9381 9381
9382 /* This is an array of standard gamma values (believe it or not I've seen 9382 /* This is an array of standard gamma values (believe it or not I've seen
9383 * every one of these mentioned somewhere.) 9383 * every one of these mentioned somewhere.)
9384 * 9384 *
9385 * In the following list the most useful values are first! 9385 * In the following list the most useful values are first!
9386 */ 9386 */
9387 static double 9387 static double
9388 gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9}; 9388 gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9};
9389 9389
9390 /* This records the command and arguments: */ 9390 /* This records the command and arguments: */
9391 size_t cp = 0; 9391 size_t cp = 0;
9392 char command[1024]; 9392 char command[1024];
9393 9393
9394 anon_context(&pm.this); 9394 anon_context(&pm.this);
9395 9395
9396 /* Add appropriate signal handlers, just the ANSI specified ones: */ 9396 /* Add appropriate signal handlers, just the ANSI specified ones: */
9397 signal(SIGABRT, signal_handler); 9397 signal(SIGABRT, signal_handler);
9398 signal(SIGFPE, signal_handler); 9398 signal(SIGFPE, signal_handler);
9399 signal(SIGILL, signal_handler); 9399 signal(SIGILL, signal_handler);
9400 signal(SIGINT, signal_handler); 9400 signal(SIGINT, signal_handler);
9401 signal(SIGSEGV, signal_handler); 9401 signal(SIGSEGV, signal_handler);
9402 signal(SIGTERM, signal_handler); 9402 signal(SIGTERM, signal_handler);
9403 9403
9404#ifdef HAVE_FEENABLEEXCEPT 9404#ifdef HAVE_FEENABLEEXCEPT
9405 /* Only required to enable FP exceptions on platforms where they start off 9405 /* Only required to enable FP exceptions on platforms where they start off
9406 * disabled; this is not necessary but if it is not done pngvalid will likely 9406 * disabled; this is not necessary but if it is not done pngvalid will likely
9407 * end up ignoring FP conditions that other platforms fault. 9407 * end up ignoring FP conditions that other platforms fault.
9408 */ 9408 */
9409 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); 9409 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
9410#endif 9410#endif
9411 9411
9412 modifier_init(&pm); 9412 modifier_init(&pm);
9413 9413
9414 /* Preallocate the image buffer, because we know how big it needs to be, 9414 /* Preallocate the image buffer, because we know how big it needs to be,
9415 * note that, for testing purposes, it is deliberately mis-aligned by tag 9415 * note that, for testing purposes, it is deliberately mis-aligned by tag
9416 * bytes either side. All rows have an additional five bytes of padding for 9416 * bytes either side. All rows have an additional five bytes of padding for
9417 * overwrite checking. 9417 * overwrite checking.
9418 */ 9418 */
9419 store_ensure_image(&pm.this, NULL, 2, TRANSFORM_ROWMAX, TRANSFORM_HEIGHTMAX); 9419 store_ensure_image(&pm.this, NULL, 2, TRANSFORM_ROWMAX, TRANSFORM_HEIGHTMAX);
9420 9420
9421 /* Don't give argv[0], it's normally some horrible libtool string: */ 9421 /* Don't give argv[0], it's normally some horrible libtool string: */
9422 cp = safecat(command, sizeof command, cp, "pngvalid"); 9422 cp = safecat(command, sizeof command, cp, "pngvalid");
9423 9423
9424 /* Default to error on warning: */ 9424 /* Default to error on warning: */
9425 pm.this.treat_warnings_as_errors = 1; 9425 pm.this.treat_warnings_as_errors = 1;
9426 9426
9427 /* Store the test gammas */ 9427 /* Store the test gammas */
9428 pm.gammas = gammas; 9428 pm.gammas = gammas;
9429 pm.ngammas = (sizeof gammas) / (sizeof gammas[0]); 9429 pm.ngammas = (sizeof gammas) / (sizeof gammas[0]);
9430 pm.ngamma_tests = 0; /* default to off */ 9430 pm.ngamma_tests = 0; /* default to off */
9431 9431
9432 /* And the test encodings */ 9432 /* And the test encodings */
9433 pm.encodings = test_encodings; 9433 pm.encodings = test_encodings;
9434 pm.nencodings = (sizeof test_encodings) / (sizeof test_encodings[0]); 9434 pm.nencodings = (sizeof test_encodings) / (sizeof test_encodings[0]);
9435 9435
9436 pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */ 9436 pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */
9437 /* The following allows results to pass if they correspond to anything in the 9437 /* The following allows results to pass if they correspond to anything in the
9438 * transformed range [input-.5,input+.5]; this is is required because of the 9438 * transformed range [input-.5,input+.5]; this is is required because of the
9439 * way libpng treates the 16_TO_8 flag when building the gamma tables. 9439 * way libpng treates the 16_TO_8 flag when building the gamma tables.
9440 * 9440 *
9441 * TODO: review this 9441 * TODO: review this
9442 */ 9442 */
9443 pm.use_input_precision_16to8 = 1U; 9443 pm.use_input_precision_16to8 = 1U;
9444 9444
9445 /* Some default values (set the behavior for 'make check' here). 9445 /* Some default values (set the behavior for 'make check' here).
9446 * These values simply control the maximum error permitted in the gamma 9446 * These values simply control the maximum error permitted in the gamma
9447 * transformations. The practial limits for human perception are described 9447 * transformations. The practial limits for human perception are described
9448 * below (the setting for maxpc16), however for 8 bit encodings it isn't 9448 * below (the setting for maxpc16), however for 8 bit encodings it isn't
9449 * possible to meet the accepted capabilities of human vision - i.e. 8 bit 9449 * possible to meet the accepted capabilities of human vision - i.e. 8 bit
9450 * images can never be good enough, regardless of encoding. 9450 * images can never be good enough, regardless of encoding.
9451 */ 9451 */
9452 pm.maxout8 = .1; /* Arithmetic error in *encoded* value */ 9452 pm.maxout8 = .1; /* Arithmetic error in *encoded* value */
9453 pm.maxabs8 = .00005; /* 1/20000 */ 9453 pm.maxabs8 = .00005; /* 1/20000 */
9454 pm.maxcalc8 = .004; /* +/-1 in 8 bits for compose errors */ 9454 pm.maxcalc8 = .004; /* +/-1 in 8 bits for compose errors */
9455 pm.maxpc8 = .499; /* I.e., .499% fractional error */ 9455 pm.maxpc8 = .499; /* I.e., .499% fractional error */
9456 pm.maxout16 = .499; /* Error in *encoded* value */ 9456 pm.maxout16 = .499; /* Error in *encoded* value */
9457 pm.maxabs16 = .00005;/* 1/20000 */ 9457 pm.maxabs16 = .00005;/* 1/20000 */
9458 pm.maxcalc16 =.000015;/* +/-1 in 16 bits for compose errors */ 9458 pm.maxcalc16 =.000015;/* +/-1 in 16 bits for compose errors */
9459 9459
9460 /* NOTE: this is a reasonable perceptual limit. We assume that humans can 9460 /* NOTE: this is a reasonable perceptual limit. We assume that humans can
9461 * perceive light level differences of 1% over a 100:1 range, so we need to 9461 * perceive light level differences of 1% over a 100:1 range, so we need to
9462 * maintain 1 in 10000 accuracy (in linear light space), which is what the 9462 * maintain 1 in 10000 accuracy (in linear light space), which is what the
9463 * following guarantees. It also allows significantly higher errors at 9463 * following guarantees. It also allows significantly higher errors at
9464 * higher 16 bit values, which is important for performance. The actual 9464 * higher 16 bit values, which is important for performance. The actual
9465 * maximum 16 bit error is about +/-1.9 in the fixed point implementation but 9465 * maximum 16 bit error is about +/-1.9 in the fixed point implementation but
9466 * this is only allowed for values >38149 by the following: 9466 * this is only allowed for values >38149 by the following:
9467 */ 9467 */
9468 pm.maxpc16 = .005; /* I.e., 1/200% - 1/20000 */ 9468 pm.maxpc16 = .005; /* I.e., 1/200% - 1/20000 */
9469 9469
9470 /* Now parse the command line options. */ 9470 /* Now parse the command line options. */
9471 while (--argc >= 1) 9471 while (--argc >= 1)
9472 { 9472 {
9473 int catmore = 0; /* Set if the argument has an argument. */ 9473 int catmore = 0; /* Set if the argument has an argument. */
9474 9474
9475 /* Record each argument for posterity: */ 9475 /* Record each argument for posterity: */
9476 cp = safecat(command, sizeof command, cp, " "); 9476 cp = safecat(command, sizeof command, cp, " ");
9477 cp = safecat(command, sizeof command, cp, *++argv); 9477 cp = safecat(command, sizeof command, cp, *++argv);
9478 9478
9479 if (strcmp(*argv, "-v") == 0) 9479 if (strcmp(*argv, "-v") == 0)
9480 pm.this.verbose = 1; 9480 pm.this.verbose = 1;
9481 9481
9482 else if (strcmp(*argv, "-l") == 0) 9482 else if (strcmp(*argv, "-l") == 0)
9483 pm.log = 1; 9483 pm.log = 1;
9484 9484
9485 else if (strcmp(*argv, "-q") == 0) 9485 else if (strcmp(*argv, "-q") == 0)
9486 summary = pm.this.verbose = pm.log = 0; 9486 summary = pm.this.verbose = pm.log = 0;
9487 9487
9488 else if (strcmp(*argv, "-w") == 0) 9488 else if (strcmp(*argv, "-w") == 0)
9489 pm.this.treat_warnings_as_errors = 0; 9489 pm.this.treat_warnings_as_errors = 0;
9490 9490
9491 else if (strcmp(*argv, "--speed") == 0) 9491 else if (strcmp(*argv, "--speed") == 0)
9492 pm.this.speed = 1, pm.ngamma_tests = pm.ngammas, pm.test_standard = 0, 9492 pm.this.speed = 1, pm.ngamma_tests = pm.ngammas, pm.test_standard = 0,
9493 summary = 0; 9493 summary = 0;
9494 9494
9495 else if (strcmp(*argv, "--memory") == 0) 9495 else if (strcmp(*argv, "--memory") == 0)
9496 memstats = 1; 9496 memstats = 1;
9497 9497
9498 else if (strcmp(*argv, "--size") == 0) 9498 else if (strcmp(*argv, "--size") == 0)
9499 pm.test_size = 1; 9499 pm.test_size = 1;
9500 9500
9501 else if (strcmp(*argv, "--nosize") == 0) 9501 else if (strcmp(*argv, "--nosize") == 0)
9502 pm.test_size = 0; 9502 pm.test_size = 0;
9503 9503
9504 else if (strcmp(*argv, "--standard") == 0) 9504 else if (strcmp(*argv, "--standard") == 0)
9505 pm.test_standard = 1; 9505 pm.test_standard = 1;
9506 9506
9507 else if (strcmp(*argv, "--nostandard") == 0) 9507 else if (strcmp(*argv, "--nostandard") == 0)
9508 pm.test_standard = 0; 9508 pm.test_standard = 0;
9509 9509
9510 else if (strcmp(*argv, "--transform") == 0) 9510 else if (strcmp(*argv, "--transform") == 0)
9511 pm.test_transform = 1; 9511 pm.test_transform = 1;
9512 9512
9513 else if (strcmp(*argv, "--notransform") == 0) 9513 else if (strcmp(*argv, "--notransform") == 0)
9514 pm.test_transform = 0; 9514 pm.test_transform = 0;
9515 9515
9516#ifdef PNG_READ_TRANSFORMS_SUPPORTED 9516#ifdef PNG_READ_TRANSFORMS_SUPPORTED
9517 else if (strncmp(*argv, "--transform-disable=", 9517 else if (strncmp(*argv, "--transform-disable=",
9518 sizeof "--transform-disable") == 0) 9518 sizeof "--transform-disable") == 0)
9519 { 9519 {
9520 pm.test_transform = 1; 9520 pm.test_transform = 1;
9521 transform_disable(*argv + sizeof "--transform-disable"); 9521 transform_disable(*argv + sizeof "--transform-disable");
9522 } 9522 }
9523 9523
9524 else if (strncmp(*argv, "--transform-enable=", 9524 else if (strncmp(*argv, "--transform-enable=",
9525 sizeof "--transform-enable") == 0) 9525 sizeof "--transform-enable") == 0)
9526 { 9526 {
9527 pm.test_transform = 1; 9527 pm.test_transform = 1;
9528 transform_enable(*argv + sizeof "--transform-enable"); 9528 transform_enable(*argv + sizeof "--transform-enable");
9529 } 9529 }
9530#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 9530#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
9531 9531
9532 else if (strcmp(*argv, "--gamma") == 0) 9532 else if (strcmp(*argv, "--gamma") == 0)
9533 { 9533 {
9534 /* Just do two gamma tests here (2.2 and linear) for speed: */ 9534 /* Just do two gamma tests here (2.2 and linear) for speed: */
9535 pm.ngamma_tests = 2U; 9535 pm.ngamma_tests = 2U;
9536 pm.test_gamma_threshold = 1; 9536 pm.test_gamma_threshold = 1;
9537 pm.test_gamma_transform = 1; 9537 pm.test_gamma_transform = 1;
9538 pm.test_gamma_sbit = 1; 9538 pm.test_gamma_sbit = 1;
9539 pm.test_gamma_scale16 = 1; 9539 pm.test_gamma_scale16 = 1;
9540 pm.test_gamma_background = 1; 9540 pm.test_gamma_background = 1;
9541 pm.test_gamma_alpha_mode = 1; 9541 pm.test_gamma_alpha_mode = 1;
9542 } 9542 }
9543 9543
9544 else if (strcmp(*argv, "--nogamma") == 0) 9544 else if (strcmp(*argv, "--nogamma") == 0)
9545 pm.ngamma_tests = 0; 9545 pm.ngamma_tests = 0;
9546 9546
9547 else if (strcmp(*argv, "--gamma-threshold") == 0) 9547 else if (strcmp(*argv, "--gamma-threshold") == 0)
9548 pm.ngamma_tests = 2U, pm.test_gamma_threshold = 1; 9548 pm.ngamma_tests = 2U, pm.test_gamma_threshold = 1;
9549 9549
9550 else if (strcmp(*argv, "--nogamma-threshold") == 0) 9550 else if (strcmp(*argv, "--nogamma-threshold") == 0)
9551 pm.test_gamma_threshold = 0; 9551 pm.test_gamma_threshold = 0;
9552 9552
9553 else if (strcmp(*argv, "--gamma-transform") == 0) 9553 else if (strcmp(*argv, "--gamma-transform") == 0)
9554 pm.ngamma_tests = 2U, pm.test_gamma_transform = 1; 9554 pm.ngamma_tests = 2U, pm.test_gamma_transform = 1;
9555 9555
9556 else if (strcmp(*argv, "--nogamma-transform") == 0) 9556 else if (strcmp(*argv, "--nogamma-transform") == 0)
9557 pm.test_gamma_transform = 0; 9557 pm.test_gamma_transform = 0;
9558 9558
9559 else if (strcmp(*argv, "--gamma-sbit") == 0) 9559 else if (strcmp(*argv, "--gamma-sbit") == 0)
9560 pm.ngamma_tests = 2U, pm.test_gamma_sbit = 1; 9560 pm.ngamma_tests = 2U, pm.test_gamma_sbit = 1;
9561 9561
9562 else if (strcmp(*argv, "--nogamma-sbit") == 0) 9562 else if (strcmp(*argv, "--nogamma-sbit") == 0)
9563 pm.test_gamma_sbit = 0; 9563 pm.test_gamma_sbit = 0;
9564 9564
9565 else if (strcmp(*argv, "--gamma-16-to-8") == 0) 9565 else if (strcmp(*argv, "--gamma-16-to-8") == 0)
9566 pm.ngamma_tests = 2U, pm.test_gamma_scale16 = 1; 9566 pm.ngamma_tests = 2U, pm.test_gamma_scale16 = 1;
9567 9567
9568 else if (strcmp(*argv, "--nogamma-16-to-8") == 0) 9568 else if (strcmp(*argv, "--nogamma-16-to-8") == 0)
9569 pm.test_gamma_scale16 = 0; 9569 pm.test_gamma_scale16 = 0;
9570 9570
9571 else if (strcmp(*argv, "--gamma-background") == 0) 9571 else if (strcmp(*argv, "--gamma-background") == 0)
9572 pm.ngamma_tests = 2U, pm.test_gamma_background = 1; 9572 pm.ngamma_tests = 2U, pm.test_gamma_background = 1;
9573 9573
9574 else if (strcmp(*argv, "--nogamma-background") == 0) 9574 else if (strcmp(*argv, "--nogamma-background") == 0)
9575 pm.test_gamma_background = 0; 9575 pm.test_gamma_background = 0;
9576 9576
9577 else if (strcmp(*argv, "--gamma-alpha-mode") == 0) 9577 else if (strcmp(*argv, "--gamma-alpha-mode") == 0)
9578 pm.ngamma_tests = 2U, pm.test_gamma_alpha_mode = 1; 9578 pm.ngamma_tests = 2U, pm.test_gamma_alpha_mode = 1;
9579 9579
9580 else if (strcmp(*argv, "--nogamma-alpha-mode") == 0) 9580 else if (strcmp(*argv, "--nogamma-alpha-mode") == 0)
9581 pm.test_gamma_alpha_mode = 0; 9581 pm.test_gamma_alpha_mode = 0;
9582 9582
9583 else if (strcmp(*argv, "--expand16") == 0) 9583 else if (strcmp(*argv, "--expand16") == 0)
9584 pm.test_gamma_expand16 = 1; 9584 pm.test_gamma_expand16 = 1;
9585 9585
9586 else if (strcmp(*argv, "--noexpand16") == 0) 9586 else if (strcmp(*argv, "--noexpand16") == 0)
9587 pm.test_gamma_expand16 = 0; 9587 pm.test_gamma_expand16 = 0;
9588 9588
9589 else if (strcmp(*argv, "--more-gammas") == 0) 9589 else if (strcmp(*argv, "--more-gammas") == 0)
9590 pm.ngamma_tests = 3U; 9590 pm.ngamma_tests = 3U;
9591 9591
9592 else if (strcmp(*argv, "--all-gammas") == 0) 9592 else if (strcmp(*argv, "--all-gammas") == 0)
9593 pm.ngamma_tests = pm.ngammas; 9593 pm.ngamma_tests = pm.ngammas;
9594 9594
9595 else if (strcmp(*argv, "--progressive-read") == 0) 9595 else if (strcmp(*argv, "--progressive-read") == 0)
9596 pm.this.progressive = 1; 9596 pm.this.progressive = 1;
9597 9597
9598 else if (strcmp(*argv, "--use-update-info") == 0) 9598 else if (strcmp(*argv, "--use-update-info") == 0)
9599 ++pm.use_update_info; /* Can call multiple times */ 9599 ++pm.use_update_info; /* Can call multiple times */
9600 9600
9601 else if (strcmp(*argv, "--interlace") == 0) 9601 else if (strcmp(*argv, "--interlace") == 0)
9602 pm.interlace_type = PNG_INTERLACE_ADAM7; 9602 pm.interlace_type = PNG_INTERLACE_ADAM7;
9603 9603
9604 else if (strcmp(*argv, "--use-input-precision") == 0) 9604 else if (strcmp(*argv, "--use-input-precision") == 0)
9605 pm.use_input_precision = 1; 9605 pm.use_input_precision = 1;
9606 9606
9607 else if (strcmp(*argv, "--calculations-use-input-precision") == 0) 9607 else if (strcmp(*argv, "--calculations-use-input-precision") == 0)
9608 pm.calculations_use_input_precision = 1; 9608 pm.calculations_use_input_precision = 1;
9609 9609
9610 else if (strcmp(*argv, "--assume-16-bit-calculations") == 0) 9610 else if (strcmp(*argv, "--assume-16-bit-calculations") == 0)
9611 pm.assume_16_bit_calculations = 1; 9611 pm.assume_16_bit_calculations = 1;
9612 9612
9613 else if (strcmp(*argv, "--calculations-follow-bit-depth") == 0) 9613 else if (strcmp(*argv, "--calculations-follow-bit-depth") == 0)
9614 pm.calculations_use_input_precision = 9614 pm.calculations_use_input_precision =
9615 pm.assume_16_bit_calculations = 0; 9615 pm.assume_16_bit_calculations = 0;
9616 9616
9617 else if (strcmp(*argv, "--exhaustive") == 0) 9617 else if (strcmp(*argv, "--exhaustive") == 0)
9618 pm.test_exhaustive = 1; 9618 pm.test_exhaustive = 1;
9619 9619
9620 else if (argc > 1 && strcmp(*argv, "--sbitlow") == 0) 9620 else if (argc > 1 && strcmp(*argv, "--sbitlow") == 0)
9621 --argc, pm.sbitlow = (png_byte)atoi(*++argv), catmore = 1; 9621 --argc, pm.sbitlow = (png_byte)atoi(*++argv), catmore = 1;
9622 9622
9623 else if (argc > 1 && strcmp(*argv, "--touch") == 0) 9623 else if (argc > 1 && strcmp(*argv, "--touch") == 0)
9624 --argc, touch = *++argv, catmore = 1; 9624 --argc, touch = *++argv, catmore = 1;
9625 9625
9626 else if (argc > 1 && strncmp(*argv, "--max", 5) == 0) 9626 else if (argc > 1 && strncmp(*argv, "--max", 5) == 0)
9627 { 9627 {
9628 --argc; 9628 --argc;
9629 9629
9630 if (strcmp(5+*argv, "abs8") == 0) 9630 if (strcmp(5+*argv, "abs8") == 0)
9631 pm.maxabs8 = atof(*++argv); 9631 pm.maxabs8 = atof(*++argv);
9632 9632
9633 else if (strcmp(5+*argv, "abs16") == 0) 9633 else if (strcmp(5+*argv, "abs16") == 0)
9634 pm.maxabs16 = atof(*++argv); 9634 pm.maxabs16 = atof(*++argv);
9635 9635
9636 else if (strcmp(5+*argv, "calc8") == 0) 9636 else if (strcmp(5+*argv, "calc8") == 0)
9637 pm.maxcalc8 = atof(*++argv); 9637 pm.maxcalc8 = atof(*++argv);
9638 9638
9639 else if (strcmp(5+*argv, "calc16") == 0) 9639 else if (strcmp(5+*argv, "calc16") == 0)
9640 pm.maxcalc16 = atof(*++argv); 9640 pm.maxcalc16 = atof(*++argv);
9641 9641
9642 else if (strcmp(5+*argv, "out8") == 0) 9642 else if (strcmp(5+*argv, "out8") == 0)
9643 pm.maxout8 = atof(*++argv); 9643 pm.maxout8 = atof(*++argv);
9644 9644
9645 else if (strcmp(5+*argv, "out16") == 0) 9645 else if (strcmp(5+*argv, "out16") == 0)
9646 pm.maxout16 = atof(*++argv); 9646 pm.maxout16 = atof(*++argv);
9647 9647
9648 else if (strcmp(5+*argv, "pc8") == 0) 9648 else if (strcmp(5+*argv, "pc8") == 0)
9649 pm.maxpc8 = atof(*++argv); 9649 pm.maxpc8 = atof(*++argv);
9650 9650
9651 else if (strcmp(5+*argv, "pc16") == 0) 9651 else if (strcmp(5+*argv, "pc16") == 0)
9652 pm.maxpc16 = atof(*++argv); 9652 pm.maxpc16 = atof(*++argv);
9653 9653
9654 else 9654 else
9655 { 9655 {
9656 fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv); 9656 fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv);
9657 exit(1); 9657 exit(1);
9658 } 9658 }
9659 9659
9660 catmore = 1; 9660 catmore = 1;
9661 } 9661 }
9662 9662
9663 else if (strcmp(*argv, "--log8") == 0) 9663 else if (strcmp(*argv, "--log8") == 0)
9664 --argc, pm.log8 = atof(*++argv), catmore = 1; 9664 --argc, pm.log8 = atof(*++argv), catmore = 1;
9665 9665
9666 else if (strcmp(*argv, "--log16") == 0) 9666 else if (strcmp(*argv, "--log16") == 0)
9667 --argc, pm.log16 = atof(*++argv), catmore = 1; 9667 --argc, pm.log16 = atof(*++argv), catmore = 1;
9668 9668
9669 else 9669 else
9670 { 9670 {
9671 fprintf(stderr, "pngvalid: %s: unknown argument\n", *argv); 9671 fprintf(stderr, "pngvalid: %s: unknown argument\n", *argv);
9672 exit(1); 9672 exit(1);
9673 } 9673 }
9674 9674
9675 if (catmore) /* consumed an extra *argv */ 9675 if (catmore) /* consumed an extra *argv */
9676 { 9676 {
9677 cp = safecat(command, sizeof command, cp, " "); 9677 cp = safecat(command, sizeof command, cp, " ");
9678 cp = safecat(command, sizeof command, cp, *argv); 9678 cp = safecat(command, sizeof command, cp, *argv);
9679 } 9679 }
9680 } 9680 }
9681 9681
9682 /* If pngvalid is run with no arguments default to a reasonable set of the 9682 /* If pngvalid is run with no arguments default to a reasonable set of the
9683 * tests. 9683 * tests.
9684 */ 9684 */
9685 if (pm.test_standard == 0 && pm.test_size == 0 && pm.test_transform == 0 && 9685 if (pm.test_standard == 0 && pm.test_size == 0 && pm.test_transform == 0 &&
9686 pm.ngamma_tests == 0) 9686 pm.ngamma_tests == 0)
9687 { 9687 {
9688 /* Make this do all the tests done in the test shell scripts with the same 9688 /* Make this do all the tests done in the test shell scripts with the same
9689 * parameters, where possible. The limitation is that all the progressive 9689 * parameters, where possible. The limitation is that all the progressive
9690 * read and interlace stuff has to be done in separate runs, so only the 9690 * read and interlace stuff has to be done in separate runs, so only the
9691 * basic 'standard' and 'size' tests are done. 9691 * basic 'standard' and 'size' tests are done.
9692 */ 9692 */
9693 pm.test_standard = 1; 9693 pm.test_standard = 1;
9694 pm.test_size = 1; 9694 pm.test_size = 1;
9695 pm.test_transform = 1; 9695 pm.test_transform = 1;
9696 pm.ngamma_tests = 2U; 9696 pm.ngamma_tests = 2U;
9697 } 9697 }
9698 9698
9699 if (pm.ngamma_tests > 0 && 9699 if (pm.ngamma_tests > 0 &&
9700 pm.test_gamma_threshold == 0 && pm.test_gamma_transform == 0 && 9700 pm.test_gamma_threshold == 0 && pm.test_gamma_transform == 0 &&
9701 pm.test_gamma_sbit == 0 && pm.test_gamma_scale16 == 0 && 9701 pm.test_gamma_sbit == 0 && pm.test_gamma_scale16 == 0 &&
9702 pm.test_gamma_background == 0 && pm.test_gamma_alpha_mode == 0) 9702 pm.test_gamma_background == 0 && pm.test_gamma_alpha_mode == 0)
9703 { 9703 {
9704 pm.test_gamma_threshold = 1; 9704 pm.test_gamma_threshold = 1;
9705 pm.test_gamma_transform = 1; 9705 pm.test_gamma_transform = 1;
9706 pm.test_gamma_sbit = 1; 9706 pm.test_gamma_sbit = 1;
9707 pm.test_gamma_scale16 = 1; 9707 pm.test_gamma_scale16 = 1;
9708 pm.test_gamma_background = 1; 9708 pm.test_gamma_background = 1;
9709 pm.test_gamma_alpha_mode = 1; 9709 pm.test_gamma_alpha_mode = 1;
9710 } 9710 }
9711 9711
9712 else if (pm.ngamma_tests == 0) 9712 else if (pm.ngamma_tests == 0)
9713 { 9713 {
9714 /* Nothing to test so turn everything off: */ 9714 /* Nothing to test so turn everything off: */
9715 pm.test_gamma_threshold = 0; 9715 pm.test_gamma_threshold = 0;
9716 pm.test_gamma_transform = 0; 9716 pm.test_gamma_transform = 0;
9717 pm.test_gamma_sbit = 0; 9717 pm.test_gamma_sbit = 0;
9718 pm.test_gamma_scale16 = 0; 9718 pm.test_gamma_scale16 = 0;
9719 pm.test_gamma_background = 0; 9719 pm.test_gamma_background = 0;
9720 pm.test_gamma_alpha_mode = 0; 9720 pm.test_gamma_alpha_mode = 0;
9721 } 9721 }
9722 9722
9723 Try 9723 Try
9724 { 9724 {
9725 /* Make useful base images */ 9725 /* Make useful base images */
9726 make_transform_images(&pm.this); 9726 make_transform_images(&pm.this);
9727 9727
9728 /* Perform the standard and gamma tests. */ 9728 /* Perform the standard and gamma tests. */
9729 if (pm.test_standard) 9729 if (pm.test_standard)
9730 { 9730 {
9731 perform_interlace_macro_validation(); 9731 perform_interlace_macro_validation();
9732 perform_formatting_test(&pm.this); 9732 perform_formatting_test(&pm.this);
9733 perform_standard_test(&pm); 9733 perform_standard_test(&pm);
9734 perform_error_test(&pm); 9734 perform_error_test(&pm);
9735 } 9735 }
9736 9736
9737 /* Various oddly sized images: */ 9737 /* Various oddly sized images: */
9738 if (pm.test_size) 9738 if (pm.test_size)
9739 { 9739 {
9740 make_size_images(&pm.this); 9740 make_size_images(&pm.this);
9741 perform_size_test(&pm); 9741 perform_size_test(&pm);
9742 } 9742 }
9743 9743
9744#ifdef PNG_READ_TRANSFORMS_SUPPORTED 9744#ifdef PNG_READ_TRANSFORMS_SUPPORTED
9745 /* Combinatorial transforms: */ 9745 /* Combinatorial transforms: */
9746 if (pm.test_transform) 9746 if (pm.test_transform)
9747 perform_transform_test(&pm); 9747 perform_transform_test(&pm);
9748#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 9748#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
9749 9749
9750#ifdef PNG_READ_GAMMA_SUPPORTED 9750#ifdef PNG_READ_GAMMA_SUPPORTED
9751 if (pm.ngamma_tests > 0) 9751 if (pm.ngamma_tests > 0)
9752 perform_gamma_test(&pm, summary); 9752 perform_gamma_test(&pm, summary);
9753#endif 9753#endif
9754 } 9754 }
9755 9755
9756 Catch_anonymous 9756 Catch_anonymous
9757 { 9757 {
9758 fprintf(stderr, "pngvalid: test aborted (probably failed in cleanup)\n"); 9758 fprintf(stderr, "pngvalid: test aborted (probably failed in cleanup)\n");
9759 if (!pm.this.verbose) 9759 if (!pm.this.verbose)
9760 { 9760 {
9761 if (pm.this.error[0] != 0) 9761 if (pm.this.error[0] != 0)
9762 fprintf(stderr, "pngvalid: first error: %s\n", pm.this.error); 9762 fprintf(stderr, "pngvalid: first error: %s\n", pm.this.error);
9763 9763
9764 fprintf(stderr, "pngvalid: run with -v to see what happened\n"); 9764 fprintf(stderr, "pngvalid: run with -v to see what happened\n");
9765 } 9765 }
9766 exit(1); 9766 exit(1);
9767 } 9767 }
9768 9768
9769 if (summary) 9769 if (summary)
9770 { 9770 {
9771 printf("%s: %s (%s point arithmetic)\n", 9771 printf("%s: %s (%s point arithmetic)\n",
9772 (pm.this.nerrors || (pm.this.treat_warnings_as_errors && 9772 (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
9773 pm.this.nwarnings)) ? "FAIL" : "PASS", 9773 pm.this.nwarnings)) ? "FAIL" : "PASS",
9774 command, 9774 command,
9775#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500 9775#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500
9776 "floating" 9776 "floating"
9777#else 9777#else
9778 "fixed" 9778 "fixed"
9779#endif 9779#endif
9780 ); 9780 );
9781 } 9781 }
9782 9782
9783 if (memstats) 9783 if (memstats)
9784 { 9784 {
9785 printf("Allocated memory statistics (in bytes):\n" 9785 printf("Allocated memory statistics (in bytes):\n"
9786 "\tread %lu maximum single, %lu peak, %lu total\n" 9786 "\tread %lu maximum single, %lu peak, %lu total\n"
9787 "\twrite %lu maximum single, %lu peak, %lu total\n", 9787 "\twrite %lu maximum single, %lu peak, %lu total\n",
9788 (unsigned long)pm.this.read_memory_pool.max_max, 9788 (unsigned long)pm.this.read_memory_pool.max_max,
9789 (unsigned long)pm.this.read_memory_pool.max_limit, 9789 (unsigned long)pm.this.read_memory_pool.max_limit,
9790 (unsigned long)pm.this.read_memory_pool.max_total, 9790 (unsigned long)pm.this.read_memory_pool.max_total,
9791 (unsigned long)pm.this.write_memory_pool.max_max, 9791 (unsigned long)pm.this.write_memory_pool.max_max,
9792 (unsigned long)pm.this.write_memory_pool.max_limit, 9792 (unsigned long)pm.this.write_memory_pool.max_limit,
9793 (unsigned long)pm.this.write_memory_pool.max_total); 9793 (unsigned long)pm.this.write_memory_pool.max_total);
9794 } 9794 }
9795 9795
9796 /* Do this here to provoke memory corruption errors in memory not directly 9796 /* Do this here to provoke memory corruption errors in memory not directly
9797 * allocated by libpng - not a complete test, but better than nothing. 9797 * allocated by libpng - not a complete test, but better than nothing.
9798 */ 9798 */
9799 store_delete(&pm.this); 9799 store_delete(&pm.this);
9800 9800
9801 /* Error exit if there are any errors, and maybe if there are any 9801 /* Error exit if there are any errors, and maybe if there are any
9802 * warnings. 9802 * warnings.
9803 */ 9803 */
9804 if (pm.this.nerrors || (pm.this.treat_warnings_as_errors && 9804 if (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
9805 pm.this.nwarnings)) 9805 pm.this.nwarnings))
9806 { 9806 {
9807 if (!pm.this.verbose) 9807 if (!pm.this.verbose)
9808 fprintf(stderr, "pngvalid: %s\n", pm.this.error); 9808 fprintf(stderr, "pngvalid: %s\n", pm.this.error);
9809 9809
9810 fprintf(stderr, "pngvalid: %d errors, %d warnings\n", pm.this.nerrors, 9810 fprintf(stderr, "pngvalid: %d errors, %d warnings\n", pm.this.nerrors,
9811 pm.this.nwarnings); 9811 pm.this.nwarnings);
9812 9812
9813 exit(1); 9813 exit(1);
9814 } 9814 }
9815 9815
9816 /* Success case. */ 9816 /* Success case. */
9817 if (touch != NULL) 9817 if (touch != NULL)
9818 { 9818 {
9819 FILE *fsuccess = fopen(touch, "wt"); 9819 FILE *fsuccess = fopen(touch, "wt");
9820 9820
9821 if (fsuccess != NULL) 9821 if (fsuccess != NULL)
9822 { 9822 {
9823 int error = 0; 9823 int error = 0;
9824 fprintf(fsuccess, "PNG validation succeeded\n"); 9824 fprintf(fsuccess, "PNG validation succeeded\n");
9825 fflush(fsuccess); 9825 fflush(fsuccess);
9826 error = ferror(fsuccess); 9826 error = ferror(fsuccess);
9827 9827
9828 if (fclose(fsuccess) || error) 9828 if (fclose(fsuccess) || error)
9829 { 9829 {
9830 fprintf(stderr, "%s: write failed\n", touch); 9830 fprintf(stderr, "%s: write failed\n", touch);
9831 exit(1); 9831 exit(1);
9832 } 9832 }
9833 } 9833 }
9834 } 9834 }
9835 9835
9836 return 0; 9836 return 0;
9837} 9837}
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/README b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/README
index 86583cc..fa979fc 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/README
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/README
@@ -1,10 +1,10 @@
1This demonstrates the use of PNG_USER_CONFIG, pngusr.h and pngusr.dfa 1This demonstrates the use of PNG_USER_CONFIG, pngusr.h and pngusr.dfa
2 2
3The makefile builds a minimal read-only decoder with embedded libpng 3The makefile builds a minimal read-only decoder with embedded libpng
4and zlib. 4and zlib.
5 5
6Specify the location of the zlib source (1.2.1 or later) as ZLIBSRC 6Specify the location of the zlib source (1.2.1 or later) as ZLIBSRC
7on the make command line. 7on the make command line.
8 8
9If you prefer to use the shared libraries, go to contrib/pngminus 9If you prefer to use the shared libraries, go to contrib/pngminus
10and build the png2pnm application there. 10and build the png2pnm application there.
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/makefile b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/makefile
index 9692e0a..e10e122 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/makefile
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/makefile
@@ -1,150 +1,150 @@
1# Makefile for PngMinus (pngm2pnm) 1# Makefile for PngMinus (pngm2pnm)
2# Linux / Unix 2# Linux / Unix
3 3
4#CC=cc 4#CC=cc
5CC=gcc 5CC=gcc
6LD=$(CC) 6LD=$(CC)
7 7
8# If awk fails try 8# If awk fails try
9# make AWK=nawk 9# make AWK=nawk
10 10
11# If cpp fails try 11# If cpp fails try
12# make CPP=/lib/cpp 12# make CPP=/lib/cpp
13 13
14RM=rm -f 14RM=rm -f
15COPY=cp 15COPY=cp
16 16
17CFLAGS=-DPNG_USER_CONFIG -DNO_GZCOMPRESS -DNO_GZIP -I. -O1 17CFLAGS=-DPNG_USER_CONFIG -DNO_GZCOMPRESS -DNO_GZIP -I. -O1
18 18
19C=.c 19C=.c
20O=.o 20O=.o
21L=.a 21L=.a
22E= 22E=
23 23
24# Where to find the source code: 24# Where to find the source code:
25PNGSRC =../../.. 25PNGSRC =../../..
26ZLIBSRC=$(PNGSRC)/../zlib 26ZLIBSRC=$(PNGSRC)/../zlib
27PROGSRC=$(PNGSRC)/contrib/pngminus 27PROGSRC=$(PNGSRC)/contrib/pngminus
28 28
29# Zlib (minimal inflate requirements - crc32 is used by libpng) 29# Zlib (minimal inflate requirements - crc32 is used by libpng)
30# zutil can be eliminated if you provide your own zcalloc and zcfree 30# zutil can be eliminated if you provide your own zcalloc and zcfree
31ZSRCS = adler32$(C) crc32$(C) \ 31ZSRCS = adler32$(C) crc32$(C) \
32 inffast$(C) inflate$(C) inftrees$(C) \ 32 inffast$(C) inflate$(C) inftrees$(C) \
33 zutil$(C) 33 zutil$(C)
34 34
35# Standard headers 35# Standard headers
36ZH = zlib.h crc32.h inffast.h inffixed.h \ 36ZH = zlib.h crc32.h inffast.h inffixed.h \
37 inflate.h inftrees.h zutil.h 37 inflate.h inftrees.h zutil.h
38 38
39# Machine generated headers 39# Machine generated headers
40ZCONF = zconf.h 40ZCONF = zconf.h
41 41
42# Headers callers use 42# Headers callers use
43ZINC = zlib.h $(ZCONF) 43ZINC = zlib.h $(ZCONF)
44 44
45# Headers the Zlib source uses 45# Headers the Zlib source uses
46ZHDRS = $(ZH) $(ZCONF) 46ZHDRS = $(ZH) $(ZCONF)
47 47
48ZOBJS = adler32$(O) crc32$(O) \ 48ZOBJS = adler32$(O) crc32$(O) \
49 inffast$(O) inflate$(O) inftrees$(O) \ 49 inffast$(O) inflate$(O) inftrees$(O) \
50 zutil$(O) 50 zutil$(O)
51 51
52# libpng 52# libpng
53PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \ 53PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \
54 pngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \ 54 pngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \
55 pngset$(C) pngtrans$(C) 55 pngset$(C) pngtrans$(C)
56 56
57# Standard headers 57# Standard headers
58PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h 58PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h
59 59
60# Machine generated headers 60# Machine generated headers
61PNGCONF=pnglibconf.h 61PNGCONF=pnglibconf.h
62 62
63# Headers callers use 63# Headers callers use
64PNGINC= png.h pngconf.h pngusr.h $(PNGCONF) 64PNGINC= png.h pngconf.h pngusr.h $(PNGCONF)
65 65
66# Headers the PNG library uses 66# Headers the PNG library uses
67PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h 67PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h
68 68
69PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \ 69PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
70 pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \ 70 pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
71 pngset$(O) pngtrans$(O) 71 pngset$(O) pngtrans$(O)
72 72
73PROGSRCS= pngm2pnm$(C) 73PROGSRCS= pngm2pnm$(C)
74PROGHDRS= 74PROGHDRS=
75PROGDOCS= 75PROGDOCS=
76PROGOBJS= pngm2pnm$(O) 76PROGOBJS= pngm2pnm$(O)
77 77
78OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS) 78OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)
79 79
80# implicit make rules ------------------------------------------------------- 80# implicit make rules -------------------------------------------------------
81 81
82# note: dependencies do not work on implicit rule lines 82# note: dependencies do not work on implicit rule lines
83.c$(O): 83.c$(O):
84 $(CC) -c $(CFLAGS) $< 84 $(CC) -c $(CFLAGS) $<
85 85
86# dependencies 86# dependencies
87 87
88all: pngm2pnm$(E) 88all: pngm2pnm$(E)
89 89
90pngm2pnm$(E): $(OBJS) 90pngm2pnm$(E): $(OBJS)
91 $(LD) -o pngm2pnm$(E) $(OBJS) 91 $(LD) -o pngm2pnm$(E) $(OBJS)
92 92
93# The DFA_XTRA setting turns all libpng options off then 93# The DFA_XTRA setting turns all libpng options off then
94# turns on those required for this minimal build. 94# turns on those required for this minimal build.
95# The CPP_FLAGS setting causes pngusr.h to be included in 95# The CPP_FLAGS setting causes pngusr.h to be included in
96# both the build of pnglibconf.h and, subsequently, when 96# both the build of pnglibconf.h and, subsequently, when
97# building libpng itself. 97# building libpng itself.
98$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak\ 98$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak\
99 $(PNGSRC)/scripts/pnglibconf.dfa \ 99 $(PNGSRC)/scripts/pnglibconf.dfa \
100 $(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa 100 $(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa
101 $(RM) pnglibconf.h pnglibconf.dfn 101 $(RM) pnglibconf.h pnglibconf.dfn
102 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\ 102 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\
103 srcdir=$(PNGSRC) CPPFLAGS="-DPNG_USER_CONFIG"\ 103 srcdir=$(PNGSRC) CPPFLAGS="-DPNG_USER_CONFIG"\
104 DFA_XTRA="pngusr.dfa" $@ 104 DFA_XTRA="pngusr.dfa" $@
105 105
106clean: 106clean:
107 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\ 107 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\
108 srcdir=$(PNGSRC) clean 108 srcdir=$(PNGSRC) clean
109 $(RM) pngm2pnm$(O) 109 $(RM) pngm2pnm$(O)
110 $(RM) pngm2pnm$(E) 110 $(RM) pngm2pnm$(E)
111 $(RM) $(OBJS) 111 $(RM) $(OBJS)
112 112
113# distclean also removes the copied source and headers 113# distclean also removes the copied source and headers
114distclean: clean 114distclean: clean
115 $(RM) -r scripts # historical reasons 115 $(RM) -r scripts # historical reasons
116 $(RM) $(PNGSRCS) $(PNGH) 116 $(RM) $(PNGSRCS) $(PNGH)
117 $(RM) $(ZSRCS) $(ZH) $(ZCONF) 117 $(RM) $(ZSRCS) $(ZH) $(ZCONF)
118 $(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS) 118 $(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS)
119 119
120# Header file dependencies: 120# Header file dependencies:
121$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC) 121$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC)
122$(PNGOBJS): $(PNGHDRS) $(ZINC) 122$(PNGOBJS): $(PNGHDRS) $(ZINC)
123$(ZOBJS): $(ZHDRS) 123$(ZOBJS): $(ZHDRS)
124 124
125# Gather the source code from the respective directories 125# Gather the source code from the respective directories
126$(PNGSRCS) $(PNGH): $(PNGSRC)/$@ 126$(PNGSRCS) $(PNGH): $(PNGSRC)/$@
127 $(RM) $@ 127 $(RM) $@
128 $(COPY) $(PNGSRC)/$@ $@ 128 $(COPY) $(PNGSRC)/$@ $@
129 129
130# No dependency on the ZLIBSRC target so that it only needs 130# No dependency on the ZLIBSRC target so that it only needs
131# to be specified once. 131# to be specified once.
132$(ZSRCS) $(ZH): 132$(ZSRCS) $(ZH):
133 $(RM) $@ 133 $(RM) $@
134 $(COPY) $(ZLIBSRC)/$@ $@ 134 $(COPY) $(ZLIBSRC)/$@ $@
135 135
136# The unconfigured zconf.h varies in name according to the 136# The unconfigured zconf.h varies in name according to the
137# zlib release 137# zlib release
138$(ZCONF): 138$(ZCONF):
139 $(RM) $@ 139 $(RM) $@
140 @for f in zconf.h.in zconf.in.h zconf.h; do\ 140 @for f in zconf.h.in zconf.in.h zconf.h; do\
141 test -r $(ZLIBSRC)/$$f &&\ 141 test -r $(ZLIBSRC)/$$f &&\
142 echo $(COPY) $(ZLIBSRC)/$$f $@ &&\ 142 echo $(COPY) $(ZLIBSRC)/$$f $@ &&\
143 $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\ 143 $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\
144 done; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1 144 done; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1
145 145
146pngm2pnm.c: $(PROGSRC)/png2pnm.c 146pngm2pnm.c: $(PROGSRC)/png2pnm.c
147 $(RM) $@ 147 $(RM) $@
148 $(COPY) $(PROGSRC)/png2pnm.c $@ 148 $(COPY) $(PROGSRC)/png2pnm.c $@
149 149
150# End of makefile for pngm2pnm 150# End of makefile for pngm2pnm
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.dfa b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.dfa
index 8a66d64..70d528b 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.dfa
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.dfa
@@ -1,39 +1,39 @@
1# pngminim/decoder/pngusr.dfa 1# pngminim/decoder/pngusr.dfa
2# 2#
3# Copyright (c) 2010-2011 Glenn Randers-Pehrson 3# Copyright (c) 2010-2011 Glenn Randers-Pehrson
4# 4#
5# This code is released under the libpng license. 5# This code is released under the libpng license.
6# For conditions of distribution and use, see the disclaimer 6# For conditions of distribution and use, see the disclaimer
7# and license in png.h 7# and license in png.h
8 8
9# First all the build options off: 9# First all the build options off:
10 10
11everything = off 11everything = off
12 12
13# All that is required is some read code. This example switches 13# All that is required is some read code. This example switches
14# on the sequential read code (see ../preader for a progressive 14# on the sequential read code (see ../preader for a progressive
15# read example). 15# read example).
16 16
17option SEQUENTIAL_READ on 17option SEQUENTIAL_READ on
18 18
19# You must choose fixed or floating point arithmetic: 19# You must choose fixed or floating point arithmetic:
20# option FLOATING_POINT on 20# option FLOATING_POINT on
21 21
22option FIXED_POINT on 22option FIXED_POINT on
23 23
24# You must chose the internal fixed point implementation or to 24# You must chose the internal fixed point implementation or to
25# use the system floating point. The latter is considerably 25# use the system floating point. The latter is considerably
26# smaller (by about 1kbyte on an x86 system): 26# smaller (by about 1kbyte on an x86 system):
27# option FLOATING_ARITHMETIC on 27# option FLOATING_ARITHMETIC on
28 28
29option FLOATING_ARITHMETIC off 29option FLOATING_ARITHMETIC off
30 30
31# Your program will probably need other options. The example 31# Your program will probably need other options. The example
32# program here, pngm2pnm, requires the following. Take a look 32# program here, pngm2pnm, requires the following. Take a look
33# at pnglibconf.h to find out the full set of what has to be 33# at pnglibconf.h to find out the full set of what has to be
34# enabled to make the following work. 34# enabled to make the following work.
35 35
36option SETJMP on 36option SETJMP on
37option STDIO on 37option STDIO on
38option READ_EXPAND on 38option READ_EXPAND on
39option READ_STRIP_16_TO_8 on 39option READ_STRIP_16_TO_8 on
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.h
index 2991c17..9d9c50c 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.h
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/decoder/pngusr.h
@@ -1,24 +1,24 @@
1/* minrdpngconf.h: headers to make a minimal png-read-only library 1/* minrdpngconf.h: headers to make a minimal png-read-only library
2 * 2 *
3 * Copyright (c) 2007, 2010-2011 Glenn Randers-Pehrson 3 * Copyright (c) 2007, 2010-2011 Glenn Randers-Pehrson
4 * 4 *
5 * This code is released under the libpng license. 5 * This code is released under the libpng license.
6 * For conditions of distribution and use, see the disclaimer 6 * For conditions of distribution and use, see the disclaimer
7 * and license in png.h 7 * and license in png.h
8 * 8 *
9 * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson 9 * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson
10 */ 10 */
11 11
12#ifndef MINRDPNGCONF_H 12#ifndef MINRDPNGCONF_H
13#define MINRDPNGCONF_H 13#define MINRDPNGCONF_H
14 14
15/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */ 15/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */
16 16
17/* List options to turn off features of the build that do not 17/* List options to turn off features of the build that do not
18 * affect the API (so are not recorded in pnglibconf.h) 18 * affect the API (so are not recorded in pnglibconf.h)
19 */ 19 */
20 20
21#define PNG_NO_WARNINGS 21#define PNG_NO_WARNINGS
22#define PNG_ALIGN_TYPE PNG_ALIGN_NONE 22#define PNG_ALIGN_TYPE PNG_ALIGN_NONE
23 23
24#endif /* MINRDPNGCONF_H */ 24#endif /* MINRDPNGCONF_H */
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/README b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/README
index f8a8b6d..ff9aa45 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/README
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/README
@@ -1,10 +1,10 @@
1This demonstrates the use of PNG_USER_CONFIG and pngusr.h 1This demonstrates the use of PNG_USER_CONFIG and pngusr.h
2 2
3The makefile builds a minimal write-only decoder with embedded libpng 3The makefile builds a minimal write-only decoder with embedded libpng
4and zlib. 4and zlib.
5 5
6Specify the location of the zlib source (1.2.1 or later) as ZLIBSRC 6Specify the location of the zlib source (1.2.1 or later) as ZLIBSRC
7on the make command line. 7on the make command line.
8 8
9If you prefer to use the shared libraries, go to contrib/pngminus 9If you prefer to use the shared libraries, go to contrib/pngminus
10and build the pnm2png application there. 10and build the pnm2png application there.
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/makefile b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/makefile
index 7374a6c..d6f39e2 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/makefile
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/makefile
@@ -1,149 +1,149 @@
1# Makefile for PngMinus (pnm2pngm) 1# Makefile for PngMinus (pnm2pngm)
2# Linux / Unix 2# Linux / Unix
3 3
4#CC=cc 4#CC=cc
5CC=gcc 5CC=gcc
6LD=$(CC) 6LD=$(CC)
7 7
8# If awk fails try 8# If awk fails try
9# make AWK=nawk 9# make AWK=nawk
10 10
11# If cpp fails try 11# If cpp fails try
12# make CPP=/lib/cpp 12# make CPP=/lib/cpp
13 13
14RM=rm -f 14RM=rm -f
15COPY=cp 15COPY=cp
16 16
17CFLAGS=-DPNG_USER_CONFIG -DNO_GZIP -I. -O1 17CFLAGS=-DPNG_USER_CONFIG -DNO_GZIP -I. -O1
18 18
19C=.c 19C=.c
20O=.o 20O=.o
21L=.a 21L=.a
22E= 22E=
23 23
24# Where to find the source code: 24# Where to find the source code:
25PNGSRC =../../.. 25PNGSRC =../../..
26ZLIBSRC=$(PNGSRC)/../zlib 26ZLIBSRC=$(PNGSRC)/../zlib
27PROGSRC=$(PNGSRC)/contrib/pngminus 27PROGSRC=$(PNGSRC)/contrib/pngminus
28 28
29# Zlib 29# Zlib
30ZSRCS = adler32$(C) compress$(C) crc32$(C) deflate$(C) \ 30ZSRCS = adler32$(C) compress$(C) crc32$(C) deflate$(C) \
31 trees$(C) zutil$(C) 31 trees$(C) zutil$(C)
32 32
33# Standard headers 33# Standard headers
34#ZH = zlib.h crc32.h deflate.h trees.h zutil.h 34#ZH = zlib.h crc32.h deflate.h trees.h zutil.h
35ZH = zlib.h crc32.h deflate.h trees.h zutil.h 35ZH = zlib.h crc32.h deflate.h trees.h zutil.h
36 36
37# Machine generated headers 37# Machine generated headers
38ZCONF = zconf.h 38ZCONF = zconf.h
39 39
40# Headers callers use 40# Headers callers use
41ZINC = zlib.h $(ZCONF) 41ZINC = zlib.h $(ZCONF)
42 42
43# Headers the Zlib source uses 43# Headers the Zlib source uses
44ZHDRS = $(ZH) $(ZCONF) 44ZHDRS = $(ZH) $(ZCONF)
45 45
46# compress is not required; it is needed to link the zlib 46# compress is not required; it is needed to link the zlib
47# code because deflate defines an unused API function deflateBound 47# code because deflate defines an unused API function deflateBound
48# which itself calls compressBound from compress. 48# which itself calls compressBound from compress.
49ZOBJS = adler32$(O) compress$(O) crc32$(O) deflate$(O) \ 49ZOBJS = adler32$(O) compress$(O) crc32$(O) deflate$(O) \
50 trees$(O) zutil$(O) 50 trees$(O) zutil$(O)
51 51
52# libpng 52# libpng
53PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \ 53PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \
54 pngset$(C) pngtrans$(C) pngwio$(C) pngwrite$(C) \ 54 pngset$(C) pngtrans$(C) pngwio$(C) pngwrite$(C) \
55 pngwtran$(C) pngwutil$(C) 55 pngwtran$(C) pngwutil$(C)
56 56
57# Standard headers 57# Standard headers
58PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h 58PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h
59 59
60# Machine generated headers 60# Machine generated headers
61PNGCONF=pnglibconf.h 61PNGCONF=pnglibconf.h
62 62
63# Headers callers use 63# Headers callers use
64PNGINC= png.h pngconf.h pngusr.h $(PNGCONF) 64PNGINC= png.h pngconf.h pngusr.h $(PNGCONF)
65 65
66# Headers the PNG library uses 66# Headers the PNG library uses
67PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h 67PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h
68 68
69PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \ 69PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
70 pngset$(O) pngtrans$(O) pngwio$(O) pngwrite$(O) \ 70 pngset$(O) pngtrans$(O) pngwio$(O) pngwrite$(O) \
71 pngwtran$(O) pngwutil$(O) 71 pngwtran$(O) pngwutil$(O)
72 72
73PROGSRCS= pnm2pngm$(C) 73PROGSRCS= pnm2pngm$(C)
74PROGHDRS= 74PROGHDRS=
75PROGDOCS= 75PROGDOCS=
76PROGOBJS= pnm2pngm$(O) 76PROGOBJS= pnm2pngm$(O)
77 77
78OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS) 78OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)
79 79
80# implicit make rules ------------------------------------------------------- 80# implicit make rules -------------------------------------------------------
81 81
82.c$(O): 82.c$(O):
83 $(CC) -c $(CFLAGS) $< 83 $(CC) -c $(CFLAGS) $<
84 84
85# dependencies 85# dependencies
86 86
87all: pnm2pngm$(E) 87all: pnm2pngm$(E)
88 88
89pnm2pngm$(E): $(OBJS) 89pnm2pngm$(E): $(OBJS)
90 $(LD) -o pnm2pngm$(E) $(OBJS) 90 $(LD) -o pnm2pngm$(E) $(OBJS)
91 91
92# The DFA_XTRA setting turns all libpng options off then 92# The DFA_XTRA setting turns all libpng options off then
93# turns on those required for this minimal build. 93# turns on those required for this minimal build.
94# The CPP_FLAGS setting causes pngusr.h to be included in 94# The CPP_FLAGS setting causes pngusr.h to be included in
95# both the build of pnglibconf.h and, subsequently, when 95# both the build of pnglibconf.h and, subsequently, when
96# building libpng itself. 96# building libpng itself.
97$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak\ 97$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak\
98 $(PNGSRC)/scripts/pnglibconf.dfa \ 98 $(PNGSRC)/scripts/pnglibconf.dfa \
99 $(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa 99 $(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa
100 $(RM) pnglibconf.h pnglibconf.dfn 100 $(RM) pnglibconf.h pnglibconf.dfn
101 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\ 101 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\
102 srcdir=$(PNGSRC) CPPFLAGS="-DPNG_USER_CONFIG"\ 102 srcdir=$(PNGSRC) CPPFLAGS="-DPNG_USER_CONFIG"\
103 DFA_XTRA="pngusr.dfa" $@ 103 DFA_XTRA="pngusr.dfa" $@
104 104
105clean: 105clean:
106 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\ 106 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\
107 srcdir=$(PNGSRC) clean 107 srcdir=$(PNGSRC) clean
108 $(RM) pnm2pngm$(O) 108 $(RM) pnm2pngm$(O)
109 $(RM) pnm2pngm$(E) 109 $(RM) pnm2pngm$(E)
110 $(RM) $(OBJS) 110 $(RM) $(OBJS)
111 111
112# distclean also removes the copied source and headers 112# distclean also removes the copied source and headers
113distclean: clean 113distclean: clean
114 $(RM) -r scripts # historical reasons 114 $(RM) -r scripts # historical reasons
115 $(RM) $(PNGSRCS) $(PNGH) 115 $(RM) $(PNGSRCS) $(PNGH)
116 $(RM) $(ZSRCS) $(ZH) $(ZCONF) 116 $(RM) $(ZSRCS) $(ZH) $(ZCONF)
117 $(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS) 117 $(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS)
118 118
119# Header file dependencies: 119# Header file dependencies:
120$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC) 120$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC)
121$(PNGOBJS): $(PNGHDRS) $(ZINC) 121$(PNGOBJS): $(PNGHDRS) $(ZINC)
122$(ZOBJS): $(ZHDRS) 122$(ZOBJS): $(ZHDRS)
123 123
124# Gather the source code from the respective directories 124# Gather the source code from the respective directories
125$(PNGSRCS) $(PNGH): $(PNGSRC)/$@ 125$(PNGSRCS) $(PNGH): $(PNGSRC)/$@
126 $(RM) $@ 126 $(RM) $@
127 $(COPY) $(PNGSRC)/$@ $@ 127 $(COPY) $(PNGSRC)/$@ $@
128 128
129# No dependency on the ZLIBSRC target so that it only needs 129# No dependency on the ZLIBSRC target so that it only needs
130# to be specified once. 130# to be specified once.
131$(ZSRCS) $(ZH): 131$(ZSRCS) $(ZH):
132 $(RM) $@ 132 $(RM) $@
133 $(COPY) $(ZLIBSRC)/$@ $@ 133 $(COPY) $(ZLIBSRC)/$@ $@
134 134
135# The unconfigured zconf.h varies in name according to the 135# The unconfigured zconf.h varies in name according to the
136# zlib release 136# zlib release
137$(ZCONF): 137$(ZCONF):
138 $(RM) $@ 138 $(RM) $@
139 @for f in zconf.h.in zconf.in.h zconf.h; do\ 139 @for f in zconf.h.in zconf.in.h zconf.h; do\
140 test -r $(ZLIBSRC)/$$f &&\ 140 test -r $(ZLIBSRC)/$$f &&\
141 echo $(COPY) $(ZLIBSRC)/$$f $@ &&\ 141 echo $(COPY) $(ZLIBSRC)/$$f $@ &&\
142 $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\ 142 $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\
143 done; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1 143 done; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1
144 144
145pnm2pngm.c: $(PROGSRC)/pnm2png.c 145pnm2pngm.c: $(PROGSRC)/pnm2png.c
146 $(RM) $@ 146 $(RM) $@
147 $(COPY) $(PROGSRC)/pnm2png.c $@ 147 $(COPY) $(PROGSRC)/pnm2png.c $@
148 148
149# End of makefile for pnm2pngm 149# End of makefile for pnm2pngm
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.dfa b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.dfa
index 448f821..ee88443 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.dfa
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.dfa
@@ -1,35 +1,35 @@
1# pngminim/encoder/pngusr.dfa 1# pngminim/encoder/pngusr.dfa
2# 2#
3# Copyright (c) 2010-2011 Glenn Randers-Pehrson 3# Copyright (c) 2010-2011 Glenn Randers-Pehrson
4# 4#
5# This code is released under the libpng license. 5# This code is released under the libpng license.
6# For conditions of distribution and use, see the disclaimer 6# For conditions of distribution and use, see the disclaimer
7# and license in png.h 7# and license in png.h
8 8
9# First all the build options off: 9# First all the build options off:
10 10
11everything = off 11everything = off
12 12
13# Switch on the write code - this makes a minimalist encoder 13# Switch on the write code - this makes a minimalist encoder
14 14
15option WRITE on 15option WRITE on
16 16
17# You must choose fixed or floating point arithmetic: 17# You must choose fixed or floating point arithmetic:
18# option FLOATING_POINT on 18# option FLOATING_POINT on
19 19
20option FIXED_POINT on 20option FIXED_POINT on
21 21
22# You must chose the internal fixed point implementation or to 22# You must chose the internal fixed point implementation or to
23# use the system floating point. The latter is considerably 23# use the system floating point. The latter is considerably
24# smaller (by about 1kbyte on an x86 system): 24# smaller (by about 1kbyte on an x86 system):
25# option FLOATING_ARITHMETIC on 25# option FLOATING_ARITHMETIC on
26 26
27option FLOATING_ARITHMETIC off 27option FLOATING_ARITHMETIC off
28 28
29# Your program will probably need other options. The example 29# Your program will probably need other options. The example
30# program here, pnm2pngm, requires the following. Take a look 30# program here, pnm2pngm, requires the following. Take a look
31# at pnglibconf.h to find out the full set of what has to be 31# at pnglibconf.h to find out the full set of what has to be
32# enabled to make the following work. 32# enabled to make the following work.
33 33
34option SETJMP on 34option SETJMP on
35option STDIO on 35option STDIO on
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.h
index bafbf13..2033aad 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.h
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/encoder/pngusr.h
@@ -1,24 +1,24 @@
1/* minwrpngconf.h: headers to make a minimal png-write-only library 1/* minwrpngconf.h: headers to make a minimal png-write-only library
2 * 2 *
3 * Copyright (c) 2007, 2010-2011 Glenn Randers-Pehrson 3 * Copyright (c) 2007, 2010-2011 Glenn Randers-Pehrson
4 * 4 *
5 * This code is released under the libpng license. 5 * This code is released under the libpng license.
6 * For conditions of distribution and use, see the disclaimer 6 * For conditions of distribution and use, see the disclaimer
7 * and license in png.h 7 * and license in png.h
8 * 8 *
9 * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson 9 * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson
10 */ 10 */
11 11
12#ifndef MINWRPNGCONF_H 12#ifndef MINWRPNGCONF_H
13#define MINWRPNGCONF_H 13#define MINWRPNGCONF_H
14 14
15/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */ 15/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */
16 16
17/* List options to turn off features of the build that do not 17/* List options to turn off features of the build that do not
18 * affect the API (so are not recorded in pnglibconf.h) 18 * affect the API (so are not recorded in pnglibconf.h)
19 */ 19 */
20 20
21#define PNG_NO_WARNINGS 21#define PNG_NO_WARNINGS
22#define PNG_ALIGN_TYPE PNG_ALIGN_NONE 22#define PNG_ALIGN_TYPE PNG_ALIGN_NONE
23 23
24#endif /* MINWRPNGCONF_H */ 24#endif /* MINWRPNGCONF_H */
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/README b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/README
index e40024e..faa8356 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/README
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/README
@@ -1,15 +1,15 @@
1This demonstrates the use of PNG_USER_CONFIG and pngusr.h 1This demonstrates the use of PNG_USER_CONFIG and pngusr.h
2 2
3The makefile builds a minimal read-only progressive decoder with 3The makefile builds a minimal read-only progressive decoder with
4embedded libpng, zlib and your system's X library. 4embedded libpng, zlib and your system's X library.
5 5
6Specify the location of the zlib source (1.2.1 or later) as ZLIBSRC 6Specify the location of the zlib source (1.2.1 or later) as ZLIBSRC
7on the make command line. 7on the make command line.
8 8
9Edit makefile if required, to find your X library and include files, 9Edit makefile if required, to find your X library and include files,
10then 10then
11 11
12 make ZLIBSRC=directory 12 make ZLIBSRC=directory
13 13
14If you prefer to use the shared libraries, go to contrib/gregbook 14If you prefer to use the shared libraries, go to contrib/gregbook
15and build the rpng2-x application there. 15and build the rpng2-x application there.
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/makefile b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/makefile
index a367661..f4b0ccd 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/makefile
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/makefile
@@ -1,165 +1,165 @@
1# Makefile for PngMinus (rpng2) 1# Makefile for PngMinus (rpng2)
2# Linux / Unix 2# Linux / Unix
3 3
4#CC=cc 4#CC=cc
5CC=gcc 5CC=gcc
6LD=$(CC) 6LD=$(CC)
7 7
8# If awk fails try 8# If awk fails try
9# make AWK=nawk 9# make AWK=nawk
10 10
11# If cpp fails try 11# If cpp fails try
12# make CPP=/lib/cpp 12# make CPP=/lib/cpp
13 13
14RM=rm -f 14RM=rm -f
15COPY=cp 15COPY=cp
16 16
17#XINC = -I/usr/include # old-style, stock X distributions 17#XINC = -I/usr/include # old-style, stock X distributions
18#XLIB = -L/usr/lib/X11 -lX11 # (including SGI IRIX) 18#XLIB = -L/usr/lib/X11 -lX11 # (including SGI IRIX)
19 19
20#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows) 20#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows)
21#XLIB = -L/usr/openwin/lib -lX11 21#XLIB = -L/usr/openwin/lib -lX11
22 22
23XINC = -I/usr/X11R6/include # new X distributions (X.org, etc.) 23XINC = -I/usr/X11R6/include # new X distributions (X.org, etc.)
24XLIB = -L/usr/X11R6/lib -lX11 24XLIB = -L/usr/X11R6/lib -lX11
25#XLIB = -L/usr/X11R6/lib64 -lX11 # e.g., Red Hat on AMD64 25#XLIB = -L/usr/X11R6/lib64 -lX11 # e.g., Red Hat on AMD64
26 26
27#XINC = -I/usr/local/include # FreeBSD 27#XINC = -I/usr/local/include # FreeBSD
28#XLIB = -L/usr/local/lib -lX11 28#XLIB = -L/usr/local/lib -lX11
29 29
30#LIBS = $(XLIB) 30#LIBS = $(XLIB)
31LIBS = $(XLIB) -lm #platforms that need libm 31LIBS = $(XLIB) -lm #platforms that need libm
32 32
33CFLAGS=-DPNG_USER_CONFIG -DNO_GZCOMPRESS -DNO_GZIP -I. $(XINC) -O1 33CFLAGS=-DPNG_USER_CONFIG -DNO_GZCOMPRESS -DNO_GZIP -I. $(XINC) -O1
34 34
35C=.c 35C=.c
36O=.o 36O=.o
37L=.a 37L=.a
38E= 38E=
39 39
40# Where to find the source code: 40# Where to find the source code:
41PNGSRC =../../.. 41PNGSRC =../../..
42ZLIBSRC=$(PNGSRC)/../zlib 42ZLIBSRC=$(PNGSRC)/../zlib
43PROGSRC=$(PNGSRC)/contrib/gregbook 43PROGSRC=$(PNGSRC)/contrib/gregbook
44 44
45# Zlib (minimal inflate requirements - crc32 is used by libpng) 45# Zlib (minimal inflate requirements - crc32 is used by libpng)
46# zutil can be eliminated if you provide your own zcalloc and zcfree 46# zutil can be eliminated if you provide your own zcalloc and zcfree
47ZSRCS = adler32$(C) crc32$(C) \ 47ZSRCS = adler32$(C) crc32$(C) \
48 inffast$(C) inflate$(C) inftrees$(C) \ 48 inffast$(C) inflate$(C) inftrees$(C) \
49 zutil$(C) 49 zutil$(C)
50 50
51# Standard headers 51# Standard headers
52ZH = zlib.h crc32.h inffast.h inffixed.h \ 52ZH = zlib.h crc32.h inffast.h inffixed.h \
53 inflate.h inftrees.h zutil.h 53 inflate.h inftrees.h zutil.h
54 54
55# Machine generated headers 55# Machine generated headers
56ZCONF = zconf.h 56ZCONF = zconf.h
57 57
58# Headers callers use 58# Headers callers use
59ZINC = zlib.h $(ZCONF) 59ZINC = zlib.h $(ZCONF)
60 60
61# Headers the Zlib source uses 61# Headers the Zlib source uses
62ZHDRS = $(ZH) $(ZCONF) 62ZHDRS = $(ZH) $(ZCONF)
63 63
64ZOBJS = adler32$(O) crc32$(O) \ 64ZOBJS = adler32$(O) crc32$(O) \
65 inffast$(O) inflate$(O) inftrees$(O) \ 65 inffast$(O) inflate$(O) inftrees$(O) \
66 zutil$(O) 66 zutil$(O)
67 67
68# libpng 68# libpng
69PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \ 69PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \
70 pngpread$(C) pngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \ 70 pngpread$(C) pngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \
71 pngset$(C) pngtrans$(C) 71 pngset$(C) pngtrans$(C)
72 72
73# Standard headers 73# Standard headers
74PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h 74PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h
75 75
76# Machine generated headers 76# Machine generated headers
77PNGCONF=pnglibconf.h 77PNGCONF=pnglibconf.h
78 78
79# Headers callers use 79# Headers callers use
80PNGINC= png.h pngconf.h pngusr.h $(PNGCONF) 80PNGINC= png.h pngconf.h pngusr.h $(PNGCONF)
81 81
82# Headers the PNG library uses 82# Headers the PNG library uses
83PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h 83PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h
84 84
85PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \ 85PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
86 pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \ 86 pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
87 pngset$(O) pngtrans$(O) 87 pngset$(O) pngtrans$(O)
88 88
89PROGSRCS= rpng2-x$(C) readpng2$(C) 89PROGSRCS= rpng2-x$(C) readpng2$(C)
90PROGHDRS= readpng2.h 90PROGHDRS= readpng2.h
91PROGDOCS= COPYING LICENSE 91PROGDOCS= COPYING LICENSE
92PROGOBJS= rpng2-x$(O) readpng2$(O) 92PROGOBJS= rpng2-x$(O) readpng2$(O)
93 93
94OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS) 94OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)
95 95
96# implicit make rules ------------------------------------------------------- 96# implicit make rules -------------------------------------------------------
97 97
98.c$(O): 98.c$(O):
99 $(CC) -c $(CFLAGS) $< 99 $(CC) -c $(CFLAGS) $<
100 100
101# dependencies 101# dependencies
102 102
103all: $(PROGDOCS) rpng2-x$(E) 103all: $(PROGDOCS) rpng2-x$(E)
104 104
105rpng2-x$(E): $(OBJS) 105rpng2-x$(E): $(OBJS)
106 $(LD) -o rpng2-x$(E) $(OBJS) $(LIBS) 106 $(LD) -o rpng2-x$(E) $(OBJS) $(LIBS)
107 107
108# The DFA_XTRA setting turns all libpng options off then 108# The DFA_XTRA setting turns all libpng options off then
109# turns on those required for this minimal build. 109# turns on those required for this minimal build.
110# The CPP_FLAGS setting causes pngusr.h to be included in 110# The CPP_FLAGS setting causes pngusr.h to be included in
111# both the build of pnglibconf.h and, subsequently, when 111# both the build of pnglibconf.h and, subsequently, when
112# building libpng itself. 112# building libpng itself.
113$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak\ 113$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak\
114 $(PNGSRC)/scripts/pnglibconf.dfa \ 114 $(PNGSRC)/scripts/pnglibconf.dfa \
115 $(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa 115 $(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa
116 $(RM) pnglibconf.h pnglibconf.dfn 116 $(RM) pnglibconf.h pnglibconf.dfn
117 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\ 117 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\
118 srcdir=$(PNGSRC) CPPFLAGS="-DPNG_USER_CONFIG"\ 118 srcdir=$(PNGSRC) CPPFLAGS="-DPNG_USER_CONFIG"\
119 DFA_XTRA="pngusr.dfa" $@ 119 DFA_XTRA="pngusr.dfa" $@
120 120
121clean: 121clean:
122 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\ 122 $(MAKE) $(MAKEFLAGS) -f $(PNGSRC)/scripts/pnglibconf.mak\
123 srcdir=$(PNGSRC) clean 123 srcdir=$(PNGSRC) clean
124 $(RM) rpng2-x$(O) 124 $(RM) rpng2-x$(O)
125 $(RM) rpng2-x$(E) 125 $(RM) rpng2-x$(E)
126 $(RM) $(OBJS) 126 $(RM) $(OBJS)
127 127
128# distclean also removes the copied source and headers 128# distclean also removes the copied source and headers
129distclean: clean 129distclean: clean
130 $(RM) -r scripts # historical reasons 130 $(RM) -r scripts # historical reasons
131 $(RM) $(PNGSRCS) $(PNGH) 131 $(RM) $(PNGSRCS) $(PNGH)
132 $(RM) $(ZSRCS) $(ZH) $(ZCONF) 132 $(RM) $(ZSRCS) $(ZH) $(ZCONF)
133 $(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS) 133 $(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS)
134 134
135# Header file dependencies: 135# Header file dependencies:
136$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC) 136$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC)
137$(PNGOBJS): $(PNGHDRS) $(ZINC) 137$(PNGOBJS): $(PNGHDRS) $(ZINC)
138$(ZOBJS): $(ZHDRS) 138$(ZOBJS): $(ZHDRS)
139 139
140# Gather the source code from the respective directories 140# Gather the source code from the respective directories
141$(PNGSRCS) $(PNGH): $(PNGSRC)/$@ 141$(PNGSRCS) $(PNGH): $(PNGSRC)/$@
142 $(RM) $@ 142 $(RM) $@
143 $(COPY) $(PNGSRC)/$@ $@ 143 $(COPY) $(PNGSRC)/$@ $@
144 144
145# No dependency on the ZLIBSRC target so that it only needs 145# No dependency on the ZLIBSRC target so that it only needs
146# to be specified once. 146# to be specified once.
147$(ZSRCS) $(ZH): 147$(ZSRCS) $(ZH):
148 $(RM) $@ 148 $(RM) $@
149 $(COPY) $(ZLIBSRC)/$@ $@ 149 $(COPY) $(ZLIBSRC)/$@ $@
150 150
151# The unconfigured zconf.h varies in name according to the 151# The unconfigured zconf.h varies in name according to the
152# zlib release 152# zlib release
153$(ZCONF): 153$(ZCONF):
154 $(RM) $@ 154 $(RM) $@
155 @for f in zconf.h.in zconf.in.h zconf.h; do\ 155 @for f in zconf.h.in zconf.in.h zconf.h; do\
156 test -r $(ZLIBSRC)/$$f &&\ 156 test -r $(ZLIBSRC)/$$f &&\
157 echo $(COPY) $(ZLIBSRC)/$$f $@ &&\ 157 echo $(COPY) $(ZLIBSRC)/$$f $@ &&\
158 $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\ 158 $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\
159 done; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1 159 done; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1
160 160
161$(PROGSRCS) $(PROGHDRS) $(PROGDOCS): $(PROGSRC)/$@ 161$(PROGSRCS) $(PROGHDRS) $(PROGDOCS): $(PROGSRC)/$@
162 $(RM) $@ 162 $(RM) $@
163 $(COPY) $(PROGSRC)/$@ $@ 163 $(COPY) $(PROGSRC)/$@ $@
164 164
165# End of makefile for rpng2-x 165# End of makefile for rpng2-x
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.dfa b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.dfa
index 0c991d3..216c421 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.dfa
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.dfa
@@ -1,40 +1,40 @@
1# pngminim/preader/pngusr.dfa 1# pngminim/preader/pngusr.dfa
2# 2#
3# Copyright (c) 2010-2011 Glenn Randers-Pehrson 3# Copyright (c) 2010-2011 Glenn Randers-Pehrson
4# 4#
5# This code is released under the libpng license. 5# This code is released under the libpng license.
6# For conditions of distribution and use, see the disclaimer 6# For conditions of distribution and use, see the disclaimer
7# and license in png.h 7# and license in png.h
8 8
9# First all the build options off: 9# First all the build options off:
10 10
11everything = off 11everything = off
12 12
13# Just switch on the progressive read code 13# Just switch on the progressive read code
14 14
15option PROGRESSIVE_READ on 15option PROGRESSIVE_READ on
16 16
17# You may choose fixed or floating point APIs: 17# You may choose fixed or floating point APIs:
18# option FLOATING_POINT on 18# option FLOATING_POINT on
19 19
20option FIXED_POINT on 20option FIXED_POINT on
21 21
22# You must chose the internal fixed point implementation or to 22# You must chose the internal fixed point implementation or to
23# use the system floating point. The latter is considerably 23# use the system floating point. The latter is considerably
24# smaller (by about 1kbyte on an x86 system): 24# smaller (by about 1kbyte on an x86 system):
25 25
26option FLOATING_ARITHMETIC on 26option FLOATING_ARITHMETIC on
27# option FLOATING_ARITHMETIC off 27# option FLOATING_ARITHMETIC off
28 28
29# Your program will probably need other options. The example 29# Your program will probably need other options. The example
30# program here, rpng2-x, requires the following. Take a look 30# program here, rpng2-x, requires the following. Take a look
31# at pnglibconf.h to find out the full set of what has to be 31# at pnglibconf.h to find out the full set of what has to be
32# enabled to make the following work. 32# enabled to make the following work.
33 33
34option SETJMP on 34option SETJMP on
35option STDIO on 35option STDIO on
36option READ_bKGD on 36option READ_bKGD on
37option READ_GAMMA on 37option READ_GAMMA on
38option READ_EXPAND on 38option READ_EXPAND on
39option READ_STRIP_16_TO_8 on 39option READ_STRIP_16_TO_8 on
40option READ_GRAY_TO_RGB on 40option READ_GRAY_TO_RGB on
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.h
index 7db806f..73cfecf 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.h
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminim/preader/pngusr.h
@@ -1,24 +1,24 @@
1/* minrdpngconf.h: headers to make a minimal png-read-only library 1/* minrdpngconf.h: headers to make a minimal png-read-only library
2 * 2 *
3 * Copyright (c) 2009, 2010-2011 Glenn Randers-Pehrson 3 * Copyright (c) 2009, 2010-2011 Glenn Randers-Pehrson
4 * 4 *
5 * This code is released under the libpng license. 5 * This code is released under the libpng license.
6 * For conditions of distribution and use, see the disclaimer 6 * For conditions of distribution and use, see the disclaimer
7 * and license in png.h 7 * and license in png.h
8 * 8 *
9 * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson 9 * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson
10 */ 10 */
11 11
12#ifndef MINPRDPNGCONF_H 12#ifndef MINPRDPNGCONF_H
13#define MINPRDPNGCONF_H 13#define MINPRDPNGCONF_H
14 14
15/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */ 15/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */
16 16
17/* List options to turn off features of the build that do not 17/* List options to turn off features of the build that do not
18 * affect the API (so are not recorded in pnglibconf.h) 18 * affect the API (so are not recorded in pnglibconf.h)
19 */ 19 */
20 20
21#define PNG_NO_WARNINGS 21#define PNG_NO_WARNINGS
22#define PNG_ALIGN_TYPE PNG_ALIGN_NONE 22#define PNG_ALIGN_TYPE PNG_ALIGN_NONE
23 23
24#endif /* MINPRDPNGCONF_H */ 24#endif /* MINPRDPNGCONF_H */
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/README b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/README
index b0516ec..bbe7407 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/README
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/README
@@ -1,153 +1,153 @@
1PngMinus 1PngMinus
2-------- 2--------
3(copyright Willem van Schaik, 1999) 3(copyright Willem van Schaik, 1999)
4 4
5 5
6License 6License
7------- 7-------
8 8
9Permission to use, copy, modify, and distribute this software and 9Permission to use, copy, modify, and distribute this software and
10its documentation for any purpose and without fee is hereby granted, 10its documentation for any purpose and without fee is hereby granted,
11provided that the above copyright notice appear in all copies and 11provided that the above copyright notice appear in all copies and
12that both that copyright notice and this permission notice appear in 12that both that copyright notice and this permission notice appear in
13supporting documentation. This software is provided "as is" without 13supporting documentation. This software is provided "as is" without
14express or implied warranty. 14express or implied warranty.
15 15
16 16
17Some history 17Some history
18------------ 18------------
19Soon after the creation of PNG in 1995, the need was felt for a set of 19Soon after the creation of PNG in 1995, the need was felt for a set of
20pnmtopng / pngtopnm utilities. Independantly Alexander Lehmann and I 20pnmtopng / pngtopnm utilities. Independantly Alexander Lehmann and I
21(Willem van Schaik) started such a project. Luckily we discovered this 21(Willem van Schaik) started such a project. Luckily we discovered this
22and merged the two together into pnmtopng.tar.gz, which is available 22and merged the two together into pnmtopng.tar.gz, which is available
23from a/o ftp://ftp.simplesystems.org/pub/libpng/png/. 23from a/o ftp://ftp.simplesystems.org/pub/libpng/png/.
24 24
25These two utilities have many, many options and make use of most of the 25These two utilities have many, many options and make use of most of the
26features of PNG, like gamma, alpha, sbit, text-chunks, etc. This makes 26features of PNG, like gamma, alpha, sbit, text-chunks, etc. This makes
27the utilities quite complex and by now not anymore very maintainable. 27the utilities quite complex and by now not anymore very maintainable.
28When we wrote these programs, libpng was still in an early stage. 28When we wrote these programs, libpng was still in an early stage.
29Therefore, lots of the functionality that we put in our software can now 29Therefore, lots of the functionality that we put in our software can now
30be done using transform-functions in libpng. 30be done using transform-functions in libpng.
31 31
32Finally, to compile these programs, you need to have installed and 32Finally, to compile these programs, you need to have installed and
33compiled three libraries: libpng, zlib and netpbm. Especially the latter 33compiled three libraries: libpng, zlib and netpbm. Especially the latter
34makes the whole setup a bit bulky. But that's unavoidable given the many 34makes the whole setup a bit bulky. But that's unavoidable given the many
35features of pnmtopng. 35features of pnmtopng.
36 36
37 37
38What now 38What now
39-------- 39--------
40At this moment libpng is in a very stable state and can do much of the 40At this moment libpng is in a very stable state and can do much of the
41work done in pnmtopng. Also, pnmtopng needs to be upgraded to the new 41work done in pnmtopng. Also, pnmtopng needs to be upgraded to the new
42interface of libpng. Hence, it is time for a rewrite from the ground up 42interface of libpng. Hence, it is time for a rewrite from the ground up
43of pnmtopng and pngtopnm. This will happen in the near future (stay 43of pnmtopng and pngtopnm. This will happen in the near future (stay
44tuned). The new package will get a different name to distinguish it from 44tuned). The new package will get a different name to distinguish it from
45the old one: PngPlus. 45the old one: PngPlus.
46 46
47To experiment a bit with the new interface of libpng, I started off with 47To experiment a bit with the new interface of libpng, I started off with
48a small prototype that contains only the basic functionality. It doesn't 48a small prototype that contains only the basic functionality. It doesn't
49have any of the options to read or write special chunks and it will do 49have any of the options to read or write special chunks and it will do
50no gamma correction. But this makes it also a simple program that is 50no gamma correction. But this makes it also a simple program that is
51quite easy to understand and can serve well as a template for other 51quite easy to understand and can serve well as a template for other
52software developments. (By now there are of course a couple of programs, 52software developments. (By now there are of course a couple of programs,
53like Greg Roelofs' rpng/wpng, that can be used just as good.) 53like Greg Roelofs' rpng/wpng, that can be used just as good.)
54 54
55 55
56Can and can not 56Can and can not
57--------------- 57---------------
58As this is the small brother of the future PngPlus, I called this fellow 58As this is the small brother of the future PngPlus, I called this fellow
59PngMinus. Because I started this development in good-old Turbo-C, I 59PngMinus. Because I started this development in good-old Turbo-C, I
60avoided the use the netpbm library, which requires DOS extenders. Again, 60avoided the use the netpbm library, which requires DOS extenders. Again,
61another reason to call it PngMinus (minus netpbm :-). So, part of the 61another reason to call it PngMinus (minus netpbm :-). So, part of the
62program are some elementary routines to read / write pgm- and ppm-files. 62program are some elementary routines to read / write pgm- and ppm-files.
63It does not read b&w pbm-files. 63It does not read b&w pbm-files.
64 64
65The downside of this approach is that you can not use them on images 65The downside of this approach is that you can not use them on images
66that require blocks of memory bigger than 64k (the DOS version). For 66that require blocks of memory bigger than 64k (the DOS version). For
67larger images you will get an out-of-memory error. 67larger images you will get an out-of-memory error.
68 68
69As said before, PngMinus doesn't correct for gamma. When reading 69As said before, PngMinus doesn't correct for gamma. When reading
70png-files you can do this just as well by piping the output of png2pnm 70png-files you can do this just as well by piping the output of png2pnm
71to pnmgamma, one of the standard PbmPlus tools. This same scenario will 71to pnmgamma, one of the standard PbmPlus tools. This same scenario will
72most probably also be followed in the full-blown future PngPlus, with 72most probably also be followed in the full-blown future PngPlus, with
73the addition of course of the possibility to create gamma-chunks when 73the addition of course of the possibility to create gamma-chunks when
74writing png-files. 74writing png-files.
75 75
76On the other hand it supports alpha-channels. When reading a png-image 76On the other hand it supports alpha-channels. When reading a png-image
77you can write the alpha-channel into a pgm-file. And when creating an 77you can write the alpha-channel into a pgm-file. And when creating an
78RGB+A png-image, you just combine a ppm-file with a corresponding 78RGB+A png-image, you just combine a ppm-file with a corresponding
79pgm-file containing the alpha-channel. When reading, transparency chunks 79pgm-file containing the alpha-channel. When reading, transparency chunks
80are converted into an alpha-channel and from there on treated the same 80are converted into an alpha-channel and from there on treated the same
81way. 81way.
82 82
83Finally you can opt for writing ascii or binary pgm- and ppm-files. When 83Finally you can opt for writing ascii or binary pgm- and ppm-files. When
84the bit-depth is 16, the format will always be ascii. 84the bit-depth is 16, the format will always be ascii.
85 85
86 86
87Using it 87Using it
88-------- 88--------
89To distinguish them from pnmtopng and PngPlus, the utilities are named 89To distinguish them from pnmtopng and PngPlus, the utilities are named
90png2pnm and pnm2png (2 instead of to). The input- and output-files can 90png2pnm and pnm2png (2 instead of to). The input- and output-files can
91be given as parameters or through redirection. Therefore the programs 91be given as parameters or through redirection. Therefore the programs
92can be part of a pipe. 92can be part of a pipe.
93 93
94To list the options type "png2pnm -h" or "pnm2png -h". 94To list the options type "png2pnm -h" or "pnm2png -h".
95 95
96 96
97Just like Scandinavian furniture 97Just like Scandinavian furniture
98-------------------------------- 98--------------------------------
99You have to put it together yourself. I did test the software under 99You have to put it together yourself. I did test the software under
100MS-DOS with Turbo-C 3.0 and under RedHat Linux 4.2 with gcc. In both 100MS-DOS with Turbo-C 3.0 and under RedHat Linux 4.2 with gcc. In both
101cases I used libpng-1.0.4 and zlib-1.1.3. Later versions should be OK, 101cases I used libpng-1.0.4 and zlib-1.1.3. Later versions should be OK,
102however some older libpng versions have a bug in pngmem.c when using 102however some older libpng versions have a bug in pngmem.c when using
103Turbo-C 3.0 (see below). 103Turbo-C 3.0 (see below).
104 104
105You can build it using one of the two makefiles (make -f makefile.###) 105You can build it using one of the two makefiles (make -f makefile.###)
106or use the batch/script files pngminus.bat / pngminus.sh. This assumes 106or use the batch/script files pngminus.bat / pngminus.sh. This assumes
107that you have built the libraries in ../libpng and ../zlib. Using Linux, 107that you have built the libraries in ../libpng and ../zlib. Using Linux,
108make sure that you have built libpng with makefile.std and not 108make sure that you have built libpng with makefile.std and not
109makefile.linux (also called .lnx in earlier versions of libpng). The 109makefile.linux (also called .lnx in earlier versions of libpng). The
110latter creates a .so shared-library, while the PngMinus makefile assumes 110latter creates a .so shared-library, while the PngMinus makefile assumes
111a normal .a static library. 111a normal .a static library.
112 112
113If you create a ../pngsuite directory and then store the basn####.png 113If you create a ../pngsuite directory and then store the basn####.png
114files from PngSuite (http://www.schaik.com/pngsuite/) in there, you can 114files from PngSuite (http://www.schaik.com/pngsuite/) in there, you can
115test in one go the proper functioning of PngMinus, see png2pnm.bat and 115test in one go the proper functioning of PngMinus, see png2pnm.bat and
116pnm2png.bat (or the .sh versions). 116pnm2png.bat (or the .sh versions).
117 117
118 118
119Warranty 119Warranty
120------- 120-------
121Please, remember that this was just a small experiment to learn a few 121Please, remember that this was just a small experiment to learn a few
122things. It will have many unforeseen features <vbg>. Who said bugs? Use 122things. It will have many unforeseen features <vbg>. Who said bugs? Use
123it when you are in need for something simple or when you want to start 123it when you are in need for something simple or when you want to start
124developing your own stuff. 124developing your own stuff.
125 125
126 126
127The Turbo bug 127The Turbo bug
128------------- 128-------------
129** pngmem.old 129** pngmem.old
130 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); 130 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
131 hptr += 16L; 131 hptr += 16L;
132** pngmem.c 132** pngmem.c
133 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); 133 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
134 hptr = hptr + 16L; 134 hptr = hptr + 16L;
135** 135**
136 136
137** pngmem.old 137** pngmem.old
138 png_ptr->offset_table_ptr[i] = (png_bytep)hptr; 138 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
139 hptr += (png_uint_32)65536L; 139 hptr += (png_uint_32)65536L;
140** pngmem.c 140** pngmem.c
141 png_ptr->offset_table_ptr[i] = (png_bytep)hptr; 141 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
142 hptr = hptr + 65536L; 142 hptr = hptr + 65536L;
143** 143**
144 144
145 145
146The end 146The end
147------- 147-------
148Willem van Schaik 148Willem van Schaik
149mailto:willem@schaik.com 149mailto:willem@schaik.com
150http://www.schaik.com/png/ 150http://www.schaik.com/png/
151------- 151-------
152Oct 1999 152Oct 1999
153 153
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.std b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.std
index a121032..fa7b590 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.std
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.std
@@ -1,65 +1,65 @@
1# Makefile for PngMinus (png2pnm and pnm2png) 1# Makefile for PngMinus (png2pnm and pnm2png)
2# Linux / Unix 2# Linux / Unix
3 3
4#CC=cc 4#CC=cc
5CC=gcc 5CC=gcc
6LD=$(CC) 6LD=$(CC)
7 7
8RM=rm -f 8RM=rm -f
9 9
10#PNGPATH = /usr/local 10#PNGPATH = /usr/local
11#PNGINC = -I$(PNGPATH)/include/libpng15 11#PNGINC = -I$(PNGPATH)/include/libpng15
12#PNGLIB = -L$(PNGPATH)/lib -lpng15 12#PNGLIB = -L$(PNGPATH)/lib -lpng15
13#PNGLIBS = $(PNGPATH)/lib/libpng15.a 13#PNGLIBS = $(PNGPATH)/lib/libpng15.a
14PNGINC = -I../.. 14PNGINC = -I../..
15PNGLIB = -L../.. -lpng 15PNGLIB = -L../.. -lpng
16PNGLIBS = ../../libpng.a 16PNGLIBS = ../../libpng.a
17 17
18#ZPATH = /usr/local 18#ZPATH = /usr/local
19#ZINC = -I$(ZPATH)/include 19#ZINC = -I$(ZPATH)/include
20#ZLIB = -L$(ZPATH)/lib -lz 20#ZLIB = -L$(ZPATH)/lib -lz
21#ZLIBS = $(ZPATH)/lib/libz.a 21#ZLIBS = $(ZPATH)/lib/libz.a
22ZINC = -I../../../zlib 22ZINC = -I../../../zlib
23ZLIB = -L../../../zlib -lz 23ZLIB = -L../../../zlib -lz
24ZLIBS = ../../../zlib/libz.a 24ZLIBS = ../../../zlib/libz.a
25 25
26CFLAGS=$(PNGINC) $(ZINC) 26CFLAGS=$(PNGINC) $(ZINC)
27LDLIBS=$(PNGLIB) $(ZLIB) 27LDLIBS=$(PNGLIB) $(ZLIB)
28LDLIBSS=$(PNGLIBS) $(ZLIBS) 28LDLIBSS=$(PNGLIBS) $(ZLIBS)
29C=.c 29C=.c
30O=.o 30O=.o
31L=.a 31L=.a
32E= 32E=
33 33
34# dependencies 34# dependencies
35 35
36#all: png2pnm$(E) pnm2png$(E) 36#all: png2pnm$(E) pnm2png$(E)
37all: png2pnm$(E) pnm2png$(E) png2pnm-static$(E) pnm2png-static$(E) 37all: png2pnm$(E) pnm2png$(E) png2pnm-static$(E) pnm2png-static$(E)
38 38
39png2pnm$(O): png2pnm$(C) 39png2pnm$(O): png2pnm$(C)
40 $(CC) -c $(CFLAGS) png2pnm$(C) 40 $(CC) -c $(CFLAGS) png2pnm$(C)
41 41
42png2pnm$(E): png2pnm$(O) 42png2pnm$(E): png2pnm$(O)
43 $(LD) $(LDFLAGS) -o png2pnm$(E) png2pnm$(O) $(LDLIBS) -lm 43 $(LD) $(LDFLAGS) -o png2pnm$(E) png2pnm$(O) $(LDLIBS) -lm
44 44
45png2pnm-static$(E): png2pnm$(O) 45png2pnm-static$(E): png2pnm$(O)
46 $(LD) $(LDFLAGS) -o png2pnm-static$(E) png2pnm$(O) $(LDLIBSS) -lm 46 $(LD) $(LDFLAGS) -o png2pnm-static$(E) png2pnm$(O) $(LDLIBSS) -lm
47 47
48pnm2png$(O): pnm2png$(C) 48pnm2png$(O): pnm2png$(C)
49 $(CC) -c $(CFLAGS) pnm2png$(C) 49 $(CC) -c $(CFLAGS) pnm2png$(C)
50 50
51pnm2png$(E): pnm2png$(O) 51pnm2png$(E): pnm2png$(O)
52 $(LD) $(LDFLAGS) -o pnm2png$(E) pnm2png$(O) $(LDLIBS) -lm 52 $(LD) $(LDFLAGS) -o pnm2png$(E) pnm2png$(O) $(LDLIBS) -lm
53 53
54pnm2png-static$(E): pnm2png$(O) 54pnm2png-static$(E): pnm2png$(O)
55 $(LD) $(LDFLAGS) -o pnm2png-static$(E) pnm2png$(O) $(LDLIBSS) -lm 55 $(LD) $(LDFLAGS) -o pnm2png-static$(E) pnm2png$(O) $(LDLIBSS) -lm
56 56
57clean: 57clean:
58 $(RM) png2pnm$(O) 58 $(RM) png2pnm$(O)
59 $(RM) pnm2png$(O) 59 $(RM) pnm2png$(O)
60 $(RM) png2pnm$(E) 60 $(RM) png2pnm$(E)
61 $(RM) pnm2png$(E) 61 $(RM) pnm2png$(E)
62 $(RM) png2pnm-static$(E) 62 $(RM) png2pnm-static$(E)
63 $(RM) pnm2png-static$(E) 63 $(RM) pnm2png-static$(E)
64 64
65# End of makefile for png2pnm / pnm2png 65# End of makefile for png2pnm / pnm2png
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.tc3 b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.tc3
index 01062cc..404f18d 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.tc3
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makefile.tc3
@@ -1,38 +1,38 @@
1# Makefile for PngMinus (png2pnm and pnm2png) 1# Makefile for PngMinus (png2pnm and pnm2png)
2# TurboC++ 3.0 2# TurboC++ 3.0
3 3
4CC=tcc -Ic:\tc3\inc 4CC=tcc -Ic:\tc3\inc
5LD=tcc -Lc:\tc3\lib 5LD=tcc -Lc:\tc3\lib
6LB=tlib 6LB=tlib
7RM=del 7RM=del
8CP=copy 8CP=copy
9MODEL=l 9MODEL=l
10CCFLAGS=-O -m$(MODEL) -I..\libpng -I..\zlib 10CCFLAGS=-O -m$(MODEL) -I..\libpng -I..\zlib
11LDFLAGS=-m$(MODEL) -L..\libpng -L..\zlib 11LDFLAGS=-m$(MODEL) -L..\libpng -L..\zlib
12C=.c 12C=.c
13O=.obj 13O=.obj
14L=.lib 14L=.lib
15E=.exe 15E=.exe
16 16
17# dependencies 17# dependencies
18 18
19all: png2pnm$(E) pnm2png$(E) 19all: png2pnm$(E) pnm2png$(E)
20 20
21png2pnm$(O): png2pnm$(C) 21png2pnm$(O): png2pnm$(C)
22 $(CC) -c $(CCFLAGS) png2pnm$(C) 22 $(CC) -c $(CCFLAGS) png2pnm$(C)
23 23
24png2pnm$(E): png2pnm$(O) 24png2pnm$(E): png2pnm$(O)
25 $(LD) $(LDFLAGS) png2pnm$(O) libpng$(L) zlib$(L) 25 $(LD) $(LDFLAGS) png2pnm$(O) libpng$(L) zlib$(L)
26 26
27pnm2png$(O): pnm2png$(C) 27pnm2png$(O): pnm2png$(C)
28 $(CC) -c $(CCFLAGS) pnm2png$(C) 28 $(CC) -c $(CCFLAGS) pnm2png$(C)
29 29
30pnm2png$(E): pnm2png$(O) 30pnm2png$(E): pnm2png$(O)
31 $(LD) $(LDFLAGS) pnm2png$(O) libpng$(L) zlib$(L) 31 $(LD) $(LDFLAGS) pnm2png$(O) libpng$(L) zlib$(L)
32 32
33clean: 33clean:
34 $(RM) *$(O) 34 $(RM) *$(O)
35 $(RM) *$(E) 35 $(RM) *$(E)
36 36
37# End of makefile for png2pnm / pnm2png 37# End of makefile for png2pnm / pnm2png
38 38
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makevms.com b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makevms.com
index 96c3147..00561bc 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makevms.com
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/makevms.com
@@ -1,92 +1,92 @@
1$!------------------------------------------------------------------------------ 1$!------------------------------------------------------------------------------
2$! make Contrib programs of libpng under OpenVMS 2$! make Contrib programs of libpng under OpenVMS
3$! 3$!
4$! 4$!
5$! Look for the compiler used 5$! Look for the compiler used
6$! 6$!
7$ zlibsrc = "[---.zlib]" 7$ zlibsrc = "[---.zlib]"
8$ ccopt="/include=(''zlibsrc',[--])" 8$ ccopt="/include=(''zlibsrc',[--])"
9$ if f$getsyi("HW_MODEL").ge.1024 9$ if f$getsyi("HW_MODEL").ge.1024
10$ then 10$ then
11$ ccopt = "/prefix=all"+ccopt 11$ ccopt = "/prefix=all"+ccopt
12$ comp = "__decc__=1" 12$ comp = "__decc__=1"
13$ if f$trnlnm("SYS").eqs."" then define sys sys$library: 13$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
14$ else 14$ else
15$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" 15$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs.""
16$ then 16$ then
17$ if f$trnlnm("SYS").eqs."" then define sys sys$library: 17$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
18$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs."" 18$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs.""
19$ then 19$ then
20$ comp = "__gcc__=1" 20$ comp = "__gcc__=1"
21$ CC :== GCC 21$ CC :== GCC
22$ else 22$ else
23$ comp = "__vaxc__=1" 23$ comp = "__vaxc__=1"
24$ endif 24$ endif
25$ else 25$ else
26$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: 26$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include:
27$ ccopt = "/decc/prefix=all"+ccopt 27$ ccopt = "/decc/prefix=all"+ccopt
28$ comp = "__decc__=1" 28$ comp = "__decc__=1"
29$ endif 29$ endif
30$ endif 30$ endif
31$ open/write lopt lib.opt 31$ open/write lopt lib.opt
32$ write lopt "[--]libpng.olb/lib" 32$ write lopt "[--]libpng.olb/lib"
33$ write lopt "''zlibsrc'libz.olb/lib" 33$ write lopt "''zlibsrc'libz.olb/lib"
34$ close lopt 34$ close lopt
35$ open/write xopt x11.opt 35$ open/write xopt x11.opt
36$ write xopt "sys$library:decw$xlibshr.exe/share" 36$ write xopt "sys$library:decw$xlibshr.exe/share"
37$ close xopt 37$ close xopt
38$ write sys$output "Compiling PNG contrib programs ..." 38$ write sys$output "Compiling PNG contrib programs ..."
39$ write sys$output "Building pnm2png..." 39$ write sys$output "Building pnm2png..."
40$ CALL MAKE pnm2png.OBJ "cc ''CCOPT' pnm2png" - 40$ CALL MAKE pnm2png.OBJ "cc ''CCOPT' pnm2png" -
41 pnm2png.c 41 pnm2png.c
42$ call make pnm2png.exe - 42$ call make pnm2png.exe -
43 "LINK pnm2png,lib.opt/opt" - 43 "LINK pnm2png,lib.opt/opt" -
44 pnm2png.obj 44 pnm2png.obj
45$ write sys$output "Building png2pnm..." 45$ write sys$output "Building png2pnm..."
46$ CALL MAKE png2pnm.OBJ "cc ''CCOPT' png2pnm" - 46$ CALL MAKE png2pnm.OBJ "cc ''CCOPT' png2pnm" -
47 png2pnm.c 47 png2pnm.c
48$ call make png2pnm.exe - 48$ call make png2pnm.exe -
49 "LINK png2pnm,lib.opt/opt" - 49 "LINK png2pnm,lib.opt/opt" -
50 png2pnm.obj 50 png2pnm.obj
51$ exit 51$ exit
52$! 52$!
53$! 53$!
54$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES 54$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
55$ V = 'F$Verify(0) 55$ V = 'F$Verify(0)
56$! P1 = What we are trying to make 56$! P1 = What we are trying to make
57$! P2 = Command to make it 57$! P2 = Command to make it
58$! P3 - P8 What it depends on 58$! P3 - P8 What it depends on
59$ 59$
60$ If F$Search(P1) .Eqs. "" Then Goto Makeit 60$ If F$Search(P1) .Eqs. "" Then Goto Makeit
61$ Time = F$CvTime(F$File(P1,"RDT")) 61$ Time = F$CvTime(F$File(P1,"RDT"))
62$arg=3 62$arg=3
63$Loop: 63$Loop:
64$ Argument = P'arg 64$ Argument = P'arg
65$ If Argument .Eqs. "" Then Goto Exit 65$ If Argument .Eqs. "" Then Goto Exit
66$ El=0 66$ El=0
67$Loop2: 67$Loop2:
68$ File = F$Element(El," ",Argument) 68$ File = F$Element(El," ",Argument)
69$ If File .Eqs. " " Then Goto Endl 69$ If File .Eqs. " " Then Goto Endl
70$ AFile = "" 70$ AFile = ""
71$Loop3: 71$Loop3:
72$ OFile = AFile 72$ OFile = AFile
73$ AFile = F$Search(File) 73$ AFile = F$Search(File)
74$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl 74$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
75$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit 75$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
76$ Goto Loop3 76$ Goto Loop3
77$NextEL: 77$NextEL:
78$ El = El + 1 78$ El = El + 1
79$ Goto Loop2 79$ Goto Loop2
80$EndL: 80$EndL:
81$ arg=arg+1 81$ arg=arg+1
82$ If arg .Le. 8 Then Goto Loop 82$ If arg .Le. 8 Then Goto Loop
83$ Goto Exit 83$ Goto Exit
84$ 84$
85$Makeit: 85$Makeit:
86$ VV=F$VERIFY(0) 86$ VV=F$VERIFY(0)
87$ write sys$output P2 87$ write sys$output P2
88$ 'P2 88$ 'P2
89$ VV='F$Verify(VV) 89$ VV='F$Verify(VV)
90$Exit: 90$Exit:
91$ If V Then Set Verify 91$ If V Then Set Verify
92$ENDSUBROUTINE 92$ENDSUBROUTINE
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.bat b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.bat
index 85abe3c..449cf36 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.bat
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.bat
@@ -1,41 +1,41 @@
1REM -- grayscale 1REM -- grayscale
2png2pnm.exe -noraw ..\pngsuite\basn0g01.png basn0g01.pgm 2png2pnm.exe -noraw ..\pngsuite\basn0g01.png basn0g01.pgm
3png2pnm.exe -noraw ..\pngsuite\basn0g02.png basn0g02.pgm 3png2pnm.exe -noraw ..\pngsuite\basn0g02.png basn0g02.pgm
4png2pnm.exe -noraw ..\pngsuite\basn0g04.png basn0g04.pgm 4png2pnm.exe -noraw ..\pngsuite\basn0g04.png basn0g04.pgm
5png2pnm.exe -noraw ..\pngsuite\basn0g08.png basn0g08.pgm 5png2pnm.exe -noraw ..\pngsuite\basn0g08.png basn0g08.pgm
6png2pnm.exe -noraw ..\pngsuite\basn0g16.png basn0g16.pgm 6png2pnm.exe -noraw ..\pngsuite\basn0g16.png basn0g16.pgm
7REM -- full-color 7REM -- full-color
8png2pnm.exe -noraw ..\pngsuite\basn2c08.png basn2c08.ppm 8png2pnm.exe -noraw ..\pngsuite\basn2c08.png basn2c08.ppm
9png2pnm.exe -noraw ..\pngsuite\basn2c16.png basn2c16.ppm 9png2pnm.exe -noraw ..\pngsuite\basn2c16.png basn2c16.ppm
10REM -- palletted 10REM -- palletted
11png2pnm.exe -noraw ..\pngsuite\basn3p01.png basn3p01.ppm 11png2pnm.exe -noraw ..\pngsuite\basn3p01.png basn3p01.ppm
12png2pnm.exe -noraw ..\pngsuite\basn3p02.png basn3p02.ppm 12png2pnm.exe -noraw ..\pngsuite\basn3p02.png basn3p02.ppm
13png2pnm.exe -noraw ..\pngsuite\basn3p04.png basn3p04.ppm 13png2pnm.exe -noraw ..\pngsuite\basn3p04.png basn3p04.ppm
14png2pnm.exe -noraw ..\pngsuite\basn3p08.png basn3p08.ppm 14png2pnm.exe -noraw ..\pngsuite\basn3p08.png basn3p08.ppm
15REM -- gray with alpha-channel 15REM -- gray with alpha-channel
16png2pnm.exe -noraw ..\pngsuite\basn4a08.png basn4a08.pgm 16png2pnm.exe -noraw ..\pngsuite\basn4a08.png basn4a08.pgm
17png2pnm.exe -noraw ..\pngsuite\basn4a16.png basn4a16.pgm 17png2pnm.exe -noraw ..\pngsuite\basn4a16.png basn4a16.pgm
18REM -- color with alpha-channel 18REM -- color with alpha-channel
19png2pnm.exe -noraw -alpha basn6a08.pgm ..\pngsuite\basn6a08.png basn6a08.ppm 19png2pnm.exe -noraw -alpha basn6a08.pgm ..\pngsuite\basn6a08.png basn6a08.ppm
20png2pnm.exe -noraw -alpha basn6a16.pgm ..\pngsuite\basn6a16.png basn6a16.ppm 20png2pnm.exe -noraw -alpha basn6a16.pgm ..\pngsuite\basn6a16.png basn6a16.ppm
21REM -- grayscale 21REM -- grayscale
22png2pnm.exe -raw ..\pngsuite\basn0g01.png rawn0g01.pgm 22png2pnm.exe -raw ..\pngsuite\basn0g01.png rawn0g01.pgm
23png2pnm.exe -raw ..\pngsuite\basn0g02.png rawn0g02.pgm 23png2pnm.exe -raw ..\pngsuite\basn0g02.png rawn0g02.pgm
24png2pnm.exe -raw ..\pngsuite\basn0g04.png rawn0g04.pgm 24png2pnm.exe -raw ..\pngsuite\basn0g04.png rawn0g04.pgm
25png2pnm.exe -raw ..\pngsuite\basn0g08.png rawn0g08.pgm 25png2pnm.exe -raw ..\pngsuite\basn0g08.png rawn0g08.pgm
26png2pnm.exe -raw ..\pngsuite\basn0g16.png rawn0g16.pgm 26png2pnm.exe -raw ..\pngsuite\basn0g16.png rawn0g16.pgm
27REM -- full-color 27REM -- full-color
28png2pnm.exe -raw ..\pngsuite\basn2c08.png rawn2c08.ppm 28png2pnm.exe -raw ..\pngsuite\basn2c08.png rawn2c08.ppm
29png2pnm.exe -raw ..\pngsuite\basn2c16.png rawn2c16.ppm 29png2pnm.exe -raw ..\pngsuite\basn2c16.png rawn2c16.ppm
30REM -- palletted 30REM -- palletted
31png2pnm.exe -raw ..\pngsuite\basn3p01.png rawn3p01.ppm 31png2pnm.exe -raw ..\pngsuite\basn3p01.png rawn3p01.ppm
32png2pnm.exe -raw ..\pngsuite\basn3p02.png rawn3p02.ppm 32png2pnm.exe -raw ..\pngsuite\basn3p02.png rawn3p02.ppm
33png2pnm.exe -raw ..\pngsuite\basn3p04.png rawn3p04.ppm 33png2pnm.exe -raw ..\pngsuite\basn3p04.png rawn3p04.ppm
34png2pnm.exe -raw ..\pngsuite\basn3p08.png rawn3p08.ppm 34png2pnm.exe -raw ..\pngsuite\basn3p08.png rawn3p08.ppm
35REM -- gray with alpha-channel 35REM -- gray with alpha-channel
36png2pnm.exe -raw ..\pngsuite\basn4a08.png rawn4a08.pgm 36png2pnm.exe -raw ..\pngsuite\basn4a08.png rawn4a08.pgm
37png2pnm.exe -raw ..\pngsuite\basn4a16.png rawn4a16.pgm 37png2pnm.exe -raw ..\pngsuite\basn4a16.png rawn4a16.pgm
38REM -- color with alpha-channel 38REM -- color with alpha-channel
39png2pnm.exe -noraw -alpha rawn6a08.pgm ..\pngsuite\basn6a08.png rawn6a08.ppm 39png2pnm.exe -noraw -alpha rawn6a08.pgm ..\pngsuite\basn6a08.png rawn6a08.ppm
40png2pnm.exe -noraw -alpha rawn6a16.pgm ..\pngsuite\basn6a16.png rawn6a16.ppm 40png2pnm.exe -noraw -alpha rawn6a16.pgm ..\pngsuite\basn6a16.png rawn6a16.ppm
41 41
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.c
index ef28d90..2281429 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.c
@@ -1,430 +1,430 @@
1/* 1/*
2 * png2pnm.c --- conversion from PNG-file to PGM/PPM-file 2 * png2pnm.c --- conversion from PNG-file to PGM/PPM-file
3 * copyright (C) 1999 by Willem van Schaik <willem@schaik.com> 3 * copyright (C) 1999 by Willem van Schaik <willem@schaik.com>
4 * 4 *
5 * version 1.0 - 1999.10.15 - First version. 5 * version 1.0 - 1999.10.15 - First version.
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software and 7 * Permission to use, copy, modify, and distribute this software and
8 * its documentation for any purpose and without fee is hereby granted, 8 * its documentation for any purpose and without fee is hereby granted,
9 * provided that the above copyright notice appear in all copies and 9 * provided that the above copyright notice appear in all copies and
10 * that both that copyright notice and this permission notice appear in 10 * that both that copyright notice and this permission notice appear in
11 * supporting documentation. This software is provided "as is" without 11 * supporting documentation. This software is provided "as is" without
12 * express or implied warranty. 12 * express or implied warranty.
13 */ 13 */
14 14
15#include <stdio.h> 15#include <stdio.h>
16#include <stdlib.h> 16#include <stdlib.h>
17#ifdef __TURBOC__ 17#ifdef __TURBOC__
18#include <mem.h> 18#include <mem.h>
19#include <fcntl.h> 19#include <fcntl.h>
20#endif 20#endif
21 21
22#ifndef BOOL 22#ifndef BOOL
23#define BOOL unsigned char 23#define BOOL unsigned char
24#endif 24#endif
25#ifndef TRUE 25#ifndef TRUE
26#define TRUE (BOOL) 1 26#define TRUE (BOOL) 1
27#endif 27#endif
28#ifndef FALSE 28#ifndef FALSE
29#define FALSE (BOOL) 0 29#define FALSE (BOOL) 0
30#endif 30#endif
31 31
32#ifdef __TURBOC__ 32#ifdef __TURBOC__
33#define STDIN 0 33#define STDIN 0
34#define STDOUT 1 34#define STDOUT 1
35#define STDERR 2 35#define STDERR 2
36#endif 36#endif
37 37
38/* to make png2pnm verbose so we can find problems (needs to be before png.h) */ 38/* to make png2pnm verbose so we can find problems (needs to be before png.h) */
39#ifndef PNG_DEBUG 39#ifndef PNG_DEBUG
40#define PNG_DEBUG 0 40#define PNG_DEBUG 0
41#endif 41#endif
42 42
43#include "png.h" 43#include "png.h"
44 44
45/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ 45/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
46#ifndef png_jmpbuf 46#ifndef png_jmpbuf
47# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) 47# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
48#endif 48#endif
49 49
50/* function prototypes */ 50/* function prototypes */
51 51
52int main (int argc, char *argv[]); 52int main (int argc, char *argv[]);
53void usage (); 53void usage ();
54BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha); 54BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha);
55 55
56/* 56/*
57 * main 57 * main
58 */ 58 */
59 59
60int main(int argc, char *argv[]) 60int main(int argc, char *argv[])
61{ 61{
62 FILE *fp_rd = stdin; 62 FILE *fp_rd = stdin;
63 FILE *fp_wr = stdout; 63 FILE *fp_wr = stdout;
64 FILE *fp_al = NULL; 64 FILE *fp_al = NULL;
65 BOOL raw = TRUE; 65 BOOL raw = TRUE;
66 BOOL alpha = FALSE; 66 BOOL alpha = FALSE;
67 int argi; 67 int argi;
68 68
69 for (argi = 1; argi < argc; argi++) 69 for (argi = 1; argi < argc; argi++)
70 { 70 {
71 if (argv[argi][0] == '-') 71 if (argv[argi][0] == '-')
72 { 72 {
73 switch (argv[argi][1]) 73 switch (argv[argi][1])
74 { 74 {
75 case 'n': 75 case 'n':
76 raw = FALSE; 76 raw = FALSE;
77 break; 77 break;
78 case 'r': 78 case 'r':
79 raw = TRUE; 79 raw = TRUE;
80 break; 80 break;
81 case 'a': 81 case 'a':
82 alpha = TRUE; 82 alpha = TRUE;
83 argi++; 83 argi++;
84 if ((fp_al = fopen (argv[argi], "wb")) == NULL) 84 if ((fp_al = fopen (argv[argi], "wb")) == NULL)
85 { 85 {
86 fprintf (stderr, "PNM2PNG\n"); 86 fprintf (stderr, "PNM2PNG\n");
87 fprintf (stderr, "Error: can not create alpha-channel file %s\n", argv[argi]); 87 fprintf (stderr, "Error: can not create alpha-channel file %s\n", argv[argi]);
88 exit (1); 88 exit (1);
89 } 89 }
90 break; 90 break;
91 case 'h': 91 case 'h':
92 case '?': 92 case '?':
93 usage(); 93 usage();
94 exit(0); 94 exit(0);
95 break; 95 break;
96 default: 96 default:
97 fprintf (stderr, "PNG2PNM\n"); 97 fprintf (stderr, "PNG2PNM\n");
98 fprintf (stderr, "Error: unknown option %s\n", argv[argi]); 98 fprintf (stderr, "Error: unknown option %s\n", argv[argi]);
99 usage(); 99 usage();
100 exit(1); 100 exit(1);
101 break; 101 break;
102 } /* end switch */ 102 } /* end switch */
103 } 103 }
104 else if (fp_rd == stdin) 104 else if (fp_rd == stdin)
105 { 105 {
106 if ((fp_rd = fopen (argv[argi], "rb")) == NULL) 106 if ((fp_rd = fopen (argv[argi], "rb")) == NULL)
107 { 107 {
108 fprintf (stderr, "PNG2PNM\n"); 108 fprintf (stderr, "PNG2PNM\n");
109 fprintf (stderr, "Error: file %s does not exist\n", argv[argi]); 109 fprintf (stderr, "Error: file %s does not exist\n", argv[argi]);
110 exit (1); 110 exit (1);
111 } 111 }
112 } 112 }
113 else if (fp_wr == stdout) 113 else if (fp_wr == stdout)
114 { 114 {
115 if ((fp_wr = fopen (argv[argi], "wb")) == NULL) 115 if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
116 { 116 {
117 fprintf (stderr, "PNG2PNM\n"); 117 fprintf (stderr, "PNG2PNM\n");
118 fprintf (stderr, "Error: can not create file %s\n", argv[argi]); 118 fprintf (stderr, "Error: can not create file %s\n", argv[argi]);
119 exit (1); 119 exit (1);
120 } 120 }
121 } 121 }
122 else 122 else
123 { 123 {
124 fprintf (stderr, "PNG2PNM\n"); 124 fprintf (stderr, "PNG2PNM\n");
125 fprintf (stderr, "Error: too many parameters\n"); 125 fprintf (stderr, "Error: too many parameters\n");
126 usage(); 126 usage();
127 exit(1); 127 exit(1);
128 } 128 }
129 } /* end for */ 129 } /* end for */
130 130
131#ifdef __TURBOC__ 131#ifdef __TURBOC__
132 /* set stdin/stdout if required to binary */ 132 /* set stdin/stdout if required to binary */
133 if (fp_rd == stdin) 133 if (fp_rd == stdin)
134 { 134 {
135 setmode (STDIN, O_BINARY); 135 setmode (STDIN, O_BINARY);
136 } 136 }
137 if ((raw) && (fp_wr == stdout)) 137 if ((raw) && (fp_wr == stdout))
138 { 138 {
139 setmode (STDOUT, O_BINARY); 139 setmode (STDOUT, O_BINARY);
140 } 140 }
141#endif 141#endif
142 142
143 /* call the conversion program itself */ 143 /* call the conversion program itself */
144 if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE) 144 if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE)
145 { 145 {
146 fprintf (stderr, "PNG2PNM\n"); 146 fprintf (stderr, "PNG2PNM\n");
147 fprintf (stderr, "Error: unsuccessful conversion of PNG-image\n"); 147 fprintf (stderr, "Error: unsuccessful conversion of PNG-image\n");
148 exit(1); 148 exit(1);
149 } 149 }
150 150
151 /* close input file */ 151 /* close input file */
152 fclose (fp_rd); 152 fclose (fp_rd);
153 /* close output file */ 153 /* close output file */
154 fclose (fp_wr); 154 fclose (fp_wr);
155 /* close alpha file */ 155 /* close alpha file */
156 if (alpha) 156 if (alpha)
157 fclose (fp_al); 157 fclose (fp_al);
158 158
159 return 0; 159 return 0;
160} 160}
161 161
162/* 162/*
163 * usage 163 * usage
164 */ 164 */
165 165
166void usage() 166void usage()
167{ 167{
168 fprintf (stderr, "PNG2PNM\n"); 168 fprintf (stderr, "PNG2PNM\n");
169 fprintf (stderr, " by Willem van Schaik, 1999\n"); 169 fprintf (stderr, " by Willem van Schaik, 1999\n");
170#ifdef __TURBOC__ 170#ifdef __TURBOC__
171 fprintf (stderr, " for Turbo-C and Borland-C compilers\n"); 171 fprintf (stderr, " for Turbo-C and Borland-C compilers\n");
172#else 172#else
173 fprintf (stderr, " for Linux (and Unix) compilers\n"); 173 fprintf (stderr, " for Linux (and Unix) compilers\n");
174#endif 174#endif
175 fprintf (stderr, "Usage: png2pnm [options] <file>.png [<file>.pnm]\n"); 175 fprintf (stderr, "Usage: png2pnm [options] <file>.png [<file>.pnm]\n");
176 fprintf (stderr, " or: ... | png2pnm [options]\n"); 176 fprintf (stderr, " or: ... | png2pnm [options]\n");
177 fprintf (stderr, "Options:\n"); 177 fprintf (stderr, "Options:\n");
178 fprintf (stderr, " -r[aw] write pnm-file in binary format (P4/P5/P6) (default)\n"); 178 fprintf (stderr, " -r[aw] write pnm-file in binary format (P4/P5/P6) (default)\n");
179 fprintf (stderr, " -n[oraw] write pnm-file in ascii format (P1/P2/P3)\n"); 179 fprintf (stderr, " -n[oraw] write pnm-file in ascii format (P1/P2/P3)\n");
180 fprintf (stderr, " -a[lpha] <file>.pgm write PNG alpha channel as pgm-file\n"); 180 fprintf (stderr, " -a[lpha] <file>.pgm write PNG alpha channel as pgm-file\n");
181 fprintf (stderr, " -h | -? print this help-information\n"); 181 fprintf (stderr, " -h | -? print this help-information\n");
182} 182}
183 183
184/* 184/*
185 * png2pnm 185 * png2pnm
186 */ 186 */
187 187
188BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha) 188BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha)
189{ 189{
190 png_struct *png_ptr = NULL; 190 png_struct *png_ptr = NULL;
191 png_info *info_ptr = NULL; 191 png_info *info_ptr = NULL;
192 png_byte buf[8]; 192 png_byte buf[8];
193 png_byte *png_pixels = NULL; 193 png_byte *png_pixels = NULL;
194 png_byte **row_pointers = NULL; 194 png_byte **row_pointers = NULL;
195 png_byte *pix_ptr = NULL; 195 png_byte *pix_ptr = NULL;
196 png_uint_32 row_bytes; 196 png_uint_32 row_bytes;
197 197
198 png_uint_32 width; 198 png_uint_32 width;
199 png_uint_32 height; 199 png_uint_32 height;
200 int bit_depth; 200 int bit_depth;
201 int channels; 201 int channels;
202 int color_type; 202 int color_type;
203 int alpha_present; 203 int alpha_present;
204 int row, col; 204 int row, col;
205 int ret; 205 int ret;
206 int i; 206 int i;
207 long dep_16; 207 long dep_16;
208 208
209 /* read and check signature in PNG file */ 209 /* read and check signature in PNG file */
210 ret = fread (buf, 1, 8, png_file); 210 ret = fread (buf, 1, 8, png_file);
211 if (ret != 8) 211 if (ret != 8)
212 return FALSE; 212 return FALSE;
213 213
214 ret = png_sig_cmp (buf, 0, 8); 214 ret = png_sig_cmp (buf, 0, 8);
215 if (ret) 215 if (ret)
216 return FALSE; 216 return FALSE;
217 217
218 /* create png and info structures */ 218 /* create png and info structures */
219 219
220 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 220 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
221 NULL, NULL, NULL); 221 NULL, NULL, NULL);
222 if (!png_ptr) 222 if (!png_ptr)
223 return FALSE; /* out of memory */ 223 return FALSE; /* out of memory */
224 224
225 info_ptr = png_create_info_struct (png_ptr); 225 info_ptr = png_create_info_struct (png_ptr);
226 if (!info_ptr) 226 if (!info_ptr)
227 { 227 {
228 png_destroy_read_struct (&png_ptr, NULL, NULL); 228 png_destroy_read_struct (&png_ptr, NULL, NULL);
229 return FALSE; /* out of memory */ 229 return FALSE; /* out of memory */
230 } 230 }
231 231
232 if (setjmp (png_jmpbuf(png_ptr))) 232 if (setjmp (png_jmpbuf(png_ptr)))
233 { 233 {
234 png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 234 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
235 return FALSE; 235 return FALSE;
236 } 236 }
237 237
238 /* set up the input control for C streams */ 238 /* set up the input control for C streams */
239 png_init_io (png_ptr, png_file); 239 png_init_io (png_ptr, png_file);
240 png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */ 240 png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */
241 241
242 /* read the file information */ 242 /* read the file information */
243 png_read_info (png_ptr, info_ptr); 243 png_read_info (png_ptr, info_ptr);
244 244
245 /* get size and bit-depth of the PNG-image */ 245 /* get size and bit-depth of the PNG-image */
246 png_get_IHDR (png_ptr, info_ptr, 246 png_get_IHDR (png_ptr, info_ptr,
247 &width, &height, &bit_depth, &color_type, 247 &width, &height, &bit_depth, &color_type,
248 NULL, NULL, NULL); 248 NULL, NULL, NULL);
249 249
250 /* set-up the transformations */ 250 /* set-up the transformations */
251 251
252 /* transform paletted images into full-color rgb */ 252 /* transform paletted images into full-color rgb */
253 if (color_type == PNG_COLOR_TYPE_PALETTE) 253 if (color_type == PNG_COLOR_TYPE_PALETTE)
254 png_set_expand (png_ptr); 254 png_set_expand (png_ptr);
255 /* expand images to bit-depth 8 (only applicable for grayscale images) */ 255 /* expand images to bit-depth 8 (only applicable for grayscale images) */
256 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) 256 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
257 png_set_expand (png_ptr); 257 png_set_expand (png_ptr);
258 /* transform transparency maps into full alpha-channel */ 258 /* transform transparency maps into full alpha-channel */
259 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) 259 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
260 png_set_expand (png_ptr); 260 png_set_expand (png_ptr);
261 261
262#ifdef NJET 262#ifdef NJET
263 /* downgrade 16-bit images to 8 bit */ 263 /* downgrade 16-bit images to 8 bit */
264 if (bit_depth == 16) 264 if (bit_depth == 16)
265 png_set_strip_16 (png_ptr); 265 png_set_strip_16 (png_ptr);
266 /* transform grayscale images into full-color */ 266 /* transform grayscale images into full-color */
267 if (color_type == PNG_COLOR_TYPE_GRAY || 267 if (color_type == PNG_COLOR_TYPE_GRAY ||
268 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 268 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
269 png_set_gray_to_rgb (png_ptr); 269 png_set_gray_to_rgb (png_ptr);
270 /* only if file has a file gamma, we do a correction */ 270 /* only if file has a file gamma, we do a correction */
271 if (png_get_gAMA (png_ptr, info_ptr, &file_gamma)) 271 if (png_get_gAMA (png_ptr, info_ptr, &file_gamma))
272 png_set_gamma (png_ptr, (double) 2.2, file_gamma); 272 png_set_gamma (png_ptr, (double) 2.2, file_gamma);
273#endif 273#endif
274 274
275 /* all transformations have been registered; now update info_ptr data, 275 /* all transformations have been registered; now update info_ptr data,
276 * get rowbytes and channels, and allocate image memory */ 276 * get rowbytes and channels, and allocate image memory */
277 277
278 png_read_update_info (png_ptr, info_ptr); 278 png_read_update_info (png_ptr, info_ptr);
279 279
280 /* get the new color-type and bit-depth (after expansion/stripping) */ 280 /* get the new color-type and bit-depth (after expansion/stripping) */
281 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 281 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
282 NULL, NULL, NULL); 282 NULL, NULL, NULL);
283 283
284 /* check for 16-bit files */ 284 /* check for 16-bit files */
285 if (bit_depth == 16) 285 if (bit_depth == 16)
286 { 286 {
287 raw = FALSE; 287 raw = FALSE;
288#ifdef __TURBOC__ 288#ifdef __TURBOC__
289 pnm_file->flags &= ~((unsigned) _F_BIN); 289 pnm_file->flags &= ~((unsigned) _F_BIN);
290#endif 290#endif
291 } 291 }
292 292
293 /* calculate new number of channels and store alpha-presence */ 293 /* calculate new number of channels and store alpha-presence */
294 if (color_type == PNG_COLOR_TYPE_GRAY) 294 if (color_type == PNG_COLOR_TYPE_GRAY)
295 channels = 1; 295 channels = 1;
296 else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 296 else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
297 channels = 2; 297 channels = 2;
298 else if (color_type == PNG_COLOR_TYPE_RGB) 298 else if (color_type == PNG_COLOR_TYPE_RGB)
299 channels = 3; 299 channels = 3;
300 else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) 300 else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
301 channels = 4; 301 channels = 4;
302 else 302 else
303 channels = 0; /* should never happen */ 303 channels = 0; /* should never happen */
304 alpha_present = (channels - 1) % 2; 304 alpha_present = (channels - 1) % 2;
305 305
306 /* check if alpha is expected to be present in file */ 306 /* check if alpha is expected to be present in file */
307 if (alpha && !alpha_present) 307 if (alpha && !alpha_present)
308 { 308 {
309 fprintf (stderr, "PNG2PNM\n"); 309 fprintf (stderr, "PNG2PNM\n");
310 fprintf (stderr, "Error: PNG-file doesn't contain alpha channel\n"); 310 fprintf (stderr, "Error: PNG-file doesn't contain alpha channel\n");
311 exit (1); 311 exit (1);
312 } 312 }
313 313
314 /* row_bytes is the width x number of channels x (bit-depth / 8) */ 314 /* row_bytes is the width x number of channels x (bit-depth / 8) */
315 row_bytes = png_get_rowbytes (png_ptr, info_ptr); 315 row_bytes = png_get_rowbytes (png_ptr, info_ptr);
316 316
317 if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) { 317 if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) {
318 png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 318 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
319 return FALSE; 319 return FALSE;
320 } 320 }
321 321
322 if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL) 322 if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL)
323 { 323 {
324 png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 324 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
325 free (png_pixels); 325 free (png_pixels);
326 png_pixels = NULL; 326 png_pixels = NULL;
327 return FALSE; 327 return FALSE;
328 } 328 }
329 329
330 /* set the individual row_pointers to point at the correct offsets */ 330 /* set the individual row_pointers to point at the correct offsets */
331 for (i = 0; i < (height); i++) 331 for (i = 0; i < (height); i++)
332 row_pointers[i] = png_pixels + i * row_bytes; 332 row_pointers[i] = png_pixels + i * row_bytes;
333 333
334 /* now we can go ahead and just read the whole image */ 334 /* now we can go ahead and just read the whole image */
335 png_read_image (png_ptr, row_pointers); 335 png_read_image (png_ptr, row_pointers);
336 336
337 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ 337 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
338 png_read_end (png_ptr, info_ptr); 338 png_read_end (png_ptr, info_ptr);
339 339
340 /* clean up after the read, and free any memory allocated - REQUIRED */ 340 /* clean up after the read, and free any memory allocated - REQUIRED */
341 png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp) NULL); 341 png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp) NULL);
342 342
343 /* write header of PNM file */ 343 /* write header of PNM file */
344 344
345 if ((color_type == PNG_COLOR_TYPE_GRAY) || 345 if ((color_type == PNG_COLOR_TYPE_GRAY) ||
346 (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) 346 (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
347 { 347 {
348 fprintf (pnm_file, "%s\n", (raw) ? "P5" : "P2"); 348 fprintf (pnm_file, "%s\n", (raw) ? "P5" : "P2");
349 fprintf (pnm_file, "%d %d\n", (int) width, (int) height); 349 fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
350 fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L)); 350 fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
351 } 351 }
352 else if ((color_type == PNG_COLOR_TYPE_RGB) || 352 else if ((color_type == PNG_COLOR_TYPE_RGB) ||
353 (color_type == PNG_COLOR_TYPE_RGB_ALPHA)) 353 (color_type == PNG_COLOR_TYPE_RGB_ALPHA))
354 { 354 {
355 fprintf (pnm_file, "%s\n", (raw) ? "P6" : "P3"); 355 fprintf (pnm_file, "%s\n", (raw) ? "P6" : "P3");
356 fprintf (pnm_file, "%d %d\n", (int) width, (int) height); 356 fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
357 fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L)); 357 fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
358 } 358 }
359 359
360 /* write header of PGM file with alpha channel */ 360 /* write header of PGM file with alpha channel */
361 361
362 if ((alpha) && 362 if ((alpha) &&
363 ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) || 363 ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
364 (color_type == PNG_COLOR_TYPE_RGB_ALPHA))) 364 (color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
365 { 365 {
366 fprintf (alpha_file, "%s\n", (raw) ? "P5" : "P2"); 366 fprintf (alpha_file, "%s\n", (raw) ? "P5" : "P2");
367 fprintf (alpha_file, "%d %d\n", (int) width, (int) height); 367 fprintf (alpha_file, "%d %d\n", (int) width, (int) height);
368 fprintf (alpha_file, "%ld\n", ((1L << (int) bit_depth) - 1L)); 368 fprintf (alpha_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
369 } 369 }
370 370
371 /* write data to PNM file */ 371 /* write data to PNM file */
372 pix_ptr = png_pixels; 372 pix_ptr = png_pixels;
373 373
374 for (row = 0; row < height; row++) 374 for (row = 0; row < height; row++)
375 { 375 {
376 for (col = 0; col < width; col++) 376 for (col = 0; col < width; col++)
377 { 377 {
378 for (i = 0; i < (channels - alpha_present); i++) 378 for (i = 0; i < (channels - alpha_present); i++)
379 { 379 {
380 if (raw) 380 if (raw)
381 fputc ((int) *pix_ptr++ , pnm_file); 381 fputc ((int) *pix_ptr++ , pnm_file);
382 else 382 else
383 if (bit_depth == 16){ 383 if (bit_depth == 16){
384 dep_16 = (long) *pix_ptr++; 384 dep_16 = (long) *pix_ptr++;
385 fprintf (pnm_file, "%ld ", (dep_16 << 8) + ((long) *pix_ptr++)); 385 fprintf (pnm_file, "%ld ", (dep_16 << 8) + ((long) *pix_ptr++));
386 } 386 }
387 else 387 else
388 fprintf (pnm_file, "%ld ", (long) *pix_ptr++); 388 fprintf (pnm_file, "%ld ", (long) *pix_ptr++);
389 } 389 }
390 if (alpha_present) 390 if (alpha_present)
391 { 391 {
392 if (!alpha) 392 if (!alpha)
393 { 393 {
394 pix_ptr++; /* alpha */ 394 pix_ptr++; /* alpha */
395 if (bit_depth == 16) 395 if (bit_depth == 16)
396 pix_ptr++; 396 pix_ptr++;
397 } 397 }
398 else /* output alpha-channel as pgm file */ 398 else /* output alpha-channel as pgm file */
399 { 399 {
400 if (raw) 400 if (raw)
401 fputc ((int) *pix_ptr++ , alpha_file); 401 fputc ((int) *pix_ptr++ , alpha_file);
402 else 402 else
403 if (bit_depth == 16){ 403 if (bit_depth == 16){
404 dep_16 = (long) *pix_ptr++; 404 dep_16 = (long) *pix_ptr++;
405 fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++); 405 fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++);
406 } 406 }
407 else 407 else
408 fprintf (alpha_file, "%ld ", (long) *pix_ptr++); 408 fprintf (alpha_file, "%ld ", (long) *pix_ptr++);
409 } 409 }
410 } /* if alpha_present */ 410 } /* if alpha_present */
411 411
412 if (!raw) 412 if (!raw)
413 if (col % 4 == 3) 413 if (col % 4 == 3)
414 fprintf (pnm_file, "\n"); 414 fprintf (pnm_file, "\n");
415 } /* end for col */ 415 } /* end for col */
416 416
417 if (!raw) 417 if (!raw)
418 if (col % 4 != 0) 418 if (col % 4 != 0)
419 fprintf (pnm_file, "\n"); 419 fprintf (pnm_file, "\n");
420 } /* end for row */ 420 } /* end for row */
421 421
422 if (row_pointers != (unsigned char**) NULL) 422 if (row_pointers != (unsigned char**) NULL)
423 free (row_pointers); 423 free (row_pointers);
424 if (png_pixels != (unsigned char*) NULL) 424 if (png_pixels != (unsigned char*) NULL)
425 free (png_pixels); 425 free (png_pixels);
426 426
427 return TRUE; 427 return TRUE;
428 428
429} /* end of source */ 429} /* end of source */
430 430
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.sh b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.sh
index ee39664..b1c0537 100755
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.sh
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/png2pnm.sh
@@ -1,42 +1,42 @@
1#!/bin/sh 1#!/bin/sh
2# -- grayscale 2# -- grayscale
3./png2pnm -noraw ../pngsuite/basn0g01.png basn0g01.pgm 3./png2pnm -noraw ../pngsuite/basn0g01.png basn0g01.pgm
4./png2pnm -noraw ../pngsuite/basn0g02.png basn0g02.pgm 4./png2pnm -noraw ../pngsuite/basn0g02.png basn0g02.pgm
5./png2pnm -noraw ../pngsuite/basn0g04.png basn0g04.pgm 5./png2pnm -noraw ../pngsuite/basn0g04.png basn0g04.pgm
6./png2pnm -noraw ../pngsuite/basn0g08.png basn0g08.pgm 6./png2pnm -noraw ../pngsuite/basn0g08.png basn0g08.pgm
7./png2pnm -noraw ../pngsuite/basn0g16.png basn0g16.pgm 7./png2pnm -noraw ../pngsuite/basn0g16.png basn0g16.pgm
8# -- full-color 8# -- full-color
9./png2pnm -noraw ../pngsuite/basn2c08.png basn2c08.ppm 9./png2pnm -noraw ../pngsuite/basn2c08.png basn2c08.ppm
10./png2pnm -noraw ../pngsuite/basn2c16.png basn2c16.ppm 10./png2pnm -noraw ../pngsuite/basn2c16.png basn2c16.ppm
11# -- palletted 11# -- palletted
12./png2pnm -noraw ../pngsuite/basn3p01.png basn3p01.ppm 12./png2pnm -noraw ../pngsuite/basn3p01.png basn3p01.ppm
13./png2pnm -noraw ../pngsuite/basn3p02.png basn3p02.ppm 13./png2pnm -noraw ../pngsuite/basn3p02.png basn3p02.ppm
14./png2pnm -noraw ../pngsuite/basn3p04.png basn3p04.ppm 14./png2pnm -noraw ../pngsuite/basn3p04.png basn3p04.ppm
15./png2pnm -noraw ../pngsuite/basn3p08.png basn3p08.ppm 15./png2pnm -noraw ../pngsuite/basn3p08.png basn3p08.ppm
16# -- gray with alpha-channel 16# -- gray with alpha-channel
17./png2pnm -noraw ../pngsuite/basn4a08.png basn4a08.pgm 17./png2pnm -noraw ../pngsuite/basn4a08.png basn4a08.pgm
18./png2pnm -noraw ../pngsuite/basn4a16.png basn4a16.pgm 18./png2pnm -noraw ../pngsuite/basn4a16.png basn4a16.pgm
19# -- color with alpha-channel 19# -- color with alpha-channel
20./png2pnm -noraw -alpha basn6a08.pgm ../pngsuite/basn6a08.png basn6a08.ppm 20./png2pnm -noraw -alpha basn6a08.pgm ../pngsuite/basn6a08.png basn6a08.ppm
21./png2pnm -noraw -alpha basn6a16.pgm ../pngsuite/basn6a16.png basn6a16.ppm 21./png2pnm -noraw -alpha basn6a16.pgm ../pngsuite/basn6a16.png basn6a16.ppm
22# -- grayscale 22# -- grayscale
23./png2pnm -raw ../pngsuite/basn0g01.png rawn0g01.pgm 23./png2pnm -raw ../pngsuite/basn0g01.png rawn0g01.pgm
24./png2pnm -raw ../pngsuite/basn0g02.png rawn0g02.pgm 24./png2pnm -raw ../pngsuite/basn0g02.png rawn0g02.pgm
25./png2pnm -raw ../pngsuite/basn0g04.png rawn0g04.pgm 25./png2pnm -raw ../pngsuite/basn0g04.png rawn0g04.pgm
26./png2pnm -raw ../pngsuite/basn0g08.png rawn0g08.pgm 26./png2pnm -raw ../pngsuite/basn0g08.png rawn0g08.pgm
27./png2pnm -raw ../pngsuite/basn0g16.png rawn0g16.pgm 27./png2pnm -raw ../pngsuite/basn0g16.png rawn0g16.pgm
28# -- full-color 28# -- full-color
29./png2pnm -raw ../pngsuite/basn2c08.png rawn2c08.ppm 29./png2pnm -raw ../pngsuite/basn2c08.png rawn2c08.ppm
30./png2pnm -raw ../pngsuite/basn2c16.png rawn2c16.ppm 30./png2pnm -raw ../pngsuite/basn2c16.png rawn2c16.ppm
31# -- palletted 31# -- palletted
32./png2pnm -raw ../pngsuite/basn3p01.png rawn3p01.ppm 32./png2pnm -raw ../pngsuite/basn3p01.png rawn3p01.ppm
33./png2pnm -raw ../pngsuite/basn3p02.png rawn3p02.ppm 33./png2pnm -raw ../pngsuite/basn3p02.png rawn3p02.ppm
34./png2pnm -raw ../pngsuite/basn3p04.png rawn3p04.ppm 34./png2pnm -raw ../pngsuite/basn3p04.png rawn3p04.ppm
35./png2pnm -raw ../pngsuite/basn3p08.png rawn3p08.ppm 35./png2pnm -raw ../pngsuite/basn3p08.png rawn3p08.ppm
36# -- gray with alpha-channel 36# -- gray with alpha-channel
37./png2pnm -raw ../pngsuite/basn4a08.png rawn4a08.pgm 37./png2pnm -raw ../pngsuite/basn4a08.png rawn4a08.pgm
38./png2pnm -raw ../pngsuite/basn4a16.png rawn4a16.pgm 38./png2pnm -raw ../pngsuite/basn4a16.png rawn4a16.pgm
39# -- color with alpha-channel 39# -- color with alpha-channel
40./png2pnm -noraw -alpha rawn6a08.pgm ../pngsuite/basn6a08.png rawn6a08.ppm 40./png2pnm -noraw -alpha rawn6a08.pgm ../pngsuite/basn6a08.png rawn6a08.ppm
41./png2pnm -noraw -alpha rawn6a16.pgm ../pngsuite/basn6a16.png rawn6a16.ppm 41./png2pnm -noraw -alpha rawn6a16.pgm ../pngsuite/basn6a16.png rawn6a16.ppm
42 42
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.bat b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.bat
index 5f8d2d4..911bb8d 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.bat
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.bat
@@ -1,4 +1,4 @@
1make -f makefile.tc3 1make -f makefile.tc3
2call png2pnm.bat 2call png2pnm.bat
3call pnm2png.bat 3call pnm2png.bat
4 4
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.sh b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.sh
index adcef55..2a0a9d8 100755
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.sh
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pngminus.sh
@@ -1,5 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2make -f makefile.std 2make -f makefile.std
3sh png2pnm.sh 3sh png2pnm.sh
4sh pnm2png.sh 4sh pnm2png.sh
5 5
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.bat b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.bat
index 5b9977a..f756cb8 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.bat
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.bat
@@ -1,41 +1,41 @@
1REM -- grayscale 1REM -- grayscale
2pnm2png.exe basn0g01.pgm basn0g01.png 2pnm2png.exe basn0g01.pgm basn0g01.png
3pnm2png.exe basn0g02.pgm basn0g02.png 3pnm2png.exe basn0g02.pgm basn0g02.png
4pnm2png.exe basn0g04.pgm basn0g04.png 4pnm2png.exe basn0g04.pgm basn0g04.png
5pnm2png.exe basn0g08.pgm basn0g08.png 5pnm2png.exe basn0g08.pgm basn0g08.png
6pnm2png.exe basn0g16.pgm basn0g16.png 6pnm2png.exe basn0g16.pgm basn0g16.png
7REM -- full-color 7REM -- full-color
8pnm2png.exe basn2c08.ppm basn2c08.png 8pnm2png.exe basn2c08.ppm basn2c08.png
9pnm2png.exe basn2c16.ppm basn2c16.png 9pnm2png.exe basn2c16.ppm basn2c16.png
10REM -- palletted 10REM -- palletted
11pnm2png.exe basn3p01.ppm basn3p01.png 11pnm2png.exe basn3p01.ppm basn3p01.png
12pnm2png.exe basn3p02.ppm basn3p02.png 12pnm2png.exe basn3p02.ppm basn3p02.png
13pnm2png.exe basn3p04.ppm basn3p04.png 13pnm2png.exe basn3p04.ppm basn3p04.png
14pnm2png.exe basn3p08.ppm basn3p08.png 14pnm2png.exe basn3p08.ppm basn3p08.png
15REM -- gray with alpha-channel 15REM -- gray with alpha-channel
16pnm2png.exe -alpha basn6a08.pgm basn4a08.pgm basn4a08.png 16pnm2png.exe -alpha basn6a08.pgm basn4a08.pgm basn4a08.png
17pnm2png.exe -alpha basn6a16.pgm basn4a16.pgm basn4a16.png 17pnm2png.exe -alpha basn6a16.pgm basn4a16.pgm basn4a16.png
18REM -- color with alpha-channel 18REM -- color with alpha-channel
19pnm2png.exe -alpha basn6a08.pgm basn6a08.ppm basn6a08.png 19pnm2png.exe -alpha basn6a08.pgm basn6a08.ppm basn6a08.png
20pnm2png.exe -alpha basn6a16.pgm basn6a16.ppm basn6a16.png 20pnm2png.exe -alpha basn6a16.pgm basn6a16.ppm basn6a16.png
21REM -- grayscale 21REM -- grayscale
22pnm2png.exe rawn0g01.pgm rawn0g01.png 22pnm2png.exe rawn0g01.pgm rawn0g01.png
23pnm2png.exe rawn0g02.pgm rawn0g02.png 23pnm2png.exe rawn0g02.pgm rawn0g02.png
24pnm2png.exe rawn0g04.pgm rawn0g04.png 24pnm2png.exe rawn0g04.pgm rawn0g04.png
25pnm2png.exe rawn0g08.pgm rawn0g08.png 25pnm2png.exe rawn0g08.pgm rawn0g08.png
26pnm2png.exe rawn0g16.pgm rawn0g16.png 26pnm2png.exe rawn0g16.pgm rawn0g16.png
27REM -- full-color 27REM -- full-color
28pnm2png.exe rawn2c08.ppm rawn2c08.png 28pnm2png.exe rawn2c08.ppm rawn2c08.png
29pnm2png.exe rawn2c16.ppm rawn2c16.png 29pnm2png.exe rawn2c16.ppm rawn2c16.png
30REM -- palletted 30REM -- palletted
31pnm2png.exe rawn3p01.ppm rawn3p01.png 31pnm2png.exe rawn3p01.ppm rawn3p01.png
32pnm2png.exe rawn3p02.ppm rawn3p02.png 32pnm2png.exe rawn3p02.ppm rawn3p02.png
33pnm2png.exe rawn3p04.ppm rawn3p04.png 33pnm2png.exe rawn3p04.ppm rawn3p04.png
34pnm2png.exe rawn3p08.ppm rawn3p08.png 34pnm2png.exe rawn3p08.ppm rawn3p08.png
35REM -- gray with alpha-channel 35REM -- gray with alpha-channel
36pnm2png.exe -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png 36pnm2png.exe -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png
37pnm2png.exe -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png 37pnm2png.exe -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png
38REM -- color with alpha-channel 38REM -- color with alpha-channel
39pnm2png.exe -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png 39pnm2png.exe -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png
40pnm2png.exe -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png 40pnm2png.exe -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png
41 41
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.c
index 2f321cc..4cdfad8 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.c
@@ -1,533 +1,533 @@
1/* 1/*
2 * pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file 2 * pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file
3 * copyright (C) 1999 by Willem van Schaik <willem@schaik.com> 3 * copyright (C) 1999 by Willem van Schaik <willem@schaik.com>
4 * 4 *
5 * version 1.0 - 1999.10.15 - First version. 5 * version 1.0 - 1999.10.15 - First version.
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software and 7 * Permission to use, copy, modify, and distribute this software and
8 * its documentation for any purpose and without fee is hereby granted, 8 * its documentation for any purpose and without fee is hereby granted,
9 * provided that the above copyright notice appear in all copies and 9 * provided that the above copyright notice appear in all copies and
10 * that both that copyright notice and this permission notice appear in 10 * that both that copyright notice and this permission notice appear in
11 * supporting documentation. This software is provided "as is" without 11 * supporting documentation. This software is provided "as is" without
12 * express or implied warranty. 12 * express or implied warranty.
13 */ 13 */
14 14
15#include <stdio.h> 15#include <stdio.h>
16#include <stdlib.h> 16#include <stdlib.h>
17#ifdef __TURBOC__ 17#ifdef __TURBOC__
18#include <mem.h> 18#include <mem.h>
19#include <fcntl.h> 19#include <fcntl.h>
20#endif 20#endif
21 21
22#ifndef BOOL 22#ifndef BOOL
23#define BOOL unsigned char 23#define BOOL unsigned char
24#endif 24#endif
25#ifndef TRUE 25#ifndef TRUE
26#define TRUE (BOOL) 1 26#define TRUE (BOOL) 1
27#endif 27#endif
28#ifndef FALSE 28#ifndef FALSE
29#define FALSE (BOOL) 0 29#define FALSE (BOOL) 0
30#endif 30#endif
31 31
32#define STDIN 0 32#define STDIN 0
33#define STDOUT 1 33#define STDOUT 1
34#define STDERR 2 34#define STDERR 2
35 35
36/* to make pnm2png verbose so we can find problems (needs to be before png.h) */ 36/* to make pnm2png verbose so we can find problems (needs to be before png.h) */
37#ifndef PNG_DEBUG 37#ifndef PNG_DEBUG
38#define PNG_DEBUG 0 38#define PNG_DEBUG 0
39#endif 39#endif
40 40
41#include "png.h" 41#include "png.h"
42 42
43/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ 43/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
44#ifndef png_jmpbuf 44#ifndef png_jmpbuf
45# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) 45# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
46#endif 46#endif
47 47
48/* function prototypes */ 48/* function prototypes */
49 49
50int main (int argc, char *argv[]); 50int main (int argc, char *argv[]);
51void usage (); 51void usage ();
52BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha); 52BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha);
53void get_token(FILE *pnm_file, char *token); 53void get_token(FILE *pnm_file, char *token);
54png_uint_32 get_data (FILE *pnm_file, int depth); 54png_uint_32 get_data (FILE *pnm_file, int depth);
55png_uint_32 get_value (FILE *pnm_file, int depth); 55png_uint_32 get_value (FILE *pnm_file, int depth);
56 56
57/* 57/*
58 * main 58 * main
59 */ 59 */
60 60
61int main(int argc, char *argv[]) 61int main(int argc, char *argv[])
62{ 62{
63 FILE *fp_rd = stdin; 63 FILE *fp_rd = stdin;
64 FILE *fp_al = NULL; 64 FILE *fp_al = NULL;
65 FILE *fp_wr = stdout; 65 FILE *fp_wr = stdout;
66 BOOL interlace = FALSE; 66 BOOL interlace = FALSE;
67 BOOL alpha = FALSE; 67 BOOL alpha = FALSE;
68 int argi; 68 int argi;
69 69
70 for (argi = 1; argi < argc; argi++) 70 for (argi = 1; argi < argc; argi++)
71 { 71 {
72 if (argv[argi][0] == '-') 72 if (argv[argi][0] == '-')
73 { 73 {
74 switch (argv[argi][1]) 74 switch (argv[argi][1])
75 { 75 {
76 case 'i': 76 case 'i':
77 interlace = TRUE; 77 interlace = TRUE;
78 break; 78 break;
79 case 'a': 79 case 'a':
80 alpha = TRUE; 80 alpha = TRUE;
81 argi++; 81 argi++;
82 if ((fp_al = fopen (argv[argi], "rb")) == NULL) 82 if ((fp_al = fopen (argv[argi], "rb")) == NULL)
83 { 83 {
84 fprintf (stderr, "PNM2PNG\n"); 84 fprintf (stderr, "PNM2PNG\n");
85 fprintf (stderr, "Error: alpha-channel file %s does not exist\n", 85 fprintf (stderr, "Error: alpha-channel file %s does not exist\n",
86 argv[argi]); 86 argv[argi]);
87 exit (1); 87 exit (1);
88 } 88 }
89 break; 89 break;
90 case 'h': 90 case 'h':
91 case '?': 91 case '?':
92 usage(); 92 usage();
93 exit(0); 93 exit(0);
94 break; 94 break;
95 default: 95 default:
96 fprintf (stderr, "PNM2PNG\n"); 96 fprintf (stderr, "PNM2PNG\n");
97 fprintf (stderr, "Error: unknown option %s\n", argv[argi]); 97 fprintf (stderr, "Error: unknown option %s\n", argv[argi]);
98 usage(); 98 usage();
99 exit(1); 99 exit(1);
100 break; 100 break;
101 } /* end switch */ 101 } /* end switch */
102 } 102 }
103 else if (fp_rd == stdin) 103 else if (fp_rd == stdin)
104 { 104 {
105 if ((fp_rd = fopen (argv[argi], "rb")) == NULL) 105 if ((fp_rd = fopen (argv[argi], "rb")) == NULL)
106 { 106 {
107 fprintf (stderr, "PNM2PNG\n"); 107 fprintf (stderr, "PNM2PNG\n");
108 fprintf (stderr, "Error: file %s does not exist\n", argv[argi]); 108 fprintf (stderr, "Error: file %s does not exist\n", argv[argi]);
109 exit (1); 109 exit (1);
110 } 110 }
111 } 111 }
112 else if (fp_wr == stdout) 112 else if (fp_wr == stdout)
113 { 113 {
114 if ((fp_wr = fopen (argv[argi], "wb")) == NULL) 114 if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
115 { 115 {
116 fprintf (stderr, "PNM2PNG\n"); 116 fprintf (stderr, "PNM2PNG\n");
117 fprintf (stderr, "Error: can not create PNG-file %s\n", argv[argi]); 117 fprintf (stderr, "Error: can not create PNG-file %s\n", argv[argi]);
118 exit (1); 118 exit (1);
119 } 119 }
120 } 120 }
121 else 121 else
122 { 122 {
123 fprintf (stderr, "PNM2PNG\n"); 123 fprintf (stderr, "PNM2PNG\n");
124 fprintf (stderr, "Error: too many parameters\n"); 124 fprintf (stderr, "Error: too many parameters\n");
125 usage(); 125 usage();
126 exit (1); 126 exit (1);
127 } 127 }
128 } /* end for */ 128 } /* end for */
129 129
130#ifdef __TURBOC__ 130#ifdef __TURBOC__
131 /* set stdin/stdout to binary, we're reading the PNM always! in binary format */ 131 /* set stdin/stdout to binary, we're reading the PNM always! in binary format */
132 if (fp_rd == stdin) 132 if (fp_rd == stdin)
133 { 133 {
134 setmode (STDIN, O_BINARY); 134 setmode (STDIN, O_BINARY);
135 } 135 }
136 if (fp_wr == stdout) 136 if (fp_wr == stdout)
137 { 137 {
138 setmode (STDOUT, O_BINARY); 138 setmode (STDOUT, O_BINARY);
139 } 139 }
140#endif 140#endif
141 141
142 /* call the conversion program itself */ 142 /* call the conversion program itself */
143 if (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE) 143 if (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE)
144 { 144 {
145 fprintf (stderr, "PNM2PNG\n"); 145 fprintf (stderr, "PNM2PNG\n");
146 fprintf (stderr, "Error: unsuccessful converting to PNG-image\n"); 146 fprintf (stderr, "Error: unsuccessful converting to PNG-image\n");
147 exit (1); 147 exit (1);
148 } 148 }
149 149
150 /* close input file */ 150 /* close input file */
151 fclose (fp_rd); 151 fclose (fp_rd);
152 /* close output file */ 152 /* close output file */
153 fclose (fp_wr); 153 fclose (fp_wr);
154 /* close alpha file */ 154 /* close alpha file */
155 if (alpha) 155 if (alpha)
156 fclose (fp_al); 156 fclose (fp_al);
157 157
158 return 0; 158 return 0;
159} 159}
160 160
161/* 161/*
162 * usage 162 * usage
163 */ 163 */
164 164
165void usage() 165void usage()
166{ 166{
167 fprintf (stderr, "PNM2PNG\n"); 167 fprintf (stderr, "PNM2PNG\n");
168 fprintf (stderr, " by Willem van Schaik, 1999\n"); 168 fprintf (stderr, " by Willem van Schaik, 1999\n");
169#ifdef __TURBOC__ 169#ifdef __TURBOC__
170 fprintf (stderr, " for Turbo-C and Borland-C compilers\n"); 170 fprintf (stderr, " for Turbo-C and Borland-C compilers\n");
171#else 171#else
172 fprintf (stderr, " for Linux (and Unix) compilers\n"); 172 fprintf (stderr, " for Linux (and Unix) compilers\n");
173#endif 173#endif
174 fprintf (stderr, "Usage: pnm2png [options] <file>.<pnm> [<file>.png]\n"); 174 fprintf (stderr, "Usage: pnm2png [options] <file>.<pnm> [<file>.png]\n");
175 fprintf (stderr, " or: ... | pnm2png [options]\n"); 175 fprintf (stderr, " or: ... | pnm2png [options]\n");
176 fprintf (stderr, "Options:\n"); 176 fprintf (stderr, "Options:\n");
177 fprintf (stderr, " -i[nterlace] write png-file with interlacing on\n"); 177 fprintf (stderr, " -i[nterlace] write png-file with interlacing on\n");
178 fprintf (stderr, " -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n"); 178 fprintf (stderr, " -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n");
179 fprintf (stderr, " -h | -? print this help-information\n"); 179 fprintf (stderr, " -h | -? print this help-information\n");
180} 180}
181 181
182/* 182/*
183 * pnm2png 183 * pnm2png
184 */ 184 */
185 185
186BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha) 186BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha)
187{ 187{
188 png_struct *png_ptr = NULL; 188 png_struct *png_ptr = NULL;
189 png_info *info_ptr = NULL; 189 png_info *info_ptr = NULL;
190 png_byte *png_pixels = NULL; 190 png_byte *png_pixels = NULL;
191 png_byte **row_pointers = NULL; 191 png_byte **row_pointers = NULL;
192 png_byte *pix_ptr = NULL; 192 png_byte *pix_ptr = NULL;
193 png_uint_32 row_bytes; 193 png_uint_32 row_bytes;
194 194
195 char type_token[16]; 195 char type_token[16];
196 char width_token[16]; 196 char width_token[16];
197 char height_token[16]; 197 char height_token[16];
198 char maxval_token[16]; 198 char maxval_token[16];
199 int color_type; 199 int color_type;
200 png_uint_32 width, alpha_width; 200 png_uint_32 width, alpha_width;
201 png_uint_32 height, alpha_height; 201 png_uint_32 height, alpha_height;
202 png_uint_32 maxval; 202 png_uint_32 maxval;
203 int bit_depth = 0; 203 int bit_depth = 0;
204 int channels; 204 int channels;
205 int alpha_depth = 0; 205 int alpha_depth = 0;
206 int alpha_present; 206 int alpha_present;
207 int row, col; 207 int row, col;
208 BOOL raw, alpha_raw = FALSE; 208 BOOL raw, alpha_raw = FALSE;
209 png_uint_32 tmp16; 209 png_uint_32 tmp16;
210 int i; 210 int i;
211 211
212 /* read header of PNM file */ 212 /* read header of PNM file */
213 213
214 get_token(pnm_file, type_token); 214 get_token(pnm_file, type_token);
215 if (type_token[0] != 'P') 215 if (type_token[0] != 'P')
216 { 216 {
217 return FALSE; 217 return FALSE;
218 } 218 }
219 else if ((type_token[1] == '1') || (type_token[1] == '4')) 219 else if ((type_token[1] == '1') || (type_token[1] == '4'))
220 { 220 {
221 raw = (type_token[1] == '4'); 221 raw = (type_token[1] == '4');
222 color_type = PNG_COLOR_TYPE_GRAY; 222 color_type = PNG_COLOR_TYPE_GRAY;
223 bit_depth = 1; 223 bit_depth = 1;
224 } 224 }
225 else if ((type_token[1] == '2') || (type_token[1] == '5')) 225 else if ((type_token[1] == '2') || (type_token[1] == '5'))
226 { 226 {
227 raw = (type_token[1] == '5'); 227 raw = (type_token[1] == '5');
228 color_type = PNG_COLOR_TYPE_GRAY; 228 color_type = PNG_COLOR_TYPE_GRAY;
229 get_token(pnm_file, width_token); 229 get_token(pnm_file, width_token);
230 sscanf (width_token, "%lu", &width); 230 sscanf (width_token, "%lu", &width);
231 get_token(pnm_file, height_token); 231 get_token(pnm_file, height_token);
232 sscanf (height_token, "%lu", &height); 232 sscanf (height_token, "%lu", &height);
233 get_token(pnm_file, maxval_token); 233 get_token(pnm_file, maxval_token);
234 sscanf (maxval_token, "%lu", &maxval); 234 sscanf (maxval_token, "%lu", &maxval);
235 if (maxval <= 1) 235 if (maxval <= 1)
236 bit_depth = 1; 236 bit_depth = 1;
237 else if (maxval <= 3) 237 else if (maxval <= 3)
238 bit_depth = 2; 238 bit_depth = 2;
239 else if (maxval <= 15) 239 else if (maxval <= 15)
240 bit_depth = 4; 240 bit_depth = 4;
241 else if (maxval <= 255) 241 else if (maxval <= 255)
242 bit_depth = 8; 242 bit_depth = 8;
243 else /* if (maxval <= 65535) */ 243 else /* if (maxval <= 65535) */
244 bit_depth = 16; 244 bit_depth = 16;
245 } 245 }
246 else if ((type_token[1] == '3') || (type_token[1] == '6')) 246 else if ((type_token[1] == '3') || (type_token[1] == '6'))
247 { 247 {
248 raw = (type_token[1] == '6'); 248 raw = (type_token[1] == '6');
249 color_type = PNG_COLOR_TYPE_RGB; 249 color_type = PNG_COLOR_TYPE_RGB;
250 get_token(pnm_file, width_token); 250 get_token(pnm_file, width_token);
251 sscanf (width_token, "%lu", &width); 251 sscanf (width_token, "%lu", &width);
252 get_token(pnm_file, height_token); 252 get_token(pnm_file, height_token);
253 sscanf (height_token, "%lu", &height); 253 sscanf (height_token, "%lu", &height);
254 get_token(pnm_file, maxval_token); 254 get_token(pnm_file, maxval_token);
255 sscanf (maxval_token, "%lu", &maxval); 255 sscanf (maxval_token, "%lu", &maxval);
256 if (maxval <= 1) 256 if (maxval <= 1)
257 bit_depth = 1; 257 bit_depth = 1;
258 else if (maxval <= 3) 258 else if (maxval <= 3)
259 bit_depth = 2; 259 bit_depth = 2;
260 else if (maxval <= 15) 260 else if (maxval <= 15)
261 bit_depth = 4; 261 bit_depth = 4;
262 else if (maxval <= 255) 262 else if (maxval <= 255)
263 bit_depth = 8; 263 bit_depth = 8;
264 else /* if (maxval <= 65535) */ 264 else /* if (maxval <= 65535) */
265 bit_depth = 16; 265 bit_depth = 16;
266 } 266 }
267 else 267 else
268 { 268 {
269 return FALSE; 269 return FALSE;
270 } 270 }
271 271
272 /* read header of PGM file with alpha channel */ 272 /* read header of PGM file with alpha channel */
273 273
274 if (alpha) 274 if (alpha)
275 { 275 {
276 if (color_type == PNG_COLOR_TYPE_GRAY) 276 if (color_type == PNG_COLOR_TYPE_GRAY)
277 color_type = PNG_COLOR_TYPE_GRAY_ALPHA; 277 color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
278 if (color_type == PNG_COLOR_TYPE_RGB) 278 if (color_type == PNG_COLOR_TYPE_RGB)
279 color_type = PNG_COLOR_TYPE_RGB_ALPHA; 279 color_type = PNG_COLOR_TYPE_RGB_ALPHA;
280 280
281 get_token(alpha_file, type_token); 281 get_token(alpha_file, type_token);
282 if (type_token[0] != 'P') 282 if (type_token[0] != 'P')
283 { 283 {
284 return FALSE; 284 return FALSE;
285 } 285 }
286 else if ((type_token[1] == '2') || (type_token[1] == '5')) 286 else if ((type_token[1] == '2') || (type_token[1] == '5'))
287 { 287 {
288 alpha_raw = (type_token[1] == '5'); 288 alpha_raw = (type_token[1] == '5');
289 get_token(alpha_file, width_token); 289 get_token(alpha_file, width_token);
290 sscanf (width_token, "%lu", &alpha_width); 290 sscanf (width_token, "%lu", &alpha_width);
291 if (alpha_width != width) 291 if (alpha_width != width)
292 return FALSE; 292 return FALSE;
293 get_token(alpha_file, height_token); 293 get_token(alpha_file, height_token);
294 sscanf (height_token, "%lu", &alpha_height); 294 sscanf (height_token, "%lu", &alpha_height);
295 if (alpha_height != height) 295 if (alpha_height != height)
296 return FALSE; 296 return FALSE;
297 get_token(alpha_file, maxval_token); 297 get_token(alpha_file, maxval_token);
298 sscanf (maxval_token, "%lu", &maxval); 298 sscanf (maxval_token, "%lu", &maxval);
299 if (maxval <= 1) 299 if (maxval <= 1)
300 alpha_depth = 1; 300 alpha_depth = 1;
301 else if (maxval <= 3) 301 else if (maxval <= 3)
302 alpha_depth = 2; 302 alpha_depth = 2;
303 else if (maxval <= 15) 303 else if (maxval <= 15)
304 alpha_depth = 4; 304 alpha_depth = 4;
305 else if (maxval <= 255) 305 else if (maxval <= 255)
306 alpha_depth = 8; 306 alpha_depth = 8;
307 else /* if (maxval <= 65535) */ 307 else /* if (maxval <= 65535) */
308 alpha_depth = 16; 308 alpha_depth = 16;
309 if (alpha_depth != bit_depth) 309 if (alpha_depth != bit_depth)
310 return FALSE; 310 return FALSE;
311 } 311 }
312 else 312 else
313 { 313 {
314 return FALSE; 314 return FALSE;
315 } 315 }
316 } /* end if alpha */ 316 } /* end if alpha */
317 317
318 /* calculate the number of channels and store alpha-presence */ 318 /* calculate the number of channels and store alpha-presence */
319 if (color_type == PNG_COLOR_TYPE_GRAY) 319 if (color_type == PNG_COLOR_TYPE_GRAY)
320 channels = 1; 320 channels = 1;
321 else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 321 else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
322 channels = 2; 322 channels = 2;
323 else if (color_type == PNG_COLOR_TYPE_RGB) 323 else if (color_type == PNG_COLOR_TYPE_RGB)
324 channels = 3; 324 channels = 3;
325 else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) 325 else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
326 channels = 4; 326 channels = 4;
327 else 327 else
328 channels = 0; /* should not happen */ 328 channels = 0; /* should not happen */
329 329
330 alpha_present = (channels - 1) % 2; 330 alpha_present = (channels - 1) % 2;
331 331
332 /* row_bytes is the width x number of channels x (bit-depth / 8) */ 332 /* row_bytes is the width x number of channels x (bit-depth / 8) */
333 row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); 333 row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
334 334
335 if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) 335 if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL)
336 return FALSE; 336 return FALSE;
337 337
338 /* read data from PNM file */ 338 /* read data from PNM file */
339 pix_ptr = png_pixels; 339 pix_ptr = png_pixels;
340 340
341 for (row = 0; row < height; row++) 341 for (row = 0; row < height; row++)
342 { 342 {
343 for (col = 0; col < width; col++) 343 for (col = 0; col < width; col++)
344 { 344 {
345 for (i = 0; i < (channels - alpha_present); i++) 345 for (i = 0; i < (channels - alpha_present); i++)
346 { 346 {
347 if (raw) 347 if (raw)
348 *pix_ptr++ = get_data (pnm_file, bit_depth); 348 *pix_ptr++ = get_data (pnm_file, bit_depth);
349 else 349 else
350 if (bit_depth <= 8) 350 if (bit_depth <= 8)
351 *pix_ptr++ = get_value (pnm_file, bit_depth); 351 *pix_ptr++ = get_value (pnm_file, bit_depth);
352 else 352 else
353 { 353 {
354 tmp16 = get_value (pnm_file, bit_depth); 354 tmp16 = get_value (pnm_file, bit_depth);
355 *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF); 355 *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF);
356 pix_ptr++; 356 pix_ptr++;
357 *pix_ptr = (png_byte) (tmp16 & 0xFF); 357 *pix_ptr = (png_byte) (tmp16 & 0xFF);
358 pix_ptr++; 358 pix_ptr++;
359 } 359 }
360 } 360 }
361 361
362 if (alpha) /* read alpha-channel from pgm file */ 362 if (alpha) /* read alpha-channel from pgm file */
363 { 363 {
364 if (alpha_raw) 364 if (alpha_raw)
365 *pix_ptr++ = get_data (alpha_file, alpha_depth); 365 *pix_ptr++ = get_data (alpha_file, alpha_depth);
366 else 366 else
367 if (alpha_depth <= 8) 367 if (alpha_depth <= 8)
368 *pix_ptr++ = get_value (alpha_file, bit_depth); 368 *pix_ptr++ = get_value (alpha_file, bit_depth);
369 else 369 else
370 { 370 {
371 tmp16 = get_value (alpha_file, bit_depth); 371 tmp16 = get_value (alpha_file, bit_depth);
372 *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF); 372 *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF);
373 *pix_ptr++ = (png_byte) (tmp16 & 0xFF); 373 *pix_ptr++ = (png_byte) (tmp16 & 0xFF);
374 } 374 }
375 } /* if alpha */ 375 } /* if alpha */
376 376
377 } /* end for col */ 377 } /* end for col */
378 } /* end for row */ 378 } /* end for row */
379 379
380 /* prepare the standard PNG structures */ 380 /* prepare the standard PNG structures */
381 png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 381 png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
382 if (!png_ptr) 382 if (!png_ptr)
383 { 383 {
384 return FALSE; 384 return FALSE;
385 } 385 }
386 info_ptr = png_create_info_struct (png_ptr); 386 info_ptr = png_create_info_struct (png_ptr);
387 if (!info_ptr) 387 if (!info_ptr)
388 { 388 {
389 png_destroy_write_struct (&png_ptr, (png_infopp) NULL); 389 png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
390 return FALSE; 390 return FALSE;
391 } 391 }
392 392
393 /* setjmp() must be called in every function that calls a PNG-reading libpng function */ 393 /* setjmp() must be called in every function that calls a PNG-reading libpng function */
394 if (setjmp (png_jmpbuf(png_ptr))) 394 if (setjmp (png_jmpbuf(png_ptr)))
395 { 395 {
396 png_destroy_write_struct (&png_ptr, (png_infopp) NULL); 396 png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
397 return FALSE; 397 return FALSE;
398 } 398 }
399 399
400 /* initialize the png structure */ 400 /* initialize the png structure */
401 png_init_io (png_ptr, png_file); 401 png_init_io (png_ptr, png_file);
402 402
403 /* we're going to write more or less the same PNG as the input file */ 403 /* we're going to write more or less the same PNG as the input file */
404 png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type, 404 png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type,
405 (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7, 405 (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7,
406 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 406 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
407 407
408 /* write the file header information */ 408 /* write the file header information */
409 png_write_info (png_ptr, info_ptr); 409 png_write_info (png_ptr, info_ptr);
410 410
411 /* if needed we will allocate memory for an new array of row-pointers */ 411 /* if needed we will allocate memory for an new array of row-pointers */
412 if (row_pointers == (unsigned char**) NULL) 412 if (row_pointers == (unsigned char**) NULL)
413 { 413 {
414 if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL) 414 if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL)
415 { 415 {
416 png_destroy_write_struct (&png_ptr, (png_infopp) NULL); 416 png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
417 return FALSE; 417 return FALSE;
418 } 418 }
419 } 419 }
420 420
421 /* set the individual row_pointers to point at the correct offsets */ 421 /* set the individual row_pointers to point at the correct offsets */
422 for (i = 0; i < (height); i++) 422 for (i = 0; i < (height); i++)
423 row_pointers[i] = png_pixels + i * row_bytes; 423 row_pointers[i] = png_pixels + i * row_bytes;
424 424
425 /* write out the entire image data in one call */ 425 /* write out the entire image data in one call */
426 png_write_image (png_ptr, row_pointers); 426 png_write_image (png_ptr, row_pointers);
427 427
428 /* write the additional chuncks to the PNG file (not really needed) */ 428 /* write the additional chuncks to the PNG file (not really needed) */
429 png_write_end (png_ptr, info_ptr); 429 png_write_end (png_ptr, info_ptr);
430 430
431 /* clean up after the write, and free any memory allocated */ 431 /* clean up after the write, and free any memory allocated */
432 png_destroy_write_struct (&png_ptr, (png_infopp) NULL); 432 png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
433 433
434 if (row_pointers != (unsigned char**) NULL) 434 if (row_pointers != (unsigned char**) NULL)
435 free (row_pointers); 435 free (row_pointers);
436 if (png_pixels != (unsigned char*) NULL) 436 if (png_pixels != (unsigned char*) NULL)
437 free (png_pixels); 437 free (png_pixels);
438 438
439 return TRUE; 439 return TRUE;
440} /* end of pnm2png */ 440} /* end of pnm2png */
441 441
442/* 442/*
443 * get_token() - gets the first string after whitespace 443 * get_token() - gets the first string after whitespace
444 */ 444 */
445 445
446void get_token(FILE *pnm_file, char *token) 446void get_token(FILE *pnm_file, char *token)
447{ 447{
448 int i = 0; 448 int i = 0;
449 449
450 /* remove white-space */ 450 /* remove white-space */
451 do 451 do
452 { 452 {
453 token[i] = (unsigned char) fgetc (pnm_file); 453 token[i] = (unsigned char) fgetc (pnm_file);
454 } 454 }
455 while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' ')); 455 while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' '));
456 456
457 /* read string */ 457 /* read string */
458 do 458 do
459 { 459 {
460 i++; 460 i++;
461 token[i] = (unsigned char) fgetc (pnm_file); 461 token[i] = (unsigned char) fgetc (pnm_file);
462 } 462 }
463 while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' ')); 463 while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' '));
464 464
465 token[i] = '\0'; 465 token[i] = '\0';
466 466
467 return; 467 return;
468} 468}
469 469
470/* 470/*
471 * get_data() - takes first byte and converts into next pixel value, 471 * get_data() - takes first byte and converts into next pixel value,
472 * taking as much bits as defined by bit-depth and 472 * taking as much bits as defined by bit-depth and
473 * using the bit-depth to fill up a byte (0Ah -> AAh) 473 * using the bit-depth to fill up a byte (0Ah -> AAh)
474 */ 474 */
475 475
476png_uint_32 get_data (FILE *pnm_file, int depth) 476png_uint_32 get_data (FILE *pnm_file, int depth)
477{ 477{
478 static int bits_left = 0; 478 static int bits_left = 0;
479 static int old_value = 0; 479 static int old_value = 0;
480 static int mask = 0; 480 static int mask = 0;
481 int i; 481 int i;
482 png_uint_32 ret_value; 482 png_uint_32 ret_value;
483 483
484 if (mask == 0) 484 if (mask == 0)
485 for (i = 0; i < depth; i++) 485 for (i = 0; i < depth; i++)
486 mask = (mask >> 1) | 0x80; 486 mask = (mask >> 1) | 0x80;
487 487
488 if (bits_left <= 0) 488 if (bits_left <= 0)
489 { 489 {
490 old_value = fgetc (pnm_file); 490 old_value = fgetc (pnm_file);
491 bits_left = 8; 491 bits_left = 8;
492 } 492 }
493 493
494 ret_value = old_value & mask; 494 ret_value = old_value & mask;
495 for (i = 1; i < (8 / depth); i++) 495 for (i = 1; i < (8 / depth); i++)
496 ret_value = ret_value || (ret_value >> depth); 496 ret_value = ret_value || (ret_value >> depth);
497 497
498 old_value = (old_value << depth) & 0xFF; 498 old_value = (old_value << depth) & 0xFF;
499 bits_left -= depth; 499 bits_left -= depth;
500 500
501 return ret_value; 501 return ret_value;
502} 502}
503 503
504/* 504/*
505 * get_value() - takes first (numeric) string and converts into number, 505 * get_value() - takes first (numeric) string and converts into number,
506 * using the bit-depth to fill up a byte (0Ah -> AAh) 506 * using the bit-depth to fill up a byte (0Ah -> AAh)
507 */ 507 */
508 508
509png_uint_32 get_value (FILE *pnm_file, int depth) 509png_uint_32 get_value (FILE *pnm_file, int depth)
510{ 510{
511 static png_uint_32 mask = 0; 511 static png_uint_32 mask = 0;
512 png_byte token[16]; 512 png_byte token[16];
513 png_uint_32 ret_value; 513 png_uint_32 ret_value;
514 int i = 0; 514 int i = 0;
515 515
516 if (mask == 0) 516 if (mask == 0)
517 for (i = 0; i < depth; i++) 517 for (i = 0; i < depth; i++)
518 mask = (mask << 1) | 0x01; 518 mask = (mask << 1) | 0x01;
519 519
520 get_token (pnm_file, (char *) token); 520 get_token (pnm_file, (char *) token);
521 sscanf ((const char *) token, "%lu", &ret_value); 521 sscanf ((const char *) token, "%lu", &ret_value);
522 522
523 ret_value &= mask; 523 ret_value &= mask;
524 524
525 if (depth < 8) 525 if (depth < 8)
526 for (i = 0; i < (8 / depth); i++) 526 for (i = 0; i < (8 / depth); i++)
527 ret_value = (ret_value << depth) || ret_value; 527 ret_value = (ret_value << depth) || ret_value;
528 528
529 return ret_value; 529 return ret_value;
530} 530}
531 531
532/* end of source */ 532/* end of source */
533 533
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.sh b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.sh
index 975f047..d79df2f 100755
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.sh
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.sh
@@ -1,42 +1,42 @@
1#!/bin/sh 1#!/bin/sh
2# -- grayscale 2# -- grayscale
3./pnm2png basn0g01.pgm basn0g01.png 3./pnm2png basn0g01.pgm basn0g01.png
4./pnm2png basn0g02.pgm basn0g02.png 4./pnm2png basn0g02.pgm basn0g02.png
5./pnm2png basn0g04.pgm basn0g04.png 5./pnm2png basn0g04.pgm basn0g04.png
6./pnm2png basn0g08.pgm basn0g08.png 6./pnm2png basn0g08.pgm basn0g08.png
7./pnm2png basn0g16.pgm basn0g16.png 7./pnm2png basn0g16.pgm basn0g16.png
8# -- full-color 8# -- full-color
9./pnm2png basn2c08.ppm basn2c08.png 9./pnm2png basn2c08.ppm basn2c08.png
10./pnm2png basn2c16.ppm basn2c16.png 10./pnm2png basn2c16.ppm basn2c16.png
11# -- palletted 11# -- palletted
12./pnm2png basn3p01.ppm basn3p01.png 12./pnm2png basn3p01.ppm basn3p01.png
13./pnm2png basn3p02.ppm basn3p02.png 13./pnm2png basn3p02.ppm basn3p02.png
14./pnm2png basn3p04.ppm basn3p04.png 14./pnm2png basn3p04.ppm basn3p04.png
15./pnm2png basn3p08.ppm basn3p08.png 15./pnm2png basn3p08.ppm basn3p08.png
16# -- gray with alpha-channel 16# -- gray with alpha-channel
17./pnm2png -alpha basn6a08.pgm basn4a08.pgm basn4a08.png 17./pnm2png -alpha basn6a08.pgm basn4a08.pgm basn4a08.png
18./pnm2png -alpha basn6a16.pgm basn4a16.pgm basn4a16.png 18./pnm2png -alpha basn6a16.pgm basn4a16.pgm basn4a16.png
19# -- color with alpha-channel 19# -- color with alpha-channel
20./pnm2png -alpha basn6a08.pgm basn6a08.ppm basn6a08.png 20./pnm2png -alpha basn6a08.pgm basn6a08.ppm basn6a08.png
21./pnm2png -alpha basn6a16.pgm basn6a16.ppm basn6a16.png 21./pnm2png -alpha basn6a16.pgm basn6a16.ppm basn6a16.png
22# -- grayscale 22# -- grayscale
23./pnm2png rawn0g01.pgm rawn0g01.png 23./pnm2png rawn0g01.pgm rawn0g01.png
24./pnm2png rawn0g02.pgm rawn0g02.png 24./pnm2png rawn0g02.pgm rawn0g02.png
25./pnm2png rawn0g04.pgm rawn0g04.png 25./pnm2png rawn0g04.pgm rawn0g04.png
26./pnm2png rawn0g08.pgm rawn0g08.png 26./pnm2png rawn0g08.pgm rawn0g08.png
27./pnm2png rawn0g16.pgm rawn0g16.png 27./pnm2png rawn0g16.pgm rawn0g16.png
28# -- full-color 28# -- full-color
29./pnm2png rawn2c08.ppm rawn2c08.png 29./pnm2png rawn2c08.ppm rawn2c08.png
30./pnm2png rawn2c16.ppm rawn2c16.png 30./pnm2png rawn2c16.ppm rawn2c16.png
31# -- palletted 31# -- palletted
32./pnm2png rawn3p01.ppm rawn3p01.png 32./pnm2png rawn3p01.ppm rawn3p01.png
33./pnm2png rawn3p02.ppm rawn3p02.png 33./pnm2png rawn3p02.ppm rawn3p02.png
34./pnm2png rawn3p04.ppm rawn3p04.png 34./pnm2png rawn3p04.ppm rawn3p04.png
35./pnm2png rawn3p08.ppm rawn3p08.png 35./pnm2png rawn3p08.ppm rawn3p08.png
36# -- gray with alpha-channel 36# -- gray with alpha-channel
37./pnm2png -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png 37./pnm2png -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png
38./pnm2png -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png 38./pnm2png -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png
39# -- color with alpha-channel 39# -- color with alpha-channel
40./pnm2png -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png 40./pnm2png -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png
41./pnm2png -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png 41./pnm2png -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png
42 42
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.c
index f3e440a..ef0984e 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.c
@@ -1,450 +1,450 @@
1/*------------------------------------- 1/*-------------------------------------
2 * PNGFILE.C -- Image File Functions 2 * PNGFILE.C -- Image File Functions
3 *------------------------------------- 3 *-------------------------------------
4 * 4 *
5 * Copyright 2000, Willem van Schaik. 5 * Copyright 2000, Willem van Schaik.
6 * 6 *
7 * This code is released under the libpng license. 7 * This code is released under the libpng license.
8 * For conditions of distribution and use, see the disclaimer 8 * For conditions of distribution and use, see the disclaimer
9 * and license in png.h 9 * and license in png.h
10 */ 10 */
11 11
12#include <windows.h> 12#include <windows.h>
13#include <commdlg.h> 13#include <commdlg.h>
14#include <stdio.h> 14#include <stdio.h>
15#include <stdlib.h> 15#include <stdlib.h>
16 16
17#include "png.h" 17#include "png.h"
18#include "pngfile.h" 18#include "pngfile.h"
19#include "cexcept.h" 19#include "cexcept.h"
20 20
21define_exception_type(const char *); 21define_exception_type(const char *);
22extern struct exception_context the_exception_context[1]; 22extern struct exception_context the_exception_context[1];
23struct exception_context the_exception_context[1]; 23struct exception_context the_exception_context[1];
24png_const_charp msg; 24png_const_charp msg;
25 25
26static OPENFILENAME ofn; 26static OPENFILENAME ofn;
27 27
28static png_structp png_ptr = NULL; 28static png_structp png_ptr = NULL;
29static png_infop info_ptr = NULL; 29static png_infop info_ptr = NULL;
30 30
31 31
32/* cexcept interface */ 32/* cexcept interface */
33 33
34static void 34static void
35png_cexcept_error(png_structp png_ptr, png_const_charp msg) 35png_cexcept_error(png_structp png_ptr, png_const_charp msg)
36{ 36{
37 if(png_ptr) 37 if(png_ptr)
38 ; 38 ;
39#ifdef PNG_CONSOLE_IO_SUPPORTED 39#ifdef PNG_CONSOLE_IO_SUPPORTED
40 fprintf(stderr, "libpng error: %s\n", msg); 40 fprintf(stderr, "libpng error: %s\n", msg);
41#endif 41#endif
42 { 42 {
43 Throw msg; 43 Throw msg;
44 } 44 }
45} 45}
46 46
47/* Windows open-file functions */ 47/* Windows open-file functions */
48 48
49void PngFileInitialize (HWND hwnd) 49void PngFileInitialize (HWND hwnd)
50{ 50{
51 static TCHAR szFilter[] = TEXT ("PNG Files (*.PNG)\0*.png\0") 51 static TCHAR szFilter[] = TEXT ("PNG Files (*.PNG)\0*.png\0")
52 TEXT ("All Files (*.*)\0*.*\0\0"); 52 TEXT ("All Files (*.*)\0*.*\0\0");
53 53
54 ofn.lStructSize = sizeof (OPENFILENAME); 54 ofn.lStructSize = sizeof (OPENFILENAME);
55 ofn.hwndOwner = hwnd; 55 ofn.hwndOwner = hwnd;
56 ofn.hInstance = NULL; 56 ofn.hInstance = NULL;
57 ofn.lpstrFilter = szFilter; 57 ofn.lpstrFilter = szFilter;
58 ofn.lpstrCustomFilter = NULL; 58 ofn.lpstrCustomFilter = NULL;
59 ofn.nMaxCustFilter = 0; 59 ofn.nMaxCustFilter = 0;
60 ofn.nFilterIndex = 0; 60 ofn.nFilterIndex = 0;
61 ofn.lpstrFile = NULL; /* Set in Open and Close functions */ 61 ofn.lpstrFile = NULL; /* Set in Open and Close functions */
62 ofn.nMaxFile = MAX_PATH; 62 ofn.nMaxFile = MAX_PATH;
63 ofn.lpstrFileTitle = NULL; /* Set in Open and Close functions */ 63 ofn.lpstrFileTitle = NULL; /* Set in Open and Close functions */
64 ofn.nMaxFileTitle = MAX_PATH; 64 ofn.nMaxFileTitle = MAX_PATH;
65 ofn.lpstrInitialDir = NULL; 65 ofn.lpstrInitialDir = NULL;
66 ofn.lpstrTitle = NULL; 66 ofn.lpstrTitle = NULL;
67 ofn.Flags = 0; /* Set in Open and Close functions */ 67 ofn.Flags = 0; /* Set in Open and Close functions */
68 ofn.nFileOffset = 0; 68 ofn.nFileOffset = 0;
69 ofn.nFileExtension = 0; 69 ofn.nFileExtension = 0;
70 ofn.lpstrDefExt = TEXT ("png"); 70 ofn.lpstrDefExt = TEXT ("png");
71 ofn.lCustData = 0; 71 ofn.lCustData = 0;
72 ofn.lpfnHook = NULL; 72 ofn.lpfnHook = NULL;
73 ofn.lpTemplateName = NULL; 73 ofn.lpTemplateName = NULL;
74} 74}
75 75
76BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) 76BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
77{ 77{
78 ofn.hwndOwner = hwnd; 78 ofn.hwndOwner = hwnd;
79 ofn.lpstrFile = pstrFileName; 79 ofn.lpstrFile = pstrFileName;
80 ofn.lpstrFileTitle = pstrTitleName; 80 ofn.lpstrFileTitle = pstrTitleName;
81 ofn.Flags = OFN_HIDEREADONLY; 81 ofn.Flags = OFN_HIDEREADONLY;
82 82
83 return GetOpenFileName (&ofn); 83 return GetOpenFileName (&ofn);
84} 84}
85 85
86BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) 86BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
87{ 87{
88 ofn.hwndOwner = hwnd; 88 ofn.hwndOwner = hwnd;
89 ofn.lpstrFile = pstrFileName; 89 ofn.lpstrFile = pstrFileName;
90 ofn.lpstrFileTitle = pstrTitleName; 90 ofn.lpstrFileTitle = pstrTitleName;
91 ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; 91 ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
92 92
93 return GetSaveFileName (&ofn); 93 return GetSaveFileName (&ofn);
94} 94}
95 95
96/* PNG image handler functions */ 96/* PNG image handler functions */
97 97
98BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData, 98BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData,
99 int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor) 99 int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor)
100{ 100{
101 static FILE *pfFile; 101 static FILE *pfFile;
102 png_byte pbSig[8]; 102 png_byte pbSig[8];
103 int iBitDepth; 103 int iBitDepth;
104 int iColorType; 104 int iColorType;
105 double dGamma; 105 double dGamma;
106 png_color_16 *pBackground; 106 png_color_16 *pBackground;
107 png_uint_32 ulChannels; 107 png_uint_32 ulChannels;
108 png_uint_32 ulRowBytes; 108 png_uint_32 ulRowBytes;
109 png_byte *pbImageData = *ppbImageData; 109 png_byte *pbImageData = *ppbImageData;
110 static png_byte **ppbRowPointers = NULL; 110 static png_byte **ppbRowPointers = NULL;
111 int i; 111 int i;
112 112
113 /* open the PNG input file */ 113 /* open the PNG input file */
114 114
115 if (!pstrFileName) 115 if (!pstrFileName)
116 { 116 {
117 *ppbImageData = pbImageData = NULL; 117 *ppbImageData = pbImageData = NULL;
118 return FALSE; 118 return FALSE;
119 } 119 }
120 120
121 if (!(pfFile = fopen(pstrFileName, "rb"))) 121 if (!(pfFile = fopen(pstrFileName, "rb")))
122 { 122 {
123 *ppbImageData = pbImageData = NULL; 123 *ppbImageData = pbImageData = NULL;
124 return FALSE; 124 return FALSE;
125 } 125 }
126 126
127 /* first check the eight byte PNG signature */ 127 /* first check the eight byte PNG signature */
128 128
129 fread(pbSig, 1, 8, pfFile); 129 fread(pbSig, 1, 8, pfFile);
130 if (png_sig_cmp(pbSig, 0, 8)) 130 if (png_sig_cmp(pbSig, 0, 8))
131 { 131 {
132 *ppbImageData = pbImageData = NULL; 132 *ppbImageData = pbImageData = NULL;
133 return FALSE; 133 return FALSE;
134 } 134 }
135 135
136 /* create the two png(-info) structures */ 136 /* create the two png(-info) structures */
137 137
138 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, 138 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
139 (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); 139 (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);
140 if (!png_ptr) 140 if (!png_ptr)
141 { 141 {
142 *ppbImageData = pbImageData = NULL; 142 *ppbImageData = pbImageData = NULL;
143 return FALSE; 143 return FALSE;
144 } 144 }
145 145
146 info_ptr = png_create_info_struct(png_ptr); 146 info_ptr = png_create_info_struct(png_ptr);
147 if (!info_ptr) 147 if (!info_ptr)
148 { 148 {
149 png_destroy_read_struct(&png_ptr, NULL, NULL); 149 png_destroy_read_struct(&png_ptr, NULL, NULL);
150 *ppbImageData = pbImageData = NULL; 150 *ppbImageData = pbImageData = NULL;
151 return FALSE; 151 return FALSE;
152 } 152 }
153 153
154 Try 154 Try
155 { 155 {
156 156
157 /* initialize the png structure */ 157 /* initialize the png structure */
158 158
159#ifdef PNG_STDIO_SUPPORTED 159#ifdef PNG_STDIO_SUPPORTED
160 png_init_io(png_ptr, pfFile); 160 png_init_io(png_ptr, pfFile);
161#else 161#else
162 png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data); 162 png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data);
163#endif 163#endif
164 164
165 png_set_sig_bytes(png_ptr, 8); 165 png_set_sig_bytes(png_ptr, 8);
166 166
167 /* read all PNG info up to image data */ 167 /* read all PNG info up to image data */
168 168
169 png_read_info(png_ptr, info_ptr); 169 png_read_info(png_ptr, info_ptr);
170 170
171 /* get width, height, bit-depth and color-type */ 171 /* get width, height, bit-depth and color-type */
172 172
173 png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth, 173 png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth,
174 &iColorType, NULL, NULL, NULL); 174 &iColorType, NULL, NULL, NULL);
175 175
176 /* expand images of all color-type and bit-depth to 3x8-bit RGB */ 176 /* expand images of all color-type and bit-depth to 3x8-bit RGB */
177 /* let the library process alpha, transparency, background, etc. */ 177 /* let the library process alpha, transparency, background, etc. */
178 178
179#ifdef PNG_READ_16_TO_8_SUPPORTED 179#ifdef PNG_READ_16_TO_8_SUPPORTED
180 if (iBitDepth == 16) 180 if (iBitDepth == 16)
181# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 181# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
182 png_set_scale_16(png_ptr); 182 png_set_scale_16(png_ptr);
183# else 183# else
184 png_set_strip_16(png_ptr); 184 png_set_strip_16(png_ptr);
185# endif 185# endif
186#endif 186#endif
187 if (iColorType == PNG_COLOR_TYPE_PALETTE) 187 if (iColorType == PNG_COLOR_TYPE_PALETTE)
188 png_set_expand(png_ptr); 188 png_set_expand(png_ptr);
189 if (iBitDepth < 8) 189 if (iBitDepth < 8)
190 png_set_expand(png_ptr); 190 png_set_expand(png_ptr);
191 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) 191 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
192 png_set_expand(png_ptr); 192 png_set_expand(png_ptr);
193 if (iColorType == PNG_COLOR_TYPE_GRAY || 193 if (iColorType == PNG_COLOR_TYPE_GRAY ||
194 iColorType == PNG_COLOR_TYPE_GRAY_ALPHA) 194 iColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
195 png_set_gray_to_rgb(png_ptr); 195 png_set_gray_to_rgb(png_ptr);
196 196
197 /* set the background color to draw transparent and alpha images over */ 197 /* set the background color to draw transparent and alpha images over */
198 if (png_get_bKGD(png_ptr, info_ptr, &pBackground)) 198 if (png_get_bKGD(png_ptr, info_ptr, &pBackground))
199 { 199 {
200 png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); 200 png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
201 pBkgColor->red = (byte) pBackground->red; 201 pBkgColor->red = (byte) pBackground->red;
202 pBkgColor->green = (byte) pBackground->green; 202 pBkgColor->green = (byte) pBackground->green;
203 pBkgColor->blue = (byte) pBackground->blue; 203 pBkgColor->blue = (byte) pBackground->blue;
204 } 204 }
205 else 205 else
206 { 206 {
207 pBkgColor = NULL; 207 pBkgColor = NULL;
208 } 208 }
209 209
210 /* if required set gamma conversion */ 210 /* if required set gamma conversion */
211 if (png_get_gAMA(png_ptr, info_ptr, &dGamma)) 211 if (png_get_gAMA(png_ptr, info_ptr, &dGamma))
212 png_set_gamma(png_ptr, (double) 2.2, dGamma); 212 png_set_gamma(png_ptr, (double) 2.2, dGamma);
213 213
214 /* after the transformations are registered, update info_ptr data */ 214 /* after the transformations are registered, update info_ptr data */
215 215
216 png_read_update_info(png_ptr, info_ptr); 216 png_read_update_info(png_ptr, info_ptr);
217 217
218 /* get again width, height and the new bit-depth and color-type */ 218 /* get again width, height and the new bit-depth and color-type */
219 219
220 png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth, 220 png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth,
221 &iColorType, NULL, NULL, NULL); 221 &iColorType, NULL, NULL, NULL);
222 222
223 223
224 /* row_bytes is the width x number of channels */ 224 /* row_bytes is the width x number of channels */
225 225
226 ulRowBytes = png_get_rowbytes(png_ptr, info_ptr); 226 ulRowBytes = png_get_rowbytes(png_ptr, info_ptr);
227 ulChannels = png_get_channels(png_ptr, info_ptr); 227 ulChannels = png_get_channels(png_ptr, info_ptr);
228 228
229 *piChannels = ulChannels; 229 *piChannels = ulChannels;
230 230
231 /* now we can allocate memory to store the image */ 231 /* now we can allocate memory to store the image */
232 232
233 if (pbImageData) 233 if (pbImageData)
234 { 234 {
235 free (pbImageData); 235 free (pbImageData);
236 pbImageData = NULL; 236 pbImageData = NULL;
237 } 237 }
238 if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight) 238 if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight)
239 * sizeof(png_byte))) == NULL) 239 * sizeof(png_byte))) == NULL)
240 { 240 {
241 png_error(png_ptr, "Visual PNG: out of memory"); 241 png_error(png_ptr, "Visual PNG: out of memory");
242 } 242 }
243 *ppbImageData = pbImageData; 243 *ppbImageData = pbImageData;
244 244
245 /* and allocate memory for an array of row-pointers */ 245 /* and allocate memory for an array of row-pointers */
246 246
247 if ((ppbRowPointers = (png_bytepp) malloc((*piHeight) 247 if ((ppbRowPointers = (png_bytepp) malloc((*piHeight)
248 * sizeof(png_bytep))) == NULL) 248 * sizeof(png_bytep))) == NULL)
249 { 249 {
250 png_error(png_ptr, "Visual PNG: out of memory"); 250 png_error(png_ptr, "Visual PNG: out of memory");
251 } 251 }
252 252
253 /* set the individual row-pointers to point at the correct offsets */ 253 /* set the individual row-pointers to point at the correct offsets */
254 254
255 for (i = 0; i < (*piHeight); i++) 255 for (i = 0; i < (*piHeight); i++)
256 ppbRowPointers[i] = pbImageData + i * ulRowBytes; 256 ppbRowPointers[i] = pbImageData + i * ulRowBytes;
257 257
258 /* now we can go ahead and just read the whole image */ 258 /* now we can go ahead and just read the whole image */
259 259
260 png_read_image(png_ptr, ppbRowPointers); 260 png_read_image(png_ptr, ppbRowPointers);
261 261
262 /* read the additional chunks in the PNG file (not really needed) */ 262 /* read the additional chunks in the PNG file (not really needed) */
263 263
264 png_read_end(png_ptr, NULL); 264 png_read_end(png_ptr, NULL);
265 265
266 /* and we're done */ 266 /* and we're done */
267 267
268 free (ppbRowPointers); 268 free (ppbRowPointers);
269 ppbRowPointers = NULL; 269 ppbRowPointers = NULL;
270 270
271 /* yepp, done */ 271 /* yepp, done */
272 } 272 }
273 273
274 Catch (msg) 274 Catch (msg)
275 { 275 {
276 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 276 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
277 277
278 *ppbImageData = pbImageData = NULL; 278 *ppbImageData = pbImageData = NULL;
279 279
280 if(ppbRowPointers) 280 if(ppbRowPointers)
281 free (ppbRowPointers); 281 free (ppbRowPointers);
282 282
283 fclose(pfFile); 283 fclose(pfFile);
284 284
285 return FALSE; 285 return FALSE;
286 } 286 }
287 287
288 fclose (pfFile); 288 fclose (pfFile);
289 289
290 return TRUE; 290 return TRUE;
291} 291}
292 292
293 293
294BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData, 294BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData,
295 int iWidth, int iHeight, png_color bkgColor) 295 int iWidth, int iHeight, png_color bkgColor)
296{ 296{
297 const int ciBitDepth = 8; 297 const int ciBitDepth = 8;
298 const int ciChannels = 3; 298 const int ciChannels = 3;
299 299
300 static FILE *pfFile; 300 static FILE *pfFile;
301 png_uint_32 ulRowBytes; 301 png_uint_32 ulRowBytes;
302 static png_byte **ppbRowPointers = NULL; 302 static png_byte **ppbRowPointers = NULL;
303 int i; 303 int i;
304 304
305 /* open the PNG output file */ 305 /* open the PNG output file */
306 306
307 if (!pstrFileName) 307 if (!pstrFileName)
308 return FALSE; 308 return FALSE;
309 309
310 if (!(pfFile = fopen(pstrFileName, "wb"))) 310 if (!(pfFile = fopen(pstrFileName, "wb")))
311 return FALSE; 311 return FALSE;
312 312
313 /* prepare the standard PNG structures */ 313 /* prepare the standard PNG structures */
314 314
315 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, 315 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
316 (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); 316 (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);
317 if (!png_ptr) 317 if (!png_ptr)
318 { 318 {
319 fclose(pfFile); 319 fclose(pfFile);
320 return FALSE; 320 return FALSE;
321 } 321 }
322 322
323 info_ptr = png_create_info_struct(png_ptr); 323 info_ptr = png_create_info_struct(png_ptr);
324 if (!info_ptr) { 324 if (!info_ptr) {
325 fclose(pfFile); 325 fclose(pfFile);
326 png_destroy_write_struct(&png_ptr, (png_infopp) NULL); 326 png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
327 return FALSE; 327 return FALSE;
328 } 328 }
329 329
330 Try 330 Try
331 { 331 {
332 /* initialize the png structure */ 332 /* initialize the png structure */
333 333
334#ifdef PNG_STDIO_SUPPORTED 334#ifdef PNG_STDIO_SUPPORTED
335 png_init_io(png_ptr, pfFile); 335 png_init_io(png_ptr, pfFile);
336#else 336#else
337 png_set_write_fn(png_ptr, (png_voidp)pfFile, png_write_data, png_flush); 337 png_set_write_fn(png_ptr, (png_voidp)pfFile, png_write_data, png_flush);
338#endif 338#endif
339 339
340 /* we're going to write a very simple 3x8-bit RGB image */ 340 /* we're going to write a very simple 3x8-bit RGB image */
341 341
342 png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth, 342 png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth,
343 PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, 343 PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
344 PNG_FILTER_TYPE_BASE); 344 PNG_FILTER_TYPE_BASE);
345 345
346 /* write the file header information */ 346 /* write the file header information */
347 347
348 png_write_info(png_ptr, info_ptr); 348 png_write_info(png_ptr, info_ptr);
349 349
350 /* swap the BGR pixels in the DiData structure to RGB */ 350 /* swap the BGR pixels in the DiData structure to RGB */
351 351
352 png_set_bgr(png_ptr); 352 png_set_bgr(png_ptr);
353 353
354 /* row_bytes is the width x number of channels */ 354 /* row_bytes is the width x number of channels */
355 355
356 ulRowBytes = iWidth * ciChannels; 356 ulRowBytes = iWidth * ciChannels;
357 357
358 /* we can allocate memory for an array of row-pointers */ 358 /* we can allocate memory for an array of row-pointers */
359 359
360 if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL) 360 if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL)
361 Throw "Visualpng: Out of memory"; 361 Throw "Visualpng: Out of memory";
362 362
363 /* set the individual row-pointers to point at the correct offsets */ 363 /* set the individual row-pointers to point at the correct offsets */
364 364
365 for (i = 0; i < iHeight; i++) 365 for (i = 0; i < iHeight; i++)
366 ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2); 366 ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2);
367 367
368 /* write out the entire image data in one call */ 368 /* write out the entire image data in one call */
369 369
370 png_write_image (png_ptr, ppbRowPointers); 370 png_write_image (png_ptr, ppbRowPointers);
371 371
372 /* write the additional chunks to the PNG file (not really needed) */ 372 /* write the additional chunks to the PNG file (not really needed) */
373 373
374 png_write_end(png_ptr, info_ptr); 374 png_write_end(png_ptr, info_ptr);
375 375
376 /* and we're done */ 376 /* and we're done */
377 377
378 free (ppbRowPointers); 378 free (ppbRowPointers);
379 ppbRowPointers = NULL; 379 ppbRowPointers = NULL;
380 380
381 /* clean up after the write, and free any memory allocated */ 381 /* clean up after the write, and free any memory allocated */
382 382
383 png_destroy_write_struct(&png_ptr, (png_infopp) NULL); 383 png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
384 384
385 /* yepp, done */ 385 /* yepp, done */
386 } 386 }
387 387
388 Catch (msg) 388 Catch (msg)
389 { 389 {
390 png_destroy_write_struct(&png_ptr, (png_infopp) NULL); 390 png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
391 391
392 if(ppbRowPointers) 392 if(ppbRowPointers)
393 free (ppbRowPointers); 393 free (ppbRowPointers);
394 394
395 fclose(pfFile); 395 fclose(pfFile);
396 396
397 return FALSE; 397 return FALSE;
398 } 398 }
399 399
400 fclose (pfFile); 400 fclose (pfFile);
401 401
402 return TRUE; 402 return TRUE;
403} 403}
404 404
405#ifndef PNG_STDIO_SUPPORTED 405#ifndef PNG_STDIO_SUPPORTED
406 406
407static void 407static void
408png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) 408png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
409{ 409{
410 png_size_t check; 410 png_size_t check;
411 411
412 /* fread() returns 0 on error, so it is OK to store this in a png_size_t 412 /* fread() returns 0 on error, so it is OK to store this in a png_size_t
413 * instead of an int, which is what fread() actually returns. 413 * instead of an int, which is what fread() actually returns.
414 */ 414 */
415 check = (png_size_t)fread(data, (png_size_t)1, length, 415 check = (png_size_t)fread(data, (png_size_t)1, length,
416 (FILE *)png_ptr->io_ptr); 416 (FILE *)png_ptr->io_ptr);
417 417
418 if (check != length) 418 if (check != length)
419 { 419 {
420 png_error(png_ptr, "Read Error"); 420 png_error(png_ptr, "Read Error");
421 } 421 }
422} 422}
423 423
424static void 424static void
425png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) 425png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
426{ 426{
427 png_uint_32 check; 427 png_uint_32 check;
428 428
429 check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr)); 429 check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
430 if (check != length) 430 if (check != length)
431 { 431 {
432 png_error(png_ptr, "Write Error"); 432 png_error(png_ptr, "Write Error");
433 } 433 }
434} 434}
435 435
436static void 436static void
437png_flush(png_structp png_ptr) 437png_flush(png_structp png_ptr)
438{ 438{
439 FILE *io_ptr; 439 FILE *io_ptr;
440 io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr)); 440 io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
441 if (io_ptr != NULL) 441 if (io_ptr != NULL)
442 fflush(io_ptr); 442 fflush(io_ptr);
443} 443}
444 444
445#endif 445#endif
446 446
447/*----------------- 447/*-----------------
448 * end of source 448 * end of source
449 *----------------- 449 *-----------------
450 */ 450 */
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.h
index 66f8472..32181a4 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.h
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/PngFile.h
@@ -1,30 +1,30 @@
1/*------------------------------------------*/ 1/*------------------------------------------*/
2/* PNGFILE.H -- Header File for pngfile.c*/ 2/* PNGFILE.H -- Header File for pngfile.c*/
3/*------------------------------------------*/ 3/*------------------------------------------*/
4 4
5/* Copyright 2000, Willem van Schaik.*/ 5/* Copyright 2000, Willem van Schaik.*/
6 6
7/* This code is released under the libpng license.*/ 7/* This code is released under the libpng license.*/
8/* For conditions of distribution and use, see the disclaimer*/ 8/* For conditions of distribution and use, see the disclaimer*/
9/* and license in png.h*/ 9/* and license in png.h*/
10 10
11#include <stdio.h> 11#include <stdio.h>
12#include <stdlib.h> 12#include <stdlib.h>
13#include <string.h> 13#include <string.h>
14#include <windows.h> 14#include <windows.h>
15 15
16void PngFileInitialize (HWND hwnd) ; 16void PngFileInitialize (HWND hwnd) ;
17BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ; 17BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ;
18BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ; 18BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ;
19 19
20BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData, 20BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData,
21 int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor); 21 int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor);
22BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData, 22BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData,
23 int iWidth, int iHeight, png_color BkgColor); 23 int iWidth, int iHeight, png_color BkgColor);
24 24
25#ifndef PNG_STDIO_SUPPORTED 25#ifndef PNG_STDIO_SUPPORTED
26static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length); 26static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length);
27static void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length); 27static void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length);
28static void png_flush(png_structp png_ptr); 28static void png_flush(png_structp png_ptr);
29#endif 29#endif
30 30
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/README.txt b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/README.txt
index 7291bb2..72c5cba 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/README.txt
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/README.txt
@@ -1,61 +1,61 @@
1Microsoft Developer Studio Build File, Format Version 6.00 for VisualPng 1Microsoft Developer Studio Build File, Format Version 6.00 for VisualPng
2------------------------------------------------------------------------ 2------------------------------------------------------------------------
3 3
4Copyright 2000, Willem van Schaik. 4Copyright 2000, Willem van Schaik.
5 5
6This code is released under the libpng license. 6This code is released under the libpng license.
7For conditions of distribution and use, see the disclaimer 7For conditions of distribution and use, see the disclaimer
8and license in png.h 8and license in png.h
9 9
10As a PNG .dll demo VisualPng is finished. More features would only hinder 10As a PNG .dll demo VisualPng is finished. More features would only hinder
11the program's objective. However, further extensions (like support for other 11the program's objective. However, further extensions (like support for other
12graphics formats) are in development. To get these, or for pre-compiled 12graphics formats) are in development. To get these, or for pre-compiled
13binaries, go to "http://www.schaik.com/png/visualpng.html". 13binaries, go to "http://www.schaik.com/png/visualpng.html".
14 14
15------------------------------------------------------------------------ 15------------------------------------------------------------------------
16 16
17Assumes that 17Assumes that
18 18
19 libpng DLLs and LIBs are in ..\..\projects\msvc\win32\libpng 19 libpng DLLs and LIBs are in ..\..\projects\msvc\win32\libpng
20 zlib DLLs and LIBs are in ..\..\projects\msvc\win32\zlib 20 zlib DLLs and LIBs are in ..\..\projects\msvc\win32\zlib
21 libpng header files are in ..\..\..\libpng 21 libpng header files are in ..\..\..\libpng
22 zlib header files are in ..\..\..\zlib 22 zlib header files are in ..\..\..\zlib
23 the pngsuite images are in ..\pngsuite 23 the pngsuite images are in ..\pngsuite
24 24
25To build: 25To build:
26 26
271) On the main menu Select "Build|Set Active configuration". 271) On the main menu Select "Build|Set Active configuration".
28 Choose the configuration that corresponds to the library you want to test. 28 Choose the configuration that corresponds to the library you want to test.
29 This library must have been built using the libpng MS project located in 29 This library must have been built using the libpng MS project located in
30 the "..\..\mscv" subdirectory. 30 the "..\..\mscv" subdirectory.
31 31
322) Select "Build|Clean" 322) Select "Build|Clean"
33 33
343) Select "Build|Rebuild All" 343) Select "Build|Rebuild All"
35 35
364) After compiling and linking VisualPng will be started to view an image 364) After compiling and linking VisualPng will be started to view an image
37 from the PngSuite directory. Press Ctrl-N (and Ctrl-V) for other images. 37 from the PngSuite directory. Press Ctrl-N (and Ctrl-V) for other images.
38 38
39 39
40To install: 40To install:
41 41
42When distributing VisualPng (or a further development) the following options 42When distributing VisualPng (or a further development) the following options
43are available: 43are available:
44 44
451) Build the program with the configuration "Win32 LIB" and you only need to 451) Build the program with the configuration "Win32 LIB" and you only need to
46 include the executable from the ./lib directory in your distribution. 46 include the executable from the ./lib directory in your distribution.
47 47
482) Build the program with the configuration "Win32 DLL" and you need to put 482) Build the program with the configuration "Win32 DLL" and you need to put
49 in your distribution the executable from the ./dll directory and the dll's 49 in your distribution the executable from the ./dll directory and the dll's
50 libpng1.dll, zlib.dll and msvcrt.dll. These need to be in the user's PATH. 50 libpng1.dll, zlib.dll and msvcrt.dll. These need to be in the user's PATH.
51 51
52 52
53Willem van Schaik 53Willem van Schaik
54Calgary, June 6th 2000 54Calgary, June 6th 2000
55 55
56P.S. VisualPng was written based on preliminary work of: 56P.S. VisualPng was written based on preliminary work of:
57 57
58 - Simon-Pierre Cadieux 58 - Simon-Pierre Cadieux
59 - Glenn Randers-Pehrson 59 - Glenn Randers-Pehrson
60 - Greg Roelofs 60 - Greg Roelofs
61 61
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.c
index e672ce0..009f120 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.c
@@ -1,969 +1,969 @@
1/*------------------------------------ 1/*------------------------------------
2 * VisualPng.C -- Shows a PNG image 2 * VisualPng.C -- Shows a PNG image
3 *------------------------------------ 3 *------------------------------------
4 * 4 *
5 * Copyright 2000, Willem van Schaik. 5 * Copyright 2000, Willem van Schaik.
6 * 6 *
7 * This code is released under the libpng license. 7 * This code is released under the libpng license.
8 * For conditions of distribution and use, see the disclaimer 8 * For conditions of distribution and use, see the disclaimer
9 * and license in png.h 9 * and license in png.h
10 */ 10 */
11 11
12/* switches */ 12/* switches */
13 13
14/* defines */ 14/* defines */
15 15
16#define PROGNAME "VisualPng" 16#define PROGNAME "VisualPng"
17#define LONGNAME "Win32 Viewer for PNG-files" 17#define LONGNAME "Win32 Viewer for PNG-files"
18#define VERSION "1.0 of 2000 June 07" 18#define VERSION "1.0 of 2000 June 07"
19 19
20/* constants */ 20/* constants */
21 21
22#define MARGIN 8 22#define MARGIN 8
23 23
24/* standard includes */ 24/* standard includes */
25 25
26#include <stdio.h> 26#include <stdio.h>
27#include <stdlib.h> 27#include <stdlib.h>
28#include <string.h> 28#include <string.h>
29#include <windows.h> 29#include <windows.h>
30 30
31/* application includes */ 31/* application includes */
32 32
33#include "png.h" 33#include "png.h"
34#include "pngfile.h" 34#include "pngfile.h"
35#include "resource.h" 35#include "resource.h"
36 36
37/* macros */ 37/* macros */
38 38
39/* function prototypes */ 39/* function prototypes */
40 40
41LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); 41LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
42BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ; 42BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;
43 43
44BOOL CenterAbout (HWND hwndChild, HWND hwndParent); 44BOOL CenterAbout (HWND hwndChild, HWND hwndParent);
45 45
46BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount, 46BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,
47 int *pFileIndex); 47 int *pFileIndex);
48 48
49BOOL SearchPngList (TCHAR *pFileList, int FileCount, int *pFileIndex, 49BOOL SearchPngList (TCHAR *pFileList, int FileCount, int *pFileIndex,
50 PTSTR pstrPrevName, PTSTR pstrNextName); 50 PTSTR pstrPrevName, PTSTR pstrNextName);
51 51
52BOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName, 52BOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName,
53 png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels, 53 png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels,
54 png_color *pBkgColor); 54 png_color *pBkgColor);
55 55
56BOOL DisplayImage (HWND hwnd, BYTE **ppDib, 56BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
57 BYTE **ppDiData, int cxWinSize, int cyWinSize, 57 BYTE **ppDiData, int cxWinSize, int cyWinSize,
58 BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, 58 BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
59 BOOL bStretched); 59 BOOL bStretched);
60 60
61BOOL InitBitmap ( 61BOOL InitBitmap (
62 BYTE *pDiData, int cxWinSize, int cyWinSize); 62 BYTE *pDiData, int cxWinSize, int cyWinSize);
63 63
64BOOL FillBitmap ( 64BOOL FillBitmap (
65 BYTE *pDiData, int cxWinSize, int cyWinSize, 65 BYTE *pDiData, int cxWinSize, int cyWinSize,
66 BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, 66 BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
67 BOOL bStretched); 67 BOOL bStretched);
68 68
69/* a few global variables */ 69/* a few global variables */
70 70
71static char *szProgName = PROGNAME; 71static char *szProgName = PROGNAME;
72static char *szAppName = LONGNAME; 72static char *szAppName = LONGNAME;
73static char *szIconName = PROGNAME; 73static char *szIconName = PROGNAME;
74static char szCmdFileName [MAX_PATH]; 74static char szCmdFileName [MAX_PATH];
75 75
76/* MAIN routine */ 76/* MAIN routine */
77 77
78int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 78int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
79 PSTR szCmdLine, int iCmdShow) 79 PSTR szCmdLine, int iCmdShow)
80{ 80{
81 HACCEL hAccel; 81 HACCEL hAccel;
82 HWND hwnd; 82 HWND hwnd;
83 MSG msg; 83 MSG msg;
84 WNDCLASS wndclass; 84 WNDCLASS wndclass;
85 int ixBorders, iyBorders; 85 int ixBorders, iyBorders;
86 86
87 wndclass.style = CS_HREDRAW | CS_VREDRAW; 87 wndclass.style = CS_HREDRAW | CS_VREDRAW;
88 wndclass.lpfnWndProc = WndProc; 88 wndclass.lpfnWndProc = WndProc;
89 wndclass.cbClsExtra = 0; 89 wndclass.cbClsExtra = 0;
90 wndclass.cbWndExtra = 0; 90 wndclass.cbWndExtra = 0;
91 wndclass.hInstance = hInstance; 91 wndclass.hInstance = hInstance;
92 wndclass.hIcon = LoadIcon (hInstance, szIconName) ; 92 wndclass.hIcon = LoadIcon (hInstance, szIconName) ;
93 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); 93 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
94 wndclass.hbrBackground = NULL; /* (HBRUSH) GetStockObject (GRAY_BRUSH); */ 94 wndclass.hbrBackground = NULL; /* (HBRUSH) GetStockObject (GRAY_BRUSH); */
95 wndclass.lpszMenuName = szProgName; 95 wndclass.lpszMenuName = szProgName;
96 wndclass.lpszClassName = szProgName; 96 wndclass.lpszClassName = szProgName;
97 97
98 if (!RegisterClass (&wndclass)) 98 if (!RegisterClass (&wndclass))
99 { 99 {
100 MessageBox (NULL, TEXT ("Error: this program requires Windows NT!"), 100 MessageBox (NULL, TEXT ("Error: this program requires Windows NT!"),
101 szProgName, MB_ICONERROR); 101 szProgName, MB_ICONERROR);
102 return 0; 102 return 0;
103 } 103 }
104 104
105 /* if filename given on commandline, store it */ 105 /* if filename given on commandline, store it */
106 if ((szCmdLine != NULL) && (*szCmdLine != '\0')) 106 if ((szCmdLine != NULL) && (*szCmdLine != '\0'))
107 if (szCmdLine[0] == '"') 107 if (szCmdLine[0] == '"')
108 strncpy (szCmdFileName, szCmdLine + 1, strlen(szCmdLine) - 2); 108 strncpy (szCmdFileName, szCmdLine + 1, strlen(szCmdLine) - 2);
109 else 109 else
110 strcpy (szCmdFileName, szCmdLine); 110 strcpy (szCmdFileName, szCmdLine);
111 else 111 else
112 strcpy (szCmdFileName, ""); 112 strcpy (szCmdFileName, "");
113 113
114 /* calculate size of window-borders */ 114 /* calculate size of window-borders */
115 ixBorders = 2 * (GetSystemMetrics (SM_CXBORDER) + 115 ixBorders = 2 * (GetSystemMetrics (SM_CXBORDER) +
116 GetSystemMetrics (SM_CXDLGFRAME)); 116 GetSystemMetrics (SM_CXDLGFRAME));
117 iyBorders = 2 * (GetSystemMetrics (SM_CYBORDER) + 117 iyBorders = 2 * (GetSystemMetrics (SM_CYBORDER) +
118 GetSystemMetrics (SM_CYDLGFRAME)) + 118 GetSystemMetrics (SM_CYDLGFRAME)) +
119 GetSystemMetrics (SM_CYCAPTION) + 119 GetSystemMetrics (SM_CYCAPTION) +
120 GetSystemMetrics (SM_CYMENUSIZE) + 120 GetSystemMetrics (SM_CYMENUSIZE) +
121 1; /* WvS: don't ask me why? */ 121 1; /* WvS: don't ask me why? */
122 122
123 hwnd = CreateWindow (szProgName, szAppName, 123 hwnd = CreateWindow (szProgName, szAppName,
124 WS_OVERLAPPEDWINDOW, 124 WS_OVERLAPPEDWINDOW,
125 CW_USEDEFAULT, CW_USEDEFAULT, 125 CW_USEDEFAULT, CW_USEDEFAULT,
126 512 + 2 * MARGIN + ixBorders, 384 + 2 * MARGIN + iyBorders, 126 512 + 2 * MARGIN + ixBorders, 384 + 2 * MARGIN + iyBorders,
127/* CW_USEDEFAULT, CW_USEDEFAULT, */ 127/* CW_USEDEFAULT, CW_USEDEFAULT, */
128 NULL, NULL, hInstance, NULL); 128 NULL, NULL, hInstance, NULL);
129 129
130 ShowWindow (hwnd, iCmdShow); 130 ShowWindow (hwnd, iCmdShow);
131 UpdateWindow (hwnd); 131 UpdateWindow (hwnd);
132 132
133 hAccel = LoadAccelerators (hInstance, szProgName); 133 hAccel = LoadAccelerators (hInstance, szProgName);
134 134
135 while (GetMessage (&msg, NULL, 0, 0)) 135 while (GetMessage (&msg, NULL, 0, 0))
136 { 136 {
137 if (!TranslateAccelerator (hwnd, hAccel, &msg)) 137 if (!TranslateAccelerator (hwnd, hAccel, &msg))
138 { 138 {
139 TranslateMessage (&msg); 139 TranslateMessage (&msg);
140 DispatchMessage (&msg); 140 DispatchMessage (&msg);
141 } 141 }
142 } 142 }
143 return msg.wParam; 143 return msg.wParam;
144} 144}
145 145
146LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, 146LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,
147 LPARAM lParam) 147 LPARAM lParam)
148{ 148{
149 static HINSTANCE hInstance ; 149 static HINSTANCE hInstance ;
150 static HDC hdc; 150 static HDC hdc;
151 static PAINTSTRUCT ps; 151 static PAINTSTRUCT ps;
152 static HMENU hMenu; 152 static HMENU hMenu;
153 153
154 static BITMAPFILEHEADER *pbmfh; 154 static BITMAPFILEHEADER *pbmfh;
155 static BITMAPINFOHEADER *pbmih; 155 static BITMAPINFOHEADER *pbmih;
156 static BYTE *pbImage; 156 static BYTE *pbImage;
157 static int cxWinSize, cyWinSize; 157 static int cxWinSize, cyWinSize;
158 static int cxImgSize, cyImgSize; 158 static int cxImgSize, cyImgSize;
159 static int cImgChannels; 159 static int cImgChannels;
160 static png_color bkgColor = {127, 127, 127}; 160 static png_color bkgColor = {127, 127, 127};
161 161
162 static BOOL bStretched = TRUE; 162 static BOOL bStretched = TRUE;
163 163
164 static BYTE *pDib = NULL; 164 static BYTE *pDib = NULL;
165 static BYTE *pDiData = NULL; 165 static BYTE *pDiData = NULL;
166 166
167 static TCHAR szImgPathName [MAX_PATH]; 167 static TCHAR szImgPathName [MAX_PATH];
168 static TCHAR szTitleName [MAX_PATH]; 168 static TCHAR szTitleName [MAX_PATH];
169 169
170 static TCHAR *pPngFileList = NULL; 170 static TCHAR *pPngFileList = NULL;
171 static int iPngFileCount; 171 static int iPngFileCount;
172 static int iPngFileIndex; 172 static int iPngFileIndex;
173 173
174 BOOL bOk; 174 BOOL bOk;
175 175
176 switch (message) 176 switch (message)
177 { 177 {
178 case WM_CREATE: 178 case WM_CREATE:
179 hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; 179 hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
180 PngFileInitialize (hwnd); 180 PngFileInitialize (hwnd);
181 181
182 strcpy (szImgPathName, ""); 182 strcpy (szImgPathName, "");
183 183
184 /* in case we process file given on command-line */ 184 /* in case we process file given on command-line */
185 185
186 if (szCmdFileName[0] != '\0') 186 if (szCmdFileName[0] != '\0')
187 { 187 {
188 strcpy (szImgPathName, szCmdFileName); 188 strcpy (szImgPathName, szCmdFileName);
189 189
190 /* read the other png-files in the directory for later */ 190 /* read the other png-files in the directory for later */
191 /* next/previous commands */ 191 /* next/previous commands */
192 192
193 BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount, 193 BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,
194 &iPngFileIndex); 194 &iPngFileIndex);
195 195
196 /* load the image from file */ 196 /* load the image from file */
197 197
198 if (!LoadImageFile (hwnd, szImgPathName, 198 if (!LoadImageFile (hwnd, szImgPathName,
199 &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) 199 &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
200 return 0; 200 return 0;
201 201
202 /* invalidate the client area for later update */ 202 /* invalidate the client area for later update */
203 203
204 InvalidateRect (hwnd, NULL, TRUE); 204 InvalidateRect (hwnd, NULL, TRUE);
205 205
206 /* display the PNG into the DIBitmap */ 206 /* display the PNG into the DIBitmap */
207 207
208 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, 208 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
209 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); 209 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
210 } 210 }
211 211
212 return 0; 212 return 0;
213 213
214 case WM_SIZE: 214 case WM_SIZE:
215 cxWinSize = LOWORD (lParam); 215 cxWinSize = LOWORD (lParam);
216 cyWinSize = HIWORD (lParam); 216 cyWinSize = HIWORD (lParam);
217 217
218 /* invalidate the client area for later update */ 218 /* invalidate the client area for later update */
219 219
220 InvalidateRect (hwnd, NULL, TRUE); 220 InvalidateRect (hwnd, NULL, TRUE);
221 221
222 /* display the PNG into the DIBitmap */ 222 /* display the PNG into the DIBitmap */
223 223
224 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, 224 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
225 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); 225 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
226 226
227 return 0; 227 return 0;
228 228
229 case WM_INITMENUPOPUP: 229 case WM_INITMENUPOPUP:
230 hMenu = GetMenu (hwnd); 230 hMenu = GetMenu (hwnd);
231 231
232 if (pbImage) 232 if (pbImage)
233 EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_ENABLED); 233 EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_ENABLED);
234 else 234 else
235 EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_GRAYED); 235 EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_GRAYED);
236 236
237 return 0; 237 return 0;
238 238
239 case WM_COMMAND: 239 case WM_COMMAND:
240 hMenu = GetMenu (hwnd); 240 hMenu = GetMenu (hwnd);
241 241
242 switch (LOWORD (wParam)) 242 switch (LOWORD (wParam))
243 { 243 {
244 case IDM_FILE_OPEN: 244 case IDM_FILE_OPEN:
245 245
246 /* show the File Open dialog box */ 246 /* show the File Open dialog box */
247 247
248 if (!PngFileOpenDlg (hwnd, szImgPathName, szTitleName)) 248 if (!PngFileOpenDlg (hwnd, szImgPathName, szTitleName))
249 return 0; 249 return 0;
250 250
251 /* read the other png-files in the directory for later */ 251 /* read the other png-files in the directory for later */
252 /* next/previous commands */ 252 /* next/previous commands */
253 253
254 BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount, 254 BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,
255 &iPngFileIndex); 255 &iPngFileIndex);
256 256
257 /* load the image from file */ 257 /* load the image from file */
258 258
259 if (!LoadImageFile (hwnd, szImgPathName, 259 if (!LoadImageFile (hwnd, szImgPathName,
260 &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) 260 &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
261 return 0; 261 return 0;
262 262
263 /* invalidate the client area for later update */ 263 /* invalidate the client area for later update */
264 264
265 InvalidateRect (hwnd, NULL, TRUE); 265 InvalidateRect (hwnd, NULL, TRUE);
266 266
267 /* display the PNG into the DIBitmap */ 267 /* display the PNG into the DIBitmap */
268 268
269 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, 269 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
270 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); 270 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
271 271
272 return 0; 272 return 0;
273 273
274 case IDM_FILE_SAVE: 274 case IDM_FILE_SAVE:
275 275
276 /* show the File Save dialog box */ 276 /* show the File Save dialog box */
277 277
278 if (!PngFileSaveDlg (hwnd, szImgPathName, szTitleName)) 278 if (!PngFileSaveDlg (hwnd, szImgPathName, szTitleName))
279 return 0; 279 return 0;
280 280
281 /* save the PNG to a disk file */ 281 /* save the PNG to a disk file */
282 282
283 SetCursor (LoadCursor (NULL, IDC_WAIT)); 283 SetCursor (LoadCursor (NULL, IDC_WAIT));
284 ShowCursor (TRUE); 284 ShowCursor (TRUE);
285 285
286 bOk = PngSaveImage (szImgPathName, pDiData, cxWinSize, cyWinSize, 286 bOk = PngSaveImage (szImgPathName, pDiData, cxWinSize, cyWinSize,
287 bkgColor); 287 bkgColor);
288 288
289 ShowCursor (FALSE); 289 ShowCursor (FALSE);
290 SetCursor (LoadCursor (NULL, IDC_ARROW)); 290 SetCursor (LoadCursor (NULL, IDC_ARROW));
291 291
292 if (!bOk) 292 if (!bOk)
293 MessageBox (hwnd, TEXT ("Error in saving the PNG image"), 293 MessageBox (hwnd, TEXT ("Error in saving the PNG image"),
294 szProgName, MB_ICONEXCLAMATION | MB_OK); 294 szProgName, MB_ICONEXCLAMATION | MB_OK);
295 return 0; 295 return 0;
296 296
297 case IDM_FILE_NEXT: 297 case IDM_FILE_NEXT:
298 298
299 /* read next entry in the directory */ 299 /* read next entry in the directory */
300 300
301 if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex, 301 if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,
302 NULL, szImgPathName)) 302 NULL, szImgPathName))
303 { 303 {
304 if (strcmp (szImgPathName, "") == 0) 304 if (strcmp (szImgPathName, "") == 0)
305 return 0; 305 return 0;
306 306
307 /* load the image from file */ 307 /* load the image from file */
308 308
309 if (!LoadImageFile (hwnd, szImgPathName, &pbImage, 309 if (!LoadImageFile (hwnd, szImgPathName, &pbImage,
310 &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) 310 &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
311 return 0; 311 return 0;
312 312
313 /* invalidate the client area for later update */ 313 /* invalidate the client area for later update */
314 314
315 InvalidateRect (hwnd, NULL, TRUE); 315 InvalidateRect (hwnd, NULL, TRUE);
316 316
317 /* display the PNG into the DIBitmap */ 317 /* display the PNG into the DIBitmap */
318 318
319 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, 319 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
320 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); 320 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
321 } 321 }
322 322
323 return 0; 323 return 0;
324 324
325 case IDM_FILE_PREVIOUS: 325 case IDM_FILE_PREVIOUS:
326 326
327 /* read previous entry in the directory */ 327 /* read previous entry in the directory */
328 328
329 if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex, 329 if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,
330 szImgPathName, NULL)) 330 szImgPathName, NULL))
331 { 331 {
332 332
333 if (strcmp (szImgPathName, "") == 0) 333 if (strcmp (szImgPathName, "") == 0)
334 return 0; 334 return 0;
335 335
336 /* load the image from file */ 336 /* load the image from file */
337 337
338 if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize, 338 if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize,
339 &cyImgSize, &cImgChannels, &bkgColor)) 339 &cyImgSize, &cImgChannels, &bkgColor))
340 return 0; 340 return 0;
341 341
342 /* invalidate the client area for later update */ 342 /* invalidate the client area for later update */
343 343
344 InvalidateRect (hwnd, NULL, TRUE); 344 InvalidateRect (hwnd, NULL, TRUE);
345 345
346 /* display the PNG into the DIBitmap */ 346 /* display the PNG into the DIBitmap */
347 347
348 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, 348 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
349 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); 349 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
350 } 350 }
351 351
352 return 0; 352 return 0;
353 353
354 case IDM_FILE_EXIT: 354 case IDM_FILE_EXIT:
355 355
356 /* more cleanup needed... */ 356 /* more cleanup needed... */
357 357
358 /* free image buffer */ 358 /* free image buffer */
359 359
360 if (pDib != NULL) 360 if (pDib != NULL)
361 { 361 {
362 free (pDib); 362 free (pDib);
363 pDib = NULL; 363 pDib = NULL;
364 } 364 }
365 365
366 /* free file-list */ 366 /* free file-list */
367 367
368 if (pPngFileList != NULL) 368 if (pPngFileList != NULL)
369 { 369 {
370 free (pPngFileList); 370 free (pPngFileList);
371 pPngFileList = NULL; 371 pPngFileList = NULL;
372 } 372 }
373 373
374 /* let's go ... */ 374 /* let's go ... */
375 375
376 exit (0); 376 exit (0);
377 377
378 return 0; 378 return 0;
379 379
380 case IDM_OPTIONS_STRETCH: 380 case IDM_OPTIONS_STRETCH:
381 bStretched = !bStretched; 381 bStretched = !bStretched;
382 if (bStretched) 382 if (bStretched)
383 CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_CHECKED); 383 CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_CHECKED);
384 else 384 else
385 CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_UNCHECKED); 385 CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_UNCHECKED);
386 386
387 /* invalidate the client area for later update */ 387 /* invalidate the client area for later update */
388 388
389 InvalidateRect (hwnd, NULL, TRUE); 389 InvalidateRect (hwnd, NULL, TRUE);
390 390
391 /* display the PNG into the DIBitmap */ 391 /* display the PNG into the DIBitmap */
392 392
393 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, 393 DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
394 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); 394 pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
395 395
396 return 0; 396 return 0;
397 397
398 case IDM_HELP_ABOUT: 398 case IDM_HELP_ABOUT:
399 DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ; 399 DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ;
400 return 0; 400 return 0;
401 401
402 } /* end switch */ 402 } /* end switch */
403 403
404 break; 404 break;
405 405
406 case WM_PAINT: 406 case WM_PAINT:
407 hdc = BeginPaint (hwnd, &ps); 407 hdc = BeginPaint (hwnd, &ps);
408 408
409 if (pDib) 409 if (pDib)
410 SetDIBitsToDevice (hdc, 0, 0, cxWinSize, cyWinSize, 0, 0, 410 SetDIBitsToDevice (hdc, 0, 0, cxWinSize, cyWinSize, 0, 0,
411 0, cyWinSize, pDiData, (BITMAPINFO *) pDib, DIB_RGB_COLORS); 411 0, cyWinSize, pDiData, (BITMAPINFO *) pDib, DIB_RGB_COLORS);
412 412
413 EndPaint (hwnd, &ps); 413 EndPaint (hwnd, &ps);
414 return 0; 414 return 0;
415 415
416 case WM_DESTROY: 416 case WM_DESTROY:
417 if (pbmfh) 417 if (pbmfh)
418 { 418 {
419 free (pbmfh); 419 free (pbmfh);
420 pbmfh = NULL; 420 pbmfh = NULL;
421 } 421 }
422 422
423 PostQuitMessage (0); 423 PostQuitMessage (0);
424 return 0; 424 return 0;
425 } 425 }
426 426
427 return DefWindowProc (hwnd, message, wParam, lParam); 427 return DefWindowProc (hwnd, message, wParam, lParam);
428} 428}
429 429
430BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, 430BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,
431 WPARAM wParam, LPARAM lParam) 431 WPARAM wParam, LPARAM lParam)
432{ 432{
433 switch (message) 433 switch (message)
434 { 434 {
435 case WM_INITDIALOG : 435 case WM_INITDIALOG :
436 ShowWindow (hDlg, SW_HIDE); 436 ShowWindow (hDlg, SW_HIDE);
437 CenterAbout (hDlg, GetWindow (hDlg, GW_OWNER)); 437 CenterAbout (hDlg, GetWindow (hDlg, GW_OWNER));
438 ShowWindow (hDlg, SW_SHOW); 438 ShowWindow (hDlg, SW_SHOW);
439 return TRUE ; 439 return TRUE ;
440 440
441 case WM_COMMAND : 441 case WM_COMMAND :
442 switch (LOWORD (wParam)) 442 switch (LOWORD (wParam))
443 { 443 {
444 case IDOK : 444 case IDOK :
445 case IDCANCEL : 445 case IDCANCEL :
446 EndDialog (hDlg, 0) ; 446 EndDialog (hDlg, 0) ;
447 return TRUE ; 447 return TRUE ;
448 } 448 }
449 break ; 449 break ;
450 } 450 }
451 return FALSE ; 451 return FALSE ;
452} 452}
453 453
454/*--------------- 454/*---------------
455 * CenterAbout 455 * CenterAbout
456 *--------------- 456 *---------------
457 */ 457 */
458BOOL CenterAbout (HWND hwndChild, HWND hwndParent) 458BOOL CenterAbout (HWND hwndChild, HWND hwndParent)
459{ 459{
460 RECT rChild, rParent, rWorkArea; 460 RECT rChild, rParent, rWorkArea;
461 int wChild, hChild, wParent, hParent; 461 int wChild, hChild, wParent, hParent;
462 int xNew, yNew; 462 int xNew, yNew;
463 BOOL bResult; 463 BOOL bResult;
464 464
465 /* Get the Height and Width of the child window */ 465 /* Get the Height and Width of the child window */
466 GetWindowRect (hwndChild, &rChild); 466 GetWindowRect (hwndChild, &rChild);
467 wChild = rChild.right - rChild.left; 467 wChild = rChild.right - rChild.left;
468 hChild = rChild.bottom - rChild.top; 468 hChild = rChild.bottom - rChild.top;
469 469
470 /* Get the Height and Width of the parent window */ 470 /* Get the Height and Width of the parent window */
471 GetWindowRect (hwndParent, &rParent); 471 GetWindowRect (hwndParent, &rParent);
472 wParent = rParent.right - rParent.left; 472 wParent = rParent.right - rParent.left;
473 hParent = rParent.bottom - rParent.top; 473 hParent = rParent.bottom - rParent.top;
474 474
475 /* Get the limits of the 'workarea' */ 475 /* Get the limits of the 'workarea' */
476 bResult = SystemParametersInfo( 476 bResult = SystemParametersInfo(
477 SPI_GETWORKAREA, /* system parameter to query or set */ 477 SPI_GETWORKAREA, /* system parameter to query or set */
478 sizeof(RECT), 478 sizeof(RECT),
479 &rWorkArea, 479 &rWorkArea,
480 0); 480 0);
481 if (!bResult) { 481 if (!bResult) {
482 rWorkArea.left = rWorkArea.top = 0; 482 rWorkArea.left = rWorkArea.top = 0;
483 rWorkArea.right = GetSystemMetrics(SM_CXSCREEN); 483 rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
484 rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN); 484 rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
485 } 485 }
486 486
487 /* Calculate new X position, then adjust for workarea */ 487 /* Calculate new X position, then adjust for workarea */
488 xNew = rParent.left + ((wParent - wChild) /2); 488 xNew = rParent.left + ((wParent - wChild) /2);
489 if (xNew < rWorkArea.left) { 489 if (xNew < rWorkArea.left) {
490 xNew = rWorkArea.left; 490 xNew = rWorkArea.left;
491 } else if ((xNew+wChild) > rWorkArea.right) { 491 } else if ((xNew+wChild) > rWorkArea.right) {
492 xNew = rWorkArea.right - wChild; 492 xNew = rWorkArea.right - wChild;
493 } 493 }
494 494
495 /* Calculate new Y position, then adjust for workarea */ 495 /* Calculate new Y position, then adjust for workarea */
496 yNew = rParent.top + ((hParent - hChild) /2); 496 yNew = rParent.top + ((hParent - hChild) /2);
497 if (yNew < rWorkArea.top) { 497 if (yNew < rWorkArea.top) {
498 yNew = rWorkArea.top; 498 yNew = rWorkArea.top;
499 } else if ((yNew+hChild) > rWorkArea.bottom) { 499 } else if ((yNew+hChild) > rWorkArea.bottom) {
500 yNew = rWorkArea.bottom - hChild; 500 yNew = rWorkArea.bottom - hChild;
501 } 501 }
502 502
503 /* Set it, and return */ 503 /* Set it, and return */
504 return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | 504 return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE |
505 SWP_NOZORDER); 505 SWP_NOZORDER);
506} 506}
507 507
508/*---------------- 508/*----------------
509 * BuildPngList 509 * BuildPngList
510 *---------------- 510 *----------------
511 */ 511 */
512BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount, 512BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,
513 int *pFileIndex) 513 int *pFileIndex)
514{ 514{
515 static TCHAR szImgPathName [MAX_PATH]; 515 static TCHAR szImgPathName [MAX_PATH];
516 static TCHAR szImgFileName [MAX_PATH]; 516 static TCHAR szImgFileName [MAX_PATH];
517 static TCHAR szImgFindName [MAX_PATH]; 517 static TCHAR szImgFindName [MAX_PATH];
518 518
519 WIN32_FIND_DATA finddata; 519 WIN32_FIND_DATA finddata;
520 HANDLE hFind; 520 HANDLE hFind;
521 521
522 static TCHAR szTmp [MAX_PATH]; 522 static TCHAR szTmp [MAX_PATH];
523 BOOL bOk; 523 BOOL bOk;
524 int i, ii; 524 int i, ii;
525 int j, jj; 525 int j, jj;
526 526
527 /* free previous file-list */ 527 /* free previous file-list */
528 528
529 if (*ppFileList != NULL) 529 if (*ppFileList != NULL)
530 { 530 {
531 free (*ppFileList); 531 free (*ppFileList);
532 *ppFileList = NULL; 532 *ppFileList = NULL;
533 } 533 }
534 534
535 /* extract foldername, filename and search-name */ 535 /* extract foldername, filename and search-name */
536 536
537 strcpy (szImgPathName, pstrPathName); 537 strcpy (szImgPathName, pstrPathName);
538 strcpy (szImgFileName, strrchr (pstrPathName, '\\') + 1); 538 strcpy (szImgFileName, strrchr (pstrPathName, '\\') + 1);
539 539
540 strcpy (szImgFindName, szImgPathName); 540 strcpy (szImgFindName, szImgPathName);
541 *(strrchr (szImgFindName, '\\') + 1) = '\0'; 541 *(strrchr (szImgFindName, '\\') + 1) = '\0';
542 strcat (szImgFindName, "*.png"); 542 strcat (szImgFindName, "*.png");
543 543
544 /* first cycle: count number of files in directory for memory allocation */ 544 /* first cycle: count number of files in directory for memory allocation */
545 545
546 *pFileCount = 0; 546 *pFileCount = 0;
547 547
548 hFind = FindFirstFile(szImgFindName, &finddata); 548 hFind = FindFirstFile(szImgFindName, &finddata);
549 bOk = (hFind != (HANDLE) -1); 549 bOk = (hFind != (HANDLE) -1);
550 550
551 while (bOk) 551 while (bOk)
552 { 552 {
553 *pFileCount += 1; 553 *pFileCount += 1;
554 bOk = FindNextFile(hFind, &finddata); 554 bOk = FindNextFile(hFind, &finddata);
555 } 555 }
556 FindClose(hFind); 556 FindClose(hFind);
557 557
558 /* allocation memory for file-list */ 558 /* allocation memory for file-list */
559 559
560 *ppFileList = (TCHAR *) malloc (*pFileCount * MAX_PATH); 560 *ppFileList = (TCHAR *) malloc (*pFileCount * MAX_PATH);
561 561
562 /* second cycle: read directory and store filenames in file-list */ 562 /* second cycle: read directory and store filenames in file-list */
563 563
564 hFind = FindFirstFile(szImgFindName, &finddata); 564 hFind = FindFirstFile(szImgFindName, &finddata);
565 bOk = (hFind != (HANDLE) -1); 565 bOk = (hFind != (HANDLE) -1);
566 566
567 i = 0; 567 i = 0;
568 ii = 0; 568 ii = 0;
569 while (bOk) 569 while (bOk)
570 { 570 {
571 strcpy (*ppFileList + ii, szImgPathName); 571 strcpy (*ppFileList + ii, szImgPathName);
572 strcpy (strrchr(*ppFileList + ii, '\\') + 1, finddata.cFileName); 572 strcpy (strrchr(*ppFileList + ii, '\\') + 1, finddata.cFileName);
573 573
574 if (strcmp(pstrPathName, *ppFileList + ii) == 0) 574 if (strcmp(pstrPathName, *ppFileList + ii) == 0)
575 *pFileIndex = i; 575 *pFileIndex = i;
576 576
577 ii += MAX_PATH; 577 ii += MAX_PATH;
578 i++; 578 i++;
579 579
580 bOk = FindNextFile(hFind, &finddata); 580 bOk = FindNextFile(hFind, &finddata);
581 } 581 }
582 FindClose(hFind); 582 FindClose(hFind);
583 583
584 /* finally we must sort the file-list */ 584 /* finally we must sort the file-list */
585 585
586 for (i = 0; i < *pFileCount - 1; i++) 586 for (i = 0; i < *pFileCount - 1; i++)
587 { 587 {
588 ii = i * MAX_PATH; 588 ii = i * MAX_PATH;
589 for (j = i+1; j < *pFileCount; j++) 589 for (j = i+1; j < *pFileCount; j++)
590 { 590 {
591 jj = j * MAX_PATH; 591 jj = j * MAX_PATH;
592 if (strcmp (*ppFileList + ii, *ppFileList + jj) > 0) 592 if (strcmp (*ppFileList + ii, *ppFileList + jj) > 0)
593 { 593 {
594 strcpy (szTmp, *ppFileList + jj); 594 strcpy (szTmp, *ppFileList + jj);
595 strcpy (*ppFileList + jj, *ppFileList + ii); 595 strcpy (*ppFileList + jj, *ppFileList + ii);
596 strcpy (*ppFileList + ii, szTmp); 596 strcpy (*ppFileList + ii, szTmp);
597 597
598 /* check if this was the current image that we moved */ 598 /* check if this was the current image that we moved */
599 599
600 if (*pFileIndex == i) 600 if (*pFileIndex == i)
601 *pFileIndex = j; 601 *pFileIndex = j;
602 else 602 else
603 if (*pFileIndex == j) 603 if (*pFileIndex == j)
604 *pFileIndex = i; 604 *pFileIndex = i;
605 } 605 }
606 } 606 }
607 } 607 }
608 608
609 return TRUE; 609 return TRUE;
610} 610}
611 611
612/*---------------- 612/*----------------
613 * SearchPngList 613 * SearchPngList
614 *---------------- 614 *----------------
615 */ 615 */
616 616
617BOOL SearchPngList ( 617BOOL SearchPngList (
618 TCHAR *pFileList, int FileCount, int *pFileIndex, 618 TCHAR *pFileList, int FileCount, int *pFileIndex,
619 PTSTR pstrPrevName, PTSTR pstrNextName) 619 PTSTR pstrPrevName, PTSTR pstrNextName)
620{ 620{
621 if (FileCount > 0) 621 if (FileCount > 0)
622 { 622 {
623 /* get previous entry */ 623 /* get previous entry */
624 624
625 if (pstrPrevName != NULL) 625 if (pstrPrevName != NULL)
626 { 626 {
627 if (*pFileIndex > 0) 627 if (*pFileIndex > 0)
628 *pFileIndex -= 1; 628 *pFileIndex -= 1;
629 else 629 else
630 *pFileIndex = FileCount - 1; 630 *pFileIndex = FileCount - 1;
631 631
632 strcpy (pstrPrevName, pFileList + (*pFileIndex * MAX_PATH)); 632 strcpy (pstrPrevName, pFileList + (*pFileIndex * MAX_PATH));
633 } 633 }
634 634
635 /* get next entry */ 635 /* get next entry */
636 636
637 if (pstrNextName != NULL) 637 if (pstrNextName != NULL)
638 { 638 {
639 if (*pFileIndex < FileCount - 1) 639 if (*pFileIndex < FileCount - 1)
640 *pFileIndex += 1; 640 *pFileIndex += 1;
641 else 641 else
642 *pFileIndex = 0; 642 *pFileIndex = 0;
643 643
644 strcpy (pstrNextName, pFileList + (*pFileIndex * MAX_PATH)); 644 strcpy (pstrNextName, pFileList + (*pFileIndex * MAX_PATH));
645 } 645 }
646 646
647 return TRUE; 647 return TRUE;
648 } 648 }
649 else 649 else
650 { 650 {
651 return FALSE; 651 return FALSE;
652 } 652 }
653} 653}
654 654
655/*----------------- 655/*-----------------
656 * LoadImageFile 656 * LoadImageFile
657 *----------------- 657 *-----------------
658 */ 658 */
659 659
660BOOL LoadImageFile (HWND hwnd, PTSTR pstrPathName, 660BOOL LoadImageFile (HWND hwnd, PTSTR pstrPathName,
661 png_byte **ppbImage, int *pxImgSize, int *pyImgSize, 661 png_byte **ppbImage, int *pxImgSize, int *pyImgSize,
662 int *piChannels, png_color *pBkgColor) 662 int *piChannels, png_color *pBkgColor)
663{ 663{
664 static TCHAR szTmp [MAX_PATH]; 664 static TCHAR szTmp [MAX_PATH];
665 665
666 /* if there's an existing PNG, free the memory */ 666 /* if there's an existing PNG, free the memory */
667 667
668 if (*ppbImage) 668 if (*ppbImage)
669 { 669 {
670 free (*ppbImage); 670 free (*ppbImage);
671 *ppbImage = NULL; 671 *ppbImage = NULL;
672 } 672 }
673 673
674 /* Load the entire PNG into memory */ 674 /* Load the entire PNG into memory */
675 675
676 SetCursor (LoadCursor (NULL, IDC_WAIT)); 676 SetCursor (LoadCursor (NULL, IDC_WAIT));
677 ShowCursor (TRUE); 677 ShowCursor (TRUE);
678 678
679 PngLoadImage (pstrPathName, ppbImage, pxImgSize, pyImgSize, piChannels, 679 PngLoadImage (pstrPathName, ppbImage, pxImgSize, pyImgSize, piChannels,
680 pBkgColor); 680 pBkgColor);
681 681
682 ShowCursor (FALSE); 682 ShowCursor (FALSE);
683 SetCursor (LoadCursor (NULL, IDC_ARROW)); 683 SetCursor (LoadCursor (NULL, IDC_ARROW));
684 684
685 if (*ppbImage != NULL) 685 if (*ppbImage != NULL)
686 { 686 {
687 sprintf (szTmp, "VisualPng - %s", strrchr(pstrPathName, '\\') + 1); 687 sprintf (szTmp, "VisualPng - %s", strrchr(pstrPathName, '\\') + 1);
688 SetWindowText (hwnd, szTmp); 688 SetWindowText (hwnd, szTmp);
689 } 689 }
690 else 690 else
691 { 691 {
692 MessageBox (hwnd, TEXT ("Error in loading the PNG image"), 692 MessageBox (hwnd, TEXT ("Error in loading the PNG image"),
693 szProgName, MB_ICONEXCLAMATION | MB_OK); 693 szProgName, MB_ICONEXCLAMATION | MB_OK);
694 return FALSE; 694 return FALSE;
695 } 695 }
696 696
697 return TRUE; 697 return TRUE;
698} 698}
699 699
700/*---------------- 700/*----------------
701 * DisplayImage 701 * DisplayImage
702 *---------------- 702 *----------------
703 */ 703 */
704BOOL DisplayImage (HWND hwnd, BYTE **ppDib, 704BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
705 BYTE **ppDiData, int cxWinSize, int cyWinSize, 705 BYTE **ppDiData, int cxWinSize, int cyWinSize,
706 BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, 706 BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
707 BOOL bStretched) 707 BOOL bStretched)
708{ 708{
709 BYTE *pDib = *ppDib; 709 BYTE *pDib = *ppDib;
710 BYTE *pDiData = *ppDiData; 710 BYTE *pDiData = *ppDiData;
711 /* BITMAPFILEHEADER *pbmfh; */ 711 /* BITMAPFILEHEADER *pbmfh; */
712 BITMAPINFOHEADER *pbmih; 712 BITMAPINFOHEADER *pbmih;
713 WORD wDIRowBytes; 713 WORD wDIRowBytes;
714 png_color bkgBlack = {0, 0, 0}; 714 png_color bkgBlack = {0, 0, 0};
715 png_color bkgGray = {127, 127, 127}; 715 png_color bkgGray = {127, 127, 127};
716 png_color bkgWhite = {255, 255, 255}; 716 png_color bkgWhite = {255, 255, 255};
717 717
718 /* allocate memory for the Device Independant bitmap */ 718 /* allocate memory for the Device Independant bitmap */
719 719
720 wDIRowBytes = (WORD) ((3 * cxWinSize + 3L) >> 2) << 2; 720 wDIRowBytes = (WORD) ((3 * cxWinSize + 3L) >> 2) << 2;
721 721
722 if (pDib) 722 if (pDib)
723 { 723 {
724 free (pDib); 724 free (pDib);
725 pDib = NULL; 725 pDib = NULL;
726 } 726 }
727 727
728 if (!(pDib = (BYTE *) malloc (sizeof(BITMAPINFOHEADER) + 728 if (!(pDib = (BYTE *) malloc (sizeof(BITMAPINFOHEADER) +
729 wDIRowBytes * cyWinSize))) 729 wDIRowBytes * cyWinSize)))
730 { 730 {
731 MessageBox (hwnd, TEXT ("Error in displaying the PNG image"), 731 MessageBox (hwnd, TEXT ("Error in displaying the PNG image"),
732 szProgName, MB_ICONEXCLAMATION | MB_OK); 732 szProgName, MB_ICONEXCLAMATION | MB_OK);
733 *ppDib = pDib = NULL; 733 *ppDib = pDib = NULL;
734 return FALSE; 734 return FALSE;
735 } 735 }
736 *ppDib = pDib; 736 *ppDib = pDib;
737 memset (pDib, 0, sizeof(BITMAPINFOHEADER)); 737 memset (pDib, 0, sizeof(BITMAPINFOHEADER));
738 738
739 /* initialize the dib-structure */ 739 /* initialize the dib-structure */
740 740
741 pbmih = (BITMAPINFOHEADER *) pDib; 741 pbmih = (BITMAPINFOHEADER *) pDib;
742 pbmih->biSize = sizeof(BITMAPINFOHEADER); 742 pbmih->biSize = sizeof(BITMAPINFOHEADER);
743 pbmih->biWidth = cxWinSize; 743 pbmih->biWidth = cxWinSize;
744 pbmih->biHeight = -((long) cyWinSize); 744 pbmih->biHeight = -((long) cyWinSize);
745 pbmih->biPlanes = 1; 745 pbmih->biPlanes = 1;
746 pbmih->biBitCount = 24; 746 pbmih->biBitCount = 24;
747 pbmih->biCompression = 0; 747 pbmih->biCompression = 0;
748 pDiData = pDib + sizeof(BITMAPINFOHEADER); 748 pDiData = pDib + sizeof(BITMAPINFOHEADER);
749 *ppDiData = pDiData; 749 *ppDiData = pDiData;
750 750
751 /* first fill bitmap with gray and image border */ 751 /* first fill bitmap with gray and image border */
752 752
753 InitBitmap (pDiData, cxWinSize, cyWinSize); 753 InitBitmap (pDiData, cxWinSize, cyWinSize);
754 754
755 /* then fill bitmap with image */ 755 /* then fill bitmap with image */
756 756
757 if (pbImage) 757 if (pbImage)
758 { 758 {
759 FillBitmap ( 759 FillBitmap (
760 pDiData, cxWinSize, cyWinSize, 760 pDiData, cxWinSize, cyWinSize,
761 pbImage, cxImgSize, cyImgSize, cImgChannels, 761 pbImage, cxImgSize, cyImgSize, cImgChannels,
762 bStretched); 762 bStretched);
763 } 763 }
764 764
765 return TRUE; 765 return TRUE;
766} 766}
767 767
768/*-------------- 768/*--------------
769 * InitBitmap 769 * InitBitmap
770 *-------------- 770 *--------------
771 */ 771 */
772BOOL InitBitmap (BYTE *pDiData, int cxWinSize, int cyWinSize) 772BOOL InitBitmap (BYTE *pDiData, int cxWinSize, int cyWinSize)
773{ 773{
774 BYTE *dst; 774 BYTE *dst;
775 int x, y, col; 775 int x, y, col;
776 776
777 /* initialize the background with gray */ 777 /* initialize the background with gray */
778 778
779 dst = pDiData; 779 dst = pDiData;
780 for (y = 0; y < cyWinSize; y++) 780 for (y = 0; y < cyWinSize; y++)
781 { 781 {
782 col = 0; 782 col = 0;
783 for (x = 0; x < cxWinSize; x++) 783 for (x = 0; x < cxWinSize; x++)
784 { 784 {
785 /* fill with GRAY */ 785 /* fill with GRAY */
786 *dst++ = 127; 786 *dst++ = 127;
787 *dst++ = 127; 787 *dst++ = 127;
788 *dst++ = 127; 788 *dst++ = 127;
789 col += 3; 789 col += 3;
790 } 790 }
791 /* rows start on 4 byte boundaries */ 791 /* rows start on 4 byte boundaries */
792 while ((col % 4) != 0) 792 while ((col % 4) != 0)
793 { 793 {
794 dst++; 794 dst++;
795 col++; 795 col++;
796 } 796 }
797 } 797 }
798 798
799 return TRUE; 799 return TRUE;
800} 800}
801 801
802/*-------------- 802/*--------------
803 * FillBitmap 803 * FillBitmap
804 *-------------- 804 *--------------
805 */ 805 */
806BOOL FillBitmap ( 806BOOL FillBitmap (
807 BYTE *pDiData, int cxWinSize, int cyWinSize, 807 BYTE *pDiData, int cxWinSize, int cyWinSize,
808 BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, 808 BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
809 BOOL bStretched) 809 BOOL bStretched)
810{ 810{
811 BYTE *pStretchedImage; 811 BYTE *pStretchedImage;
812 BYTE *pImg; 812 BYTE *pImg;
813 BYTE *src, *dst; 813 BYTE *src, *dst;
814 BYTE r, g, b, a; 814 BYTE r, g, b, a;
815 const int cDIChannels = 3; 815 const int cDIChannels = 3;
816 WORD wImgRowBytes; 816 WORD wImgRowBytes;
817 WORD wDIRowBytes; 817 WORD wDIRowBytes;
818 int cxNewSize, cyNewSize; 818 int cxNewSize, cyNewSize;
819 int cxImgPos, cyImgPos; 819 int cxImgPos, cyImgPos;
820 int xImg, yImg; 820 int xImg, yImg;
821 int xWin, yWin; 821 int xWin, yWin;
822 int xOld, yOld; 822 int xOld, yOld;
823 int xNew, yNew; 823 int xNew, yNew;
824 824
825 if (bStretched) 825 if (bStretched)
826 { 826 {
827 cxNewSize = cxWinSize - 2 * MARGIN; 827 cxNewSize = cxWinSize - 2 * MARGIN;
828 cyNewSize = cyWinSize - 2 * MARGIN; 828 cyNewSize = cyWinSize - 2 * MARGIN;
829 829
830 /* stretch the image to it's window determined size */ 830 /* stretch the image to it's window determined size */
831 831
832 /* the following two are mathematically the same, but the first 832 /* the following two are mathematically the same, but the first
833 * has side-effects because of rounding 833 * has side-effects because of rounding
834 */ 834 */
835/* if ((cyNewSize / cxNewSize) > (cyImgSize / cxImgSize)) */ 835/* if ((cyNewSize / cxNewSize) > (cyImgSize / cxImgSize)) */
836 if ((cyNewSize * cxImgSize) > (cyImgSize * cxNewSize)) 836 if ((cyNewSize * cxImgSize) > (cyImgSize * cxNewSize))
837 { 837 {
838 cyNewSize = cxNewSize * cyImgSize / cxImgSize; 838 cyNewSize = cxNewSize * cyImgSize / cxImgSize;
839 cxImgPos = MARGIN; 839 cxImgPos = MARGIN;
840 cyImgPos = (cyWinSize - cyNewSize) / 2; 840 cyImgPos = (cyWinSize - cyNewSize) / 2;
841 } 841 }
842 else 842 else
843 { 843 {
844 cxNewSize = cyNewSize * cxImgSize / cyImgSize; 844 cxNewSize = cyNewSize * cxImgSize / cyImgSize;
845 cyImgPos = MARGIN; 845 cyImgPos = MARGIN;
846 cxImgPos = (cxWinSize - cxNewSize) / 2; 846 cxImgPos = (cxWinSize - cxNewSize) / 2;
847 } 847 }
848 848
849 pStretchedImage = malloc (cImgChannels * cxNewSize * cyNewSize); 849 pStretchedImage = malloc (cImgChannels * cxNewSize * cyNewSize);
850 pImg = pStretchedImage; 850 pImg = pStretchedImage;
851 851
852 for (yNew = 0; yNew < cyNewSize; yNew++) 852 for (yNew = 0; yNew < cyNewSize; yNew++)
853 { 853 {
854 yOld = yNew * cyImgSize / cyNewSize; 854 yOld = yNew * cyImgSize / cyNewSize;
855 for (xNew = 0; xNew < cxNewSize; xNew++) 855 for (xNew = 0; xNew < cxNewSize; xNew++)
856 { 856 {
857 xOld = xNew * cxImgSize / cxNewSize; 857 xOld = xNew * cxImgSize / cxNewSize;
858 858
859 r = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 0); 859 r = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 0);
860 g = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 1); 860 g = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 1);
861 b = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 2); 861 b = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 2);
862 *pImg++ = r; 862 *pImg++ = r;
863 *pImg++ = g; 863 *pImg++ = g;
864 *pImg++ = b; 864 *pImg++ = b;
865 if (cImgChannels == 4) 865 if (cImgChannels == 4)
866 { 866 {
867 a = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) 867 a = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld)
868 + 3); 868 + 3);
869 *pImg++ = a; 869 *pImg++ = a;
870 } 870 }
871 } 871 }
872 } 872 }
873 873
874 /* calculate row-bytes */ 874 /* calculate row-bytes */
875 875
876 wImgRowBytes = cImgChannels * cxNewSize; 876 wImgRowBytes = cImgChannels * cxNewSize;
877 wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2; 877 wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;
878 878
879 /* copy image to screen */ 879 /* copy image to screen */
880 880
881 for (yImg = 0, yWin = cyImgPos; yImg < cyNewSize; yImg++, yWin++) 881 for (yImg = 0, yWin = cyImgPos; yImg < cyNewSize; yImg++, yWin++)
882 { 882 {
883 if (yWin >= cyWinSize - cyImgPos) 883 if (yWin >= cyWinSize - cyImgPos)
884 break; 884 break;
885 src = pStretchedImage + yImg * wImgRowBytes; 885 src = pStretchedImage + yImg * wImgRowBytes;
886 dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels; 886 dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;
887 887
888 for (xImg = 0, xWin = cxImgPos; xImg < cxNewSize; xImg++, xWin++) 888 for (xImg = 0, xWin = cxImgPos; xImg < cxNewSize; xImg++, xWin++)
889 { 889 {
890 if (xWin >= cxWinSize - cxImgPos) 890 if (xWin >= cxWinSize - cxImgPos)
891 break; 891 break;
892 r = *src++; 892 r = *src++;
893 g = *src++; 893 g = *src++;
894 b = *src++; 894 b = *src++;
895 *dst++ = b; /* note the reverse order */ 895 *dst++ = b; /* note the reverse order */
896 *dst++ = g; 896 *dst++ = g;
897 *dst++ = r; 897 *dst++ = r;
898 if (cImgChannels == 4) 898 if (cImgChannels == 4)
899 { 899 {
900 a = *src++; 900 a = *src++;
901 } 901 }
902 } 902 }
903 } 903 }
904 904
905 /* free memory */ 905 /* free memory */
906 906
907 if (pStretchedImage != NULL) 907 if (pStretchedImage != NULL)
908 { 908 {
909 free (pStretchedImage); 909 free (pStretchedImage);
910 pStretchedImage = NULL; 910 pStretchedImage = NULL;
911 } 911 }
912 912
913 } 913 }
914 914
915 /* process the image not-stretched */ 915 /* process the image not-stretched */
916 916
917 else 917 else
918 { 918 {
919 /* calculate the central position */ 919 /* calculate the central position */
920 920
921 cxImgPos = (cxWinSize - cxImgSize) / 2; 921 cxImgPos = (cxWinSize - cxImgSize) / 2;
922 cyImgPos = (cyWinSize - cyImgSize) / 2; 922 cyImgPos = (cyWinSize - cyImgSize) / 2;
923 923
924 /* check for image larger than window */ 924 /* check for image larger than window */
925 925
926 if (cxImgPos < MARGIN) 926 if (cxImgPos < MARGIN)
927 cxImgPos = MARGIN; 927 cxImgPos = MARGIN;
928 if (cyImgPos < MARGIN) 928 if (cyImgPos < MARGIN)
929 cyImgPos = MARGIN; 929 cyImgPos = MARGIN;
930 930
931 /* calculate both row-bytes */ 931 /* calculate both row-bytes */
932 932
933 wImgRowBytes = cImgChannels * cxImgSize; 933 wImgRowBytes = cImgChannels * cxImgSize;
934 wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2; 934 wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;
935 935
936 /* copy image to screen */ 936 /* copy image to screen */
937 937
938 for (yImg = 0, yWin = cyImgPos; yImg < cyImgSize; yImg++, yWin++) 938 for (yImg = 0, yWin = cyImgPos; yImg < cyImgSize; yImg++, yWin++)
939 { 939 {
940 if (yWin >= cyWinSize - MARGIN) 940 if (yWin >= cyWinSize - MARGIN)
941 break; 941 break;
942 src = pbImage + yImg * wImgRowBytes; 942 src = pbImage + yImg * wImgRowBytes;
943 dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels; 943 dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;
944 944
945 for (xImg = 0, xWin = cxImgPos; xImg < cxImgSize; xImg++, xWin++) 945 for (xImg = 0, xWin = cxImgPos; xImg < cxImgSize; xImg++, xWin++)
946 { 946 {
947 if (xWin >= cxWinSize - MARGIN) 947 if (xWin >= cxWinSize - MARGIN)
948 break; 948 break;
949 r = *src++; 949 r = *src++;
950 g = *src++; 950 g = *src++;
951 b = *src++; 951 b = *src++;
952 *dst++ = b; /* note the reverse order */ 952 *dst++ = b; /* note the reverse order */
953 *dst++ = g; 953 *dst++ = g;
954 *dst++ = r; 954 *dst++ = r;
955 if (cImgChannels == 4) 955 if (cImgChannels == 4)
956 { 956 {
957 a = *src++; 957 a = *src++;
958 } 958 }
959 } 959 }
960 } 960 }
961 } 961 }
962 962
963 return TRUE; 963 return TRUE;
964} 964}
965 965
966/*----------------- 966/*-----------------
967 * end of source 967 * end of source
968 *----------------- 968 *-----------------
969 */ 969 */
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.rc b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.rc
index 6e0623a..151c68c 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.rc
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/VisualPng.rc
@@ -1,152 +1,152 @@
1//Microsoft Developer Studio generated resource script. 1//Microsoft Developer Studio generated resource script.
2// 2//
3#include "resource.h" 3#include "resource.h"
4 4
5#define APSTUDIO_READONLY_SYMBOLS 5#define APSTUDIO_READONLY_SYMBOLS
6///////////////////////////////////////////////////////////////////////////// 6/////////////////////////////////////////////////////////////////////////////
7// 7//
8// Generated from the TEXTINCLUDE 2 resource. 8// Generated from the TEXTINCLUDE 2 resource.
9// 9//
10#include "afxres.h" 10#include "afxres.h"
11 11
12///////////////////////////////////////////////////////////////////////////// 12/////////////////////////////////////////////////////////////////////////////
13#undef APSTUDIO_READONLY_SYMBOLS 13#undef APSTUDIO_READONLY_SYMBOLS
14 14
15///////////////////////////////////////////////////////////////////////////// 15/////////////////////////////////////////////////////////////////////////////
16// English (U.S.) resources 16// English (U.S.) resources
17 17
18#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 18#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
19#ifdef _WIN32 19#ifdef _WIN32
20LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 20LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
21#pragma code_page(1252) 21#pragma code_page(1252)
22#endif //_WIN32 22#endif //_WIN32
23 23
24#ifdef APSTUDIO_INVOKED 24#ifdef APSTUDIO_INVOKED
25///////////////////////////////////////////////////////////////////////////// 25/////////////////////////////////////////////////////////////////////////////
26// 26//
27// TEXTINCLUDE 27// TEXTINCLUDE
28// 28//
29 29
301 TEXTINCLUDE DISCARDABLE 301 TEXTINCLUDE DISCARDABLE
31BEGIN 31BEGIN
32 "resource.h\0" 32 "resource.h\0"
33END 33END
34 34
352 TEXTINCLUDE DISCARDABLE 352 TEXTINCLUDE DISCARDABLE
36BEGIN 36BEGIN
37 "#include ""afxres.h""\r\n" 37 "#include ""afxres.h""\r\n"
38 "\0" 38 "\0"
39END 39END
40 40
413 TEXTINCLUDE DISCARDABLE 413 TEXTINCLUDE DISCARDABLE
42BEGIN 42BEGIN
43 "\r\n" 43 "\r\n"
44 "\0" 44 "\0"
45END 45END
46 46
47#endif // APSTUDIO_INVOKED 47#endif // APSTUDIO_INVOKED
48 48
49 49
50///////////////////////////////////////////////////////////////////////////// 50/////////////////////////////////////////////////////////////////////////////
51// 51//
52// Menu 52// Menu
53// 53//
54 54
55VISUALPNG MENU DISCARDABLE 55VISUALPNG MENU DISCARDABLE
56BEGIN 56BEGIN
57 POPUP "&File" 57 POPUP "&File"
58 BEGIN 58 BEGIN
59 MENUITEM "&Open Image...\tCtrl+O", IDM_FILE_OPEN 59 MENUITEM "&Open Image...\tCtrl+O", IDM_FILE_OPEN
60 MENUITEM "Save &As...", IDM_FILE_SAVE 60 MENUITEM "Save &As...", IDM_FILE_SAVE
61 MENUITEM SEPARATOR 61 MENUITEM SEPARATOR
62 MENUITEM "&Next Image\tCtrl+N", IDM_FILE_NEXT 62 MENUITEM "&Next Image\tCtrl+N", IDM_FILE_NEXT
63 MENUITEM "Pre&vious Image\tCtrl+V", IDM_FILE_PREVIOUS 63 MENUITEM "Pre&vious Image\tCtrl+V", IDM_FILE_PREVIOUS
64 MENUITEM SEPARATOR 64 MENUITEM SEPARATOR
65 MENUITEM "E&xit\tAlt+X", IDM_FILE_EXIT 65 MENUITEM "E&xit\tAlt+X", IDM_FILE_EXIT
66 END 66 END
67 POPUP "&Options" 67 POPUP "&Options"
68 BEGIN 68 BEGIN
69 MENUITEM "&Stretch", IDM_OPTIONS_STRETCH, CHECKED 69 MENUITEM "&Stretch", IDM_OPTIONS_STRETCH, CHECKED
70 END 70 END
71 POPUP "&Help" 71 POPUP "&Help"
72 BEGIN 72 BEGIN
73 MENUITEM "&About", IDM_HELP_ABOUT 73 MENUITEM "&About", IDM_HELP_ABOUT
74 END 74 END
75END 75END
76 76
77 77
78///////////////////////////////////////////////////////////////////////////// 78/////////////////////////////////////////////////////////////////////////////
79// 79//
80// Accelerator 80// Accelerator
81// 81//
82 82
83VISUALPNG ACCELERATORS DISCARDABLE 83VISUALPNG ACCELERATORS DISCARDABLE
84BEGIN 84BEGIN
85 "N", IDM_FILE_NEXT, VIRTKEY, CONTROL, NOINVERT 85 "N", IDM_FILE_NEXT, VIRTKEY, CONTROL, NOINVERT
86 "O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT 86 "O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
87 "P", IDM_FILE_PREVIOUS, VIRTKEY, CONTROL, NOINVERT 87 "P", IDM_FILE_PREVIOUS, VIRTKEY, CONTROL, NOINVERT
88 "V", IDM_FILE_PREVIOUS, VIRTKEY, CONTROL, NOINVERT 88 "V", IDM_FILE_PREVIOUS, VIRTKEY, CONTROL, NOINVERT
89 "X", IDM_FILE_EXIT, VIRTKEY, ALT, NOINVERT 89 "X", IDM_FILE_EXIT, VIRTKEY, ALT, NOINVERT
90END 90END
91 91
92 92
93///////////////////////////////////////////////////////////////////////////// 93/////////////////////////////////////////////////////////////////////////////
94// 94//
95// Icon 95// Icon
96// 96//
97 97
98// Icon with lowest ID value placed first to ensure application icon 98// Icon with lowest ID value placed first to ensure application icon
99// remains consistent on all systems. 99// remains consistent on all systems.
100VISUALPNG ICON DISCARDABLE "VisualPng.ico" 100VISUALPNG ICON DISCARDABLE "VisualPng.ico"
101 101
102///////////////////////////////////////////////////////////////////////////// 102/////////////////////////////////////////////////////////////////////////////
103// 103//
104// Dialog 104// Dialog
105// 105//
106 106
107ABOUTBOX DIALOG DISCARDABLE 0, 0, 186, 94 107ABOUTBOX DIALOG DISCARDABLE 0, 0, 186, 94
108STYLE DS_MODALFRAME | WS_POPUP 108STYLE DS_MODALFRAME | WS_POPUP
109FONT 8, "MS Sans Serif" 109FONT 8, "MS Sans Serif"
110BEGIN 110BEGIN
111 DEFPUSHBUTTON "OK",IDOK,68,67,50,14 111 DEFPUSHBUTTON "OK",IDOK,68,67,50,14
112 CTEXT "VisualPng 1.0 - June 2000",IDC_STATIC,49,14,88,8 112 CTEXT "VisualPng 1.0 - June 2000",IDC_STATIC,49,14,88,8
113 LTEXT "a PNG image viewer",IDC_STATIC,60,30,66,8 113 LTEXT "a PNG image viewer",IDC_STATIC,60,30,66,8
114 LTEXT "(c) Willem van Schaik, 2000",IDC_STATIC,48,52,90,8 114 LTEXT "(c) Willem van Schaik, 2000",IDC_STATIC,48,52,90,8
115 LTEXT "to demonstrate the use of libpng in Visual C", 115 LTEXT "to demonstrate the use of libpng in Visual C",
116 IDC_STATIC,25,38,136,8 116 IDC_STATIC,25,38,136,8
117END 117END
118 118
119 119
120///////////////////////////////////////////////////////////////////////////// 120/////////////////////////////////////////////////////////////////////////////
121// 121//
122// DESIGNINFO 122// DESIGNINFO
123// 123//
124 124
125#ifdef APSTUDIO_INVOKED 125#ifdef APSTUDIO_INVOKED
126GUIDELINES DESIGNINFO DISCARDABLE 126GUIDELINES DESIGNINFO DISCARDABLE
127BEGIN 127BEGIN
128 "ABOUTBOX", DIALOG 128 "ABOUTBOX", DIALOG
129 BEGIN 129 BEGIN
130 LEFTMARGIN, 7 130 LEFTMARGIN, 7
131 RIGHTMARGIN, 179 131 RIGHTMARGIN, 179
132 TOPMARGIN, 7 132 TOPMARGIN, 7
133 BOTTOMMARGIN, 87 133 BOTTOMMARGIN, 87
134 END 134 END
135END 135END
136#endif // APSTUDIO_INVOKED 136#endif // APSTUDIO_INVOKED
137 137
138#endif // English (U.S.) resources 138#endif // English (U.S.) resources
139///////////////////////////////////////////////////////////////////////////// 139/////////////////////////////////////////////////////////////////////////////
140 140
141 141
142 142
143#ifndef APSTUDIO_INVOKED 143#ifndef APSTUDIO_INVOKED
144///////////////////////////////////////////////////////////////////////////// 144/////////////////////////////////////////////////////////////////////////////
145// 145//
146// Generated from the TEXTINCLUDE 3 resource. 146// Generated from the TEXTINCLUDE 3 resource.
147// 147//
148 148
149 149
150///////////////////////////////////////////////////////////////////////////// 150/////////////////////////////////////////////////////////////////////////////
151#endif // not APSTUDIO_INVOKED 151#endif // not APSTUDIO_INVOKED
152 152
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h
index 83c8bfe..5f45d76 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h
@@ -1,248 +1,248 @@
1/*=== 1/*===
2cexcept.h 2.0.1 (2008-Jul-19-Sat) 2cexcept.h 2.0.1 (2008-Jul-19-Sat)
3http://www.nicemice.net/cexcept/ 3http://www.nicemice.net/cexcept/
4Adam M. Costello 4Adam M. Costello
5http://www.nicemice.net/amc/ 5http://www.nicemice.net/amc/
6 6
7An interface for exception-handling in ANSI C (C89 and subsequent ISO 7An interface for exception-handling in ANSI C (C89 and subsequent ISO
8standards), developed jointly with Cosmin Truta. 8standards), developed jointly with Cosmin Truta.
9 9
10 Copyright (c) 2000-2008 Adam M. Costello and Cosmin Truta. 10 Copyright (c) 2000-2008 Adam M. Costello and Cosmin Truta.
11 This software may be modified only if its author and version 11 This software may be modified only if its author and version
12 information is updated accurately, and may be redistributed 12 information is updated accurately, and may be redistributed
13 only if accompanied by this unaltered notice. Subject to those 13 only if accompanied by this unaltered notice. Subject to those
14 restrictions, permission is granted to anyone to do anything 14 restrictions, permission is granted to anyone to do anything
15 with this software. The copyright holders make no guarantees 15 with this software. The copyright holders make no guarantees
16 regarding this software, and are not responsible for any damage 16 regarding this software, and are not responsible for any damage
17 resulting from its use. 17 resulting from its use.
18 18
19The cexcept interface is not compatible with and cannot interact 19The cexcept interface is not compatible with and cannot interact
20with system exceptions (like division by zero or memory segmentation 20with system exceptions (like division by zero or memory segmentation
21violation), compiler-generated exceptions (like C++ exceptions), or 21violation), compiler-generated exceptions (like C++ exceptions), or
22other exception-handling interfaces. 22other exception-handling interfaces.
23 23
24When using this interface across multiple .c files, do not include 24When using this interface across multiple .c files, do not include
25this header file directly. Instead, create a wrapper header file that 25this header file directly. Instead, create a wrapper header file that
26includes this header file and then invokes the define_exception_type 26includes this header file and then invokes the define_exception_type
27macro (see below). The .c files should then include that header file. 27macro (see below). The .c files should then include that header file.
28 28
29The interface consists of one type, one well-known name, and six macros. 29The interface consists of one type, one well-known name, and six macros.
30 30
31 31
32define_exception_type(type_name); 32define_exception_type(type_name);
33 33
34 This macro is used like an external declaration. It specifies 34 This macro is used like an external declaration. It specifies
35 the type of object that gets copied from the exception thrower to 35 the type of object that gets copied from the exception thrower to
36 the exception catcher. The type_name can be any type that can be 36 the exception catcher. The type_name can be any type that can be
37 assigned to, that is, a non-constant arithmetic type, struct, union, 37 assigned to, that is, a non-constant arithmetic type, struct, union,
38 or pointer. Examples: 38 or pointer. Examples:
39 39
40 define_exception_type(int); 40 define_exception_type(int);
41 41
42 enum exception { out_of_memory, bad_arguments, disk_full }; 42 enum exception { out_of_memory, bad_arguments, disk_full };
43 define_exception_type(enum exception); 43 define_exception_type(enum exception);
44 44
45 struct exception { int code; const char *msg; }; 45 struct exception { int code; const char *msg; };
46 define_exception_type(struct exception); 46 define_exception_type(struct exception);
47 47
48 Because throwing an exception causes the object to be copied (not 48 Because throwing an exception causes the object to be copied (not
49 just once, but twice), programmers may wish to consider size when 49 just once, but twice), programmers may wish to consider size when
50 choosing the exception type. 50 choosing the exception type.
51 51
52 52
53struct exception_context; 53struct exception_context;
54 54
55 This type may be used after the define_exception_type() macro has 55 This type may be used after the define_exception_type() macro has
56 been invoked. A struct exception_context must be known to both 56 been invoked. A struct exception_context must be known to both
57 the thrower and the catcher. It is expected that there be one 57 the thrower and the catcher. It is expected that there be one
58 context for each thread that uses exceptions. It would certainly 58 context for each thread that uses exceptions. It would certainly
59 be dangerous for multiple threads to access the same context. 59 be dangerous for multiple threads to access the same context.
60 One thread can use multiple contexts, but that is likely to be 60 One thread can use multiple contexts, but that is likely to be
61 confusing and not typically useful. The application can allocate 61 confusing and not typically useful. The application can allocate
62 this structure in any way it pleases--automatic, static, or dynamic. 62 this structure in any way it pleases--automatic, static, or dynamic.
63 The application programmer should pretend not to know the structure 63 The application programmer should pretend not to know the structure
64 members, which are subject to change. 64 members, which are subject to change.
65 65
66 66
67struct exception_context *the_exception_context; 67struct exception_context *the_exception_context;
68 68
69 The Try/Catch and Throw statements (described below) implicitly 69 The Try/Catch and Throw statements (described below) implicitly
70 refer to a context, using the name the_exception_context. It is 70 refer to a context, using the name the_exception_context. It is
71 the application's responsibility to make sure that this name yields 71 the application's responsibility to make sure that this name yields
72 the address of a mutable (non-constant) struct exception_context 72 the address of a mutable (non-constant) struct exception_context
73 wherever those statements are used. Subject to that constraint, the 73 wherever those statements are used. Subject to that constraint, the
74 application may declare a variable of this name anywhere it likes 74 application may declare a variable of this name anywhere it likes
75 (inside a function, in a parameter list, or externally), and may 75 (inside a function, in a parameter list, or externally), and may
76 use whatever storage class specifiers (static, extern, etc) or type 76 use whatever storage class specifiers (static, extern, etc) or type
77 qualifiers (const, volatile, etc) it likes. Examples: 77 qualifiers (const, volatile, etc) it likes. Examples:
78 78
79 static struct exception_context 79 static struct exception_context
80 * const the_exception_context = &foo; 80 * const the_exception_context = &foo;
81 81
82 { struct exception_context *the_exception_context = bar; ... } 82 { struct exception_context *the_exception_context = bar; ... }
83 83
84 int blah(struct exception_context *the_exception_context, ...); 84 int blah(struct exception_context *the_exception_context, ...);
85 85
86 extern struct exception_context the_exception_context[1]; 86 extern struct exception_context the_exception_context[1];
87 87
88 The last example illustrates a trick that avoids creating a pointer 88 The last example illustrates a trick that avoids creating a pointer
89 object separate from the structure object. 89 object separate from the structure object.
90 90
91 The name could even be a macro, for example: 91 The name could even be a macro, for example:
92 92
93 struct exception_context ec_array[numthreads]; 93 struct exception_context ec_array[numthreads];
94 #define the_exception_context (ec_array + thread_id) 94 #define the_exception_context (ec_array + thread_id)
95 95
96 Be aware that the_exception_context is used several times by the 96 Be aware that the_exception_context is used several times by the
97 Try/Catch/Throw macros, so it shouldn't be expensive or have side 97 Try/Catch/Throw macros, so it shouldn't be expensive or have side
98 effects. The expansion must be a drop-in replacement for an 98 effects. The expansion must be a drop-in replacement for an
99 identifier, so it's safest to put parentheses around it. 99 identifier, so it's safest to put parentheses around it.
100 100
101 101
102void init_exception_context(struct exception_context *ec); 102void init_exception_context(struct exception_context *ec);
103 103
104 For context structures allocated statically (by an external 104 For context structures allocated statically (by an external
105 definition or using the "static" keyword), the implicit 105 definition or using the "static" keyword), the implicit
106 initialization to all zeros is sufficient, but contexts allocated 106 initialization to all zeros is sufficient, but contexts allocated
107 by other means must be initialized using this macro before they 107 by other means must be initialized using this macro before they
108 are used by a Try/Catch statement. It does no harm to initialize 108 are used by a Try/Catch statement. It does no harm to initialize
109 a context more than once (by using this macro on a statically 109 a context more than once (by using this macro on a statically
110 allocated context, or using this macro twice on the same context), 110 allocated context, or using this macro twice on the same context),
111 but a context must not be re-initialized after it has been used by a 111 but a context must not be re-initialized after it has been used by a
112 Try/Catch statement. 112 Try/Catch statement.
113 113
114 114
115Try statement 115Try statement
116Catch (expression) statement 116Catch (expression) statement
117 117
118 The Try/Catch/Throw macros are capitalized in order to avoid 118 The Try/Catch/Throw macros are capitalized in order to avoid
119 confusion with the C++ keywords, which have subtly different 119 confusion with the C++ keywords, which have subtly different
120 semantics. 120 semantics.
121 121
122 A Try/Catch statement has a syntax similar to an if/else statement, 122 A Try/Catch statement has a syntax similar to an if/else statement,
123 except that the parenthesized expression goes after the second 123 except that the parenthesized expression goes after the second
124 keyword rather than the first. As with if/else, there are two 124 keyword rather than the first. As with if/else, there are two
125 clauses, each of which may be a simple statement ending with a 125 clauses, each of which may be a simple statement ending with a
126 semicolon or a brace-enclosed compound statement. But whereas 126 semicolon or a brace-enclosed compound statement. But whereas
127 the else clause is optional, the Catch clause is required. The 127 the else clause is optional, the Catch clause is required. The
128 expression must be a modifiable lvalue (something capable of being 128 expression must be a modifiable lvalue (something capable of being
129 assigned to) of the same type (disregarding type qualifiers) that 129 assigned to) of the same type (disregarding type qualifiers) that
130 was passed to define_exception_type(). 130 was passed to define_exception_type().
131 131
132 If a Throw that uses the same exception context as the Try/Catch is 132 If a Throw that uses the same exception context as the Try/Catch is
133 executed within the Try clause (typically within a function called 133 executed within the Try clause (typically within a function called
134 by the Try clause), and the exception is not caught by a nested 134 by the Try clause), and the exception is not caught by a nested
135 Try/Catch statement, then a copy of the exception will be assigned 135 Try/Catch statement, then a copy of the exception will be assigned
136 to the expression, and control will jump to the Catch clause. If no 136 to the expression, and control will jump to the Catch clause. If no
137 such Throw is executed, then the assignment is not performed, and 137 such Throw is executed, then the assignment is not performed, and
138 the Catch clause is not executed. 138 the Catch clause is not executed.
139 139
140 The expression is not evaluated unless and until the exception is 140 The expression is not evaluated unless and until the exception is
141 caught, which is significant if it has side effects, for example: 141 caught, which is significant if it has side effects, for example:
142 142
143 Try foo(); 143 Try foo();
144 Catch (p[++i].e) { ... } 144 Catch (p[++i].e) { ... }
145 145
146 IMPORTANT: Jumping into or out of a Try clause (for example via 146 IMPORTANT: Jumping into or out of a Try clause (for example via
147 return, break, continue, goto, longjmp) is forbidden--the compiler 147 return, break, continue, goto, longjmp) is forbidden--the compiler
148 will not complain, but bad things will happen at run-time. Jumping 148 will not complain, but bad things will happen at run-time. Jumping
149 into or out of a Catch clause is okay, and so is jumping around 149 into or out of a Catch clause is okay, and so is jumping around
150 inside a Try clause. In many cases where one is tempted to return 150 inside a Try clause. In many cases where one is tempted to return
151 from a Try clause, it will suffice to use Throw, and then return 151 from a Try clause, it will suffice to use Throw, and then return
152 from the Catch clause. Another option is to set a flag variable and 152 from the Catch clause. Another option is to set a flag variable and
153 use goto to jump to the end of the Try clause, then check the flag 153 use goto to jump to the end of the Try clause, then check the flag
154 after the Try/Catch statement. 154 after the Try/Catch statement.
155 155
156 IMPORTANT: The values of any non-volatile automatic variables 156 IMPORTANT: The values of any non-volatile automatic variables
157 changed within the Try clause are undefined after an exception is 157 changed within the Try clause are undefined after an exception is
158 caught. Therefore, variables modified inside the Try block whose 158 caught. Therefore, variables modified inside the Try block whose
159 values are needed later outside the Try block must either use static 159 values are needed later outside the Try block must either use static
160 storage or be declared with the "volatile" type qualifier. 160 storage or be declared with the "volatile" type qualifier.
161 161
162 162
163Throw expression; 163Throw expression;
164 164
165 A Throw statement is very much like a return statement, except that 165 A Throw statement is very much like a return statement, except that
166 the expression is required. Whereas return jumps back to the place 166 the expression is required. Whereas return jumps back to the place
167 where the current function was called, Throw jumps back to the Catch 167 where the current function was called, Throw jumps back to the Catch
168 clause of the innermost enclosing Try clause. The expression must 168 clause of the innermost enclosing Try clause. The expression must
169 be compatible with the type passed to define_exception_type(). The 169 be compatible with the type passed to define_exception_type(). The
170 exception must be caught, otherwise the program may crash. 170 exception must be caught, otherwise the program may crash.
171 171
172 Slight limitation: If the expression is a comma-expression, it must 172 Slight limitation: If the expression is a comma-expression, it must
173 be enclosed in parentheses. 173 be enclosed in parentheses.
174 174
175 175
176Try statement 176Try statement
177Catch_anonymous statement 177Catch_anonymous statement
178 178
179 When the value of the exception is not needed, a Try/Catch statement 179 When the value of the exception is not needed, a Try/Catch statement
180 can use Catch_anonymous instead of Catch (expression). 180 can use Catch_anonymous instead of Catch (expression).
181 181
182 182
183Everything below this point is for the benefit of the compiler. The 183Everything below this point is for the benefit of the compiler. The
184application programmer should pretend not to know any of it, because it 184application programmer should pretend not to know any of it, because it
185is subject to change. 185is subject to change.
186 186
187===*/ 187===*/
188 188
189 189
190#ifndef CEXCEPT_H 190#ifndef CEXCEPT_H
191#define CEXCEPT_H 191#define CEXCEPT_H
192 192
193 193
194#include <setjmp.h> 194#include <setjmp.h>
195 195
196#define define_exception_type(etype) \ 196#define define_exception_type(etype) \
197struct exception_context { \ 197struct exception_context { \
198 jmp_buf *penv; \ 198 jmp_buf *penv; \
199 int caught; \ 199 int caught; \
200 volatile struct { etype etmp; } v; \ 200 volatile struct { etype etmp; } v; \
201} 201}
202 202
203/* etmp must be volatile because the application might use automatic */ 203/* etmp must be volatile because the application might use automatic */
204/* storage for the_exception_context, and etmp is modified between */ 204/* storage for the_exception_context, and etmp is modified between */
205/* the calls to setjmp() and longjmp(). A wrapper struct is used to */ 205/* the calls to setjmp() and longjmp(). A wrapper struct is used to */
206/* avoid warnings about a duplicate volatile qualifier in case etype */ 206/* avoid warnings about a duplicate volatile qualifier in case etype */
207/* already includes it. */ 207/* already includes it. */
208 208
209#define init_exception_context(ec) ((void)((ec)->penv = 0)) 209#define init_exception_context(ec) ((void)((ec)->penv = 0))
210 210
211#define Try \ 211#define Try \
212 { \ 212 { \
213 jmp_buf *exception__prev, exception__env; \ 213 jmp_buf *exception__prev, exception__env; \
214 exception__prev = the_exception_context->penv; \ 214 exception__prev = the_exception_context->penv; \
215 the_exception_context->penv = &exception__env; \ 215 the_exception_context->penv = &exception__env; \
216 if (setjmp(exception__env) == 0) { \ 216 if (setjmp(exception__env) == 0) { \
217 do 217 do
218 218
219#define exception__catch(action) \ 219#define exception__catch(action) \
220 while (the_exception_context->caught = 0, \ 220 while (the_exception_context->caught = 0, \
221 the_exception_context->caught); \ 221 the_exception_context->caught); \
222 } \ 222 } \
223 else { \ 223 else { \
224 the_exception_context->caught = 1; \ 224 the_exception_context->caught = 1; \
225 } \ 225 } \
226 the_exception_context->penv = exception__prev; \ 226 the_exception_context->penv = exception__prev; \
227 } \ 227 } \
228 if (!the_exception_context->caught || action) { } \ 228 if (!the_exception_context->caught || action) { } \
229 else 229 else
230 230
231#define Catch(e) exception__catch(((e) = the_exception_context->v.etmp, 0)) 231#define Catch(e) exception__catch(((e) = the_exception_context->v.etmp, 0))
232#define Catch_anonymous exception__catch(0) 232#define Catch_anonymous exception__catch(0)
233 233
234/* Try ends with do, and Catch begins with while(0) and ends with */ 234/* Try ends with do, and Catch begins with while(0) and ends with */
235/* else, to ensure that Try/Catch syntax is similar to if/else */ 235/* else, to ensure that Try/Catch syntax is similar to if/else */
236/* syntax. */ 236/* syntax. */
237/* */ 237/* */
238/* The 0 in while(0) is expressed as x=0,x in order to appease */ 238/* The 0 in while(0) is expressed as x=0,x in order to appease */
239/* compilers that warn about constant expressions inside while(). */ 239/* compilers that warn about constant expressions inside while(). */
240/* Most compilers should still recognize that the condition is always */ 240/* Most compilers should still recognize that the condition is always */
241/* false and avoid generating code for it. */ 241/* false and avoid generating code for it. */
242 242
243#define Throw \ 243#define Throw \
244 for (;; longjmp(*the_exception_context->penv, 1)) \ 244 for (;; longjmp(*the_exception_context->penv, 1)) \
245 the_exception_context->v.etmp = 245 the_exception_context->v.etmp =
246 246
247 247
248#endif /* CEXCEPT_H */ 248#endif /* CEXCEPT_H */
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/resource.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/resource.h
index a06050a..b62176d 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/resource.h
+++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/resource.h
@@ -1,23 +1,23 @@
1//{{NO_DEPENDENCIES}} 1//{{NO_DEPENDENCIES}}
2// Microsoft Developer Studio generated include file. 2// Microsoft Developer Studio generated include file.
3// Used by VisualPng.rc 3// Used by VisualPng.rc
4// 4//
5#define IDM_FILE_OPEN 40001 5#define IDM_FILE_OPEN 40001
6#define IDM_FILE_SAVE 40002 6#define IDM_FILE_SAVE 40002
7#define IDM_FILE_NEXT 40003 7#define IDM_FILE_NEXT 40003
8#define IDM_FILE_PREVIOUS 40004 8#define IDM_FILE_PREVIOUS 40004
9#define IDM_FILE_EXIT 40005 9#define IDM_FILE_EXIT 40005
10#define IDM_OPTIONS_BACKGROUND 40006 10#define IDM_OPTIONS_BACKGROUND 40006
11#define IDM_OPTIONS_STRETCH 40007 11#define IDM_OPTIONS_STRETCH 40007
12#define IDM_HELP_ABOUT 40008 12#define IDM_HELP_ABOUT 40008
13 13
14// Next default values for new objects 14// Next default values for new objects
15// 15//
16#ifdef APSTUDIO_INVOKED 16#ifdef APSTUDIO_INVOKED
17#ifndef APSTUDIO_READONLY_SYMBOLS 17#ifndef APSTUDIO_READONLY_SYMBOLS
18#define _APS_NEXT_RESOURCE_VALUE 113 18#define _APS_NEXT_RESOURCE_VALUE 113
19#define _APS_NEXT_COMMAND_VALUE 40009 19#define _APS_NEXT_COMMAND_VALUE 40009
20#define _APS_NEXT_CONTROL_VALUE 1001 20#define _APS_NEXT_CONTROL_VALUE 1001
21#define _APS_NEXT_SYMED_VALUE 101 21#define _APS_NEXT_SYMED_VALUE 101
22#endif 22#endif
23#endif 23#endif