1 /* Copyright 2007-2012 Fredrik Wikstrom. All rights reserved.
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
7 ** 1. Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
10 ** 2. Redistributions in binary form must reproduce the above copyright
11 ** notice, this list of conditions and the following disclaimer in the
12 ** documentation and/or other materials provided with the distribution.
14 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 ** POSSIBILITY OF SUCH DAMAGE.
29 #include <libraries/z.h>
30 #include <proto/exec.h>
31 #include <proto/dos.h>
37 #define PNG_SIGNATURE "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"
44 #define ID_IHDR MAKE_ID('I','H','D','R')
45 #define ID_PLTE MAKE_ID('P','L','T','E')
46 #define ID_IDAT MAKE_ID('I','D','A','T')
47 #define ID_IEND MAKE_ID('I','E','N','D')
61 static inline WORD
abs (WORD x
) {
62 return x
>= 0 ? x
: -x
;
65 /*static void PrintULONG (ULONG x) {
69 for (i = 0; i < 8; i++) {
70 y = (x & 0xf0000000UL) >> 28;
75 buffer[i] = y + 'A' - 10;
80 Write(Output(), buffer, 9);
83 BOOL
LoadPNG (struct ClassData
*data
, const char *filename
, LONG index
) {
84 BOOL ihdr_found
= FALSE
;
90 ULONG original_crc
/*, crc*/;
91 const LONG pix_size
= 4;
94 ULONG png_data_size
= 0;
95 ULONG packed_size
= 0;
97 UBYTE
*unpacked
= NULL
;
98 ULONG dest_len
, source_len
;
105 file
= Open(filename
, MODE_OLDFILE
);
110 if (FRead(file
, signature
, 1, sizeof(signature
)) != sizeof(signature
)) {
113 if (memcmp(signature
, PNG_SIGNATURE
, sizeof(signature
))) {
118 if (FRead(file
, &chunk
, 1, sizeof(chunk
)) != sizeof(chunk
)) {
121 /*crc = CRC32(0, &chunk.id, sizeof(chunk.id));*/
122 wbe32(&chunk
.size
, chunk
.size
);
126 if (chunk
.size
!= sizeof(ihdr
)) {
129 if (FRead(file
, &ihdr
, 1, chunk
.size
) != chunk
.size
) {
132 if (FRead(file
, &original_crc
, 1, sizeof(original_crc
)) != sizeof(original_crc
)) {
135 /*crc = CRC32(crc, &ihdr, chunk.size);*/
137 PrintULONG(original_crc);*/
138 /*if (crc != original_crc) {
141 if (index
== IMG_NORMAL
) {
142 data
->width
= rbe32(&ihdr
.width
);
143 data
->height
= rbe32(&ihdr
.height
);
145 if (data
->width
!= rbe32(&ihdr
.width
) || data
->height
!= rbe32(&ihdr
.height
)) {
149 if (ihdr
.depth
!= 8 || ihdr
.color_type
!= 6 || ihdr
.compression
!= 0 ||
150 ihdr
.filter
!= 0 || ihdr
.interlace
!= 0)
154 row_size
= data
->width
* pix_size
;
155 data_size
= row_size
* data
->height
;
156 data
->image
[index
] = AllocVec(data_size
, MEMF_ANY
);
157 if (!data
->image
[index
]) {
160 png_data_size
= data_size
+ data
->height
;
162 packed
= AllocVec(png_data_size
, MEMF_ANY
);
163 unpacked
= AllocVec(png_data_size
, MEMF_ANY
);
164 if (!packed
|| !unpacked
) {
173 if (packed_size
+ chunk
.size
> png_data_size
) {
176 if (FRead(file
, packed
+ packed_size
, 1, chunk
.size
) != chunk
.size
) {
179 if (FRead(file
, &original_crc
, 1, sizeof(original_crc
)) != sizeof(original_crc
)) {
182 /*crc = CRC32(crc, packed + packed_size, chunk.size);*/
184 PrintULONG(original_crc);*/
185 /*if (crc != original_crc) {
188 packed_size
+= chunk
.size
;
192 if (!ihdr_found
|| !packed_size
) {
195 if (chunk
.size
!= 0) {
198 if (FRead(file
, &original_crc
, 1, sizeof(original_crc
)) != sizeof(original_crc
)) {
202 PrintULONG(original_crc);*/
203 /*if (crc != original_crc) {
206 dest_len
= png_data_size
;
207 source_len
= packed_size
;
208 if (Uncompress(unpacked
, &dest_len
, packed
, source_len
) != Z_OK
) {
211 if (dest_len
!= png_data_size
) {
215 dst
= data
->image
[index
];
216 for (y
= 0; y
< data
->height
; y
++) {
219 for (x
= 0; x
< row_size
; x
++) {
220 if (x
>= pix_size
) a
= dst
[-pix_size
];
221 if (y
>= 1) b
= dst
[-row_size
];
222 if (y
>= 1 && x
>= pix_size
) c
= dst
[-pix_size
-row_size
];
235 *dst
++ = d
+ ((a
+ b
) / 2);
242 if (pa
<= pb
&& pa
<= pc
)
258 if (Seek(file
, chunk
.size
+ 4, OFFSET_CURRENT
) == -1) {
268 if (file
) Close(file
);