📄 imgdcd_png_decode.c
字号:
freeBytes(decompBuf); src->seek(src, lastGoodPos); } else if (chunkType == IEND_CHUNK) { /* shouldn't happen because getChunk checks for this! */ } else { /* unrecognized -- skip */ CRC = skip(src, chunkLength, CRC); } if (!check_CRC(src, CRC)) { REPORT_WARN1(LC_LOWUI, "PNG data corrupted (CRC mismatch for a chunk of 0x%X type)", chunkType); /* interrupt image decoding only if the chunk is critical */ if (chunkType == IHDR_CHUNK) { goto formaterror; } } } // No chunks or other content follow the IEND chunk if (chunkType != IEND_CHUNK) { goto formaterror; } done: return OK; formaterror: OK = FALSE; goto done;}booldecode_png_image(imageSrcPtr src, imageDstPtr dst) { long * paletteData; unsigned char * transData; paletteData = pcsl_mem_malloc(sizeof(long) * 256); if (paletteData == NULL) { /* out of memory */ return FALSE; } else { transData = pcsl_mem_malloc(sizeof(unsigned char) * 256); if (transData == NULL) { /* out of memory */ pcsl_mem_free(paletteData); return FALSE; } else { bool retval = PNGdecodeImage_real(src, dst, paletteData, transData); pcsl_mem_free(paletteData); pcsl_mem_free(transData); return retval; } }}/** Interlacing parameters for ADAM7 interlace pattern:** 1 6 4 6 2 6 4 6* 7 7 7 7 7 7 7 7* 5 6 5 6 5 6 5 6* 7 7 7 7 7 7 7 7* 3 6 4 6 3 6 4 6* 7 7 7 7 7 7 7 7* 5 6 5 6 5 6 5 6* 7 7 7 7 7 7 7 7**/static const char * const pStartX = "\000\004\000\002\000\001\000\000";static const char * const pIncX = "\010\010\004\004\002\002\001\001";/* pass number 1 2 3 4 5 6 7 - *//* static const char * const pStartY = "\000\000\004\000\002\000\001\000"; *//* static const char * const pIncY = "\010\010\010\004\004\002\002\001"; */static intfindPassWidth(int pass, pngData *data){ int ix = ((pass < 0) || (pass > 7)) ? 7 : pass; int pixels = (data->width - pStartX[ix] + pIncX[ix] - 1) / pIncX[ix]; int channels = (data->colorType & CT_COLOR) ? 3 : 1; if (data->colorType & CT_ALPHA) ++channels; if (data->colorType & CT_PALETTE) channels = 1; /* palette is always 1 channel */ if (pixels <= 0) { return 0; } return 1 + ((pixels*data->depth*channels + 7) >> 3);}static unsigned longreadHeader(imageSrcPtr src, long length, pngData *data, unsigned long CRC){ unsigned char buf[13]; src->getBytes(src, buf, sizeof(buf)); data->width = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; data->height = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; data->depth = buf[8]; data->colorType = buf[9]; data->compress = buf[10]; data->filter = buf[11]; data->interlace = buf[12];#if REPORT_LEVEL <= LOG_INFORMATION reportToLog(LOG_INFORMATION, LC_LOWUI, "reading PNG image, %dx%dx%d%s%s%s%s\n", data->width, data->height, data->depth, data->colorType & CT_PALETTE ? " palette" : "", data->colorType & CT_COLOR ? " color" : " grayscale", data->colorType & CT_ALPHA ? " w/alpha" : "", data->interlace ? ", INTERLACED" : "");#endif if (data->interlace) { data->pass = 0; } else { data->pass = 7; } switch (data->colorType) { case 0: case 3: data->bytesPerPixel = (data->depth + 7) / 8; break; case 2: data->bytesPerPixel = 3*data->depth / 8; break; case 4: data->bytesPerPixel = data->depth / 4; break; case 6: data->bytesPerPixel = data->depth / 2; break; } data->scanlength = findPassWidth(6, data); /* pass 6 => no windowing */ CRC = update_crc(CRC, buf, sizeof(buf)); length -= sizeof(buf); while (length > 0) { int n = (length < (long)sizeof(buf)) ? length : (long)sizeof(buf); src->getBytes(src, buf, n); CRC = update_crc(CRC, buf, n); } return CRC;}static unsigned longreadPalette(imageSrcPtr src, long length, pngData *data, long *buffer, unsigned long CRC){ int i; data->paletteLength = (unsigned short)(length / 3); data->palette = buffer; for (i = 0; i < data->paletteLength; ++i) { unsigned char buf[3]; src->getBytes(src, buf, 3); CRC = update_crc(CRC, buf, 3); data->palette[i] = (buf[0] << 16) | (buf[1] << 8) | buf[2]; } return CRC;}static unsigned longreadTransPal(imageSrcPtr src, long length, pngData *data, unsigned char *buffer, unsigned long CRC){ int i; data->transLength = (unsigned short)length; data->trans = buffer; if (data->colorType & CT_PALETTE) { /* palette */ for (i = 0; i < data->transLength; i++) { unsigned char buf[1]; buf[0] = src->getByte(src); CRC = update_crc(CRC, buf, 1); data->trans[i] = buf[0]; } } else if ((data->colorType & CT_COLOR) == 0) { /* grayscale */ unsigned char buf[2]; src->getBytes(src, buf, 2); CRC = update_crc(CRC, buf, 2); data->trans[0] = buf[0]; data->trans[1] = buf[1]; data->transLength = 2; } else if (data->colorType & CT_COLOR) { /* truecolor */ unsigned char buf[6]; src->getBytes(src, buf, 6); CRC = update_crc(CRC, buf, 6); data->trans[0] = buf[0]; data->trans[1] = buf[1]; data->trans[2] = buf[2]; data->trans[3] = buf[3]; data->trans[4] = buf[4]; data->trans[5] = buf[5]; data->transLength = 6; } return CRC;}static voidapplyFilter(int filterType, unsigned char *buf, int n, unsigned char *prev, int bpp){ int x; if (filterType == 0) { return; } else if (prev == NULL) { if (filterType == 4) { filterType = 1; } else if (filterType == 3) { for (x = bpp; x < n; ++x) { buf[x] += buf[x - bpp] >> 1; } return; } else if (filterType == 2) { return; } } switch (filterType) { case 1: /* * We start at x == bpp because for x < bpp, buf[x - bpp] is * to be treated as zero. */ for (x = bpp; x < n; ++x) { buf[x] += buf[x - bpp]; } break; case 2: for (x = 0; x < n; ++x) { buf[x] += prev[x]; } break; case 3: /* * There is no valid "buf[x - bpp]" until (x == bpp), so the * first few values are treated as zero. */ for (x = 0; x < bpp; ++x) { buf[x] += prev[x] >> 1; } /* * But for x >= bpp we can do the full computation. */ for (x = bpp; x < n; ++x) { buf[x] += (prev[x] + (buf[x - bpp])) >> 1; } break; case 4: /* * There is no valid "buf[x - bpp]" or "prev[x - bpp]" until * (x == bpp). In the meantime, those values are treated as * zeroes, which causes the Paeth predictor to degenerate to * the value prev[x]. (Set a and c to zero and try it.) */ for (x = 0; x < bpp; ++x) { buf[x] += prev[x]; } /* * Now we can do the full computation. */ for (x = bpp; x < n; ++x) { int a, b, c, p, pa, pb, pc; a = buf[x - bpp]; b = prev[x]; c = prev[x - bpp]; p = a + b - c; pa = p > a ? p - a : a - p; pb = p > b ? p - b : b - p; pc = p > c ? p - c : c - p; buf[x] += ((pa <= pb) && (pa <= pc)) ? a : ((pb <= pc) ? b : c); } break; default: REPORT_WARN1(LC_LOWUI, "Illegal filter value %d\n", filterType); break; }}static voidfilterAllRows(unsigned char *pixels, pngData *data) { if (data->interlace) { int pass = 0; while (pass <= 6) { int n = data->lineBytes[pass]; unsigned char *end = pixels + data->passSize[pass]; unsigned char *rowBuf = pixels; unsigned char *prevRow = NULL; while (rowBuf < end) { applyFilter(rowBuf[0], rowBuf + 1, n - 1, prevRow, data->bytesPerPixel); prevRow = rowBuf + 1; rowBuf += n; } pixels = end; ++pass; } } else { unsigned char *rowBuf = pixels; unsigned char *prevRow = NULL; int n = data->lineBytes[6]; int y; for (y = 0; y < data->height; ++y) { applyFilter(rowBuf[0], rowBuf + 1, n - 1, prevRow, data->bytesPerPixel); prevRow = rowBuf + 1; rowBuf += n; } }}#define INIT_TRANS_PACK_RGB(b, x, a) \ (x) = ((b) > 8) ? 1 : 0; \ (a) = ((b) > 8) ? 6 : 3#define TRANS_PACK_RGB(d, s, x, a, tmap) \ *(d)++ = (s)[0]; \ *(d)++ = (s)[1 << x]; \ *(d)++ = (s)[2 << x]; \ if(x) { \ *(d)++ = (memcmp(s,tmap,a)) ? 0xFF: 0x00; \ } else { \ *(d)++ = ((s[0] == tmap[1]) && \ (s[1] == tmap[3]) && \ (s[2] == tmap[5])) \ ? 0x00: 0xFF; \ } \ (s) += (a)#define INIT_TRANS_PACK_GS(b, x, a) \ (x) = ((b) > 8) ? 1 : 0; \ (a) = ((b) > 8) ? 2 : 1#define TRANS_PACK_GS(d, s, x, a, tmap) \ *(d)++ = (s)[0]; \ if(x) { \ *(d)++ = ((s[0] == tmap[0]) && \ (s[1] == tmap[1]) ) \ ? 0x00: 0xFF; \ } else { \ *(d)++ = ((s[1] == tmap[1])) \ ? 0x00: 0xFF; \ } \ (s) += (a)#define INIT_TRANS_UNPACK_GS(b, x, m) \ (x) = (8 - (b)); \ (m) = 0xff ^ (0xff >> (x))#define TRANS_UNPACK_GS(d, s, x, m, b, x0, m0, tmap) \ *(d)++ = ((*s) & (m)) >> (x); \ *(d) = (*(d-1) == tmap[1]) \ ? 0x00 : 0xFF; \ (d)++; \ if (x) { \ (m) >>= (b); \ (x) -= (b); \ } else { \ (x) = (x0); \ (m) = (m0); \ ++(s); \ }#define INIT_UNPACK(b, x, m) \ (x) = (8 - (b)); \ (m) = 0xff ^ (0xff >> (x))#define UNPACK(d, s, x, m, b, x0, m0) \ *(d)++ = ((*s) & (m)) >> (x); \ if (x) { \ (m) >>= (b); \ (x) -= (b); \ } else { \ (x) = (x0); \ (m) = (m0); \ ++(s); \ }#define INIT_PACK3(b, t, x, a) \ (x) = ((b) > 8) ? 1 : 0; \ (a) = ((t) ? 4 : 3) << (x)#define PACK3(d, s, x, a, cta) \ *(d)++ = (s)[0]; \ *(d)++ = (s)[1 << x]; \ *(d)++ = (s)[2 << x]; \ if (cta) *(d)++ = (s)[3 << x]; \ (s) += (a)#define INIT_PACK1(b, t, x, a) \ (x) = ((b) > 8) ? 1 : 0; \ (a) = ((t) ? 2 : 1) << (x)#define PACK1(d, s, x, a, cta) \ *(d)++ = (s)[0]; \ if (cta) *(d)++ = (s)[1 << x]; \ (s) += (a)static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -