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

📄 imgdcd_png_decode.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *    * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */#include <string.h>#include <jar.h>#include <pcsl_memory.h>#include <midp_logging.h>#include "imgdcd_intern_image_decode.h"#define UNDF_CHUNK 0x00000000#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) pcsl_mem_free((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 int   lineBytes[7];    unsigned int   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 bool handleImageData(unsigned char *, int, imageDstPtr, pngData *);static unsigned long getInt(imageSrcPtr);static unsigned long skip(imageSrcPtr, int, unsigned long);static bool getChunk(imageSrcPtr, unsigned long *, long *);static bool signatureOK(imageSrcPtr);static bool headerOK(pngData *);static unsigned long init_CRC(unsigned long);static bool 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;static intPNGdecodeImage_getByte(void *p){    idatInflateData *d = (idatInflateData *)p;    imageSrcPtr src = d->src;    unsigned long chunkType = UNDF_CHUNK;    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;}static longPNGdecodeImage_getBytes(void *p, unsigned char *buffer, long count){    idatInflateData *d = (idatInflateData *)p;    imageSrcPtr src = d->src;    unsigned long chunkType = UNDF_CHUNK;    /* 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 <= (int)count) {        count = d->clen;    }    count = (long)(src->getBytes(src, buffer, (int)count));    d->clen -= (int)count;    return count;}static long PNGdecodeImage_size(void* p) {    /* This function is not used by inflateData. */    (void)p;    return 0;}/* Emulates fseek. See fseek doc for offset and whence values. */static int PNGdecodeImage_seek(void* p, long offset, int whence) {    /* This function is not used by inflateData */    (void)p;    (void)offset;    (void)whence;    return -1;}/* returns a memory handle, call addrFromHandle to use */static void* allocFunction(void* state, int n) {    (void)state;    return pcsl_mem_malloc(n);}/* handle, is a memory handle */static void freeFunction(void* state, void* handle) {    (void)state;    pcsl_mem_free(handle);}/* This function is to support heaps that compact memory. */static void* addrFromHandleFunction(void* state, void* handle) {    (void)state;    return handle;}bool get_decoded_png_imagesize(imageSrcPtr src, int* width, int* height) {    unsigned long chunkType = UNDF_CHUNK;    long chunkLength;    unsigned long CRC;    pngData data;    if (!signatureOK(src)) {        /* not a PNG image */        return FALSE;    }    if (!getChunk(src, &chunkType, &chunkLength)) {        return FALSE;    }    CRC = init_CRC(chunkType);    if (chunkType != IHDR_CHUNK) {        return FALSE;    }            if (chunkLength < 13) {        return FALSE;    }    memset(&data, 0, sizeof(data));    CRC = readHeader(src, chunkLength, &data, CRC);    if (!headerOK(&data)) {        return FALSE;    }    *width = data.width;    *height = data.height;    return TRUE;}staticboolPNGdecodeImage_real(imageSrcPtr src, imageDstPtr dst, 		    long *paletteData, unsigned char *transData) {    bool       OK = TRUE;    bool saw_IDAT = FALSE,             saw_PLTE = FALSE,             saw_tRNS = FALSE;    pngData      data;    unsigned long chunkType = UNDF_CHUNK;    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 < 0) || (chunkLength > (256 * 3)) ||                    ((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 = 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 = TRUE;        } else if (chunkType == IDAT_CHUNK) {            idatInflateData  _data;            FileObj fileObj;            HeapManObj heapManObj;            int compLen = 0;            int decompLen = data.scanlength * data.height;            unsigned char *decompBuf;            long startPos = 0, lastGoodPos = 0;            saw_IDAT = 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*)pcsl_mem_malloc(decompLen);            if (decompBuf == NULL) {                OK = FALSE;		goto done;            }            /*             * inflate ignores the method and flags             */            compLen -= 2;	    PNGdecodeImage_getByte(&_data);	    PNGdecodeImage_getByte(&_data);            fileObj.state = &_data;            fileObj.size = PNGdecodeImage_size;            fileObj.read = PNGdecodeImage_getBytes;            fileObj.seek = PNGdecodeImage_seek;            fileObj.readChar = PNGdecodeImage_getByte;            heapManObj.state = NULL;            heapManObj.alloc = allocFunction;            heapManObj.free = freeFunction;            heapManObj.addrFromHandle = addrFromHandleFunction;            /* subtract 4 bytes from compLen -- it's the ZLIB trailer */            if (inflateData(&fileObj, &heapManObj, compLen - 4,                             decompBuf, decompLen, 0) != 0) {                freeBytes(decompBuf);		goto formaterror;	    }            OK = handleImageData(decompBuf, decompLen, dst, &data);

⌨️ 快捷键说明

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