Skip to content

Commit 407d80c

Browse files
committed
Resync
1 parent 40c1ec5 commit 407d80c

2 files changed

Lines changed: 100 additions & 109 deletions

File tree

formats/png/rpng.c

Lines changed: 100 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2121
*/
2222

23+
#ifdef DEBUG
2324
#include <stdio.h>
25+
#endif
2426
#include <stdint.h>
2527
#include <stdlib.h>
2628
#include <string.h>
@@ -80,12 +82,6 @@ struct idat_buffer
8082
size_t size;
8183
};
8284

83-
struct png_chunk
84-
{
85-
uint32_t size;
86-
char type[4];
87-
};
88-
8985
struct rpng_process
9086
{
9187
uint32_t *data;
@@ -135,97 +131,69 @@ static INLINE uint32_t dword_be(const uint8_t *buf)
135131
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0);
136132
}
137133

138-
static enum png_chunk_type png_chunk_type(char chunk_type[4])
139-
{
140-
unsigned i;
141-
struct
142-
{
143-
const char *id;
144-
enum png_chunk_type type;
145-
} static const chunk_map[] = {
146-
{ "IHDR", PNG_CHUNK_IHDR },
147-
{ "IDAT", PNG_CHUNK_IDAT },
148-
{ "IEND", PNG_CHUNK_IEND },
149-
{ "PLTE", PNG_CHUNK_PLTE },
150-
{ "tRNS", PNG_CHUNK_tRNS },
151-
};
152-
153-
for (i = 0; i < ARRAY_SIZE(chunk_map); i++)
154-
{
155-
if (!memcmp(chunk_type, chunk_map[i].id, 4))
156-
return chunk_map[i].type;
157-
}
158-
159-
return PNG_CHUNK_NOOP;
160-
}
161-
162134
static bool png_process_ihdr(struct png_ihdr *ihdr)
163135
{
164136
unsigned i;
165-
bool ret = true;
137+
uint8_t ihdr_depth = ihdr->depth;
166138

167139
switch (ihdr->color_type)
168140
{
169141
case PNG_IHDR_COLOR_RGB:
170142
case PNG_IHDR_COLOR_GRAY_ALPHA:
171143
case PNG_IHDR_COLOR_RGBA:
172-
if (ihdr->depth != 8 && ihdr->depth != 16)
173-
GOTO_END_ERROR();
144+
if (ihdr_depth != 8 && ihdr_depth != 16)
145+
{
146+
#ifdef DEBUG
147+
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__);
148+
#endif
149+
return false;
150+
}
174151
break;
175152
case PNG_IHDR_COLOR_GRAY:
153+
/* Valid bitdepths are: 1, 2, 4, 8, 16 */
154+
if (ihdr_depth > 16 || (0x977F7FFF << ihdr_depth) & 0x80000000)
176155
{
177-
static const unsigned valid_bpp[] = { 1, 2, 4, 8, 16 };
178-
bool correct_bpp = false;
179-
180-
for (i = 0; i < ARRAY_SIZE(valid_bpp); i++)
181-
{
182-
if (valid_bpp[i] == ihdr->depth)
183-
{
184-
correct_bpp = true;
185-
break;
186-
}
187-
}
188-
189-
if (!correct_bpp)
190-
GOTO_END_ERROR();
156+
#ifdef DEBUG
157+
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__);
158+
#endif
159+
return false;
191160
}
192161
break;
193162
case PNG_IHDR_COLOR_PLT:
163+
/* Valid bitdepths are: 1, 2, 4, 8 */
164+
if (ihdr_depth > 8 || (0x977F7FFF << ihdr_depth) & 0x80000000)
194165
{
195-
static const unsigned valid_bpp[] = { 1, 2, 4, 8 };
196-
bool correct_bpp = false;
197-
198-
for (i = 0; i < ARRAY_SIZE(valid_bpp); i++)
199-
{
200-
if (valid_bpp[i] == ihdr->depth)
201-
{
202-
correct_bpp = true;
203-
break;
204-
}
205-
}
206-
207-
if (!correct_bpp)
208-
GOTO_END_ERROR();
166+
#ifdef DEBUG
167+
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__);
168+
#endif
169+
return false;
209170
}
210171
break;
211172
default:
212-
GOTO_END_ERROR();
173+
#ifdef DEBUG
174+
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__);
175+
#endif
176+
return false;
213177
}
214178

