␉return 1;␊ |
}␊ |
␊ |
uint32_t vector8_resizev(vector8_t *p, size_t size, uint8_t value)␊ |
{␉// resize and give all new elements the value␊ |
␉size_t oldsize = p->size, i;␊ |
␉if (!vector8_resize(p, size))␊ |
␉␉return 0;␊ |
␉for (i = oldsize; i < size; i++)␊ |
␉␉p->data[i] = value;␊ |
␉return 1;␊ |
}␊ |
␊ |
void vector8_init(vector8_t *p)␊ |
{␊ |
␉p->data = NULL;␊ |
␉p->size = p->allocsize = 0;␊ |
}␊ |
␊ |
vector8_t *vector8_new(size_t size, uint8_t value)␊ |
{␊ |
␉vector8_t *p = png_alloc_malloc(sizeof (vector8_t));␊ |
␉if(!p)␊ |
␉{␊ |
␉␉return NULL;␊ |
␉}␊ |
␉vector8_init(p);␊ |
␉if (size && !vector8_resizev(p, size, value))␊ |
␉{␊ |
␉␉vector8_cleanup(p);␊ |
␉if (!p)␊ |
return NULL;␊ |
␉p->data = NULL;␊ |
␉p->size = p->allocsize = 0;␊ |
␉if (size) {␊ |
size_t i;␊ |
size_t newsize = size * sizeof (uint32_t) * 2;␊ |
void *data = png_alloc_malloc(newsize);␊ |
if (!data) {␊ |
␉␉png_alloc_free(p);␊ |
␉␉return NULL;␊ |
␉}␊ |
}␊ |
p->data = (uint8_t *) data;␊ |
p->allocsize = newsize;␊ |
p->size = size;␊ |
for (i = 0; i < size; ++i)␊ |
p->data[i] = value;␊ |
}␊ |
␉return p;␊ |
}␊ |
␊ |
|
int PNG_convert(const PNG_info_t *info, vector8_t *out, const uint8_t *in)␊ |
{␉// converts from any color type to 32-bit. return value = LodePNG error code␊ |
␉size_t i, c;␊ |
␉uint32_t bitDepth, colorType;␊ |
␉bitDepth = info->bitDepth;␊ |
␉colorType = info->colorType;␊ |
␉size_t numpixels = info->width * info->height, bp = 0;␊ |
␉vector8_resize(out, numpixels * 4);␊ |
␉uint8_t *out_data = out->size ? out->data : 0;␊ |
␉size_t numpixels = info->width * info->height;␊ |
if (!numpixels)␊ |
return 0; // nothing to do␊ |
␉if (!vector8_resize(out, numpixels * 4))␊ |
return 83; // out of memory␊ |
size_t bp = 0;␊ |
␉uint32_t bitDepth = info->bitDepth;␊ |
␉uint32_t colorType = info->colorType;␊ |
␉uint8_t *out_data = out->data;␊ |
␉if (bitDepth == 8 && colorType == 0) // greyscale␊ |
␉␉for (i = 0; i < numpixels; i++) {␊ |
␉␉␉out_data[4 * i + 0] = out_data[4 * i + 1] = out_data[4 * i + 2] = in[i];␊ |
|
␉␉return NULL;␊ |
␉size_t pos = 33; // first byte of the first chunk after the header␊ |
␉vector8_t *idat = NULL; // the data from idat chunks␊ |
␉bool IEND = false, known_type = true;␊ |
␉bool IEND = false;␊ |
␉info->key_defined = false;␊ |
␉// loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. IDAT data is␊ |
␉// put at the start of the in buffer␊ |
␉while (!IEND) {␊ |
␉␉size_t i, j;␊ |
␉␉size_t i;␊ |
␉␉if (pos + 8 >= size) {␊ |
␉␉␉PNG_error = 30; // error: size of the in buffer too small to contain next chunk␊ |
␉␉␉return NULL;␊ |
|
␉␉␉␉return NULL;␊ |
␉␉␉}␊ |
␉␉␉for (i = 0; i < info->palette->size; i += 4) {␊ |
size_t j;␊ |
␉␉␉␉for (j = 0; j < 3; j++)␊ |
␉␉␉␉␉info->palette->data[i + j] = in[pos++]; // RGB␊ |
␉␉␉␉info->palette->data[i + 3] = 255; // alpha␊ |
|
␉␉␉␉return NULL;␊ |
␉␉␉}␊ |
␉␉␉pos += (chunkLength + 4); // skip 4 letters and uninterpreted data of unimplemented chunk␊ |
␉␉␉known_type = false;␊ |
␉␉}␊ |
␉␉pos += 4; // step over CRC (which is ignored)␊ |
␉}␊ |
if (!idat) {␊ |
PNG_error = 1; // no data seen␊ |
return NULL;␊ |
}␊ |
␉uint32_t bpp = PNG_getBpp(info);␊ |
␉vector8_t *scanlines; // now the out buffer will be filled␊ |
␉scanlines = vector8_new(((info->width * (info->height * bpp + 7)) / 8) + info->height, 0);␊ |