Example #1
0
static void
ppmTo256ColorPcx(pixel **            const pixels, 
                 int                 const cols, 
                 int                 const rows, 
                 struct pcxCmapEntry const pcxcmap[], 
                 int                 const colors, 
                 colorhash_table     const cht,
                 unsigned int        const xPos, 
                 unsigned int        const yPos) {

    int row;
    unsigned int i;
    unsigned char *rawrow;

    rawrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char));

    /* 8 bits per pixel, 1 plane */
    write_header(stdout, cols, rows, 8, 1, NULL, xPos, yPos);
    for (row = 0; row < rows; ++row) {
        int col;
        for (col = 0; col < cols; ++col)
            rawrow[col] = indexOfColor(cht, pixels[row][col]);
        PCXEncode(stdout, rawrow, cols);
    }
    Putbyte(PCX_256_COLORS, stdout);
    for (i = 0; i < MAXCOLORS; ++i) {
        Putbyte(pcxcmap[i].r, stdout);
        Putbyte(pcxcmap[i].g, stdout);
        Putbyte(pcxcmap[i].b, stdout);
    }
    pm_freerow((void*)rawrow);
}
Example #2
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);
}
Example #3
0
static void
putinit (int const rows, int const cols)
{

  if (pm_writebigshort (stdout, (short) 1) == -1 /* Image file version */
      || pm_writebigshort (stdout, (short) 8) == -1 /* Header length */
      || pm_writebigshort (stdout, (short) 1) == -1 /* Number of planes */
      || pm_writebigshort (stdout, (short) 1) == -1 /* Pattern length */
      || pm_writebigshort (stdout, (short) 372) == -1 /* Pixel width */
      || pm_writebigshort (stdout, (short) 372) == -1 /* Pixel height */
      || pm_writebigshort (stdout, (short) cols) == -1
      || pm_writebigshort (stdout, (short) rows) == -1)
    pm_error ("write error");
  item = 0;
  bitsperitem = 0;
  bitshift = 7;
  outcol = 0;
  outmax = (cols + 7) / 8;
  outrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char));
  lastrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char));
  linerepeat = -1;
}
Example #4
0
int
main(int    argc,
     char * argv[]) {

    struct cmdlineInfo cmdline;
    FILE * ifP;
    int cols, rows;
    int median;
    enum medianMethod medianMethod;

    pgm_init(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);
    
    ifP = pm_openr(cmdline.inputFileName);

    ccolso2 = cmdline.width / 2;
    crowso2 = cmdline.height / 2;

    pgm_readpgminit(ifP, &cols, &rows, &maxval, &format);
    pgm_writepgminit(stdout, cols, rows, maxval, forceplain);

    /* Allocate space for number of rows in mask size. */
    grays = pgm_allocarray(cols, cmdline.height);
    grayrow = pgm_allocrow(cols);

    /* Allocate pointers to mask row buffer. */
    rowptr = (gray **) pm_allocrow(cmdline.height, sizeof(gray *));

    /* Read in and write out initial rows that won't get changed. */
    for (row = 0; row < cmdline.height - 1; ++row) {
        pgm_readpgmrow(ifP, grays[row], cols, maxval, format);
        /* Write out the unchanged row. */
        if (row < crowso2)
            pgm_writepgmrow(stdout, grays[row], cols, maxval, forceplain);
    }

    median = (cmdline.height * cmdline.width) / 2;

    /* Choose which sort to run. */
    if (cmdline.type == MEDIAN_UNSPECIFIED) {
        if ((maxval / ((cmdline.width * cmdline.height) - 1)) < cmdline.cutoff)
            medianMethod = HISTOGRAM_SORT_MEDIAN;
        else
            medianMethod = SELECT_MEDIAN;
    } else
        medianMethod = cmdline.type;

    switch (medianMethod) {
    case SELECT_MEDIAN:
        select_median(ifP, cmdline.width, cmdline.height, cols, rows, median);
        break;
        
    case HISTOGRAM_SORT_MEDIAN:
        histogram_sort_median(ifP, cmdline.width, cmdline.height,
                              cols, rows, median);
        break;
    case MEDIAN_UNSPECIFIED:
        pm_error("INTERNAL ERROR: median unspecified");
    }
    
    pm_close(ifP);
    pm_close(stdout);

    pgm_freearray(grays, cmdline.height);
    pgm_freerow(grayrow);
    pm_freerow(rowptr);

    return 0;
}
Example #5
0
static void
histogram_sort_median(FILE * const ifp,
                      int    const ccols,
                      int    const crows,
                      int    const cols,
                      int    const rows,
                      int    const median) {

    int const histmax = maxval + 1;

    int *hist;
    int mdn, ltmdn;
    gray *left_col, *right_col;

    hist = (int *) pm_allocrow( histmax, sizeof( int ) );
    left_col = pgm_allocrow( crows );
    right_col = pgm_allocrow( crows );

    /* Apply median to main part of image. */
    for ( ; row < rows; ++row ) {
        int col;
        int temprow;
        int rownum;
        int irow;
        int i;
        /* initialize hist[] */
        for ( i = 0; i < histmax; ++i )
            hist[i] = 0;

        temprow = row % crows;
        pgm_readpgmrow( ifp, grays[temprow], cols, maxval, format );

        /* Rotate pointers to rows, so rows can be accessed in order. */
        temprow = ( row + 1 ) % crows;
        rownum = 0;
        for ( irow = temprow; irow < crows; ++rownum, ++irow )
            rowptr[rownum] = grays[irow];
        for ( irow = 0; irow < temprow; ++rownum, ++irow )
            rowptr[rownum] = grays[irow];

        for ( col = 0; col < cols; ++col ) {
            if ( col < ccolso2 || col >= cols - ccolso2 )
                grayrow[col] = rowptr[crowso2][col];
            else if ( col == ccolso2 ) {
                int crow;
                int const leftcol = col - ccolso2;
                i = 0;
                for ( crow = 0; crow < crows; ++crow ) {
                    int ccol;
                    gray * const temprptr = rowptr[crow] + leftcol;
                    for ( ccol = 0; ccol < ccols; ++ccol ) {
                        gray const g = *( temprptr + ccol );
                        ++hist[g];
                        ++i;
                    }
                }
                ltmdn = 0;
                for ( mdn = 0; ltmdn <= median; ++mdn )
                    ltmdn += hist[mdn];
                mdn--;
                if ( ltmdn > median ) 
                    ltmdn -= hist[mdn];

                grayrow[col] = mdn;
            } else {
                int crow;
                int const subcol = col - ( ccolso2 + 1 );
                int const addcol = col + ccolso2;
                for ( crow = 0; crow < crows; ++crow ) {
                    left_col[crow] = *( rowptr[crow] + subcol );
                    right_col[crow] = *( rowptr[crow] + addcol );
                }
                for ( crow = 0; crow < crows; ++crow ) {
                    {
                        gray const g = left_col[crow];
                        hist[(int) g]--;
                        if ( (int) g < mdn )
                            ltmdn--;
                    }
                    {
                        gray const g = right_col[crow];
                        hist[(int) g]++;
                        if ( (int) g < mdn )
                            ltmdn++;
                    }
                }
                if ( ltmdn > median )
                    do {
                        mdn--;
                        ltmdn -= hist[mdn];
                    } while ( ltmdn > median );
                else {
                    /* This one change from Pitas algorithm can reduce run
                    ** time by up to 10%.
                    */
                    while ( ltmdn <= median ) {
                        ltmdn += hist[mdn];
                        mdn++;
                    }
                    mdn--;
                    if ( ltmdn > median ) 
                        ltmdn -= hist[mdn];
                }
                grayrow[col] = mdn;
            }
        }
        pgm_writepgmrow( stdout, grayrow, cols, maxval, forceplain );
    }

    {
        /* Write out remaining unchanged rows. */
        int irow;
        for ( irow = crowso2 + 1; irow < crows; ++irow )
            pgm_writepgmrow( stdout, rowptr[irow], cols, maxval, forceplain );
    }
    pm_freerow( (char *) hist );
    pgm_freerow( left_col );
    pgm_freerow( right_col );
}
Example #6
0
static void
select_median(FILE * const ifp,
              int    const ccols,
              int    const crows,
              int    const cols,
              int    const rows,
              int    const median) {

    int ccol, col;
    int crow;
    int rownum, irow, temprow;
    gray *temprptr;
    int i, leftcol;
    int num_values;
    gray *garray;

    int *parray;
    int addcol;
    int *subcol;
    int tsum;

    /* Allocate storage for array of the current gray values. */
    garray = pgm_allocrow( crows * ccols );

    num_values = crows * ccols;

    parray = (int *) pm_allocrow( crows * ccols, sizeof(int) );
    subcol = (int *) pm_allocrow( cols, sizeof(int) );

    for ( i = 0; i < cols; ++i )
        subcol[i] = ( i - (ccolso2 + 1) ) % ccols;

    /* Apply median to main part of image. */
    for ( ; row < rows; ++row ) {
        temprow = row % crows;
        pgm_readpgmrow( ifp, grays[temprow], cols, maxval, format );

        /* Rotate pointers to rows, so rows can be accessed in order. */
        temprow = ( row + 1 ) % crows;
        rownum = 0;
        for ( irow = temprow; irow < crows; ++rownum, ++irow )
            rowptr[rownum] = grays[irow];
        for ( irow = 0; irow < temprow; ++rownum, ++irow )
            rowptr[rownum] = grays[irow];

        for ( col = 0; col < cols; ++col ) {
            if ( col < ccolso2 || col >= cols - ccolso2 ) {
                grayrow[col] = rowptr[crowso2][col];
            } else if ( col == ccolso2 ) {
                leftcol = col - ccolso2;
                i = 0;
                for ( crow = 0; crow < crows; ++crow ) {
                    temprptr = rowptr[crow] + leftcol;
                    for ( ccol = 0; ccol < ccols; ++ccol ) {
                        garray[i] = *( temprptr + ccol );
                        parray[i] = i;
                        ++i;
                    }
                }
                select_489( garray, parray, num_values, median );
                grayrow[col] = garray[parray[median]];
            } else {
                addcol = col + ccolso2;
                for (crow = 0, tsum = 0; crow < crows; ++crow, tsum += ccols)
                    garray[tsum + subcol[col]] = *(rowptr[crow] + addcol );
                select_489( garray, parray, num_values, median );
                grayrow[col] = garray[parray[median]];
            }
        }
        pgm_writepgmrow( stdout, grayrow, cols, maxval, forceplain );
    }

    /* Write out remaining unchanged rows. */
    for ( irow = crowso2 + 1; irow < crows; ++irow )
        pgm_writepgmrow( stdout, rowptr[irow], cols, maxval, forceplain );

    pgm_freerow( garray );
    pm_freerow( (char *) parray );
    pm_freerow( (char *) subcol );
}
Example #7
0
/*-----------------------------------------------------------------------------
 *                                      Write the rle data portion of the file.
 */
static void
write_rle_data()
{
    register int     x;
    register int     scan;
    register xel     *xelrow, *pP;
    rle_pixel        ***scanlines, **scanline;
    /*
     * Allocate some memory.
     */
    /*xelrow = pnm_allowcrow(width);*/
    xelrow = (xel*) pm_allocrow( width, sizeof(xel) );
    MALLOCARRAY(scanlines, height);
    RLE_CHECK_ALLOC( hdr.cmd, scanlines, "scanline pointers" );

    for ( scan = 0; scan < height; scan++ )
        RLE_CHECK_ALLOC( hdr.cmd, (rle_row_alloc(&hdr, &scanlines[scan]) >= 0),
                         "pixel memory" );
    /*
     * Loop through the pnm files image window, read data and flip vertically.
     */
    switch (format) {
    case PBM_FORMAT:
    case RPBM_FORMAT:
        for (scan = 0; scan < height; scan++) {
            scanline = scanlines[height - scan - 1];
            pnm_readpnmrow(fp, xelrow, width, maxval, format);
            for (x = 0, pP = xelrow; x < width; x++, pP++) {
                scanline[RLE_RED][x]   = (PNM_GET1(*pP) ? 255 : 0);
                if (do_alpha) {
                    scanline[RLE_ALPHA][x] = scanline[RLE_RED][x];
                }
            }
        }
        break;
    case PGM_FORMAT:
    case RPGM_FORMAT:
        for (scan = 0; scan < height; scan++) {
            scanline = scanlines[height - scan - 1];
            pnm_readpnmrow(fp, xelrow, width, maxval, format);
            for (x = 0, pP = xelrow; x < width; x++, pP++) {
                scanline[RLE_RED][x]   = PNM_GET1(*pP);
                if (do_alpha) {
                    scanline[RLE_ALPHA][x] = (scanline[RLE_RED][x] ? 255 : 0);
                }
            }
        }
        break;
    case PPM_FORMAT:
    case RPPM_FORMAT:
        for (scan = 0; scan < height; scan++) {
            scanline = scanlines[height - scan - 1];
            pnm_readpnmrow(fp, xelrow, width, maxval, format);
            for (x = 0, pP = xelrow; x < width; x++, pP++) {
                scanline[RLE_RED][x]   = PPM_GETR(*pP);
                scanline[RLE_GREEN][x] = PPM_GETG(*pP);
                scanline[RLE_BLUE][x]  = PPM_GETB(*pP);
                if (do_alpha) {
                    scanline[RLE_ALPHA][x] = (scanline[RLE_RED][x] ||
                                              scanline[RLE_GREEN][x] ||
                                              scanline[RLE_BLUE][x] ? 255 : 0);
                }
            }
        }
        break;
    }
    /*
     * Write out data in URT order (bottom to top).
     */
    for ( scan = 0; scan < height; scan++ ) {
        rle_putrow(scanlines[scan], width, &hdr);
        rle_row_free( &hdr, scanlines[scan] );
    }
    free( scanlines );

    VPRINTF(stderr, "Done -- write eof to RLE data.\n");
    rle_puteof(&hdr);
}
Example #8
0
int
main(int argc, const char ** argv) {

    FILE * ifP;
    FILE *vf, *uf, *yf;
    pixel *pixelrow1, *pixelrow2;
    int rows, cols;
    int format;
    unsigned int row;
    pixval maxval;
    unsigned char *y1buf, *y2buf, *ubuf, *vbuf;
    struct FileNameSet fname;
        /* Output file names - .U, .V, .Y */

    pm_proginit(&argc, argv);

    if ((argc-1 > 2) || (argc-1 < 1))
        pm_error("Wrong number of arguments: %u.  "
                 "Arguments are basename for output files "
                 "and optional input file name", argc-1);

    if (argc-1 == 2)
        ifP = pm_openr(argv[2]);
    else
        ifP = stdin;

    makeOutputFileName(argv[1], &fname);

    uf = pm_openw(fname.u);
    vf = pm_openw(fname.v);
    yf = pm_openw(fname.y);

    termFileNameSet(fname);

    ppm_readppminit(ifP, &cols, &rows, &maxval, &format);

    if (cols % 2 == 1)
        pm_message("Warning: odd columns count %u, excess ignored", cols);

    if (rows % 2 == 1)
        pm_message("Warning: odd rows count %u, excess ignored", rows);

    pixelrow1 = ((pixel*) pm_allocrow(cols, sizeof(pixel)));
    pixelrow2 = ((pixel*) pm_allocrow(cols, sizeof(pixel)));

    y1buf = (unsigned char *) pm_allocrow(cols, 1);
    y2buf = (unsigned char *) pm_allocrow(cols, 1);
    ubuf = (unsigned char *) pm_allocrow(cols, 1);
    vbuf = (unsigned char *) pm_allocrow(cols, 1);

    for (row = 0; row < (rows & ~1); row += 2) {
        unsigned char *y1ptr, *y2ptr, *uptr, *vptr;
        pixel *pP1, *pP2;
        unsigned int col;

        ppm_readppmrow(ifP, pixelrow1, cols, maxval, format);
        ppm_readppmrow(ifP, pixelrow2, cols, maxval, format);

        pP1 = &pixelrow1[0]; pP2 = &pixelrow2[0];
        y1ptr = y1buf; y2ptr = y2buf; vptr = vbuf; uptr = ubuf;

        for (col = 0 ; col < (cols & ~1); col += 2) {
            pixval r0,g0,b0,r1,g1,b1,r2,g2,b2,r3,g3,b3;
            myLONG u, v, y0, y1, y2, y3, u0, u1, u2, u3, v0, v1, v2, v3;

            /* first pixel */
            r0 = PPM_GETR(*pP1);
            g0 = PPM_GETG(*pP1);
            b0 = PPM_GETB(*pP1);
            pP1++;
            /* 2nd pixel */
            r1 = PPM_GETR(*pP1);
            g1 = PPM_GETG(*pP1);
            b1 = PPM_GETB(*pP1);
            pP1++;
            /* 3rd pixel */
            r2 = PPM_GETR(*pP2);
            g2 = PPM_GETG(*pP2);
            b2 = PPM_GETB(*pP2);
            pP2++;
            /* 4th pixel */
            r3 = PPM_GETR(*pP2);
            g3 = PPM_GETG(*pP2);
            b3 = PPM_GETB(*pP2);
            pP2++;


            /* The JFIF RGB to YUV Matrix for $00010000 = 1.0

               [Y]   [19595   38469    7471][R]
               [U] = [-11056  -21712  32768][G]
               [V]   [32768   -27440  -5328][B]

            */

            y0 =  19595 * r0 + 38469 * g0 +  7471 * b0;
            u0 = -11056 * r0 - 21712 * g0 + 32768 * b0;
            v0 =  32768 * r0 - 27440 * g0 -  5328 * b0;

            y1 =  19595 * r1 + 38469 * g1 +  7471 * b1;
            u1 = -11056 * r1 - 21712 * g1 + 32768 * b1;
            v1 =  32768 * r1 - 27440 * g1 -  5328 * b1;

            y2 =  19595 * r2 + 38469 * g2 +  7471 * b2;
            u2 = -11056 * r2 - 21712 * g2 + 32768 * b2;
            v2 =  32768 * r2 - 27440 * g2 -  5328 * b2;

            y3 =  19595 * r3 + 38469 * g3 +  7471 * b3;
            u3 = -11056 * r3 - 21712 * g3 + 32768 * b3;
            v3 =  32768 * r3 - 27440 * g3 -  5328 * b3;

            /* mean the chroma for subsampling */

            u  = (u0+u1+u2+u3)>>2;
            v  = (v0+v1+v2+v3)>>2;

            y0 = (y0 * 219)/255 + 1048576;
            y1 = (y1 * 219)/255 + 1048576;
            y2 = (y2 * 219)/255 + 1048576;
            y3 = (y3 * 219)/255 + 1048576;

            u  = (u * 224)/255 ;
            v  = (v * 224)/255 ;

            *y1ptr++  = (y0 >> 16) ;
            *y1ptr++  = (y1 >> 16) ;
            *y2ptr++  = (y2 >> 16) ;
            *y2ptr++  = (y3 >> 16) ;


            *uptr++   = (u >> 16)+128 ;
            *vptr++   = (v >> 16)+128 ;

        }
        fwrite(y1buf, (cols & ~1), 1, yf);
        fwrite(y2buf, (cols & ~1), 1, yf);
        fwrite(ubuf, cols/2, 1, uf);
        fwrite(vbuf, cols/2, 1, vf);
    }

    pm_close(ifP);
    fclose(yf);
    fclose(uf);
    fclose(vf);
    return 0;
}