示例#1
0
static void
makePalette(pixel **          const xorPPMarray,
            int               const xorCols,
            int               const xorRows,
            pixval            const xorMaxval,
            IC_Palette *      const paletteP,
            colorhash_table * const xorChtP,
            int *             const colorsP,
            const char **     const errorP) {
   /*
    * Figure out the colormap and turn it into the appropriate GIF
    * colormap - this code's pretty much straight from ppmtobpm
    */
    colorhist_vector xorChv;
    unsigned int i;
    int colors;
    IC_Palette palette = createCleanPalette();

    if (verbose) pm_message("computing colormap...");
    xorChv = ppm_computecolorhist(xorPPMarray, xorCols, xorRows, MAXCOLORS, 
                                  &colors);
    if (xorChv == NULL)
        asprintfN(errorP,
                  "image has too many colors - try doing a 'pnmquant %d'",
                  MAXCOLORS);
    else {
        *errorP = NULL;

        if (verbose) pm_message("%d colors found", colors);
        
        if (verbose && (xorMaxval > 255))
            pm_message("maxval is not 255 - automatically rescaling colors");
        for (i = 0; i < colors; ++i) {
            if (xorMaxval == 255) {
                addColorToPalette(palette,i,
                                  PPM_GETR(xorChv[i].color),
                                  PPM_GETG(xorChv[i].color),
                                  PPM_GETB(xorChv[i].color));
            } else {
                addColorToPalette(palette,i,
                                  PPM_GETR(xorChv[i].color) * 255 / xorMaxval,
                                  PPM_GETG(xorChv[i].color) * 255 / xorMaxval,
                                  PPM_GETB(xorChv[i].color) * 255 / xorMaxval);
            }
        }
        
        /* And make a hash table for fast lookup. */
        *xorChtP = ppm_colorhisttocolorhash(xorChv, colors);
        
        ppm_freecolorhist(xorChv);
        
        *paletteP = palette;
        *colorsP = colors;
    }
}
示例#2
0
static void
computeColormap(pixel **           const pixels, 
                gray **            const alpha,
                int                const cols, 
                int                const rows,
                gray               const alphaMaxval,
                colorhist_vector * const chvP, 
                colorhash_table *  const chtP,
                unsigned int *     const ncolorsP,
                bool *             const transparentSomewhereP) {
/*----------------------------------------------------------------------------
   Compute the color map for the image 'pixels', which is 'cols' by 'rows',
   in Netpbm data structures (a colorhist_vector for index-to-color lookups
   and a colorhash_table for color-to-index lookups).

   Exclude pixels that alpha mask 'alpha' (which has maxval
   'alphaMaxval') says are mostly transparent.  alpha == NULL means all
   pixels are opaque.

   We return as *chvP an array of the colors present in 'pixels',
   excluding those that are mostly transparent.  We return as
   *ncolorsP the number of such colors.  We return
   *transparentSomewhereP == TRUE iff the image has at least one
   pixel that is mostly transparent.
-----------------------------------------------------------------------------*/
    colorhash_table histCht;

    pm_message("(Computing colormap...");
    computecolorhash(pixels, alpha, cols, rows, alphaMaxval, 
                     &histCht, ncolorsP, transparentSomewhereP);
    pm_message("...Done.  %d colors found.)", *ncolorsP);
    
    *chvP = ppm_colorhashtocolorhist(histCht, *ncolorsP);
    ppm_freecolorhash(histCht);
    /* Despite the name, the following generates an index on *chvP,
       with which given a color you can quickly find the entry number
       in *chvP that contains that color.
    */
    *chtP = ppm_colorhisttocolorhash(*chvP, *ncolorsP);
}
示例#3
0
static void
makePcxColormapFromImage(pixel **               const pixels,
                         int                    const cols,
                         int                    const rows,
                         pixval                 const maxval,
                         struct pcxCmapEntry ** const pcxcmapP,
                         colorhash_table *      const chtP,
                         int *                  const colorsP,
                         bool *                 const tooManyColorsP) {
/*----------------------------------------------------------------------------
   Make a colormap (palette) for the PCX header that can be used
   for the image described by 'pixels', 'cols', 'rows', and 'maxval'.

   Return it in newly malloc'ed storage and return its address as
   *pcxcmapP.

   Also return a lookup hash to relate a color in the image to the
   appropriate index in *pcxcmapP.  Return that in newly malloc'ed 
   storage as *chtP.

   Iff there are too many colors to do that (i.e. more than 256), 
   return *tooManyColorsP == TRUE.
-----------------------------------------------------------------------------*/
    int colors;
    colorhist_vector chv;

    pm_message("computing colormap...");

    chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors);
    if (chv == NULL)
        *tooManyColorsP = TRUE;
    else {
        int i;
        struct pcxCmapEntry * pcxcmap;

        *tooManyColorsP = FALSE;

        pm_message("%d colors found", colors);
        
        moveBlackToIndex0(chv, colors);

        MALLOCARRAY_NOFAIL(pcxcmap, MAXCOLORS);

        *pcxcmapP = pcxcmap;

        for (i = 0; i < colors; ++i) {
            pixel p;

            PPM_DEPTH(p, chv[i].color, maxval, PCX_MAXVAL);

            pcxcmap[i].r = PPM_GETR(p);
            pcxcmap[i].g = PPM_GETG(p);
            pcxcmap[i].b = PPM_GETB(p);
        }

        /* Fill it out with black */
        for ( ; i < MAXCOLORS; ++i) {
            pcxcmap[i].r = 0;
            pcxcmap[i].g = 0;
            pcxcmap[i].b = 0;
        }

        *chtP = ppm_colorhisttocolorhash(chv, colors);

        *colorsP = colors;

        ppm_freecolorhist(chv);
    }
}
示例#4
0
CONVERT_IMAGERESULT
write_PNG_file (CONVERT_IMG_ARRAY p_rowarray,CONVERT_IMGCONTEXT *output,CONVERT_IMG_INFO *p_imageinfo,CONVERT_CALLBACKS p_callbacks)
{
    int16 colors,i;
    int16 maxcolor=MAXCOLORS-1;
    colorhist_vector chv;
    pixval maxval=MAXCOLORS-1;
    colorhash_table cht=NULL;
    png_structp write_ptr;
    png_infop info_ptr;/* important!*/
    png_bytep rowbuf=NULL;

    int32 y;
    int num_pass, pass;
    CONVERT_IMAGERESULT result=CONV_OK;

    if (!output||!p_imageinfo)
    {
        return CONVERR_INVALIDPARAMS;
    }

    /* Figure out the colormap. */
    chv = ppm_computecolorhist( (pixel **)p_rowarray, p_imageinfo->m_image_width, p_imageinfo->m_image_height, MAXCOLORS, &colors );
    if ( chv == (colorhist_vector) 0 )/*more than 256 colors*/
    {
        result=quantize_colors(p_rowarray,p_imageinfo->m_image_width,p_imageinfo->m_image_height,&maxcolor,&colors,&chv);
        if (result!=CONV_OK)
            return result;
        if ( chv == (colorhist_vector) 0 )
            return CONVERR_INVALIDCOLORMAP;
    }

    /* And make a hash table for fast lookup. */
    cht = ppm_colorhisttocolorhash( chv, colors );
    if (!cht)
    {
        XP_ASSERT(FALSE);
        return CONVERR_OUTOFMEMORY;
    }

    write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (void *)NULL,
      (png_error_ptr)NULL, (png_error_ptr)NULL);

    info_ptr=png_create_info_struct(write_ptr);
    info_ptr->width=p_imageinfo->m_image_width;
    info_ptr->height=p_imageinfo->m_image_height;
    info_ptr->bit_depth=8;
    info_ptr->color_type=3; /*3= indexed color*/
    info_ptr->compression_type=0; /* only option available*/
    info_ptr->filter_type=0; /* only valid value for adaptive filtering*/
    info_ptr->interlace_type=0;/*0= no interlacing*/
    info_ptr->num_palette=colors; /*from quantize_colors*/
    info_ptr->palette=XP_ALLOC(3*colors);/*remember to free this*/
    info_ptr->valid|=PNG_INFO_PLTE;
    for (i=0;i<colors;i++)
    {
	    info_ptr->palette[i].red = PPM_GETR( chv[i].color );
	    info_ptr->palette[i].green = PPM_GETG( chv[i].color );
	    info_ptr->palette[i].blue = PPM_GETB( chv[i].color );
    }
    ppm_freecolorhist( chv );
    if (!info_ptr->palette)
    {
      png_destroy_write_struct(&write_ptr, &info_ptr);
    }

    /*transparancy???*/

    if (setjmp(write_ptr->jmpbuf))
    {
      png_destroy_write_struct(&write_ptr, &info_ptr);
      return CONVERR_BADWRITE;
    }

    png_init_io(write_ptr, output->m_stream.m_file);

    png_write_info(write_ptr, info_ptr);

    num_pass = 1;
    /*we need to look up each RGB  and change it to the index of the color table*/
    rowbuf=(png_bytep) XP_ALLOC(p_imageinfo->m_image_width);
    if (!rowbuf)
    {
      png_destroy_write_struct(&write_ptr, &info_ptr);
      return CONVERR_BADWRITE;
    }

    for (pass = 0; pass < num_pass; pass++)
    {
      for (y = 0; y < p_imageinfo->m_image_height; y++)
      {
         fill_png_row(p_rowarray[y],rowbuf,p_imageinfo->m_image_width,cht);
         png_write_rows(write_ptr, &rowbuf, 1);
      }
    }
    XP_FREE(rowbuf);
    png_write_end(write_ptr, NULL);
    XP_FREE(info_ptr->palette);
    png_destroy_write_struct(&write_ptr, &info_ptr);
    fclose(output->m_stream.m_file);
    return CONV_OK;
}
示例#5
0
int
main(int argc, const char ** const argv) {

    FILE * ifP;
    int rows, cols;
    int colorCt;
    int argn;
    unsigned int bitsPerPixel;
    pixval maxval;
    colorhist_vector chv;
    char rgb[CLUTCOLORCT];
    const char * windowName;
    int display, expand;
    int winflag;
    const char* const usage = "[-windowname windowname] [-expand expand] [-display display] [ppmfile]";
    pixel** pixels;
    colorhash_table cht;

    pm_proginit(&argc, argv);

    argn = 1;
    windowName = "untitled";
    winflag = 0;
    expand = 1;
    display = 0;

    while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
    {
        if ( pm_keymatch(argv[argn],"-windowname",2) && argn + 1 < argc )
        {
            ++argn;
            windowName = argv[argn];
            winflag = 1;
        }
        else if ( pm_keymatch(argv[argn],"-expand",2) && argn + 1 < argc )
        {
            ++argn;
            if ( sscanf( argv[argn], "%d",&expand ) != 1 )
                pm_usage( usage );
        }
        else if ( pm_keymatch(argv[argn],"-display",2) && argn + 1 < argc )
        {
            ++argn;
            if ( sscanf( argv[argn], "%d",&display ) != 1 )
                pm_usage( usage );
        }
        else
            pm_usage( usage );
    }

    if ( argn < argc )
    {
        ifP = pm_openr( argv[argn] );
        if ( ! winflag )
            windowName = argv[argn];
        ++argn;
    }
    else
        ifP = stdin;

    if ( argn != argc )
        pm_usage( usage );

    pixels = ppm_readppm(ifP, &cols, &rows, &maxval);

    pm_close(ifP);

    /* Figure out the colormap. */
    pm_message("Computing colormap..." );
    chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORCT, &colorCt);
    if (!chv)
        pm_error("Too many colors - try doing a 'pnmquant %u'", MAXCOLORCT);
    pm_message("%u colors found", colorCt );

    makeIcrColormap(chv, colorCt, maxval, rgb);

    bitsPerPixel = bppFromColorCt(colorCt);

    /* And make a hash table for fast lookup. */
    cht = ppm_colorhisttocolorhash(chv, colorCt);

    ppm_freecolorhist(chv);

    /************** Create a new window using ICR protocol *********/
    /* Format is "ESC^W;left;top;width;height;display;windowname"  */

    pm_message("Creating window %s ...", windowName);

    printf("\033^W;%d;%d;%d;%d;%d;%s^",
           0, 0, cols * expand, rows * expand, display, windowName);
    fflush(stdout);

    /****************** Download the colormap.  ********************/

    downloadColormap(rgb, windowName);

    sendOutPicture(pixels, rows, cols, cht, expand, windowName);

    return 0;
}