Exemple #1
0
static void
readPpmPalette(const char *   const paletteFileName,
               pixel       (* const ppmPaletteP)[], 
               unsigned int * const paletteSizeP) {

    FILE * pfP;
    pixel ** pixels;
    int cols, rows;
    pixval maxval;
    
    pfP = pm_openr(paletteFileName);

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

    pm_close(pfP);
    
    *paletteSizeP = rows * cols;
    if (*paletteSizeP > MAXCOLORS) 
        pm_error("ordered palette image contains %d pixels.  Maximum is %d",
                 *paletteSizeP, MAXCOLORS);

    {
        int j;
        int row;
        j = 0;  /* initial value */
        for (row = 0; row < rows; ++row) {
            int col;
            for (col = 0; col < cols; ++col) 
                (*ppmPaletteP)[j++] = pixels[row][col];
        }
    }
    ppm_freearray(pixels, rows);
}        
unsigned char* CircularBuffer::bufferFromImage(char *photoLocation)
{
    pixel** pixarray;
    FILE *fp;
    int cols, rows;
    pixval maxval;
    register int x, y;
    unsigned char *buf=NULL;

    if ((fp = fopen (photoLocation,"r")) == NULL) {
      	fprintf (stderr, "%s: Can't open input file:\n %s.\n", photoLocation);
      	exit (1);
    }

    pixarray = ppm_readppm (fp, &cols, &rows, &maxval);
    fclose (fp);

    if (buf == NULL)
      buf = (unsigned char *)malloc(IMG_SIZE);

    /* Use this double 'for loop' in the consumer/client threads.
     * You'll need to modify this code to read from a socket into 
     * a data structure called "pixarray" first.
     */

    for (y = 0; y < rows; y++) {
      for (x = 0; x < cols; x++) {
	buf[(y*cols+x)*3+0] = PPM_GETR(pixarray[rows-y-1][x]);
	buf[(y*cols+x)*3+1] = PPM_GETG(pixarray[rows-y-1][x]);
	buf[(y*cols+x)*3+2] = PPM_GETB(pixarray[rows-y-1][x]);
      }
    }
   ppm_freearray (pixarray, rows);
   return buf;
}
char* get_arr(int *rows, int *cols, char shapefile[]) {

    char *arr;
    int k, i, j;

    pixval maxval;
    pixel **pixels;

    FILE* ppmshape = fopen(shapefile, "r");

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

    arr = (char*)malloc((*cols)*(*rows));


    for(i = 0, k = 0; i < *rows; i++)
        for(j = 0; j < *cols; j++, k++)
        {
            char r, g, b;

            r = (0xff * PPM_GETR(pixels[i][j])) / maxval;
            g = (0xff * PPM_GETR(pixels[i][j])) / maxval;
            b = (0xff * PPM_GETR(pixels[i][j])) / maxval;

            if(r==0 && b==0 && g==0)
                arr[k] = 0;
            else
                arr[k] = 0xff;
        }

    ppm_freearray(pixels, *rows);


    return arr;
}
/** return data */
const void *GeoImage::data()
{
  if (data_)
    return (void *) data_;
  qDebug("GeoImage::data() - load data");
  QString fname = filename();
  qDebug("GeoImage::data() %s", fname.toLatin1().constData());

  FILE *fp;
  fp = fopen(fname.toLatin1().constData(), "r");
  if (!fp) {
    qDebug("#  (ERROR)GeoImage::load(%s) Can't open file for reading!",
           fname.toLatin1().constData());
    return 0;
  }
  int cols, rows;
  //float minval, maxval;
  switch (type_) {
  case PFM_FLOAT:
  case PFM_UINT:
  case PFM_SINT:
  case PFM_SINT16:
  case PFM_UINT16:
  case PFM_BYTE:
  case PFM_3BYTE:
    data_ = pfm_readpfm_type(fp, &cols, &rows, &minval_, &maxval_, type_, 0);
    testSize(cols, rows, type_);
    break;
  case PBM:
    data_ = (void *) pbm_readpbm(fp, &cols, &rows);
    minval_ = 0.0, maxval_ = 1.0;
    testSize(cols, rows, type_);
    break;
  case PGM:{
      gray maxval, **data_g;
      data_g = pgm_readpgm(fp, &cols, &rows, &maxval);
      data_ = (void *) data_g;
      minval_ = 0.0, maxval_ = (float) maxval;
      testSize(cols, rows, type_);
    }
    break;
  case PPM:
    pixval maxval;
    pixel **dat_p;
    dat_p = ppm_readppm(fp, &cols, &rows, &maxval);
    data_ = (void *) dat_p;
    minval_ = 0.0, maxval_ = (float) maxval;
    testSize(cols, rows, type_);
    break;
  default:
    qDebug("Unknown type %d",type_);
    fclose(fp);
    return 0;
  }
  fclose(fp);
  if (data_) dataSize_=rows_*cols_*sizeOfData(type_);
  cache_.useImage(this);
  return data_;
}
Exemple #5
0
int main(int argc, char **argv)
{
    FILE            *ifp;
    pixel           **pixels;
    int             rows, row, cols, col,
                    pal_len, i;
    pixval          maxval;
    struct cmdlineInfo
                    cmdline;
    unsigned char   rgb[NUM_COLORS][3];
    char            ansi_code[NUM_COLORS][MAX_ANSI_STR_LEN];

    
    ppm_init(&argc, argv);    

    parseCommandLine(argc, argv, &cmdline);

    ifp = pm_openr(cmdline.inputFilespec);
    
    pixels = ppm_readppm(ifp, &cols, &rows, &maxval);

    pm_close(ifp);
        
    pal_len=generate_palette(rgb, ansi_code);
    
    for (row = 0; row < rows; ++row) {
        for (col = 0; col < cols; col++) {
            pixval const r=(int)PPM_GETR(pixels[row][col])*255/maxval;
            pixval const g=(int)PPM_GETG(pixels[row][col])*255/maxval;
            pixval const b=(int)PPM_GETB(pixels[row][col])*255/maxval;
            int val, dist;
            
            /*
            The following loop calculates the index that
            corresponds to the minimum color distance
            between the given RGB values and the values
            available in the palette.
            */
            for(i=0, dist=sqr(255)*3, val=0; i<pal_len; i++) {
                pixval const pr=rgb[i][0];
                pixval const pg=rgb[i][1];
                pixval const pb=rgb[i][2];
                unsigned int j;
                if( (j=sqr(r-pr)+sqr(b-pb)+sqr(g-pg))<dist ) {
                    dist=j;
                    val=i;
                }
            }
            printf("%s%c", ansi_code[val],0xB1);
        }
        printf(ESC"\x30m\n");
    }
    printf(ESC"\x30m");

    ppm_freearray(pixels, rows);
    
    exit(0);
}
Exemple #6
0
static void
doOneImage(FILE *          const ifP,
           struct script * const scriptP)  {

    pixel ** pixels;
    pixval maxval;
    int rows, cols;
    
    pixels = ppm_readppm(ifP, &cols, &rows, &maxval);
    
    executeScript(scriptP, pixels, cols, rows, maxval);
    
    ppm_writeppm(stdout, pixels, cols, rows, maxval, 0);
    
    ppm_freearray(pixels, rows);
}
Exemple #7
0
struct rgb_image_t load_rgb_ppm(char *file_name) {
	int cols, rows;
	pixval max;
	FILE *fp = fopen(file_name, "r");
	pixel **data = ppm_readppm(fp, &cols, &rows, &max);

