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

📄 pnmtopalm.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* pnmtopalm.c - read a portable pixmap and write a Palm Tbmp file * * Program originally ppmtoTbmp.c by Ian Goldberg <iang@cs.berkeley.edu> * * Mods for multiple bits per pixel by George Caswell  * <tetsujin@sourceforge.net> *  and Bill Janssen <bill@janssen.org> *  * See LICENSE file for licensing information. * * Based on ppmtopuzz.c by Jef Poskanzer, from the netpbm-1mar1994 package. */#include <stdio.h>#include <assert.h>#include <limits.h>#include "pnm.h"#include "palm.h"#include "shhopt.h"#include "mallocvar.h"struct cmdline_info {    /* All the information the user supplied in the command line,       in a form easy for the program to use.    */    const char *inputFilespec;  /* Filespecs of input files */    char *transparent;    /* -transparent value.  Null if unspec */    unsigned int depth;     /* -depth value.  0 if unspec */    unsigned int maxdepth;     /* -maxdepth value.  0 if unspec */    unsigned int rle_compression;    unsigned int scanline_compression;    unsigned int verbose;    unsigned int colormap;    unsigned int offset;};static voidparseCommandLine(int argc, char ** argv,                 struct cmdline_info *cmdlineP) {/*----------------------------------------------------------------------------   Note that the file spec array we return is stored in the storage that   was passed to us as the argv array.-----------------------------------------------------------------------------*/    optStruct3 opt;  /* set by OPTENT3 */    optEntry *option_def;    unsigned int option_def_index;    unsigned int transSpec, depthSpec, maxdepthSpec;    MALLOCARRAY_NOFAIL(option_def, 100);    option_def_index = 0;   /* incremented by OPTENTRY */    OPTENT3(0, "transparent",      OPT_STRING,             &cmdlineP->transparent, &transSpec, 0);    OPTENT3(0, "depth",            OPT_UINT,             &cmdlineP->depth,       &depthSpec, 0);    OPTENT3(0, "maxdepth",         OPT_UINT,             &cmdlineP->maxdepth,    &maxdepthSpec, 0);    OPTENT3(0, "rle_compression",  OPT_FLAG,             NULL,                   &cmdlineP->rle_compression, 0);    OPTENT3(0, "scanline_compression", OPT_FLAG,             NULL,                   &cmdlineP->scanline_compression, 0);    OPTENT3(0, "verbose",          OPT_FLAG,             NULL,                   &cmdlineP->verbose, 0);    OPTENT3(0, "colormap",         OPT_FLAG,             NULL,                   &cmdlineP->colormap, 0);    OPTENT3(0, "offset",           OPT_FLAG,             NULL,                   &cmdlineP->offset, 0);    opt.opt_table = option_def;    opt.short_allowed = FALSE; /* We have some short (old-fashioned) options */    opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */    optParseOptions3(&argc, argv, opt, sizeof(opt), 0);        /* Uses and sets argc, argv, and some of *cmdline_p and others. */    if (depthSpec) {        if (cmdlineP->depth != 1 && cmdlineP->depth != 2             && cmdlineP->depth != 4 && cmdlineP->depth != 8            && cmdlineP->depth != 16)            pm_error("invalid value for -depth: %u.  Valid values are "                     "1, 2, 4, 8, and 16", cmdlineP->depth);    } else        cmdlineP->depth = 0;    if (maxdepthSpec) {        if (cmdlineP->maxdepth != 1 && cmdlineP->maxdepth != 2             && cmdlineP->maxdepth != 4 && cmdlineP->maxdepth != 8            && cmdlineP->maxdepth != 16)            pm_error("invalid value for -maxdepth: %u.  Valid values are "                     "1, 2, 4, 8, and 16", cmdlineP->maxdepth);    } else        cmdlineP->maxdepth = 0;    if (depthSpec && maxdepthSpec &&         cmdlineP->depth > cmdlineP->maxdepth)        pm_error("-depth value (%u) is greater than -maxdepth (%u) value.",                 cmdlineP->depth, cmdlineP->maxdepth);    if (!transSpec)        cmdlineP->transparent = NULL;    if (cmdlineP->offset &&        (cmdlineP->rle_compression || cmdlineP->scanline_compression))        pm_error("You can't specify -offset with -rle_compression or "                 "-scanline_compression.");     if (argc-1 > 1)        pm_error("This program takes at most 1 argument: the file name.  "                 "You specified %d", argc-1);    else if (argc-1 > 0)         cmdlineP->inputFilespec = argv[1];    else        cmdlineP->inputFilespec = "-";}static voiddeterminePalmFormat(unsigned int   const cols,                     unsigned int   const rows,                     xelval         const maxval,                     int            const format,                     xel **         const xels,                    unsigned int   const specified_bpp,                    unsigned int   const max_bpp,                     bool           const custom_colormap,                    bool           const verbose,                    unsigned int * const bppP,                     unsigned int * const maxmaxvalP,                     bool *         const directColorP,                     Colormap *     const colormapP) {    if (PNM_FORMAT_TYPE(format) == PBM_TYPE) {        if (custom_colormap)            pm_error("You specified -colormap with a black and white input "                     "image.  -colormap is valid only with color.");        if (specified_bpp)            *bppP = specified_bpp;        else            *bppP = 1;    /* no point in wasting bits */        *maxmaxvalP = 1;        *directColorP = FALSE;        *colormapP = NULL;        if (verbose)            pm_message("output is black and white");    } else if (PNM_FORMAT_TYPE(format) == PGM_TYPE) {        /* we can usually handle this one, but may not have enough           pixels.  So check... */        if (custom_colormap)            pm_error("You specified -colormap with a black and white input"                     "image.  -colormap is valid only with color.");        if (specified_bpp)            *bppP = specified_bpp;        else if (max_bpp && (maxval >= (1 << max_bpp)))            *bppP = max_bpp;        else if (maxval > 16)            *bppP = 4;        else {            /* scale to minimum number of bpp needed */            for (*bppP = 1;  (1 << *bppP) < maxval;  *bppP *= 2)                ;        }        if (*bppP > 4)            *bppP = 4;        if (verbose)            pm_message("output is grayscale %d bits-per-pixel", *bppP);        *maxmaxvalP = PGM_OVERALLMAXVAL;        *directColorP = FALSE;        *colormapP = NULL;    } else if (PNM_FORMAT_TYPE(format) == PPM_TYPE) {        /* We assume that we only get a PPM if the image cannot be           represented as PBM or PGM.  There are two options here: either           8-bit with a colormap, either the standard one or a custom one,           or 16-bit direct color.  In the 8-bit case, if "custom_colormap"           is specified (not recommended by Palm) we will put in our own           colormap; otherwise we will assume that the colors have been           mapped to the default Palm colormap by appropriate use of           pnmquant.  We try for 8-bit color first, since it works on           more PalmOS devices. */        if ((specified_bpp == 16) ||             (specified_bpp == 0 && max_bpp == 16)) {            /* we do the 16-bit direct color */            *directColorP = TRUE;            *colormapP = NULL;            *bppP = 16;        } else if (!custom_colormap) {            /* standard indexed 8-bit color */            *colormapP = palmcolor_build_default_8bit_colormap();            *bppP = 8;            if (((specified_bpp != 0) && (specified_bpp != 8)) ||                ((max_bpp != 0) && (max_bpp < 8)))                pm_error("Must use depth of 8 for color pixmap without "                         "custom color table.");            *directColorP = FALSE;            if (verbose)                pm_message("Output is color with default colormap at 8 bpp");        } else {            /* indexed 8-bit color with a custom colormap */            *colormapP =                 palmcolor_build_custom_8bit_colormap(rows, cols, xels);            for (*bppP = 1; (1 << *bppP) < (*colormapP)->ncolors; *bppP *= 2);            if (specified_bpp != 0) {                if (specified_bpp >= *bppP)                    *bppP = specified_bpp;                else                    pm_error("Too many colors for specified depth.  "                             "Use pnmquant to reduce.");            } else if ((max_bpp != 0) && (max_bpp < *bppP)) {                pm_error("Too many colors for specified max depth.  "                         "Use pnmquant to reduce.");            }            *directColorP = FALSE;            if (verbose)                pm_message("Output is color with custom colormap "                           "with %d colors at %d bpp",                            (*colormapP)->ncolors, *bppP);        }        *maxmaxvalP = PPM_OVERALLMAXVAL;    } else {        pm_error("unknown format 0x%x on input file\n", (unsigned) format);    }}static const char * formatName(int const format) {        const char * retval;    switch(PNM_FORMAT_TYPE(format)) {    case PBM_TYPE: retval = "black and white"; break;    case PGM_TYPE: retval = "grayscale";       break;    case PPM_TYPE: retval = "color";           break;    default:       retval = "???";             break;    }    return retval;}        static voidfindTransparentColor(char *         const colorSpec,                      pixval         const newMaxval,                     bool           const directColor,                      pixval         const maxval,                      Colormap       const colormap,                     xel *          const transcolorP,                      unsigned int * const transindexP) {    *transcolorP = ppm_parsecolor(colorSpec, maxval);    if (!directColor) {        Color_s const temp_color =             ((((PPM_GETR(*transcolorP)*newMaxval) / maxval) << 16)              | (((PPM_GETG(*transcolorP)*newMaxval) / maxval) << 8)             | ((PPM_GETB(*transcolorP)*newMaxval) / maxval));        Color const found =             (bsearch(&temp_color,                     colormap->color_entries, colormap->ncolors,                     sizeof(Color_s), palmcolor_compare_colors));        if (!found) {            pm_error("Specified transparent color %s not found "                     "in colormap.", colorSpec);        } else            *transindexP = (*found >> 24) & 0xFF;    }}static voidwriteHeader(unsigned int const cols,            unsigned int const rows,            unsigned int const rowbytes,            unsigned int const bpp,            bool         const transparent,            unsigned int const transindex,            bool         const rleCompression,            bool         const scanlineCompression,            bool         const colormap,            bool         const directColor,            unsigned int const nextDepthOffset) {/*----------------------------------------------------------------------------   Write the Tbmp header.  This is 16 bytes; it does not include   colormap.-----------------------------------------------------------------------------*/    unsigned short flags;    int version;    flags = 0;  /* initial value */    if (transparent)        flags |= PALM_HAS_TRANSPARENCY_FLAG;    if (colormap)        flags |= PALM_HAS_COLORMAP_FLAG;    if (rleCompression || scanlineCompression)        flags |= PALM_IS_COMPRESSED_FLAG;    if (directColor)        flags |= PALM_DIRECT_COLOR;    if (cols > USHRT_MAX)        pm_error("Too many columns for Palm pixmap: %u", cols);    pm_writebigshort(stdout, cols);    /* width */    if (rows > USHRT_MAX)        pm_error("Too many columns for Palm pixmap: %u", rows);    pm_writebigshort(stdout, rows);    /* height */    if (rows > USHRT_MAX)        pm_error("Too many bytes per row for Palm pixmap: %u", rowbytes);    pm_writebigshort(stdout, rowbytes);    pm_writebigshort(stdout, flags);    assert(bpp <= UCHAR_MAX);    fputc(bpp, stdout);    /* we need to mark this as version 1 if we use more than 1 bpp,       version 2 if we use compression or transparency     */    version = (transparent || rleCompression || scanlineCompression) ?         2 : (((bpp > 1) || colormap) ? 1 : 0);    fputc(version, stdout);    if (nextDepthOffset > USHRT_MAX)        pm_error("Image too large for Palm pixmap");    pm_writebigshort(stdout, nextDepthOffset);    assert(transindex <= UCHAR_MAX);    fputc(transindex, stdout);  /* transparent index */    if (rleCompression)        fputc(PALM_COMPRESSION_RLE, stdout);    else if (scanlineCompression)        fputc(PALM_COMPRESSION_SCANLINE, stdout);    else        fputc(PALM_COMPRESSION_NONE, stdout);    pm_writebigshort(stdout, 0);   /* reserved by Palm */}static voidwriteColormap(bool         const explicitColormap,              Colormap     const colormap,              bool         const directColor,              unsigned int const bpp,              bool         const transparent,              xel          const transcolor,              xelval       const maxval) {                  /* if there's a colormap, write it out */    if (explicitColormap) {        unsigned int row;        if (!colormap)            pm_error("Internal error: user specified -colormap, but we did "                     "not generate a colormap.");        qsort (colormap->color_entries, colormap->ncolors,               sizeof(Color_s), palmcolor_compare_indices);        pm_writebigshort( stdout, colormap->ncolors );        for (row = 0;  row < colormap->ncolors; ++row)            pm_writebiglong (stdout, colormap->color_entries[row]);        qsort (colormap->color_entries, colormap->ncolors,               sizeof(Color_s), palmcolor_compare_colors);    }

⌨️ 快捷键说明

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