Esempio n. 1
0
void pnm_ppm_free(ppm_t *ppm)
{
  if (!ppm) return;
  if (ppm->pixels)
    ppm_freearray(ppm->pixels, ppm->rows);
  pnm_ppm_init(ppm);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
static void
destroyCanvas(canvas * const canvasP) {

    ppm_freearray(canvasP->pixels, canvasP->height);

    free(canvasP);
}
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;
}
Esempio n. 5
0
/** frees the data */
void GeoImage::freeData()
{
  if (data_) {
    switch (type_) {
    case PBM:
      pbm_freearray(data_, rows_);
      break;
    case PGM:
      pgm_freearray(data_, rows_);
      break;
    case PPM:
      ppm_freearray(data_, rows_);
      break;
    case PFM_3BYTE:{
        PFM3Byte *ppmbuf = (PFM3Byte *) data_;
        free(ppmbuf->r);
        free(ppmbuf->g);
        free(ppmbuf->b);
        free(data_);
      }
      break;
    default:
      free(data_);
      break;
    }
    data_ = 0;
    dataSize_=0;
  }
}
Esempio n. 6
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);
}        
    bool saveAsPPM(const std::unique_ptr<Image>& img_ptr, const char* filepath)
    {
        FILE* fp = fopen(filepath, "wb");
        if (!fp)
        {
            printf("error loading file %s at saveAsPPM()\n", filepath);
            return false;
        }

        const size_t w = img_ptr->getWidth();
        const size_t h = img_ptr->getHeight();
        const pixval maxVal = 255;

        pixel** pxls = ppm_allocarray(w, h);
        if (!pxls)
        {
            printf("error allocating memory space at saveAsPPM()");
            fclose(fp);
            return false;
        }

        for (size_t y = 0; y < h; y++)
        {
            for (size_t x = 0; x < w; x++)
            {
                if (img_ptr->getChannelNum() >= 3)
                {
                    float vclip[3];
                    for (size_t c = 0; c < 3; c++)
                    {
                        vclip[c] = (img_ptr->getValues(c))[y*w + x];
                        if (vclip[c] < 0)
                            vclip[c] = 0;
                        if (vclip[c] > 1)
                            vclip[c] = 1;
                    }
                    pxls[y][x].r = static_cast<pixval>(vclip[0] * maxVal);
                    pxls[y][x].g = static_cast<pixval>(vclip[1] * maxVal);
                    pxls[y][x].b = static_cast<pixval>(vclip[2] * maxVal);
                }
                else
                {
                    float vclip = (img_ptr->getValues(0))[y*w + x];
                    if (vclip < 0)
                        vclip = 0;
                    if (vclip > 1)
                        vclip = 1;
                    pxls[y][x].r = static_cast<pixval>(vclip * maxVal);
                    pxls[y][x].g = static_cast<pixval>(vclip * maxVal);
                    pxls[y][x].b = static_cast<pixval>(vclip * maxVal);
                }
            }
        }

        ppm_writeppm(fp, pxls, w, h, maxVal, 0);
        ppm_freearray(pxls, h);
        fclose(fp);
        return true;
    }
