Skip to content

Commit

Permalink
Support png bit depths 1, 2 and 4
Browse files Browse the repository at this point in the history
  • Loading branch information
DusanJovic-NOAA committed Oct 3, 2024
1 parent e3c68dd commit bc6c302
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 10 deletions.
19 changes: 13 additions & 6 deletions src/decenc_png.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ dec_png(unsigned char *pngbuf, g2int *width, g2int *height,
unsigned char *cout)
{
int interlace, color, compres, filter, bit_depth;
g2int j, k, n, bytes, clen;
g2int j, k, n, bytes;
png_structp png_ptr;
png_infop info_ptr, end_info;
png_bytepp row_pointers;
Expand Down Expand Up @@ -171,11 +171,13 @@ dec_png(unsigned char *pngbuf, g2int *width, g2int *height,

/* Copy image data to output string */
n = 0;
bytes = bit_depth / 8;
clen = (*width) * bytes;
bytes = (*width * bit_depth) / 8;
if ((*width * bit_depth) % 8 != 0) {
bytes++;
}
for (j = 0; j < *height; j++)
{
for (k = 0; k < clen; k++)
for (k = 0; k < bytes; k++)
{
cout[n] = *(row_pointers[j] + k);
n++;
Expand Down Expand Up @@ -254,10 +256,15 @@ enc_png(unsigned char *data, g2int width, g2int height, g2int nbits,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

/* Put image data into the PNG info structure. */
bytes = nbits / 8;
bytes = (width * nbits) / 8;
if ((width * nbits) % 8 != 0) {
bytes++;
}

row_pointers = malloc(height * sizeof(png_bytep));
for (j = 0; j < height; j++)
row_pointers[j] = (png_bytep *)(data + (j * width * bytes));
row_pointers[j] = (png_bytep *)(data + (j * bytes));

png_set_rows(png_ptr, info_ptr, (png_bytepp)row_pointers);

/* Do the PNG encoding, and write out PNG stream. */
Expand Down
17 changes: 14 additions & 3 deletions src/pngpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,13 @@ pngpack_int(void *fld, int fld_is_double, g2int width, g2int height, g2int *idrs

/* Pack data into full octets, then do PNG encode and
* calculate the length of the packed data in bytes. */
if (nbits <= 8)
if (nbits <= 1)
nbits = 1;
else if (nbits <= 2)
nbits = 2;
else if (nbits <= 4)
nbits = 4;
else if (nbits <= 8)
nbits = 8;
else if (nbits <= 16)
nbits = 16;
Expand All @@ -177,9 +183,14 @@ pngpack_int(void *fld, int fld_is_double, g2int width, g2int height, g2int *idrs
else
nbits = 32;

nbytes = (nbits / 8) * ndpts;
int bytes_per_row = (nbits * width) / 8;
if ((width * nbits) % 8 != 0) {
bytes_per_row++;
}
nbytes = bytes_per_row * height;
ctemp = calloc(nbytes, 1);
sbits(ctemp, ifld, 0, nbits, 0, ndpts);
for (j = 0; j < height; j++)
sbits(ctemp + (j * bytes_per_row), ifld + (j * width), 0, nbits, 0, width);

/* Encode data into PNG Format. */
if ((*lcpack = (g2int)enc_png(ctemp, width, height, nbits, cpack)) <= 0)
Expand Down
10 changes: 9 additions & 1 deletion src/pngunpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,15 @@ pngunpack_int(unsigned char *cpack, g2int len, g2int *idrstmpl, g2int ndpts,
return G2C_ENOMEM;
}
dec_png(cpack, &width, &height, ctemp);
gbits(ctemp, ifld, 0, nbits, 0, ndpts);

int bytes_per_row = (nbits * width) / 8;
if ((width * nbits) % 8 != 0) {
bytes_per_row++;
}
for (j = 0; j < height; j++) {
gbits(ctemp + (j * bytes_per_row), ifld + (j * width), 0, nbits, 0, width);
}

for (j = 0; j < ndpts; j++)
{
if (fld_is_double)
Expand Down

0 comments on commit bc6c302

Please sign in to comment.