	// Copy data into internal data structure
	struct rgb_image_t image;
	for(int x = 0; x < IMG_WIDTH; x++) {
		for(int y = 0; y < IMG_HEIGHT; y++) {
			// PPM data is indexed by y, then x
			image.pixels[x][y].r = PPM_GETR(data[y][x]);
			image.pixels[x][y].g = PPM_GETG(data[y][x]);
			image.pixels[x][y].b = PPM_GETB(data[y][x]);
		}
	}

	return image;
}
Exemple #8
0
static void
convertWithMap(FILE * const ifP,
               unsigned int const cols,
               unsigned int const rows,
               gray         const maxval,
               int          const format,
               const char * const mapFileName,
               FILE *       const ofP,
               gray *       const grayrow,
               pixel *      const pixelrow) {

    unsigned int row;
    FILE * mapFileP;
    int mapcols, maprows;
    pixval mapmaxval;
    pixel ** mappixels;
    unsigned int mapmaxcolor;
    
    mapFileP = pm_openr(mapFileName);
    mappixels = ppm_readppm(mapFileP, &mapcols, &maprows, &mapmaxval);
    pm_close(mapFileP);
    mapmaxcolor = maprows * mapcols - 1;

    ppm_writeppminit(ofP, cols, rows, mapmaxval, 0);

    for (row = 0; row < rows; ++row) {
        unsigned int col;
            
        pgm_readpgmrow(ifP, grayrow, cols, maxval, format);

        for (col = 0; col < cols; ++col) {
            unsigned int c;
            if (maxval == mapmaxcolor)
                c = grayrow[col];
            else
                c = grayrow[col] * mapmaxcolor / maxval;
            pixelrow[col] = mappixels[c / mapcols][c % mapcols];
        }
        ppm_writeppmrow(ofP, pixelrow, cols, mapmaxval, 0);
    }
    ppm_freearray(mappixels, maprows);
}
int main(int argc, char **argv)
{
  FILE *infile, *outfile;
  int cols, rows;
  pixval maxval;
  pixel **pic;
  int ncols, nrows;
  pixel **npic;
  int r,c;
  int x1,y1,x2,y2;

  if ( argc != 7) Usage();

  infile=fopen(argv[1],"r");
  if (!infile) {
      fprintf(stderr,"Can't open file %s for reading!\n",argv[1]);
      exit(0);
    }
  outfile=fopen(argv[2],"w");
  if (!outfile) {
      fprintf(stderr,"Can't open file %s for writing!\n",argv[2]);
      exit(0);
    }
  sscanf(argv[3],"%d",&x1);
  sscanf(argv[4],"%d",&y1);
  sscanf(argv[5],"%d",&x2);
  sscanf(argv[6],"%d",&y2);
  pic=ppm_readppm(infile,&cols,&rows,&maxval);
  printf("cols=%d, rows=%d, region=(%d,%d) (%d,%d)\n",cols,rows,x1,y1,x2,y2);
  ncols=x2-x1+1;
  nrows=y2-y1+1;
  npic=ppm_allocarray(ncols,nrows);
  for (r=0; r<nrows; r++) 
    for (c=0; c<ncols; c++)
      npic[r][c]=pic[y1+r][x1+c];
  printf("Cutting done\n");
  ppm_writeppm(outfile,npic,ncols,nrows,maxval,0);
  fclose(infile);
  fclose(outfile);
  return 1;
}
    std::unique_ptr<Image> loadPPMImage(const char* filepath)
    {
        FILE* fp = fopen(filepath, "rb");
        if (!fp)
        {
            printf("error loading file %s at loadPPMImage()\n", filepath);
            return std::unique_ptr<Image>();
        }

        int img_w, img_h;
        pixval max_pval;
        pixel** pixels = ppm_readppm(fp, &img_w, &img_h, &max_pval);
        if (!pixels)
        {
            printf("error reading image from file %s at loadPPMImage()\n", filepath);
            fclose(fp);
            return std::unique_ptr<Image>();
        }

        auto img_ptr = std::make_unique<Image>(img_w, img_h, 3);

        for (int y = 0; y < img_h; y++)
        {
            for (int x = 0; x < img_w; x++)
            {
                (img_ptr->getValues(0))[y * img_w + x] = static_cast<float>(pixels[y][x].r)
                        / max_pval;
                (img_ptr->getValues(1))[y * img_w + x] = static_cast<float>(pixels[y][x].g)
                        / max_pval;
                (img_ptr->getValues(2))[y * img_w + x] = static_cast<float>(pixels[y][x].b)
                        / max_pval;
            }
        }

        ppm_freearray(pixels, img_h);
        fclose(fp);
        return img_ptr;
    }