Esempio n. 8
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);
}
Esempio n. 9
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);
}
Esempio n. 10
0
void process_file(const char *fname) {
	FILE *in;
	int codec, num_images, format;
	int i;
	int width, height, size, maxval;
	unsigned char *data;
	pixel **img;

	in = fopen(fname, "rb");
	if (in == NULL) {
		perror(fname);
		exit(1);
	}
	read_header(in, &codec, &num_images, &format);

	for (i = 0; i < num_images; i++) {
		width = read_LEint32(in);
		height = read_LEint32(in);
		data = malloc(width * height * 2);

		if (codec == 0)
			read_data_codec0(in, width, height, data);
		else if (codec == 3) {
			size = read_LEint32(in);
			read_data_codec3(in, size, data);
		} else {
			fprintf(stderr, "%s: unsupported codec %d\n", fname, codec);
			exit(1);
		}

		if (format == 1) {
			img = toimg_fmt1(data, width, height);
			maxval = 255;
		} else if (format == 5) {
			img = toimg_fmt5(data, width, height);
			maxval = 255;
		} else {
			fprintf(stderr, "%s: unsupported format %d\n", fname, format);
			exit(1);
		}

		write_img(img, fname, i, width, height, maxval);
		free(data);
		ppm_freearray(img, height);
	}
	fclose(in);
}
Esempio n. 11
0
void savebmp(const char *filename, float wf, float hf, int dpi,  std::vector< std::vector <Pixel> >* data)
{
       /* Example program fragment to read a PAM or PNM image
      from stdin, add up the values of every sample in it
      (I don't know why), and write the image unchanged to
      stdout. */
   FILE* f = fopen(filename,"wb");
   pm_init(filename, 0);
   pixel** truePix = ppm_allocarray(wf,hf);
   for (int i = 0; i < wf; i++)
   {
       for (int j = 0; j < hf; j++)
       {
           PPM_ASSIGN(truePix[i][j],data->at(i).at(j).getColor()->getRed(), data->at(i).at(j).getColor()->getGreen(), data->at(i).at(j).getColor()->getBlue());
       }
   }
   ppm_writeppm(f, truePix, (int)wf, (int)hf, 256, 0); 
   ppm_freearray(truePix, (int)hf);
}
Esempio n. 12
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);
}
Esempio n. 13
0
void write_img(FILE *f, const char *fname, int n, int num_img) {
	FILE *out;
	int32_t width, height;
	int x, y;
	unsigned char p;
	pixel **img;
	char newname[1024];
	const char *basename;

	fseek(f, 116 + 40 * (num_img - 1), SEEK_SET);
	width = read_LEint32(f);
	height = read_LEint32(f);
	img = ppm_allocarray(width, height);
	fseek(f, 100 + 40 * num_img + (width * height + 24) * n, SEEK_SET);
	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++) {
			p = getc(f);
			img[y][x] = cmap[p];
		}

		basename = strrchr(fname, '/');
		if (basename != NULL)
			basename++;
		else
			basename = fname;
		strcpy(newname, basename);
		if (strlen(newname) > 4 &&
			strcasecmp(newname + strlen(newname) - 4, ".mat") == 0)
			newname[strlen(newname) - 4] = '\0';
		sprintf(newname + strlen(newname), "_%d.ppm", n);

		out = fopen(newname, "wb");
		if (out == NULL) {
			perror(newname);
			exit(1);
		}

		ppm_writeppm(out, img, width, height, 255, 0);
		ppm_freearray(img, height);
		fclose(out);
}
Esempio n. 14
0
    std::unique_ptr<Image> loadPGMImage(const char* filepath)
    {
        FILE* fp = fopen(filepath, "rb");
        if (!fp)
        {
            printf("error loading file %s at loadPGMImage()\n", filepath);
            return std::unique_ptr<Image>();
        }

        int img_w, img_h;
        gray max_pval;
        gray** pixels = pgm_readpgm(fp, &img_w, &img_h, &max_pval);
        if (!pixels)
        {
            printf("error reading image from file %s at loadPGMImage()\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])
                        / max_pval;
                (img_ptr->getValues(1))[y * img_w + x] = static_cast<float>(pixels[y][x])
                        / max_pval;
                (img_ptr->getValues(2))[y * img_w + x] = static_cast<float>(pixels[y][x])
                        / max_pval;
            }
        }

        ppm_freearray(pixels, img_h);
        fclose(fp);
        return img_ptr;
    }
Esempio n. 15
0
/** write a scrap of the data,
  * return the filename,
  * if the file exist do nothing
  * argument fname is optional
  * the coordinates of the image part are geodata e.g. Gauss Krueger **/
