⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pngdecode.c

📁 用于移动设备上的java虚拟机源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * @(#)pngDecode.c	1.30 02/09/17 @(#) * * Copyright (c) 2000-2002 Sun Microsystems, Inc.  All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. */#include <kni.h>#include <defaultLCDUI.h>#include <imageDecode.h>#include <midpMalloc.h>#include <midpServices.h>#define IHDR_CHUNK 0x49484452#define PLTE_CHUNK 0x504C5445#define IDAT_CHUNK 0x49444154#define IEND_CHUNK 0x49454E44#define tRNS_CHUNK 0x74524E53#define CT_PALETTE  0x01#define CT_COLOR    0x02#define CT_ALPHA    0x04#define freeBytes(p) midpFree((p))typedef struct _pngData {      signed int   width;      signed int   height;    /* current location, for writing pixels */             int   y;    unsigned int   scanlength;    unsigned short bytesPerPixel;    /* palette in stream is RGB (3 bytes) but we store it as XRGB (int) */             long *palette;    unsigned short paletteLength;    unsigned char *trans;    unsigned short transLength;    unsigned char  pass;         /* pass #, for interlace loading        */    unsigned char  depth;        /* bits per pixel: 1,2,4,8,16           */    unsigned char  colorType;    /* 1=palette  2=hasColor  4=hasAlpha    */    unsigned char  compress;     /* compression type, must be zero       */    unsigned char  filter;       /* filter type, must be zero            */    unsigned char  interlace;    /* interlacing: 0 (none) or 1 (adam7)   */    unsigned short lineBytes[7];    unsigned short passSize[7];} pngData;static unsigned long readHeader(imageSrcPtr, long, pngData *, unsigned long);static unsigned long readPalette(imageSrcPtr, long, pngData *,                                 long *, unsigned long);static unsigned long readTransPal(imageSrcPtr, long, pngData *,                                  unsigned char *, unsigned long);static jboolean handleImageData(unsigned char *, int, imageDstPtr, pngData *);static unsigned long getInt(imageSrcPtr);static unsigned long skip(imageSrcPtr, int, unsigned long);static jboolean getChunk(imageSrcPtr, unsigned long *, long *);static jboolean signatureOK(imageSrcPtr);static jboolean headerOK(pngData *);static unsigned long init_CRC(unsigned long);static jboolean check_CRC(imageSrcPtr, unsigned long);static unsigned long update_crc(unsigned long, unsigned char *, int);static int findPassWidth(int, pngData *);typedef struct _iid {    imageSrcPtr src;    long clen;} idatInflateData;unsigned intPNGdecodeImage_getByte(void *p){    idatInflateData *d = (idatInflateData *)p;    imageSrcPtr    src = d->src;    unsigned long chunkType;    unsigned int  byte;    /* while, because it's possible to have 0-length chunks! */    while (d->clen == 0) {        /* unsigned long CRC = */ (void)getInt(src);        getChunk(src, &chunkType, &(d->clen));        if (chunkType != IDAT_CHUNK) {            return -1;        }    }    --(d->clen);    byte = src->getByte(src);    return byte;}unsigned intPNGdecodeImage_getBytes(unsigned char *buffer, int count, void *p){    idatInflateData *d = (idatInflateData *)p;    imageSrcPtr    src = d->src;    unsigned long chunkType;    /* while, because it's possible to have 0-length chunks! */    while (d->clen == 0) {        /* unsigned long CRC = */ (void)getInt(src);        getChunk(src, &chunkType, &(d->clen));        if (chunkType != IDAT_CHUNK) {            return 0;        }    }    if (d->clen <= count) {        count = d->clen;    }    count = src->getBytes(src, buffer, count);    d->clen -= count;    return count;}jbooleanPNGdecodeImage_real(imageSrcPtr src, imageDstPtr dst, 		    long *paletteData, unsigned char *transData) {    jboolean       OK = KNI_TRUE;    jboolean saw_IDAT = KNI_FALSE,             saw_PLTE = KNI_FALSE,             saw_tRNS = KNI_FALSE;    pngData      data;    unsigned long chunkType;    long chunkLength;    unsigned long CRC;    if (!signatureOK(src)) {        goto formaterror;               /* not a PNG image */    }    memset(&data, 0, sizeof(data));    while (getChunk(src, &chunkType, &chunkLength)) {        CRC = init_CRC(chunkType);        if (chunkType == IHDR_CHUNK) {            /* size of header is known.  headerOK => IHDR_CHUNK already seen */            if ((chunkLength < 13) || headerOK(&data)) {                goto formaterror;            }            CRC = readHeader(src, chunkLength, &data, CRC);            if (!headerOK(&data)) {                goto formaterror;            }            dst->setSize(dst, data.width, data.height);            if ((data.colorType & CT_COLOR) == 0) {                /* grayscale--set up a palette */                int n = 0;                long _p[4];                switch (data.depth) {                case 1:                    _p[0] = 0;                    _p[1] = 0xffffff;                    n = 2;                    dst->setColormap(dst, _p, n);                    break;                case 2:                    _p[0] = 0;                    _p[1] = 0x555555;                    _p[2] = 0xaaaaaa;                    _p[3] = 0xffffff;                    n = 4;                    dst->setColormap(dst, _p, n);                    break;                case 4:                    {                    long p[16];                    for (n = 0; n < 16; ++n) {                        p[n] = n*0x111111;                    }                    dst->setColormap(dst, p, n);                    }                    break;                default:                    {                    long p[256];                    for (n = 0; n < 256; ++n) {                        p[n] = (n << 16) | (n << 8) | n;                    }                    dst->setColormap(dst, p, n);                    }                    break;                }            }        } else if (chunkType == PLTE_CHUNK) {            if ((chunkLength > 768) || ((chunkLength % 3) != 0)) {                goto formaterror;            }            if ((data.paletteLength > 0) || saw_IDAT || saw_tRNS) {                goto formaterror;            }            CRC = readPalette(src, chunkLength, &data, paletteData, CRC);            if (data.palette == NULL) {                goto formaterror;            }            if (data.colorType & CT_PALETTE) {                dst->setColormap(dst, data.palette, data.paletteLength);            }            saw_PLTE = KNI_TRUE;        } else if (chunkType == tRNS_CHUNK) {            if (saw_IDAT || data.colorType == 4                          || data.colorType == 6) {                goto formaterror;            }            CRC = readTransPal(src, chunkLength, &data, transData, CRC);            if (data.trans == NULL) {                goto formaterror;            }            dst->setTransMap(dst, data.trans, data.transLength,                             saw_PLTE ? data.paletteLength : -1);            saw_tRNS = KNI_TRUE;        } else if (chunkType == IDAT_CHUNK) {            idatInflateData  _data;            int compLen = 0;            int decompLen = data.scanlength * data.height;            unsigned char *decompBuf;            long startPos = 0, lastGoodPos = 0;            saw_IDAT = KNI_TRUE;            if (data.interlace) {                int i;                /* decompLen is harder to calculate--there are extra rows! */                decompLen = 0;                for (i = 0; i < 7; ++i) {                    int off    = 7 >> (i/2);            /* 7 7 3 3 1 1 0 */                    int shift  = 3 - (((i - 1) / 2));   /* 3 3 3 2 2 1 1 */                    int height = ((data.height + off) >> shift);                    int width  = findPassWidth(i, &data);                    data.lineBytes[i] = width;                    data.passSize[i]  = width * height;                    decompLen += data.passSize[i];                }            } else {                data.lineBytes[6] = data.scanlength;                data.passSize[6]  = decompLen;            }            if ((data.colorType & CT_PALETTE) && (data.palette == NULL)) {                goto formaterror;            }            /*             * we need to decompress all of the IDAT chunks en masse.             * first step is to find out how much actual data there is.             * While we're at it, we can look at the CRCs for all of             * the blocks.             */            _data.src  = src;            _data.clen = chunkLength;            lastGoodPos = startPos = src->getpos(src);            do {                /* Make sure we only process IDAT chunks */                if (chunkType != IDAT_CHUNK) break;                CRC = init_CRC(chunkType);                compLen += chunkLength;                CRC = skip(src, chunkLength, CRC);                lastGoodPos = src->getpos(src);                if (!check_CRC(src, CRC)) {                    goto formaterror;                }            } while (getChunk(src, &chunkType, &chunkLength));            /*             * IMPORTANT: CRC now contains the correct value for             * the last IDAT_CHUNK.  This is checked at the bottom             * of the loop so it must contain the right value.             */            src->seek(src, startPos);    /* reset to the first IDAT_CHUNK */            decompBuf = (unsigned char*)midpMalloc(decompLen);            if (decompBuf == NULL) {                OK = KNI_FALSE;		goto done;            }            /*             * inflate ignores the method and flags             */            compLen -= 2;	    PNGdecodeImage_getByte(&_data);	    PNGdecodeImage_getByte(&_data);            /* subtract 4 bytes from compLen -- it's the ZLIB trailer */            if (!midp_pngInflate(&_data, compLen - 4, &decompBuf, decompLen)) {                freeBytes(decompBuf);		goto formaterror;	    }                        OK = handleImageData(decompBuf, decompLen, dst, &data);            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)) {            /* fprintf(stderr, "PNG data corrupted (CRC mismatch)\n"); */            goto formaterror;        }    } done:    return OK; formaterror:    OK = KNI_FALSE;    KNI_ThrowNew("java/lang/IllegalArgumentException", "");    goto done;}jbooleanPNGdecodeImage(imageSrcPtr src, imageDstPtr dst) {    long * paletteData;    unsigned char * transData;    paletteData = midpMalloc(sizeof(long) * 256);    if (paletteData == NULL) {	/* out of memory */	return KNI_FALSE;    } else {	transData = midpMalloc(sizeof(unsigned char) * 256);	if (transData == NULL) {	    /* out of memory */	    midpFree(paletteData);	    return KNI_FALSE;	} else {	    jboolean retval = PNGdecodeImage_real(src, dst, 						  paletteData, transData);	    midpFree(paletteData);	    midpFree(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 char *pStartX = "\000\004\000\002\000\001\000\000";static char *pIncX   = "\010\010\004\004\002\002\001\001";/* pass number            1   2   3   4   5   6   7   - *//* static char *pStartY = "\000\000\004\000\002\000\001\000"; *//* static char *pIncY   = "\010\010\010\004\004\002\002\001"; */static intfindPassWidth(int pass, pngData *data){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -