Пример #1
0
static void
makeNewXel(xel * const outputXelP, xel const curXel, xel const prevXel,
           double const fracnew0, double const omfracnew0, int const format) {
/*----------------------------------------------------------------------------
   Create an output xel as *outputXel, which is part curXel and part
   prevXel, the part given by the fractions omfracnew0 and fracnew0,
   respectively.  These fraction values are the numerator of a fraction
   whose denominator is SCALE.

   The format of the pixel is 'format'.
-----------------------------------------------------------------------------*/

    switch ( PNM_FORMAT_TYPE(format) ) {
    case PPM_TYPE:
        PPM_ASSIGN( *outputXelP,
                    ( fracnew0 * PPM_GETR(prevXel) 
                      + omfracnew0 * PPM_GETR(curXel) 
                      + HALFSCALE ) / SCALE,
                    ( fracnew0 * PPM_GETG(prevXel) 
                      + omfracnew0 * PPM_GETG(curXel) 
                      + HALFSCALE ) / SCALE,
                    ( fracnew0 * PPM_GETB(prevXel) 
                      + omfracnew0 * PPM_GETB(curXel) 
                      + HALFSCALE ) / SCALE );
        break;
        
    default:
        PNM_ASSIGN1( *outputXelP,
                     ( fracnew0 * PNM_GET1(prevXel) 
                       + omfracnew0 * PNM_GET1(curXel) 
                       + HALFSCALE ) / SCALE );
        break;
    }
}
Пример #2
0
static void
makeIcrColormap(colorhist_vector const chv,
                unsigned int     const colorCt,
                pixval           const maxval,
                char *           const rgb) {

    unsigned int i;

    if (maxval > 255)
        pm_message("Maxval is not 255 - automatically rescaling colors" );

    for (i = 0; i < CLUTCOLORCT; ++i)
        rgb[i] = 0;

    for (i = 0; i < colorCt; ++i) {
        unsigned int j;

        j = (3 * i);

        if (maxval == 255) {
            rgb[j++] = PPM_GETR(chv[i].color) ;
            rgb[j++] = PPM_GETG(chv[i].color) ;
            rgb[j++] = PPM_GETB(chv[i].color) ;
        } else {
            rgb[j++] = (unsigned int) PPM_GETR(chv[i].color) * 255 / maxval;
            rgb[j++] = (unsigned int) PPM_GETG(chv[i].color) * 255 / maxval;
            rgb[j++] = (unsigned int) PPM_GETB(chv[i].color) * 255 / maxval;
        }
    }
}
Пример #3
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;
    }
}
Пример #4
0
char*
ppm_colorname(const pixel* const colorP, 
              pixval       const maxval, 
              int          const hexok)   {

    int r, g, b;
    FILE* f;
    static char colorname[200];

    if (maxval == 255) {
        r = PPM_GETR(*colorP);
        g = PPM_GETG(*colorP);
        b = PPM_GETB(*colorP);
    } else {
        r = (int) PPM_GETR(*colorP) * 255 / (int) maxval;
        g = (int) PPM_GETG(*colorP) * 255 / (int) maxval;
        b = (int) PPM_GETB(*colorP) * 255 / (int) maxval;
    }

    f = pm_openColornameFile(NULL, !hexok);
    if (f != NULL) {
        int best_diff, this_diff;
        bool eof;

        best_diff = 32767;
        eof = FALSE;
        while (!eof && best_diff > 0 ) {
            struct colorfile_entry const ce = pm_colorget(f);
            if (ce.colorname)  {
                this_diff = abs(r - ce.r) + abs(g - ce.g) + abs(b - ce.b);
                if (this_diff < best_diff) {
                    best_diff = this_diff;
                    strcpy(colorname, ce.colorname);
                }
            } else
                eof = TRUE;
        }
        fclose(f);
        if (best_diff != 32767 && (best_diff == 0 || ! hexok))
            return colorname;
    }

    /* Color lookup failed, but caller is willing to take an X11-style
       hex specifier, so return that.
    */
    sprintf(colorname, "#%02x%02x%02x", r, g, b);
    return colorname;
}
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;
}
Пример #6
0
static void
ppm_writeppmrowplain(FILE *        const fileP,
                     const pixel * const pixelrow,
                     unsigned int  const cols,
                     pixval        const maxval) {

    unsigned int col;
    unsigned int charcount;

    charcount = 0;

    for (col = 0; col < cols; ++col) {
        if (charcount >= 65) {
            putc('\n', fileP);
            charcount = 0;
        } else if (charcount > 0) {
            putc(' ', fileP);
            putc(' ', fileP);
            charcount += 2;
        }
        putus(PPM_GETR(pixelrow[col]), fileP);
        putc(' ', fileP);
        putus(PPM_GETG(pixelrow[col]), fileP);
        putc(' ', fileP);
        putus(PPM_GETB(pixelrow[col]), fileP);
        charcount += 11;
    }
    if (charcount > 0)
        putc('\n', fileP);
}
Пример #7
0
static void
format2bpsRow(const pixel *   const pixelrow,
              unsigned int    const cols,
              unsigned char * const rowBuffer) {
    
    /* two byte samples. */

    unsigned int col;
    unsigned int bufferCursor;

    bufferCursor = 0;

    for (col = 0; col < cols; ++col) {
        pixval const r = PPM_GETR(pixelrow[col]);
        pixval const g = PPM_GETG(pixelrow[col]);
        pixval const b = PPM_GETB(pixelrow[col]);
        
        rowBuffer[bufferCursor++] = r >> 8;
        rowBuffer[bufferCursor++] = (unsigned char)r;
        rowBuffer[bufferCursor++] = g >> 8;
        rowBuffer[bufferCursor++] = (unsigned char)g;
        rowBuffer[bufferCursor++] = b >> 8;
        rowBuffer[bufferCursor++] = (unsigned char)b;
    }
}
Пример #8
0
static void
convertPpmRaster(FILE *          const ifP,
                 int             const format,
                 xelval          const maxval,
                 unsigned int    const cols,
                 unsigned int    const rows,
                 FILE *          const ofP,
                 unsigned int    const bytesPerLine,
                 unsigned char * const data) {

    pixel * const pixels = ppm_allocrow(cols);

    unsigned int row;

    for (row = 0; row < rows; ++row) {
        unsigned char * p;
        unsigned int col;
        size_t bytesWritten;

        p = &data[0];

        ppm_readppmrow(ifP, pixels, cols, maxval, format);

        for (col = 0; col < cols; ++col) {
            *p++ = PPM_GETR(pixels[col]);
            *p++ = PPM_GETG(pixels[col]);
            *p++ = PPM_GETB(pixels[col]);
        }
        bytesWritten =  fwrite(data, 1, bytesPerLine, ofP);
        if (bytesWritten != bytesPerLine)
            pm_error("File write error on Row %u", row);
    }
    ppm_freerow(pixels);
}
Пример #9
0
static void
getSpecifiedMissingColor(struct pam * const pamP,
                         const char * const colorName,
                         tuple *      const specColorP) {

    tuple specColor;
                             
    specColor = pnm_allocpamtuple(pamP);

    if (colorName) {
        pixel const color = ppm_parsecolor(colorName, pamP->maxval);
        if (pamP->depth == 3) {
            specColor[PAM_RED_PLANE] = PPM_GETR(color);
            specColor[PAM_GRN_PLANE] = PPM_GETG(color);
            specColor[PAM_BLU_PLANE] = PPM_GETB(color);
        } else if (pamP->depth == 1) {
            specColor[0] = ppm_luminosity(color);
        } else {
            pm_error("You may not use -missing with a colormap that is not "
                     "of depth 1 or 3.  Yours has depth %u",
                     pamP->depth);
        }
    }
    *specColorP = specColor;
}
Пример #10
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);
}
Пример #11
0
static void
convertLinear(FILE * const ifP,
              unsigned int const cols,
              unsigned int const rows,
              gray         const maxval,
              int          const format,
              const char * const colorNameBlack,
              const char * const colorNameWhite,
              FILE *       const ofP,
              gray *       const grayrow,
              pixel *      const pixelrow) {

    pixel colorBlack, colorWhite;
    pixval red0, grn0, blu0, red1, grn1, blu1;
    unsigned int row;

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

    colorBlack = ppm_parsecolor(colorNameBlack, maxval);
    colorWhite = ppm_parsecolor(colorNameWhite, maxval);
 
    red0 = PPM_GETR(colorBlack);
    grn0 = PPM_GETG(colorBlack);
    blu0 = PPM_GETB(colorBlack);
    red1 = PPM_GETR(colorWhite);
    grn1 = PPM_GETG(colorWhite);
    blu1 = PPM_GETB(colorWhite);

    for (row = 0; row < rows; ++row) {
        unsigned int col;

        pgm_readpgmrow(ifP, grayrow, cols, maxval, format);

        for (col = 0; col < cols; ++col) {
            gray const input = grayrow[col];
            PPM_ASSIGN(
                pixelrow[col],
                (red0 * (maxval - input) + red1 * input) / maxval,
                (grn0 * (maxval - input) + grn1 * input) / maxval,
                (blu0 * (maxval - input) + blu1 * input) / maxval);
        }
        ppm_writeppmrow(ofP, pixelrow, cols, maxval, 0);
    }
}
Пример #12
0
/** gets the id at the picture coordinatex x, y */
int GeoImage::getId(int x, int y)
{
  if (x < 0 || x >= cols_ || y < 0 || y >= rows_) {
    qDebug("GeoImage::getId() out of range (%d,%d) image size %dx%d", x, y,
           cols_, rows_);
    return -1;
  }
  Q_ASSERT(x >= 0);
  Q_ASSERT(x < cols_);
  Q_ASSERT(y >= 0);
  Q_ASSERT(y < rows_);
  const void* data_p=data();
  if (!data_p)
    return 0;
  switch (type_) {
  case PFM_SINT:{
      const signed int *p = (const signed int *) data_p;
      return (int) p[y * cols_ + x];
    }
  case PFM_SINT16:{
      const signed short int *p = (const signed short int *) data_p;
      return (int) p[y * cols_ + x];
    }
  case PFM_UINT16:{
      const unsigned short int *p = (const unsigned short int *) data_p;
      return (int) p[y * cols_ + x];
    }
  case PFM_BYTE:{
      const unsigned char *p = (const unsigned char *) data_p;
      return (int) p[y * cols_ + x];
    }
  case PFM_3BYTE:{
      const PFM3Byte *p = (const PFM3Byte *) data_p;
      unsigned char r = (p->r)[y * cols_ + x];
      unsigned char g = (p->g)[y * cols_ + x];
      unsigned char b = (p->b)[y * cols_ + x];
      return qRgb(r, g, b);
    }
  case PBM:{
      const bit *p = (const bit *) data_p;
      return (int) p[y * cols_ + x];
    }
  case PGM:{
      const gray *p = (const gray *) data_p;
      return (int) p[y * cols_ + x];
    }
  case PPM:{
      const pixel **p = (const pixel **) data_p;
      pixel v = p[y][x];
      return qRgb(PPM_GETR(v), PPM_GETG(v), PPM_GETB(v));
    }
  default:
    return 0;
  }
}
Пример #13
0
static struct pcxCmapEntry
pcxCmapEntryFromPixel(pixel const colorPixel) {

    struct pcxCmapEntry retval;

    retval.r = PPM_GETR(colorPixel);
    retval.g = PPM_GETG(colorPixel);
    retval.b = PPM_GETB(colorPixel);

    return retval;
}
Пример #14
0
static void
out_splines(FILE *                 const fileP,
            spline_list_array_type const shape,
            unsigned int           const height) {

    unsigned listSeq;
    pixel lastColor;
    
    PPM_ASSIGN(lastColor, 0, 0, 0);
    
    for (listSeq = 0;
         listSeq < SPLINE_LIST_ARRAY_LENGTH(shape);
         ++listSeq) {
        
        spline_list_type const splineList =
            SPLINE_LIST_ARRAY_ELT(shape, listSeq);
        spline_type const first = SPLINE_LIST_ELT(splineList, 0);

        if (listSeq == 0 || !PPM_EQUAL(splineList.color, lastColor)) {
            if (listSeq > 0) {
                /* Close previous <path> element */
                if (!(shape.centerline || splineList.open))
                    fputs("z", fileP);
                fputs("\"/>\n", fileP);
            }
            /* Open new <path> element */
            fprintf(fileP, "<path style=\"%s:#%02x%02x%02x; %s:none;\" d=\"",
                    (shape.centerline || splineList.open) ? "stroke" : "fill",
                    PPM_GETR(splineList.color),
                    PPM_GETG(splineList.color),
                    PPM_GETB(splineList.color),
                    (shape.centerline || splineList.open) ? "fill" : "stroke");
        }
        fprintf(fileP, "M%g %g",
                START_POINT(first).x, height - START_POINT(first).y);

        outSplineList(fileP, splineList, height);

        lastColor = splineList.color;
    }

    if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0) {
        spline_list_type const lastSplineList =
            SPLINE_LIST_ARRAY_ELT(shape, SPLINE_LIST_ARRAY_LENGTH(shape)-1);

        if (!(shape.centerline || lastSplineList.open))
            fputs("z", fileP);

        /* Close last <path> element */
        fputs("\"/>\n", fileP);
    }
}
Пример #15
0
static void
ppmToTruecolorPcx(pixel **     const pixels, 
                  int          const cols, 
                  int          const rows, 
                  pixval       const maxval,
                  unsigned int const xPos, 
                  unsigned int const yPos) {

    unsigned char *redrow, *greenrow, *bluerow;
    int col, row;

    redrow   = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char));
    greenrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char));
    bluerow  = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char));

    /* 8 bits per pixel, 3 planes */
    write_header(stdout, cols, rows, 8, 3, NULL, xPos, yPos);
    for( row = 0; row < rows; row++ ) {
        register pixel *pP = pixels[row];
        for( col = 0; col < cols; col++, pP++ ) {
            if( maxval != PCX_MAXVAL ) {
                redrow[col]   = (long)PPM_GETR(*pP) * PCX_MAXVAL / maxval;
                greenrow[col] = (long)PPM_GETG(*pP) * PCX_MAXVAL / maxval;
                bluerow[col]  = (long)PPM_GETB(*pP) * PCX_MAXVAL / maxval;
            }
            else {
                redrow[col]   = PPM_GETR(*pP);
                greenrow[col] = PPM_GETG(*pP);
                bluerow[col]  = PPM_GETB(*pP);
            }
        }
        PCXEncode(stdout, redrow, cols);
        PCXEncode(stdout, greenrow, cols);
        PCXEncode(stdout, bluerow, cols);
    }
    pm_freerow((void*)bluerow);
    pm_freerow((void*)greenrow);
    pm_freerow((void*)redrow);
}
Пример #16
0
static void
fillPpmBins(FILE *          const ifP,
            unsigned int    const cols,
            unsigned int    const rows,
            xelval          const maxval,
            int             const format,
            bool            const colorWanted[3],
            bool            const verbose,
            xelval          const startval,
            xelval          const endval,
            unsigned int    const histWidth,
            unsigned int ** const hist) {
/*----------------------------------------------------------------------------
   For each wanted color component, given by colorWanted[], hist[color] is the
   histogram.  Each histogram as 'histWidth' bins; we ignore color component
   values less than 'startval' and greater than or equal to 'endval' and
   spread the rest evenly across the 'histWidth' bins.

   We get the color component values from the PNM image on *ifP,
   which is positioned to the raster, whose format is described
   by 'cols', 'rows', 'maxval', and 'format'.
-----------------------------------------------------------------------------*/
    pixel * pixrow;
    unsigned int row;

    pixrow = ppm_allocrow(cols);

    if (verbose)
        pm_message("making histogram...");

    for (row = 0; row < rows; ++row) {
        unsigned int col;
        ppm_readppmrow(ifP, pixrow, cols, maxval, format);
        for (col = 0; col < cols; ++col) {
            if (colorWanted[WANT_RED])
                countComp(PPM_GETR(pixrow[col]),
                          startval, endval, histWidth, hist[WANT_RED]);

            if (colorWanted[WANT_GRN])
                countComp(PPM_GETG(pixrow[col]),
                          startval, endval, histWidth, hist[WANT_GRN]);

            if (colorWanted[WANT_BLU])
                countComp(PPM_GETB(pixrow[col]),
                          startval, endval, histWidth, hist[WANT_BLU]);
        }
    }
    ppm_freerow(pixrow);
}
Пример #17
0
static void print_image_clut(int clut_len)
{
    int i, j;

    for (i = 0, j = 0; i < clut_len; i++, j = (j+1) % 4) {
	if (j == 0)
	    printf("   ");
	printf(" 0x%02x, 0x%02x, 0x%02x,", PPM_GETR(clut[i]),
	       PPM_GETG(clut[i]), PPM_GETB(clut[i]));
	if (j == 3)
	    putchar('\n');
    }
    if (j != 0)
	putchar('\n');
}
Пример #18
0
static void print_rgb888_data(xel **pnm, int cols, int rows)
{
    int i, j, k;

    for (i = 0, k = 0; i < rows; i++)
	for (j = 0; j < cols; j++, k = (k+1) % 4) {
	    if (k == 0)
		printf("   ");
	    printf(" 0x%02x, 0x%02x, 0x%02x,", PPM_GETR(pnm[i][j]),
		   PPM_GETG(pnm[i][j]), PPM_GETB(pnm[i][j]));
	    if (k == 3)
		putchar('\n');
	}
    if (k != 0)
	putchar('\n');
}
Пример #19
0
pnm_image_t *pnm_ppm2image(pnm_image_t *image, ppm_t *ppm)
{
  int i,j,k;
  if (!ppm) return (image);
  if (!image)
    image = pnm_image_alloc(NULL, 3, ppm->cols, ppm->rows);

  for (j=0; j < image->rows; j++)
    for (k=0; k < image->cols; k++) {
      image->pixels[0][j][k] = (pnm_pixval) PPM_GETR(ppm->pixels[j][k]);
      image->pixels[1][j][k] = (pnm_pixval) PPM_GETG(ppm->pixels[j][k]);
      image->pixels[2][j][k] = (pnm_pixval) PPM_GETB(ppm->pixels[j][k]);  
    }
  image->maxval = ppm->maxval;
  return (image);
}
Пример #20
0
static void
format1bpsRow(const pixel *   const pixelrow,
              unsigned int    const cols,
              unsigned char * const rowBuffer) {

    /* single byte samples. */

    unsigned int col;
    unsigned int bufferCursor;

    bufferCursor = 0;

    for (col = 0; col < cols; ++col) {
        rowBuffer[bufferCursor++] = PPM_GETR(pixelrow[col]);
        rowBuffer[bufferCursor++] = PPM_GETG(pixelrow[col]);
        rowBuffer[bufferCursor++] = PPM_GETB(pixelrow[col]);
    }
}
Пример #21
0
static unsigned int
indexOfColor(colorhash_table const cht,
             pixel           const color) {
/*----------------------------------------------------------------------------
   Return the index in the palette described by 'cht' of the color 'color'.

   Abort program with error message if the color is not in the palette.
-----------------------------------------------------------------------------*/

    int const rc = ppm_lookupcolor(cht, &color);
            
    if (rc < 0)
        pm_error("Image contains color which is not "
                 "in the palette: %u/%u/%u", 
                 PPM_GETR(color), PPM_GETG(color), PPM_GETB(color));

    return rc;
}
Пример #22
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;
}
Пример #23
0
static int fill_clut(xel **pnm, int cols, int rows)
{
    int clut_len = 0;
    int i, j, k;

    for (i = 0 ; i < rows; i++)
	for (j = 0; j < cols; j++) {
	    for (k = 0; k < clut_len; k++)
		if (PPM_EQUAL(pnm[i][j], clut[k]))
		    break;
	    if (k == clut_len) {
		if (clut_len == 256)
		    return 257;
		PPM_ASSIGN(clut[clut_len], PPM_GETR(pnm[i][j]),
			   PPM_GETG(pnm[i][j]), PPM_GETB(pnm[i][j]));
		clut_len++;
	    }
	}
    return clut_len;
}
Пример #24
0
static void
fs_adjust(ppm_fs_info * const fi, 
          int           const col) {

    int     const errcol = col+1;
    pixel * const pP     = &(fi->pixrow[col]);
    pixval  const maxval = fi->maxval;

    long r, g, b;

    /* Use Floyd-Steinberg errors to adjust actual color. */
    r = fi->thisrederr  [errcol]; if( r < 0 ) r -= 8; else r += 8; r /= 16;
    g = fi->thisgreenerr[errcol]; if( g < 0 ) g -= 8; else g += 8; g /= 16;
    b = fi->thisblueerr [errcol]; if( b < 0 ) b -= 8; else b += 8; b /= 16;

    r += PPM_GETR(*pP); if ( r < 0 ) r = 0; else if ( r > maxval ) r = maxval;
    g += PPM_GETG(*pP); if ( g < 0 ) g = 0; else if ( g > maxval ) g = maxval;
    b += PPM_GETB(*pP); if ( b < 0 ) b = 0; else if ( b > maxval ) b = maxval;

    PPM_ASSIGN(*pP, r, g, b);
    fi->red = r; fi->green = g; fi->blue = b;
}
Пример #25
0
static void
writePam(FILE *   const ofP,
         canvas * const canvasP) {

    unsigned int row;
    struct pam pam;
    tuple * tuplerow;

    pam.size             = sizeof(pam);
    pam.len              = PAM_STRUCT_SIZE(tuple_type);
    pam.file             = ofP;
    pam.format           = PAM_FORMAT;
    pam.plainformat      = 0;
    pam.width            = canvasP->width;
    pam.height           = canvasP->height;
    pam.depth            = 3;
    pam.maxval           = OUTPUT_MAXVAL;
    strcpy(pam.tuple_type, PAM_PPM_TUPLETYPE);
    
    pnm_writepaminit(&pam);

    tuplerow = pnm_allocpamrow(&pam);

    for (row = 0; row < (unsigned)pam.height; ++row) {
        pixel * const pixelrow = canvasP->pixels[row];
        unsigned int col;

        for (col = 0; col < (unsigned)pam.width; ++col) {
            pixel const thisPixel = pixelrow[col];
            assert(pam.depth >= 3);

            tuplerow[col][PAM_RED_PLANE] = PPM_GETR(thisPixel);
            tuplerow[col][PAM_GRN_PLANE] = PPM_GETG(thisPixel);
            tuplerow[col][PAM_BLU_PLANE] = PPM_GETB(thisPixel);
        }
        pnm_writepamrow(&pam, tuplerow);
    }
    pnm_freepamrow(tuplerow);
}
Пример #26
0
struct hsv
ppm_hsv_from_color(pixel  const color,
                   pixval const maxval) {

    double const epsilon = 1e-5;

    double const R = (double)PPM_GETR(color) / maxval;
    double const G = (double)PPM_GETG(color) / maxval;
    double const B = (double)PPM_GETB(color) / maxval;

    enum hueSector {SECTOR_RED, SECTOR_GRN, SECTOR_BLU};
    enum hueSector hueSector;

    struct hsv retval;
    double range;

    if (R >= G) {
        if (R >= B) {
            hueSector = SECTOR_RED;
            retval.v = R;
        } else {
            hueSector = SECTOR_BLU;
            retval.v = B;
        }
    } else {
        if (G >= B) {
            hueSector = SECTOR_GRN;
            retval.v = G;
        } else {
            hueSector = SECTOR_BLU;
            retval.v = B;
        }
    }

    range = retval.v - MIN(R, MIN(G, B));

    if (retval.v < epsilon)
        retval.s = 0.0;
    else
        retval.s = range/retval.v;

    if (range < epsilon)
        /* It's gray, so hue really has no meaning.  We arbitrarily pick 0 */
        retval.h = 0.0;
    else {
        double const cr = (retval.v - R) / range;
        double const cg = (retval.v - G) / range;
        double const cb = (retval.v - B) / range;

        double angle;  /* hue angle, in range -30 - +330 */

        switch(hueSector) {
        case SECTOR_RED: angle =   0.0 + 60.0 * (cb - cg); break;
        case SECTOR_GRN: angle = 120.0 + 60.0 * (cr - cb); break;
        case SECTOR_BLU: angle = 240.0 + 60.0 * (cg - cr); break;
        }
        retval.h = angle >= 0.0 ? angle : 360 + angle;
    }

    return retval;
}
Пример #27
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);
	}
}
Пример #28
0
void thin3(bitmap_type *image, Pixel colour) 
{ 
      Pixel *ptr, *y_ptr, *y1_ptr;
      Pixel bg_color;
      unsigned int    xsize, ysize;   /* Image resolution             */ 
      unsigned int    x, y;           /* Pixel location               */ 
      unsigned int    i;              /* Pass index           */ 
      unsigned int    pc      = 0;    /* Pass count           */ 
      unsigned int    count   = 1;    /* Deleted pixel count          */ 
      unsigned int    p, q;           /* Neighborhood maps of adjacent*/ 
                                      /* cells                        */ 
      unsigned char   *qb;            /* Neighborhood maps of previous*/ 
                                      /* scanline                     */ 
      unsigned int    m;              /* Deletion direction mask      */ 
 
      bg_color[0] = PPM_GETR(background);
      bg_color[1] = PPM_GETG(background);
      bg_color[2] = PPM_GETB(background);

      LOG (" Thinning image.....\n "); 
      xsize = image->width;
      ysize = image->height;
      MALLOCARRAY_NOFAIL(qb, xsize); 
      qb[xsize-1] = 0;                /* Used for lower-right pixel   */ 
      ptr = (Pixel*)image->bitmap;
 
      while ( count ) {               /* Scan image while deletions   */ 
          pc++; 
          count = 0; 
 
          for ( i = 0 ; i < 4 ; i++ ) { 
 
              m = masks[i]; 
 
              /* Build initial previous scan buffer.                  */ 
              p = PIXEL_EQUAL(ptr[0], colour); 
              for ( x = 0 ; x < xsize-1 ; x++ ) 
                  qb[x] = (unsigned char) (p = ((p<<1)&0006) | (unsigned int) PIXEL_EQUAL(ptr[x+1],
				   colour)); 
 
              /* Scan image for pixel deletion candidates.            */ 
	      y_ptr = ptr; y1_ptr = ptr + xsize; 
              for (y = 0; y < ysize - 1; y++, y_ptr += xsize, y1_ptr += xsize)
	      { 
                  q = qb[0]; 
                  p = ((q<<2)&0330) | (unsigned int) PIXEL_EQUAL(y1_ptr[0], colour); 
 
                  for ( x = 0 ; x < xsize-1 ; x++ ) { 
                      q = qb[x]; 
                      p = ((p<<1)&0666) | ((q<<3)&0110) | 
			  (unsigned int) PIXEL_EQUAL(y1_ptr[x+1], colour);
                      qb[x] = (unsigned char) p; 
                      if ((i != 2 || x != 0) && ((p&m) == 0) && todelete[p] ) { 
                          count++;  /* delete the pixel */ 
			  PIXEL_SET(y_ptr[x], bg_color);
                      } 
                  } 
 
                  /* Process right edge pixel.                        */ 
                  p = (p<<1)&0666; 
                  if  (i != 3 && (p&m) == 0 && todelete[p] ) { 
                      count++; 
		      PIXEL_SET(y_ptr[xsize-1], bg_color);
                  } 
              } 
 
	      if (i != 1)
	      {
            /* Process bottom scan line.                            */ 
            q = qb[0]; 
            p = ((q<<2)&0330); 

            y_ptr = ptr + xsize * (ysize - 1);
            for ( x = 0 ; x < xsize ; x++ ) { 
              q = qb[x]; 
              p = ((p<<1)&0666) | ((q<<3)&0110); 
              if ((i != 2 || x != 0) && (p&m) == 0 && todelete[p]) { 
                count++; 
                PIXEL_SET(y_ptr[x], bg_color);
		      } 
            } 
           }
          } 
          LOG2 ("ThinImage: pass %d, %d pixels deleted\n", pc, count); 
      } 
      free (qb); 
} 
Пример #29
0
void
thin_image(bitmap_type *image, bool bgSpec, pixel bg,
           at_exception_type * exp)
{ 
    /* This is nasty as we need to call thin once for each  
     * colour in the image the way I do this is to keep a second  
     * copy of the bitmap and to use this to keep 
     * track of which colours have not yet been processed, 
     * trades time for pathological case memory.....*/ 
    long m, n, num_pixels;
    bitmap_type bm; 
    unsigned int const spp = image->np;
	unsigned int const width = image->width;
	unsigned int const height = image->height;

    if (bgSpec)
        background = bg;
    else 
        PPM_ASSIGN(background, 255, 255, 255);

    /* Clone the image */
    bm.height = image->height;
    bm.width = image->width;
    bm.np = image->np;
    MALLOCARRAY(bm.bitmap, height * width * spp); 
    if (bm.bitmap == NULL)
        pm_error("Unable to get memory for thin image bitmap clone");
    memcpy(bm.bitmap, image->bitmap, height * width * spp); 

    num_pixels = height * width;
    switch (spp)
    {
	case 3:
	{
	    Pixel *ptr = (Pixel*)bm.bitmap;
	    Pixel bg_color;
	    bg_color[0] = PPM_GETR(background);
	    bg_color[1] = PPM_GETG(background);
	    bg_color[2] = PPM_GETB(background);

	    for (n = num_pixels - 1; n >= 0L; --n)
	    {
		Pixel p;

		PIXEL_SET(p, ptr[n]);
		if (!PIXEL_EQUAL(p, bg_color))
		{ 
		    /* we have a new colour in the image */ 
		    LOG3("Thinning colour (%x, %x, %x)\n", p[0], p[1], p[2]);
		    for (m = n - 1; m >= 0L; --m)
		    {
			if (PIXEL_EQUAL(ptr[m], p))
			    PIXEL_SET(ptr[m], bg_color);
		    }
		    thin3(image, p); 
		} 
	    } 
	    break;
	} 

	case 1:
	{
	    unsigned char * const ptr = bm.bitmap;
	    unsigned char bg_color;

	    if (PPM_ISGRAY(background))
            bg_color = PPM_GETR(background);
	    else
            bg_color = PPM_LUMIN(background);

	    for (n = num_pixels - 1; n >= 0L; --n)
	    {
		unsigned char c = ptr[n];
		if (c != bg_color)
		{ 
		    LOG1 ("Thinning colour %x\n", c);
		    for (m = n - 1; m >= 0L; --m)
			if (ptr[m] == c) ptr[m] = bg_color;
		    thin1(image, c); 
		} 
	    } 
	    break;
	} 

	default:
	{
	  LOG1 ("thin_image: %u-plane images are not supported", spp);
	  at_exception_fatal(exp, "thin_image: wrong plane images are passed");
	  goto cleanup;
	}
    }
 cleanup:
    free (bm.bitmap); 
} 
Пример #30
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);
    }
}