QString
  GeoImage::part(float west, float north, float east, float south,
                 QString fname)
{
  if (fname.isEmpty()) {        //create output filname
    Q_ASSERT(contains("key"));
    QString dir = CleanUp::getTmpDir();
    fname.sprintf("%s/%s_%f_%f_%f_%f", 
		  dir.toLatin1().constData(), 
		  value("key").toLatin1().constData(),
                  west, north, east, south);
  }
  qDebug("#  GeoImage::part %s (%f, %f, %f, %f)", 
	 fname.toLatin1().constData(), west,
         north, east, south);
  QFile f(fname);
  if (f.exists())
    return fname;

  const void *data_p = data();        //get pointer to data
  Q_ASSERT(data_p);
  if (type_ == UNKNOWN)
    return 0;
  int dx, dy, i, j, rx1, ry1, rx2, ry2;
  picBBox(west, north, east, south, rx1, ry2, rx2, ry1);
  dx = rx2 - rx1 + 1;
  dy = ry2 - ry1 + 1;
  if (dx <= 0 || dy <= 0) {
    qDebug("#  (ERROR) GeoImage::part: (dx=%d=%d-%d || dy=%d=%d-%d)", dx, rx2,
           rx1, dy, ry2, ry1);
    throw ImageException(rx1,rx2,dx,ry1,ry2,dy); 
  }

  FILE *of = fopen(fname.toLatin1().constData(), "w");
  if (!of) {
    throw FileIOException(FileIOException::OPEN_FAILED,fname);
  }

  switch (type_) {
  case PBM:{
      bit *bpi, *bpo, **dat_b_out = pbm_allocarray(dx, dy);
      bit **dat_b = (bit **) data_p;
      for (i = 0; i < dy; i++) {
        bpi = dat_b[i + ry1] + rx1;
        bpo = dat_b_out[i];
        for (j = 0; j < dx; j++) {
          *bpo = *bpi;
          bpo++;
          bpi++;
        }
      }
      pbm_writepbm(of, (bit **) dat_b_out, dx, dy, 0);
      pbm_freearray(dat_b_out, dy);
    }
    break;
  case PGM:{
      gray *gpi, *gpo, **dat_g_out = pgm_allocarray(dx, dy);
      gray **dat_g = (gray **) data_p;
      gray maxval = 0;
      for (i = 0; i < dy; i++) {
        gpi = dat_g[i + ry1] + rx1;
        gpo = dat_g_out[i];
        for (j = 0; j < dx; j++) {
          *gpo = *gpi;
          if (*gpi > maxval)
            maxval = *gpi;
          gpo++;
          gpi++;
        }
      }
      pgm_writepgm(of, (gray **) dat_g_out, dx, dy, maxval, 0);
      pgm_freearray(dat_g_out, dy);
    }
    break;
  case PPM:{
      pixel *ppi, *ppo, **dat_p_out = ppm_allocarray(dx, dy);
      pixel **dat_p = (pixel **) data_p;
      pixval maxval = 255;      //! should be calculated
      for (i = 0; i < dy; i++) {
        ppi = dat_p[i + ry1] + rx1;
        ppo = dat_p_out[i];
        for (j = 0; j < dx; j++) {
          *ppo = *ppi;
          ppo++;
          ppi++;
        }
      }
      ppm_writeppm(of, (pixel **) dat_p_out, dx, dy, maxval, 0);
      ppm_freearray(dat_p_out, dy);
    }
    break;
  default:
    pfm_geo_set(geoWest(),geoNorth(),geoEast(),geoSouth());
    pfm_writepfm_region_type(of, data_, cols_, rows_, minval_, maxval_,
                             rx1, ry1, rx2, ry2, type_);
    break;
  }
  fclose(of);
  return fname;
}
Esempio n. 16
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++;
		}
	}                                                                           
}
Esempio n. 17
0
// Sends the pixarray for a given slot in the circular buffer
// The size of the frame we send is (rows * cols * 3) + 1.
// The *3 is for the three channels per pixel (RGB) and the +1
// is an extra byte which lets the client know whether or not
// more data is coming (we denote this byte as the TERM flag).
// If the term flag == 1, then there is more data coming, so the
// client should keep the connection open.
// If the term flag == 0, then there is no more data coming, and
// the client should close the connection.
void sendFrame(int bufferIndex) { 
	int i = bufferIndex;
	int sizeToSend = buffer[i].rows * buffer[i].cols * 3 + 1;
	int x, y;
	int rows = buffer[i].rows;
	int cols = buffer[i].cols;
	unsigned char *buf = NULL;

	// +1 slot used to determine if there is more data coming: 0 or 1
	buf = (unsigned char *)malloc ((cols*rows*3) + 1);
	if (!buf) {
		perror("Could not malloc memory for buf\n");	
		exit(1);
	}

	// Place the frame data into a char array
	for (y = 0; y < rows; y++) {
		for (x = 0; x < cols; x++) {
			buf[(y*cols+x)*3+0] = PPM_GETR(buffer[i].pixArray[rows-y-1][x]);
			buf[(y*cols+x)*3+1] = PPM_GETG(buffer[i].pixArray[rows-y-1][x]);
			buf[(y*cols+x)*3+2] = PPM_GETB(buffer[i].pixArray[rows-y-1][x]);
		}
	}
	char* clientID = buffer[i].clientRequest->clientID;

	// Determine if this is part of a movie which was already stopped by client
	int inStopList = searchStopList(clientID);

	// clientRequest objects are shared for all frames belonging to a single
	// client request.  Therefore, no need to make redundant copies, just pointers.
	// Only free this client request obj when the last frame is serviced!
	int deleteFlag = FALSE;

	// Check to see if the movie has repeat = 1, if so, there is more data to send even
	// though the movie is done playing.
	if (buffer[i].frame == 100) {
		// If its a repeat, and the client hasnt requested a stop movie, then copy this request again
		if (buffer[i].repeat == TRUE && inStopList == FALSE) {
			// Add a start_movie request to the request list, with repeat flag = 1
			// Set the 100th frame with more data flag = 1
			deleteFlag = FALSE;
			insertRequest(buffer[i].clientRequest);
			buf[cols*rows*3] = NOTCLOSE;
		}
		else {
			// Call deleteStopID(clientID)
			// Set the 100th frame with more data flag = 0
			deleteStopID(clientID);
			buf[cols*rows*3] = CLOSE;
			deleteFlag = TRUE;
		}
	}
	// If its not the last frame
	else {
		// If it is part of a movie which was stopped, then this is the last frame
		// and the client should just close the connection
		if (inStopList == TRUE) {
			buf[cols*rows*3] = CLOSE;
		}
		// Otherwise this is a frame for a movie which has regular playback
		// so don't close the connection, just receive the movie frames
		else {
			buf[cols*rows*3] = NOTCLOSE;
		}
	}

	// The movie hasn't been stopped, so send the frame data
	if (inStopList == FALSE) {
		// Send the entire frame (reduces write syscalls)
#ifdef DEBUG
		printf("Send frame: %d    request string: %s\n", 
				buffer[i].frame, buffer[i].clientRequest->requestString);
#endif
		write(buffer[i].clientRequest->clientSD, buf, sizeToSend);
		if (errno == EPIPE) {
#ifdef DEBUG
			printf("Got EPIPE error   errno: %d\n", errno);
#endif
			insertStopID(buffer[i].clientRequest->clientID);
			close(buffer[i].clientRequest->clientSD);
			errno = 0;
		}
	}

	// Release the memory 
	ppm_freearray (buffer[i].pixArray, buffer[i].rows);
	free(buf);

	// If this clientRequest obj is not going to be used anymore, free
	if (deleteFlag == TRUE) {
		free(buffer[i].clientRequest);
	}
}
Esempio n. 18
0
static void convert_image(const char *filename, const char *name)
{
    FILE *fp;
    xel **pnm;
    xelval maxval;
    int cols, rows, fmt, clut_len = 0, size;
    const char *type;

    // Load the image
    if (!strcmp(filename, "-"))
	fp = stdin;
    else {
	fp = fopen(filename, "r");
	if (!fp) {
	    fprintf(stderr, "Cannot open file %s: %s\n", filename,
		    strerror(errno));
	    exit(1);
	}
    }
    pnm = pnm_readpnm(fp, &cols, &rows, &maxval, &fmt);
    if (!pnm) {
	fprintf(stderr, "Error reading PNM file: %s\n", strerror(errno));
	exit(1);
    }

    switch (PNM_FORMAT_TYPE(fmt)) {
	case PPM_TYPE:
	    normalize_ppm(pnm, cols, rows, maxval);
	    clut_len = fill_clut(pnm, cols, rows);
	    if (clut_len > 0 && clut_len <= 256) {
		type = "CLUT256";
		size = cols*rows;
	    } else {
		type = "RGB888";
		size = cols*rows*3;
	    }
	    break;

	case PGM_TYPE:
	    type = "GREY256";
	    size = cols*rows;
	    break;

	case PBM_TYPE:
	    type = "BW";
	    size = (cols+7)/8*rows;
	    break;

	default:
	    fprintf(stderr, "Unknown PNM format %d\n", PNM_FORMAT_TYPE(fmt));
	    exit(1);
    }

    // Print header
    printf("    /*\n");
    printf("     *  Image %s\n", name);
    printf("     */\n\n");
    printf("#include \"image.h\"\n\n");

    // Print forward declarations
    printf("static const unsigned char %s_data[];\n", name);
    if (clut_len > 0 && clut_len <= 256)
	printf("static const unsigned char %s_clut[];\n", name);
    printf("\n");

    // Print image structure
    printf("const struct image %s = {\n", name);
    printf("    width:\t%d,\n", cols);
    printf("    height:\t%d,\n", rows);
    printf("    type:\tIMAGE_%s,\n", type);
    printf("    data:\t%s_data,\n", name);
    if (clut_len > 0 && clut_len <= 256) {
	printf("    clut_len:\t%d,\n", clut_len);
	printf("    clut:\t%s_clut\n", name);
    }
    printf("};\n\n");

    // Print image data
    printf("static const unsigned char %s_data[%d] = {\n", name, size);
    switch (PNM_FORMAT_TYPE(fmt)) {
	case PPM_TYPE:
	    if (clut_len > 0 && clut_len <= 256)
		print_clut256_data(pnm, cols, rows, clut_len);
	    else
		print_rgb888_data(pnm, cols, rows);
	    break;

	case PGM_TYPE:
	    print_grey256_data(pnm, cols, rows, maxval);
	    break;

	case PBM_TYPE:
	    print_bw_data(pnm, cols, rows);
	    break;
    }
    printf("};\n\n");

    // Print image clut
    if (clut_len > 0 && clut_len <= 256) {
	printf("static const unsigned char %s_clut[%d] = {\n", name,
	       clut_len*3);
	print_image_clut(clut_len);
	printf("};\n\n");
    }

    // Free temporary data
    ppm_freearray(pnm, rows);
}
Esempio n. 19
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;
}