215179
#ifdef RPNG_TEST
216180
fprintf(stderr, "IHDR: (%u x %u), bpc = %u, palette = %s, color = %s, alpha = %s, adam7 = %s.\n",
217181
ihdr->width, ihdr->height,
218-
ihdr->depth, (ihdr->color_type == PNG_IHDR_COLOR_PLT) ? "yes" : "no",
219-
(ihdr->color_type & PNG_IHDR_COLOR_RGB) ? "yes" : "no",
220-
(ihdr->color_type & PNG_IHDR_COLOR_GRAY_ALPHA) ? "yes" : "no",
182+
ihdr_depth, (ihdr->color_type == PNG_IHDR_COLOR_PLT) ? "yes" : "no",
183+
(ihdr->color_type & PNG_IHDR_COLOR_RGB) ? "yes" : "no",
184+
(ihdr->color_type & PNG_IHDR_COLOR_GRAY_ALPHA) ? "yes" : "no",
221185
ihdr->interlace == 1 ? "yes" : "no");
222186
#endif
223187

224188
if (ihdr->compression != 0)
225-
GOTO_END_ERROR();
189+
{
190+
#ifdef DEBUG
191+
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__);
192+
#endif
193+
return false;
194+
}
226195

227-
end:
228-
return ret;
196+
return true;
229197
}
230198

231199
static void png_reverse_filter_copy_line_rgb(uint32_t *data,
@@ -951,16 +919,15 @@ static struct rpng_process *rpng_process_init(rpng_t *rpng)
951919
return NULL;
952920
}
953921

954-
static bool read_chunk_header(uint8_t *buf, uint8_t *buf_end,
955-
struct png_chunk *chunk)
922+
static enum png_chunk_type read_chunk_header(uint8_t *buf, uint8_t *buf_end,
923+
uint32_t chunk_size)
956924
{
957925
unsigned i;
958-
959-
chunk->size = dword_be(buf);
926+
char type[4];
960927

961928
/* Check whether chunk will overflow the data buffer */
962-
if (buf + 8 + chunk->size > buf_end)
963-
return false;
929+
if (buf + 8 + chunk_size > buf_end)
930+
return PNG_CHUNK_ERROR;
964931

965932
for (i = 0; i < 4; i++)
966933
{
@@ -969,12 +936,51 @@ static bool read_chunk_header(uint8_t *buf, uint8_t *buf_end,
969936
/* All four bytes of the chunk type must be
970937
* ASCII letters (codes 65-90 and 97-122) */
971938
if ((byte < 65) || ((byte > 90) && (byte < 97)) || (byte > 122))
972-
return false;
973-
974-
chunk->type[i] = byte;
939+
return PNG_CHUNK_ERROR;
940+
type[i] = byte;
975941
}
976942

977-
return true;
943+
if (
944+
type[0] == 'I'
945+
&& type[1] == 'H'
946+
&& type[2] == 'D'
947+
&& type[3] == 'R'
948+
)
949+
return PNG_CHUNK_IHDR;
950+
else if
951+
(
952+
type[0] == 'I'
953+
&& type[1] == 'D'
954+
&& type[2] == 'A'
955+
&& type[3] == 'T'
956+
)
957+
return PNG_CHUNK_IDAT;
958+
else if
959+
(
960+
type[0] == 'I'
961+
&& type[1] == 'E'
962+
&& type[2] == 'N'
963+
&& type[3] == 'D'
964+
)
965+
return PNG_CHUNK_IEND;
966+
else if
967+
(
968+
type[0] == 'P'
969+
&& type[1] == 'L'
970+
&& type[2] == 'T'
971+
&& type[3] == 'E'
972+
)
973+
return PNG_CHUNK_PLTE;
974+
else if
975+
(
976+
type[0] == 't'
977+
&& type[1] == 'R'
978+
&& type[2] == 'N'
979+
&& type[3] == 'S'
980+
)
981+
return PNG_CHUNK_tRNS;
982+
983+
return PNG_CHUNK_NOOP;
978984
}
979985

980986
static bool png_parse_ihdr(uint8_t *buf,
@@ -998,11 +1004,8 @@ static bool png_parse_ihdr(uint8_t *buf,
9981004
bool rpng_iterate_image(rpng_t *rpng)
9991005
{
10001006
unsigned i;
1001-
struct png_chunk chunk;
1002-
uint8_t *buf = (uint8_t*)rpng->buff_data;
1003-
1004-
chunk.size = 0;
1005-
chunk.type[0] = 0;
1007+
uint8_t *buf = (uint8_t*)rpng->buff_data;
1008+
uint32_t chunk_size = 0;
10061009

10071010
/* Check whether data buffer pointer is valid */
10081011
if (buf > rpng->buff_end)
@@ -1012,10 +1015,10 @@ bool rpng_iterate_image(rpng_t *rpng)
10121015
* the data buffer */
10131016
if (rpng->buff_end - buf < 8)
10141017
return false;
1015-
if (!read_chunk_header(buf, rpng->buff_end, &chunk))
1016-
return false;
10171018

1018-
switch (png_chunk_type(chunk.type))
1019+
chunk_size = dword_be(buf);
1020+
1021+
switch (read_chunk_header(buf, rpng->buff_end, chunk_size))
10191022
{
10201023
case PNG_CHUNK_NOOP:
10211024
default:
@@ -1028,7 +1031,7 @@ bool rpng_iterate_image(rpng_t *rpng)
10281031
if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend)
10291032
return false;
10301033

1031-
if (chunk.size != 13)
1034+
if (chunk_size != 13)
10321035
return false;
10331036

10341037
if (!png_parse_ihdr(buf, &rpng->ihdr))
@@ -1042,12 +1045,12 @@ bool rpng_iterate_image(rpng_t *rpng)
10421045

10431046
case PNG_CHUNK_PLTE:
10441047
{
1045-
unsigned entries = chunk.size / 3;
1048+
unsigned entries = chunk_size / 3;
10461049

10471050
if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat || rpng->has_trns)
10481051
return false;
10491052

1050-
if (chunk.size % 3)
1053+
if (chunk_size % 3)
10511054
return false;
10521055

10531056
if (entries > 256)
@@ -1069,12 +1072,12 @@ bool rpng_iterate_image(rpng_t *rpng)
10691072
if (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT)
10701073
{
10711074
/* we should compare with the number of palette entries */
1072-
if (chunk.size > 256)
1075+
if (chunk_size > 256)
10731076
return false;
10741077

10751078
buf += 8;
10761079

1077-
if (!png_read_trns(buf, rpng->palette, chunk.size))
1080+
if (!png_read_trns(buf, rpng->palette, chunk_size))
10781081
return false;
10791082
}
10801083
/* TODO: support colorkey in grayscale and truecolor images */
@@ -1086,15 +1089,15 @@ bool rpng_iterate_image(rpng_t *rpng)
10861089
if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT && !(rpng->has_plte)))
10871090
return false;
10881091

1089-
if (!png_realloc_idat(&rpng->idat_buf, chunk.size))
1092+
if (!png_realloc_idat(&rpng->idat_buf, chunk_size))
10901093
return false;
10911094

10921095
buf += 8;
10931096

1094-
for (i = 0; i < chunk.size; i++)
1097+
for (i = 0; i < chunk_size; i++)
10951098
rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i];
10961099

1097-
rpng->idat_buf.size += chunk.size;
1100+
rpng->idat_buf.size += chunk_size;
10981101

10991102
rpng->has_idat = true;
11001103
break;
@@ -1107,7 +1110,7 @@ bool rpng_iterate_image(rpng_t *rpng)
11071110
return false;
11081111
}
11091112

