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

📄 pnmtopalm.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (directColor) {        if (bpp == 16) {            fputc(5, stdout);   /* # of bits of red */            fputc(6, stdout);   /* # of bits of green */                fputc(5, stdout);   /* # of bits of blue */            fputc(0, stdout);   /* reserved by Palm */        } else            pm_error("Don't know how to create %d bit DirectColor bitmaps.",                      bpp);        if (transparent) {            fputc(0, stdout);            fputc((PPM_GETR(transcolor) * 255) / maxval, stdout);            fputc((PPM_GETG(transcolor) * 255) / maxval, stdout);            fputc((PPM_GETB(transcolor) * 255) / maxval, stdout);        } else            pm_writebiglong(stdout, 0);     /* no transparent color */    }}static voidwriteSize(bool const scanline_compression,          bool const rle_compression) {        unsigned int compressedSize = 0;    /* Quick hack -- at least some readers can read these images.  The       full job requires knowing at this point in the processing how big       the compressed image will be.    */    if (scanline_compression || rle_compression)         pm_writebigshort(stdout, compressedSize); }static voidcomputeRawRowDirectColor(const xel *     const xelrow,                         unsigned int    const cols,                         xelval          const maxval,                         unsigned char * const rowdata) {    unsigned int col;    unsigned char *outptr;        for (col = 0, outptr = rowdata; col < cols; ++col) {        unsigned int const color =             ((((PPM_GETR(xelrow[col])*31)/maxval) << 11) |             (((PPM_GETG(xelrow[col])*63)/maxval) << 5) |             ((PPM_GETB(xelrow[col])*31)/maxval));        *outptr++ = (color >> 8) & 0xFF;        *outptr++ = color & 0xFF;    }}static voidcomputeRawRowNonDirect(const xel *     const xelrow,                       unsigned int    const cols,                       xelval          const maxval,                       unsigned int    const bpp,                       Colormap        const colormap,                       unsigned int    const newMaxval,                       unsigned char * const rowdata) {    unsigned int col;    unsigned char *outptr;    unsigned char outbyte;        /* Accumulated bits to be output */    unsigned char outbit;        /* The lowest bit number we want to access for this pixel */    outbyte = 0x00;    outptr = rowdata;    for (outbit = 8 - bpp, col = 0; col < cols; ++col) {        unsigned int color;        if (!colormap) {            /* we assume grayscale, and use simple scaling */            color = (PNM_GET1(xelrow[col]) * newMaxval)/maxval;            if (color > newMaxval)                pm_error("oops.  Bug in color re-calculation code.  "                         "color of %u.", color);            color = newMaxval - color; /* note grayscale maps are inverted */        } else {            Color_s const temp_color =                ((((PPM_GETR(xelrow[col])*newMaxval)/maxval)<<16)                  | (((PPM_GETG(xelrow[col])*newMaxval)/maxval)<<8)                 | (((PPM_GETB(xelrow[col])*newMaxval)/maxval)));            Color const found = (bsearch (&temp_color,                                          colormap->color_entries,                                           colormap->ncolors,                                          sizeof(Color_s),                                           palmcolor_compare_colors));            if (!found) {                pm_error("Color %d:%d:%d not found in colormap.  "                         "Try using pnmquant to reduce the "                         "number of colors.",                         PPM_GETR(xelrow[col]),                          PPM_GETG(xelrow[col]),                          PPM_GETB(xelrow[col]));            }            color = (*found >> 24) & 0xFF;        }        if (color > newMaxval)            pm_error("oops.  Bug in color re-calculation code.  "                     "color of %u.", color);        outbyte |= (color << outbit);        if (outbit == 0) {            /* Bit buffer is full.  Flush to to rowdata. */            *outptr++ = outbyte;            outbyte = 0x00;            outbit = 8 - bpp;        } else            outbit -= bpp;    }    if ((cols % (8 / bpp)) != 0) {        /* Flush bits remaining in the bit buffer to rowdata */        *outptr++ = outbyte;    }}static voidscanlineCompressAndWriteRow(const unsigned char * const rowdata,                            unsigned int          const rowbytes,                            const unsigned char * const lastrow) {    unsigned int col;    for (col = 0;  col < rowbytes;  col += 8) {        unsigned int const limit = MIN(rowbytes - col, 8);        unsigned char outbit;        unsigned char map;        /* mask indicating which of the next 8 pixels are different           from the previous row, and therefore present in the           file immediately following the map byte.        */        unsigned char *outptr;        unsigned char differentPixels[8];                    for (outbit = 0, map = 0x00, outptr = differentPixels;             outbit < limit;               ++outbit) {            if (!lastrow                 || (lastrow[col + outbit] != rowdata[col + outbit])) {                map |= (1 << (7 - outbit));                *outptr++ = rowdata[col + outbit];            }        }        putc(map, stdout);        fwrite(differentPixels, (outptr - differentPixels), 1, stdout);    }}static voidrleCompressAndWriteRow(const unsigned char * const rowdata,                       unsigned int          const rowbytes) {            unsigned int col;    /* we output a count of the number of bytes a value is       repeated, followed by that byte value     */    col = 0;    while (col < rowbytes) {        unsigned int repeatcount;        for (repeatcount = 1;               repeatcount < (rowbytes - col) && repeatcount < 255;               ++repeatcount)            if (rowdata[col+repeatcount] != rowdata[col])                break;        putc(repeatcount, stdout);        putc(rowdata[col], stdout);        col += repeatcount;    }}static voidwriteRowFromRawRowdata(const unsigned char *  const rowdata,                       unsigned int           const rowbytes,                       bool                   const scanlineCompression,                       bool                   const rleCompression,                       const unsigned char *  const lastrow) {/*----------------------------------------------------------------------------   Starting with a raw (uncompressed) Palm raster line, do the required   compression and write the row to stdout.-----------------------------------------------------------------------------*/    if (scanlineCompression)        scanlineCompressAndWriteRow(rowdata, rowbytes, lastrow);    else if (rleCompression)        rleCompressAndWriteRow(rowdata, rowbytes);    else         fwrite(rowdata, rowbytes, 1, stdout);}static voidwriteRow(const xel *     const xelrow,         unsigned int    const cols,         xelval          const maxval,         unsigned int    const rowbytes,         unsigned int    const bpp,         unsigned int    const newMaxval,         bool            const scanlineCompression,         bool            const rleCompression,         bool            const directColor,         Colormap        const colormap,         unsigned char * const rowdata,         unsigned char * const lastrow) {/*----------------------------------------------------------------------------   Write one row of the raster to stdout.   'rowdata' is a work buffer 'rowbytes' in size.   'lastrow' is the contents of the row most recently written (useful in   doing compression), or NULL if there is no previous row.-----------------------------------------------------------------------------*/    if (directColor)        computeRawRowDirectColor(xelrow, cols, maxval, rowdata);        else         computeRawRowNonDirect(xelrow, cols, maxval, bpp, colormap, newMaxval,                               rowdata);    writeRowFromRawRowdata(rowdata, rowbytes,                            scanlineCompression, rleCompression,                           lastrow);}static void writeRaster(xel **       const xels,            unsigned int const cols,            unsigned int const rows,            xelval       const maxval,            unsigned int const rowbytes,            unsigned int const bpp,            unsigned int const newMaxval,            bool         const scanlineCompression,            bool         const rleCompression,            bool         const directColor,            Colormap     const colormap) {        unsigned char * rowdata;    unsigned char * lastrow;    unsigned int row;    MALLOCARRAY_NOFAIL(rowdata, rowbytes);    MALLOCARRAY_NOFAIL(lastrow, rowbytes);    /* And write out the data. */    for (row = 0; row < rows; ++row) {        writeRow(xels[row], cols, maxval, rowbytes, bpp, newMaxval,                 scanlineCompression, rleCompression,                 directColor, colormap, rowdata, row > 0 ? lastrow : NULL);        memcpy(lastrow, rowdata, rowbytes);    }    free(lastrow);    free(rowdata);}int main( int argc, char **argv ) {    struct cmdline_info cmdline;     FILE* ifp;    xel** xels;    xel transcolor;    unsigned int transindex;    int rows, cols;    unsigned int rowbytes;    xelval maxval;    int format;    unsigned int bpp;    bool directColor;    unsigned int maxmaxval;    unsigned int newMaxval;    Colormap colormap;    unsigned int nextDepthOffset;        /* Offset from the beginning of the image we write to the beginning           of the next one, assuming User writes another one following this           one.        */    unsigned int padBytesRequired;        /* Number of bytes of padding we need to put after the image in           order to align properly for User to add the next image to the           stream.        */    unsigned int i;    /* Parse default params */    pnm_init(&argc, argv);    parseCommandLine(argc, argv, &cmdline);    ifp = pm_openr(cmdline.inputFilespec);    xels = pnm_readpnm (ifp, &cols, &rows, &maxval, &format);    pm_close(ifp);    if (cmdline.verbose)        pm_message("Input is %dx%d %s, maxval %d",                    cols, rows, formatName(format), maxval);        determinePalmFormat(cols, rows, maxval, format, xels,                         cmdline.depth, cmdline.maxdepth, cmdline.colormap,                         cmdline.verbose,                         &bpp, &maxmaxval, &directColor, &colormap);    newMaxval = (1 << bpp) - 1;    if (cmdline.transparent)         findTransparentColor(cmdline.transparent, newMaxval, directColor,                             maxval, colormap, &transcolor, &transindex);    else         transindex = 0;    rowbytes = ((cols + (16 / bpp -1)) / (16 / bpp)) * 2;            /* bytes per row - always a word boundary */    if (cmdline.offset) {        /* Offset is measured in 4-byte words (double words in           Intel/Microsoft terminology).  Account for header,           colormap, and raster size and round up         */        unsigned int const rasterSize = rowbytes * rows;        unsigned int const headerSize = 16;        unsigned int const colormapSize =  (directColor ? 8 : 0) +            (cmdline.colormap ? (2 + colormap->ncolors * 4) : 0);        nextDepthOffset = (rasterSize + headerSize + colormapSize + 3) / 4;        padBytesRequired = 4 - (rasterSize + headerSize + colormapSize)%4;    } else {        nextDepthOffset = 0;        padBytesRequired = 0;    }    writeHeader(cols, rows, rowbytes, bpp, !!cmdline.transparent,                transindex,                cmdline.rle_compression, cmdline.scanline_compression,                cmdline.colormap, directColor, nextDepthOffset);    writeColormap(cmdline.colormap, colormap, directColor, bpp,                   !!cmdline.transparent, transcolor, maxval);    writeSize(cmdline.scanline_compression, cmdline.rle_compression);    writeRaster(xels, cols, rows, maxval, rowbytes, bpp, newMaxval,                cmdline.scanline_compression, cmdline.rle_compression,                directColor, colormap);    for (i = 0; i < padBytesRequired; ++i)        fputc(0x00, stdout);    return 0;}

⌨️ 快捷键说明

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