Skip to content

Commit

Permalink
Introduce the lgpng_err enum
Browse files Browse the repository at this point in the history
Provides a more granular error system and allows to progressively remove
the fprintf in the library.
  • Loading branch information
tleguern committed Jun 14, 2023
1 parent 20f1caf commit 40fdd71
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 182 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ MANS= ${MAN1S}
REGRESS = regress/test-data \
regress/test-stream

all: lgpng.c liblgpng.a pngdump pngexplode pnginfo pngshuffle
all: lgpng.c liblgpng.a pngdump pngexplode pnginfo pngshuffle ${REGRESS}

regress: ${REGRESS}
@for f in ${REGRESS} ; do \
Expand Down
41 changes: 25 additions & 16 deletions lgpng.h
Original file line number Diff line number Diff line change
Expand Up @@ -687,24 +687,33 @@ int lgpng_create_waLV_from_data(struct waLV *, uint8_t *, size_t);
int lgpng_create_msOG_from_data(struct msOG *, uint8_t *, size_t);
int lgpng_create_tpNG_from_data(struct tpNG *, uint8_t *, size_t);

/* data */
bool lgpng_data_is_png(uint8_t *, size_t);
bool lgpng_data_get_length(uint8_t *, size_t, uint32_t *);
bool lgpng_data_get_type(uint8_t *, size_t, uint8_t [4]);
bool lgpng_data_get_data(uint8_t *, size_t, uint32_t, uint8_t **);
bool lgpng_data_get_crc(uint8_t *, size_t, uint32_t *);
int lgpng_data_write_sig(uint8_t *);
int lgpng_data_write_chunk(uint8_t *, uint32_t, uint8_t [4], uint8_t *, uint32_t);
enum lgpng_err {
LGPNG_OK = 0,
LGPNG_INVALID_PARAM,
LGPNG_TOO_SHORT,
LGPNG_INVALID_CHUNK_LENGTH,
LGPNG_INVALID_CHUNK_NAME,
/* Generic error, to be refined */
LGPNG_ERROR,
};

enum lgpng_err lgpng_data_is_png(uint8_t *, size_t);
enum lgpng_err lgpng_data_get_length(uint8_t *, size_t, uint32_t *);
enum lgpng_err lgpng_data_get_type(uint8_t *, size_t, uint8_t [4]);
enum lgpng_err lgpng_data_get_data(uint8_t *, size_t, uint32_t, uint8_t **);
enum lgpng_err lgpng_data_get_crc(uint8_t *, size_t, uint32_t *);
int lgpng_data_write_sig(uint8_t *);
int lgpng_data_write_chunk(uint8_t *, uint32_t, uint8_t [4], uint8_t *, uint32_t);

/* stream */
bool lgpng_stream_is_png(FILE *);
bool lgpng_stream_get_length(FILE *, uint32_t *);
bool lgpng_stream_get_type(FILE *, uint8_t [4]);
bool lgpng_stream_get_data(FILE *, uint32_t, uint8_t **);
bool lgpng_stream_skip_data(FILE *, uint32_t);
bool lgpng_stream_get_crc(FILE *, uint32_t *);
bool lgpng_stream_write_sig(FILE *);
bool lgpng_stream_write_chunk(FILE *, uint32_t, uint8_t [4], uint8_t *, uint32_t);
enum lgpng_err lgpng_stream_is_png(FILE *);
enum lgpng_err lgpng_stream_get_length(FILE *, uint32_t *);
enum lgpng_err lgpng_stream_get_type(FILE *, uint8_t [4]);
enum lgpng_err lgpng_stream_get_data(FILE *, uint32_t, uint8_t **);
enum lgpng_err lgpng_stream_skip_data(FILE *, uint32_t);
enum lgpng_err lgpng_stream_get_crc(FILE *, uint32_t *);
enum lgpng_err lgpng_stream_write_sig(FILE *);
enum lgpng_err lgpng_stream_write_chunk(FILE *, uint32_t, uint8_t [4], uint8_t *, uint32_t);

/* crc */
extern uint32_t lgpng_crc_table[256];
Expand Down
73 changes: 29 additions & 44 deletions lgpng_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,112 +18,97 @@

#include <ctype.h>
#include COMPAT_ENDIAN_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lgpng.h"

bool
enum lgpng_err
lgpng_data_is_png(uint8_t *src, size_t srcz)
{
if (NULL == src) {
return(false);
return(LGPNG_INVALID_PARAM);
}
if (srcz < 8) {
return(false);
return(LGPNG_TOO_SHORT);
}
if (memcmp(src, png_sig, sizeof(png_sig)) == 0)
return(true);
return(false);
return(LGPNG_OK);
return(LGPNG_ERROR);
}

bool
enum lgpng_err
lgpng_data_get_length(uint8_t *src, size_t srcz, uint32_t *length)
{
if (NULL == src) {
return(false);
}
if (NULL == length) {
return(false);
if (NULL == src || NULL == length) {
return(LGPNG_INVALID_PARAM);
}
if (srcz < 4) {
return(false);
return(LGPNG_TOO_SHORT);
}
/* Read the first four bytes to gather the length of the data part */
(void)memcpy(length, src, 4);
*length = be32toh(*length);
if (*length > INT32_MAX) {
fprintf(stderr, "Chunk length is too big (%u)\n", *length);
return(false);
return(LGPNG_INVALID_CHUNK_LENGTH);
}
return(true);
return(LGPNG_OK);
}

bool
enum lgpng_err
lgpng_data_get_type(uint8_t *src, size_t srcz, uint8_t name[4])
{
uint8_t type[4];
int err = LGPNG_OK;

if (NULL == src) {
return(false);
return(LGPNG_INVALID_PARAM);
}
if (srcz < 4) {
fprintf(stderr, "Not enough data to read chunk's type\n");
return(false);
return(LGPNG_TOO_SHORT);
}

(void)memcpy(type, src, 4);
for (size_t i = 0; i < 4; i++) {
/* Copy the chunk name even if invalid */
name[i] = type[i];
if (isalpha(type[i]) == 0) {
fprintf(stderr, "Invalid chunk type\n");
return(false);
err = LGPNG_INVALID_CHUNK_NAME;
}
}
for (size_t i = 0; i < 4; i++) {
name[i] = type[i];
}
return(true);
return(err);
}

bool
enum lgpng_err
lgpng_data_get_data(uint8_t *src, size_t srcz, uint32_t length, uint8_t **data)
{
if (NULL == src) {
return(false);
}
if (NULL == data) {
return(false);
if (NULL == src || NULL == data) {
return(LGPNG_INVALID_PARAM);
}
if (srcz < length) {
fprintf(stderr, "Not enough data to read chunk's data\n");
return(false);
return(LGPNG_TOO_SHORT);
}

if (0 != length) {
(void)memcpy((*data), src, length);
(*data)[length] = '\0';
}
return(true);
return(LGPNG_OK);
}

bool
enum lgpng_err
lgpng_data_get_crc(uint8_t *src, size_t srcz, uint32_t *crc)
{
if (NULL == src) {
return(false);
}
if (NULL == crc) {
return(false);
if (NULL == src || NULL == crc) {
return(LGPNG_INVALID_PARAM);
}
if (srcz < 4) {
fprintf(stderr, "Not enough data to read chunk's CRC\n");
return(false);
return(LGPNG_TOO_SHORT);
}

(void)memcpy(crc, src, 4);
*crc = be32toh(*crc);
return(true);
return(LGPNG_OK);
}

int
Expand Down
Loading

0 comments on commit 40fdd71

Please sign in to comment.