Exemple #11
0
int
main(int argc, char *argv[]) {

    struct cmdlineInfo cmdline;
    FILE* ifP;
    int rows, cols;
    pixval maxval;
    pixel **pixels;
    struct pcxCmapEntry * pcxcmap;
    colorhash_table cht;
    bool truecolor;
    int colors;

    ppm_init(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);

    ifP = pm_openr(cmdline.inputFilespec);
    pixels = ppm_readppm(ifP, &cols, &rows, &maxval);
    pm_close(ifP);

    if (cmdline.truecolor)
        truecolor = TRUE;
    else {
        if (cmdline.stdpalette) {
            truecolor = FALSE;
            generateStandardPalette(&pcxcmap, maxval, &cht, &colors);
        } else if (cmdline.palette) {
            truecolor = FALSE;
            readPaletteFromFile(&pcxcmap, cmdline.palette, maxval, 
                                &cht, &colors);
        } else {
            bool tooManyColors;
            makePcxColormapFromImage(pixels, cols, rows, maxval,
                                     &pcxcmap, &cht, &colors,
                                     &tooManyColors);
            
            if (tooManyColors) {
                pm_message("too many colors - writing a 24bit PCX file");
                pm_message("if you want a non-24bit file, "
                           " a 'pnmquant %d'", MAXCOLORS);
                truecolor = TRUE;
            } else
                truecolor = FALSE;
        }
    }

    if (truecolor)
        ppmToTruecolorPcx(pixels, cols, rows, maxval, 
                          cmdline.xpos, cmdline.ypos);
    else {
        ppmToPalettePcx(pixels, cols, rows, maxval, 
                        cmdline.xpos, cmdline.ypos,
                        pcxcmap, cht, colors, cmdline.packed, 
                        cmdline.planes, cmdline.use_8_bit);
        
        ppm_freecolorhash(cht);
        free(pcxcmap);
    }
    return 0;
}
Exemple #12
0
// Generates the messages based on the function requested by the client
// Function name is either: start_movie, stop_movie, seek_movie
void generateMessages(int workerThreadID, request* req) {
	int frame, messageID, endFrame, startFrame;
	int repeat;
	char* clientID = req->clientID;

	// Handle a stop_movie request
	// Add the clientID into the stopList
	if(strcmp(req->funcRequest, "stop_movie") == 0) {\
		insertStopID(clientID);
#ifdef DEBUG
		printStopList();
#endif
		return;
	}

	// Handle a start_movie request
	if (strcmp(req->funcRequest, "start_movie") == 0) {
		startFrame = 1;  
		repeat = req->argument; 
	}
	// Handle a seek_movie request
	else if(strcmp(req->funcRequest, "seek_movie") == 0) {
		// Start frame is the seek frame
		startFrame = req->argument;
		repeat = 0;
		// Do some minor error checking
		if (startFrame <= 0) {
			startFrame = 1;
		}
	}

	messageID = 1;
	endFrame = 100; //magic cookie bad

	// Create a message for each frame from the startframe to the endframe
	// For start_movie, it is the entire movie
	// For seek_movie, it is seekFrame-->endFrame
	for (frame = startFrame; frame <= endFrame; frame++) {
		pixel** pixArray;
		FILE *fp;
		int cols, rows;
		pixval maxval;
		char s[80];

		// Attempt to open the frame for processing
		sprintf (s, "./images/%s%d.ppm", req->filePrefix, frame);
		if ((fp = fopen (s,"r")) == NULL) {
			fprintf (stderr, "%s: Can't open input file:\n %s.\n", s);
			exit (1);
		}

		// Read the ppm image into a multidimensional array
		pixArray = ppm_readppm (fp, &cols, &rows, &maxval);
		fclose (fp);

		// Since all slots have a copy of the original client request
		// create a pointer to the request object so we don't waste memory
		request* copyReq = req;

		// IMPORTANT regarding stopping playback	
		// We check every 20 frames to reduce redundancy
		// We don't want to generate messages for a movie that the client
		// has already requested be stopped, so check every 20 messages to make sure
		if (frame != 100 && ((frame % 20) == 0)) {
			// If the message is part of a movie which the client has already
			// requested be stopped, then stop sending them frames and
			// jump to the last frame
			if (searchStopList(clientID) == TRUE) {
				frame = 99;	
				ppm_freearray (pixArray, rows);
			}
			// Otherwise this is still part of a valid movie request
			else {
				// Insert this message into the buffer	and increment the message id
				insertToBuffer(workerThreadID, copyReq, messageID, pixArray, rows, cols, frame, repeat);
				messageID++;
			}
		}
		else {
			// Insert this message into the buffer	and increment the message id
			insertToBuffer(workerThreadID, copyReq, messageID, pixArray, rows, cols, frame, repeat);
			messageID++;
		}
	}                                                                           
}
Exemple #13
0
static void 
addEntryToIcon(MS_Ico       const MSIconData, 
               const char * const xorPpmFname,
               const char * const andPgmFname,
               bool         const trueTransparent) {

    IC_Entry entry;
    FILE * xorfile;
    pixel ** xorPPMarray;
    gray ** andPGMarray;
    ICON_bmp xorBitmap;
    ICON_bmp andBitmap;
    int rows, cols;
    int bpp, colors;
    int entry_cols;
    IC_Palette palette;
    colorhash_table  xorCht;
    colorhash_table  andCht; 
    const char * error;
   
    pixval xorMaxval;
    gray andMaxval;

    MALLOCVAR_NOFAIL(entry);

   /*
    * Read the xor PPM.
    */
    xorfile = pm_openr(xorPpmFname);
    xorPPMarray = ppm_readppm(xorfile, &cols, &rows, &xorMaxval);
    pm_close(xorfile);
    /*
    * Since the entry uses 1 byte to hold the width and height of the icon, the
    * image can't be more than 256 x 256.
    */
    if (rows > 255 || cols > 255) {
        pm_error("Max size for a icon is 255 x 255 (1 byte fields).  "
                 "%s is %d x %d", xorPpmFname, cols, rows);
    }
   
    if (verbose) pm_message("read PPM: %dw x %dh, maxval = %d", 
                            cols, rows, xorMaxval);

    makePalette(xorPPMarray, cols, rows, xorMaxval, 
                &palette, &xorCht, &colors, &error);

    if (error)
        pm_error("Unable to make palette for '%s'.  %s", xorPpmFname, error);
   /*
    * All the icons I found seemed to pad the palette to the max entries
    * for that bitdepth.
    * 
    * The spec indicates this isn't neccessary, but I'll follow this behaviour
    * just in case.
    */
    if (colors < 3) {
        bpp = 1;
        entry_cols = 2;
    } else if (colors < 17) {
        bpp = 4;
        entry_cols = 16;
    } else {
        bpp = 8;
        entry_cols = 256;
    }

    getOrFakeAndMap(andPgmFname, cols, rows,
                    &andPGMarray, &andMaxval, &andCht, &error);
    if (error)
        pm_error("Error in and map for '%s'.  %s", xorPpmFname, error);

    if (andPGMarray && trueTransparent)
        blackenTransparentAreas(xorPPMarray, cols, rows, 
                                andPGMarray, andMaxval);

    xorBitmap = createBitmap(bpp, xorPPMarray, cols, rows, xorCht);
    andBitmap = createAndBitmap(andPGMarray, cols, rows, andMaxval);
    /*
     * Fill in the entry data fields.
    */
    entry->width         = cols;
    entry->height        = rows;
    entry->color_count   = entry_cols;
    entry->reserved      = 0;
    entry->planes        = 1;
    /* 
    * all the icons I looked at ignored this value...
    */
    entry->bitcount      = bpp;
    entry->ih            = createInfoHeader(entry, xorBitmap, andBitmap);
    entry->colors        = palette->colors;
    overflow2(4, entry->color_count);
    overflow_add(xorBitmap->size, andBitmap->size);
    overflow_add(xorBitmap->size + andBitmap->size, 40);
    overflow_add(xorBitmap->size + andBitmap->size + 40, 4 * entry->color_count);
    entry->size_in_bytes = 
        xorBitmap->size + andBitmap->size + 40 + (4 * entry->color_count);
    if (verbose) 
        pm_message("entry->size_in_bytes = %d + %d + %d = %d",
                   xorBitmap->size ,andBitmap->size, 
                   40, entry->size_in_bytes );
    /*
    * We don't know the offset ATM, set to 0 for now.
    * Have to calculate this at the end.
    */
    entry->file_offset   = 0;
    entry->xorBitmapOut  = xorBitmap->data;
    entry->andBitmapOut  = andBitmap->data;
    entry->xBytesXor     = xorBitmap->xBytes;
    entry->xBytesAnd     = andBitmap->xBytes;  
    /*
    * Add the entry to the entries array.
    */
    overflow_add(MSIconData->count,1);
    MSIconData->count++;
    /* 
    * Perhaps I should use something that allocs a decent amount at start...
    */
    MSIconData->entries = 
        realloc2 (MSIconData->entries, MSIconData->count * sizeof(IC_Entry *));
    MSIconData->entries[MSIconData->count-1] = entry;
}
Exemple #14
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;
}
Exemple #15
0
int
main(int argc, char *argv[]) {

    FILE *ifp;
    int rows, cols;
    unsigned int ncolors;
    bool transparentSomewhere;
    pixval maxval, alphaMaxval;
    colorhash_table cht;
    colorhist_vector chv;

    colorhash_table colornameHash;
        /* Hash table to map colors to their names */
    const char ** colornames;
        /* Table of color names; 'colornameHash' yields an index into this
           array.
        */

    pixel **pixels;
    gray **alpha;

    /* Used for rgb value -> character-pixel string mapping */
    cixel_map *cmap;  /* malloc'ed */
        /* The XPM colormap */
    unsigned int cmapSize;
        /* Number of entries in 'cmap' */
    unsigned int transIndex;
        /* Index into 'cmap' of the transparent color, if there is one */

    unsigned int charsPerPixel;  

    struct cmdlineInfo cmdline;

    ppm_init(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);

    ifp = pm_openr(cmdline.inputFilename);
    pixels = ppm_readppm(ifp, &cols, &rows, &maxval);
    pm_close(ifp);

    if (cmdline.alpha_filename) 
        readAlpha(cmdline.alpha_filename, &alpha, cols, rows, &alphaMaxval);
    else
        alpha = NULL;

    computeColormap(pixels, alpha, cols, rows, alphaMaxval,
                    &chv, &cht, &ncolors, &transparentSomewhere);

    if (cmdline.hexonly)
        colornameHash = NULL;
    else if (cmdline.rgb)
        ppm_readcolornamefile(cmdline.rgb, TRUE, &colornameHash, &colornames);
    else
        ppm_readcolornamefile(NULL, FALSE, &colornameHash, &colornames);

    /* Now generate the character-pixel colormap table. */
    genCmap(chv, ncolors, maxval, 
            colornameHash, colornames, transparentSomewhere, 
            &cmap, &transIndex, &cmapSize, &charsPerPixel);

    writeXpmFile(stdout, pixels, alpha, alphaMaxval,
                 cmdline.name, cols, rows, cmapSize,
                 charsPerPixel, cmap, cht, transIndex);
    
    if (colornameHash) {
        ppm_freecolorhash(colornameHash);
        ppm_freecolornames(colornames);
    }
    destroyCmap(cmap, cmapSize);
    ppm_freearray(pixels, rows);
    if (alpha) pgm_freearray(alpha, rows);

    return 0;
}