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

📄 palmtopnm.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************                             palmtopnm*******************************************************************************  By Bryan Henderson, San Jose, California, June 2004.  Inspired by and using methods from Tbmptopnm by Ian Goldberg  <iang@cs.berkeley.edu>, and Bill Janssen <bill@janssen.org>.  Bryan's work is contributed to the public domain by its author.******************************************************************************/#include <assert.h>#include "pnm.h"#include "shhopt.h"#include "mallocvar.h"#include "palm.h"enum palmCompressionType {    COMPRESSION_NONE,     COMPRESSION_RLE,     COMPRESSION_SCANLINE,    COMPRESSION_PACKBITS};struct palmHeader {    unsigned short cols;    unsigned short rows;    unsigned short bytesPerRow;    unsigned short flags;    unsigned char  pixelSize;    unsigned char  version;    unsigned char  transparentIndex;    enum palmCompressionType compressionType;};struct directColorInfo {    unsigned int redbits;    unsigned int greenbits;    unsigned int bluebits;    Color_s      transparentColor;};struct cmdlineInfo {    /* All the information the user supplied in the command line,       in a form easy for the program to use.    */    const char * inputFilespec;    unsigned int verbose;    unsigned int rendition;    unsigned int showhist;    unsigned int transparent;};static voidparseCommandLine(int argc, char ** argv,                 struct cmdlineInfo *cmdlineP) {/*----------------------------------------------------------------------------   Note that the file spec array we return is stored in the storage that   was passed to us as the argv array.-----------------------------------------------------------------------------*/    optEntry *option_def = malloc( 100*sizeof( optEntry ) );        /* Instructions to optParseOptions3 on how to parse our options.         */    optStruct3 opt;    unsigned int renditionSpec;    unsigned int option_def_index;    option_def_index = 0;   /* incremented by OPTENTRY */    OPTENT3(0, "verbose",     OPT_FLAG, NULL,            &cmdlineP->verbose,  0);    OPTENT3(0, "showhist",    OPT_FLAG, NULL,            &cmdlineP->showhist, 0);    OPTENT3(0, "transparent",    OPT_FLAG, NULL,            &cmdlineP->transparent, 0);    OPTENT3(0, "rendition",  OPT_UINT, &cmdlineP->rendition,             &renditionSpec, 0);    opt.opt_table = option_def;    opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */    opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */    optParseOptions3(&argc, argv, opt, sizeof(opt), 0);        /* Uses and sets argc, argv, and some of *cmdlineP and others. */    if (renditionSpec) {        if (cmdlineP->rendition < 1)            pm_error("The -rendition value must be at least 1");    } else         cmdlineP->rendition = 1;        if (cmdlineP->transparent) {        if (renditionSpec)            pm_error("You can't specify -rendition with -transparent");        if (cmdlineP->showhist)            pm_error("You can't specify -showhist with -transparent");    }    if (argc-1 < 1)        cmdlineP->inputFilespec = "-";    else {        cmdlineP->inputFilespec = argv[1];        if (argc-1 > 1)            pm_error("Too many arguments (%d).  The only non-option "                     "argument is the file name", argc-1);    }}static xelval *createGraymap(unsigned int const ncolors,               unsigned int const minval,               xelval       const maxval) {    int i;    xelval *map;    MALLOCARRAY_NOFAIL(map, ncolors);    for (i = 0; i < ncolors; ++i) {        map[i] = maxval - (i * (maxval - minval)) / (ncolors - 1);    }    return map;}static void skipbytes(FILE *       const ifP,           unsigned int const nbytes) {    unsigned char buf[256];    unsigned int n;    n = nbytes;  /* initial value */    while (n > 0) {        if (n > sizeof(buf)) {            fread(buf, sizeof(buf), 1, ifP);            n -= sizeof(buf);        } else {            fread(buf, n, 1, ifP);            n = 0;        }    }    }static voidinterpretCompression(unsigned short             const flags,                     unsigned char              const compressionValue,                     enum palmCompressionType * const compressionTypeP) {        switch (compressionValue) {    case PALM_COMPRESSION_RLE:        *compressionTypeP = COMPRESSION_RLE;        break;    case PALM_COMPRESSION_SCANLINE:        *compressionTypeP = COMPRESSION_SCANLINE;        break;    case PALM_COMPRESSION_PACKBITS:        *compressionTypeP = COMPRESSION_PACKBITS;        break;    case PALM_COMPRESSION_NONE:        *compressionTypeP = COMPRESSION_NONE;        break;    default:        pm_error("The Palm image header has an unrecognized value for "                 "compression type: 0x%02x", (unsigned)compressionValue);    }}static voidreadHeader(FILE *              const ifP,           unsigned int        const requestedRendition,           struct palmHeader * const palmHeaderP) {        bool gotHeader;    unsigned int currentRendition;    gotHeader = FALSE;    currentRendition = 1;    while (!gotHeader) {        short cols, rows, bytesPerRow, flags, nextDepthOffset;        unsigned char pixelSize, version;        pm_readbigshort(ifP, &cols);        pm_readbigshort(ifP, &rows);        pm_readbigshort(ifP, &bytesPerRow);        pm_readbigshort(ifP, &flags);        pixelSize = fgetc(ifP);        version = fgetc(ifP);        pm_readbigshort(ifP, &nextDepthOffset);        if (currentRendition < requestedRendition) {            if (nextDepthOffset == 0)                pm_error("Not enough renditions in the input pixmap "                         "to extract the %dth", requestedRendition);            /* nextDepthOffset is calculated in 4 byte words             * from the beginning of this bitmap (so it equals it's size) */            skipbytes(ifP, (nextDepthOffset*4)-12);            ++currentRendition;        } else {            short pad;            unsigned char compressionType;            palmHeaderP->transparentIndex = fgetc(ifP);            compressionType = fgetc(ifP);                        pm_readbigshort(ifP, &pad);	/* reserved by Palm as of 8/9/00 */            gotHeader = TRUE;            palmHeaderP->cols = cols;            palmHeaderP->rows = rows;            palmHeaderP->bytesPerRow = bytesPerRow;            palmHeaderP->flags = flags;            palmHeaderP->pixelSize = pixelSize;            palmHeaderP->version = version;            interpretCompression(palmHeaderP->flags, compressionType,                                 &palmHeaderP->compressionType);        }    }}static voidreportPalmHeader(struct palmHeader const palmHeader) {    const char *ctype;    switch (palmHeader.compressionType) {    case COMPRESSION_RLE:        ctype = "rle (Palm OS 3.5)";        break;    case COMPRESSION_SCANLINE:        ctype = "scanline (Palm OS 2.0)";        break;    case COMPRESSION_PACKBITS:        ctype = "packbits (Palm OS 4.0)";        break;    case COMPRESSION_NONE:        ctype = "none";        break;    }    pm_message("Dimensions: %hu columns x %hu rows",               palmHeader.cols, palmHeader.rows);    pm_message("Row layout: %hu bytes per row, %hu bits per pixel",               palmHeader.bytesPerRow, palmHeader.pixelSize);    pm_message("Flags: 0x%04hx", palmHeader.flags);    pm_message("Version %d", palmHeader.version);    pm_message("Transparent index: %d", palmHeader.transparentIndex);    pm_message("Compression type: %s", ctype);}static voiddetermineOutputFormat(struct palmHeader const palmHeader,                      int *             const formatP,                      xelval *          const maxvalP) {    if (palmHeader.flags & PALM_DIRECT_COLOR) {        *formatP = PPM_TYPE;        *maxvalP = 255;    } else if (palmHeader.flags & PALM_HAS_COLORMAP_FLAG) {        *formatP = PPM_TYPE;        *maxvalP = 255;    } else if (palmHeader.pixelSize == 1) {        *formatP = PBM_TYPE;        *maxvalP = 1;    } else if (palmHeader.pixelSize >= 8) {        *formatP = PPM_TYPE;        *maxvalP = pm_bitstomaxval(palmHeader.pixelSize);    } else {        *formatP = PGM_TYPE;        *maxvalP = pm_bitstomaxval(palmHeader.pixelSize);    }}static voidgetColorInfo(struct palmHeader        const palmHeader,             FILE *                   const ifP,             Colormap *               const colormapP,             unsigned int *           const ncolorsP,             struct directColorInfo * const directColorInfoP) {                 if (palmHeader.flags & PALM_DIRECT_COLOR) {        *colormapP = NULL;        directColorInfoP->redbits   = fgetc(ifP);        directColorInfoP->greenbits = fgetc(ifP);        directColorInfoP->bluebits  = fgetc(ifP);        fgetc(ifP);  /* padding */        fgetc(ifP);  /* padding */        directColorInfoP->transparentColor =             (fgetc(ifP) << 16) | (fgetc(ifP) << 8) | fgetc(ifP);    } else if (palmHeader.flags & PALM_HAS_COLORMAP_FLAG)        *colormapP = palmcolor_read_colormap (ifP);    else if (palmHeader.pixelSize >= 8) {        Colormap colormap;        colormap = palmcolor_build_default_8bit_colormap();        qsort(colormap->color_entries, colormap->ncolors,               sizeof(Color_s), palmcolor_compare_indices);        *colormapP = colormap;    } else        *colormapP = NULL;    *ncolorsP = 1 << palmHeader.pixelSize;}static voiddoTransparent(unsigned short         const flags,              unsigned char          const transparentIndex,              unsigned char          const pixelSize,              Colormap               const colormap,              struct directColorInfo const directColorInfo) {    if (flags & PALM_HAS_TRANSPARENCY_FLAG) {        if (colormap) {            Color_s const color = transparentIndex << 24;            Color const actualColor = (bsearch(&color,                                               colormap->color_entries,                                                colormap->ncolors,                                               sizeof(color),                                                palmcolor_compare_indices));            printf("#%02x%02x%02x\n",                    (unsigned int) ((*actualColor >> 16) & 0xFF),                   (unsigned int) ((*actualColor >>  8) & 0xFF),                    (unsigned int) ((*actualColor >>  0 )& 0xFF));        } else if (flags & PALM_DIRECT_COLOR) {            Color_s const color = directColorInfo.transparentColor;            printf("#%02x%02x%02x\n",                    (unsigned int)((color >> 16) & 0xFF),                    (unsigned int)((color >>  8) & 0xFF),                    (unsigned int)((color >>  0 )& 0xFF));        } else {            unsigned int const maxval = pm_bitstomaxval(pixelSize);            unsigned int const grayval =                 ((maxval - transparentIndex) * 256) / maxval;            printf("#%02x%02x%02x\n", grayval, grayval, grayval);        }    }}

⌨️ 快捷键说明

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