1110-
rpng->buff_data += chunk.size + 12;
1113+
rpng->buff_data += chunk_size + 12;
11111114

11121115
/* Check whether data buffer pointer is valid */
11131116
if (rpng->buff_data > rpng->buff_end)
@@ -1184,7 +1187,6 @@ void rpng_free(rpng_t *rpng)
11841187
bool rpng_start(rpng_t *rpng)
11851188
{
11861189
unsigned i;
1187-
char header[8];
11881190

11891191
if (!rpng)
11901192
return false;
@@ -1194,12 +1196,8 @@ bool rpng_start(rpng_t *rpng)
11941196
if (rpng->buff_end - rpng->buff_data < 8)
11951197
return false;
11961198

1197-
header[0] = '\0';
1198-
1199-
for (i = 0; i < 8; i++)
1200-
header[i] = rpng->buff_data[i];
1201-
1202-
if (string_is_not_equal_fast(header, png_magic, sizeof(png_magic)))
1199+
if (string_is_not_equal_fast(
1200+
rpng->buff_data, png_magic, sizeof(png_magic)))
12031201
return false;
12041202

12051203
rpng->buff_data += 8;

formats/png/rpng_internal.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@
2727
#include <filters.h>
2828
#include <formats/rpng.h>
2929

30-
#undef GOTO_END_ERROR
31-
#define GOTO_END_ERROR() do { \
32-
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__); \
33-
ret = false; \
34-
goto end; \
35-
} while (0)
36-
3730
#ifndef ARRAY_SIZE
3831
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
3932
#endif

0 commit comments

Comments
 (0)