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

📄 palmtopnm.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
static voidcreateHistogram(unsigned int    const ncolors,                unsigned int ** const seenP) {    unsigned int * seen;    MALLOCARRAY(seen, ncolors);    if (!seen)        pm_error("Can't allocate array for keeping track of "                 "how many pixels of each of %u colors are in the image.",                  ncolors);    {            /* Initialize the counter for each color to zero */        unsigned int i;        for (i = 0; i < ncolors; ++i)            seen[i] = 0;    }    *seenP = seen;}static voidreadRleRow(FILE *          const ifP,           unsigned char * const palmrow,           unsigned int    const bytesPerRow) {    unsigned int j;    for (j = 0;  j < bytesPerRow; ) {        unsigned int const incount = fgetc(ifP);        unsigned int const inval   = fgetc(ifP);        memset(palmrow + j, inval, incount);        j += incount;    }} static voidreadScanlineRow(FILE *          const ifP,                unsigned char * const palmrow,                unsigned char * const lastrow,                unsigned int    const bytesPerRow,                bool            const firstRow) {    unsigned int j;    unsigned int incount, inval;    unsigned char inbit;    for (j = 0;  j < bytesPerRow;  j += 8) {        incount = fgetc(ifP);        inval   = MIN(bytesPerRow - j, 8);                for (inbit = 0;  inbit < inval;  inbit += 1) {            /* the first row cannot be compressed */            if (firstRow || ((incount & (1 << (7 - inbit))) != 0))                palmrow[j + inbit] = fgetc(ifP);            else                palmrow[j + inbit] = lastrow[j + inbit];        }    }    memcpy(lastrow, palmrow, bytesPerRow);}static voidreadUncompressedRow(FILE *          const ifP,                    unsigned char * const palmrow,                    unsigned int    const bytesPerRow) {    int bytesRead;        bytesRead = fread(palmrow, 1, bytesPerRow, ifP);    if (bytesRead != bytesPerRow)        pm_error("Error reading Palm file.  Short read.");}static voidreadDecompressedRow(FILE *                   const ifP,                    unsigned char *          const palmrow,                    unsigned char *          const lastrow,                    enum palmCompressionType const compressionType,                    unsigned int             const bytesPerRow,                    bool                     const firstRow,                    bool                     const verbose) {    switch (compressionType) {    case COMPRESSION_RLE:        readRleRow(ifP, palmrow, bytesPerRow);        break;    case COMPRESSION_SCANLINE:        readScanlineRow(ifP, palmrow, lastrow, bytesPerRow, firstRow);        break;    case COMPRESSION_PACKBITS:        pm_error("INTERNAL ERROR: impossible value of compressionType");        break;    case COMPRESSION_NONE:        readUncompressedRow(ifP, palmrow, bytesPerRow);        break;    }}static voidconvertRowToPnmDirect(const unsigned char * const palmrow,                      xel *                 const xelrow,                      unsigned int          const cols,                      xelval                const maxval,                      unsigned int *        const seen) {    /* There's a problem with this.  Take the Palm 16-bit       direct color.  That's 5 bits for the red, 6 for the       green, and 5 for the blue.  So what should the MAXVAL       be?  I decided to use 255 (8 bits) for everything,       since that's the theoretical max of the number of bits       in any one color, according to Palm.  So the Palm color       0xFFFF (white) would be red=0x1F, green=0x3F, and       blue=0x1F.  How do we promote those colors?  Simple       shift would give us R=248,G=252,B=248; which is       slightly green.  Hardly seems right.              So I've perverted the math a bit.  Each color value is       multiplied by 255, then divided by either 31 (red or       blue) or 63 (green).  That's the right way to do it       anyway.      */    const unsigned char *inbyte;    unsigned int j;        for (inbyte = palmrow, j = 0;  j < cols;  ++j) {        unsigned int inval;        inval = *inbyte++ << 8;        inval |= *inbyte++;                if (seen)            ++seen[inval];                PPM_ASSIGN(xelrow[j],                    (((inval >> 11) & 0x1F) * maxval) / 0x1F,                    (((inval >>  5) & 0x3F) * maxval) / 0x3F,                    (((inval >>  0) & 0x1F) * maxval) / 0x1F            );    }}static voidconvertRowToPnmNotDirect(const unsigned char * const palmrow,                         xel *                 const xelrow,                         unsigned int          const cols,                         Colormap              const colormap,                         xelval *              const graymap,                         unsigned int *        const seen,                         unsigned int          const pixelSize) {    unsigned int const mask = (1 << pixelSize) - 1;    const unsigned char *inbyte;    unsigned int inbit;    unsigned int j;        inbit = 8 - pixelSize;    inbyte = palmrow;    for (j = 0; j < cols; ++j) {        short const color = ((*inbyte) & (mask << inbit)) >> inbit;        if (seen)            ++seen[color];                if (colormap) {            Color_s const color2      = color << 24;            Color   const actualColor = (bsearch (&color2,                                                  colormap->color_entries,                                                   colormap->ncolors,                                                  sizeof(color2),                                                   palmcolor_compare_indices));            PPM_ASSIGN(xelrow[j],                        (*actualColor >> 16) & 0xFF,                        (*actualColor >>  8) & 0xFF,                        (*actualColor >>  0) & 0xFF);        } else            PNM_ASSIGN1(xelrow[j], graymap[color]);                if (!inbit) {            ++inbyte;            inbit = 8 - pixelSize;        } else            inbit -= pixelSize;    }}static voidwritePnm(struct palmHeader const palmHeader,         FILE *            const ifP,         Colormap          const colormap,         xelval *          const graymap,         unsigned int      const nColors,         int               const format,         xelval            const maxval,         unsigned int **   const seenP,         bool              const verbose) {    int const cols = palmHeader.cols;    int const rows = palmHeader.rows;    unsigned char * palmrow;    unsigned char * lastrow;    xel *           xelrow;    unsigned int *  seen;    unsigned int    row;        pnm_writepnminit(stdout, cols, rows, maxval, format, 0);    xelrow = pnm_allocrow(cols);    /* Read the picture data, one row at a time */    MALLOCARRAY_NOFAIL(palmrow, palmHeader.bytesPerRow);    MALLOCARRAY_NOFAIL(lastrow, palmHeader.bytesPerRow);         if (seenP) {        createHistogram(nColors, &seen);        *seenP = seen;    } else        seen = NULL;    if (palmHeader.compressionType != COMPRESSION_NONE) {        if (palmHeader.version < 3) {            short compressedDataSize16;            pm_readbigshort(ifP, &compressedDataSize16);        } else {            long compressedDataSize32;            pm_readbiglong(ifP, &compressedDataSize32);        }    }    for (row = 0; row < rows; ++row) {        readDecompressedRow(ifP, palmrow, lastrow,                             palmHeader.compressionType,                             palmHeader.bytesPerRow,                            row == 0, verbose);        if (palmHeader.flags & PALM_DIRECT_COLOR) {            assert(palmHeader.pixelSize == 16);            convertRowToPnmDirect(palmrow, xelrow, cols, maxval, seen);        } else            convertRowToPnmNotDirect(palmrow, xelrow, cols, colormap, graymap,                                     seen, palmHeader.pixelSize);        pnm_writepnmrow(stdout, xelrow, cols, maxval, format, 0);    }    free(lastrow);    free(palmrow);    pnm_freerow(xelrow);}static voidshowHistogram(unsigned int * const seen,              Colormap       const colormap,              const xelval * const graymap,              unsigned int   const ncolors) {    unsigned int colorIndex;        for (colorIndex = 0;  colorIndex < ncolors; ++colorIndex) {        if (!colormap)            pm_message("%.3d -> %.3d:  %d",                        colorIndex, graymap[colorIndex], seen[colorIndex]);        else {            Color_s const color = colorIndex << 24;            Color const actualColor = (bsearch(&color,                                               colormap->color_entries,                                                colormap->ncolors,                                               sizeof(color),                                                palmcolor_compare_indices));            if (actualColor)                pm_message("%.3d -> %ld,%ld,%ld:  %d", colorIndex,                           (*actualColor >> 16) & 0xFF,                           (*actualColor >> 8) & 0xFF,                           (*actualColor & 0xFF), seen[colorIndex]);        }    }}intmain(int argc, char **argv) {    struct cmdlineInfo cmdline;    FILE* ifP;    struct palmHeader palmHeader;    Colormap colormap;    struct directColorInfo directColorInfo;    int format;    xelval maxval;    unsigned int nColors;    /* Parse default params */    pnm_init(&argc, argv);    parseCommandLine(argc, argv, &cmdline);    ifP = pm_openr(cmdline.inputFilespec);    readHeader(ifP, cmdline.rendition, &palmHeader);        if (cmdline.verbose)        reportPalmHeader(palmHeader);    if (palmHeader.compressionType == COMPRESSION_PACKBITS)        pm_error("The image is compression with the packbits method.  "                 "This program does not know how to read that.");    if ((palmHeader.flags & PALM_DIRECT_COLOR) &&        palmHeader.pixelSize != 16)        pm_error("The image is of the direct color type, but has %u "                 "bits per pixel.  The only kind of direct color images "                 "this program understands are 16 bit ones.",                  palmHeader.pixelSize);    determineOutputFormat(palmHeader, &format, &maxval);        getColorInfo(palmHeader, ifP, &colormap, &nColors, &directColorInfo);    if (cmdline.transparent)        doTransparent(palmHeader.flags, palmHeader.transparentIndex,                       palmHeader.pixelSize, colormap, directColorInfo);    else {        unsigned int * seen;        xelval * graymap;        graymap = createGraymap(nColors, 0, maxval);        writePnm(palmHeader, ifP, colormap, graymap, nColors, format, maxval,                  cmdline.showhist ? &seen : NULL,                 cmdline.verbose);                if (cmdline.showhist)            showHistogram(seen, colormap, graymap, nColors);                free(graymap);    }    pm_close(ifP);    return 0;}

⌨️ 快捷键说明

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