Exemple #1
0
static void
readOffBorderPbm(unsigned int const height,
                 FILE *       const ifP,
                 unsigned int const cols,
                 int          const format) {

    unsigned char * bitrow;
    unsigned int i;

    bitrow = pbm_allocrow_packed(cols);

    for (i = 0; i < height; ++i)
        pbm_readpbmrow_packed(ifP, bitrow, cols, format);

    pbm_freerow_packed(bitrow);
}
Exemple #2
0
static void
outputNewBorderPbm(unsigned int const height,
                   unsigned int const width,
                   unsigned int const blackWhite,
                   FILE *       const ofP) {
/*----------------------------------------------------------------------------
   Output to 'ofP' a horizontal border (i.e. top or bottom)
   of height 'height', width 'width'.  Make it black if 'blackWhite' is
   1; white if 'blackWhite' is 0.  'blackWhite' can't be anything else.
-----------------------------------------------------------------------------*/
    unsigned char * bitrow;
    unsigned int i;

    bitrow = pbm_allocrow_packed(width);

    fillRowPBM(bitrow, width, blackWhite);

    for (i = 0; i < height; ++i)
        pbm_writepbmrow_packed(ofP, bitrow, width, 0);
    
    pbm_freerow_packed(bitrow);
}
Exemple #3
0
static void
writeCroppedPBM(FILE *       const ifP,
                unsigned int const cols,
                unsigned int const rows,
                int          const format,
                cropSet      const crop,
                xel          const backgroundColor,
                FILE *       const ofP) {
    
    /* See comments for writeCroppedNonPBM(), which uses identical logic flow. 
       Uses pbm functions instead of general pnm functions.
    */

    unsigned int const foregroundCols =
        cols - crop.op[LEFT].removeSize - crop.op[RIGHT].removeSize;
    unsigned int const outputCols     = 
        foregroundCols + crop.op[LEFT].padSize + crop.op[RIGHT].padSize;
    unsigned int const foregroundRows =
        rows - crop.op[TOP].removeSize - crop.op[BOTTOM].removeSize;
    unsigned int const outputRows     =
        foregroundRows + crop.op[TOP].padSize + crop.op[BOTTOM].padSize;

    unsigned int const foregroundLeft  =
        MAX(crop.op[LEFT].removeSize, crop.op[LEFT].padSize);
    unsigned int const foregroundRight = foregroundLeft + foregroundCols;

    unsigned int const allocCols =
        foregroundRight + 
        MAX(crop.op[RIGHT].removeSize, crop.op[RIGHT].padSize);

    unsigned int const backgroundBlackWhite =
        PNM_EQUAL(backgroundColor, pnm_whitexel(1, PBM_TYPE)) ? 0: 1;

    unsigned int const readOffset    =
        foregroundLeft - crop.op[LEFT].removeSize;
    unsigned int const writeOffset   = foregroundLeft - crop.op[LEFT].padSize;
    unsigned int const lastWriteChar = writeOffset/8 + (outputCols-1)/8;
    unsigned char * bitrow;
    unsigned int i;
    
    pbm_writepbminit(ofP, outputCols, outputRows, 0);

    bitrow = pbm_allocrow_packed(allocCols);

    readOffBorderPbm(crop.op[TOP].removeSize, ifP, cols, format);

    outputNewBorderPbm(crop.op[TOP].padSize, outputCols, backgroundBlackWhite,
                       ofP);

    /* Prepare padding: left and/or right */
    fillRowPBM(bitrow, allocCols, backgroundBlackWhite);

    /* Read and output foreground rows */
    for (i = 0; i < foregroundRows; ++i) {
        /* Read foreground pixels */
        pbm_readpbmrow_bitoffset(ifP, bitrow, cols, format, readOffset);
  
        pbm_writepbmrow_bitoffset(ofP,
                                  bitrow, outputCols, format, writeOffset);
                              
        /* If there is right-side padding, repair the write buffer
           distorted by pbm_writepbmrow_bitoffset() 
           (No need to mend any left-side padding)
        */
        if (crop.op[RIGHT].padSize > 0)    
            bitrow[lastWriteChar] = backgroundBlackWhite * 0xff;
    }

    readOffBorderPbm(crop.op[BOTTOM].removeSize, ifP, cols, format);

    outputNewBorderPbm(crop.op[BOTTOM].padSize, outputCols,
                       backgroundBlackWhite,
                       ofP);

    pbm_freerow_packed(bitrow);
}
Exemple #4
0
static void
concatenateTopBottomPbm(FILE *             const ofP,
                        unsigned int       const nfiles,
                        int                const newcols,
                        int                const newrows,
                        enum justification const justification,
                        struct imgInfo     const img[],
                        enum backcolor     const backcolor) {

    unsigned char * const outrow = pbm_allocrow_packed(newcols);
        /* Like the left-right PBM case, all padding and image data
           goes directly into outrow.  There is no proberow.
        */
    unsigned char background, backgroundPrev;
        /* 0x00 means white; 0xff means black */
    unsigned int  padleft;
    bool          backChange;
        /* Background color is different from that of the previous
           input image.
        */

    unsigned int i;
    unsigned int row, startRow;
    
    outrow[pbm_packed_bytes(newcols)-1] = 0x00;

    switch (backcolor){
    case BACK_AUTO:   /* do nothing */    break;
    case BACK_BLACK:  background = 0xff;  break;
    case BACK_WHITE:  background = 0x00;  break;
    }

    for (i = 0; i < nfiles; ++i) {
        if (img[i].cols == newcols) {
            /* No padding */
            startRow = 0;
            backChange = FALSE;
            padleft = 0;
            outrow[pbm_packed_bytes(newcols)-1] = 0x00;
        } else {
            /* Determine amount of padding and color */
            switch (justification) {
            case JUST_MIN:     padleft = 0;                           break;
            case JUST_MAX:     padleft = newcols - img[i].cols;       break;
            case JUST_CENTER:  padleft = (newcols - img[i].cols) / 2; break;
            }

            switch (backcolor) {
            case BACK_AUTO: {
                bit bgBit;

                startRow = 1;
                
                pbm_readpbmrow_bitoffset(img[i].ifP,
                                         outrow, img[i].cols, img[i].format,
                                         padleft);

                bgBit = pbm_backgroundbitrow(outrow, img[i].cols, padleft);
                background = bgBit == PBM_BLACK ? 0xff : 0x00;

                backChange = (i == 0 || background != backgroundPrev);
            } break;
            case BACK_WHITE:
            case BACK_BLACK:
                startRow = 0;
                backChange = (i==0);
                break;
            }

            if (backChange || (i > 0 && img[i-1].cols > img[i].cols)) {
                unsigned int const padright = newcols - padleft - img[i].cols;
                
                if (padleft > 0)
                    padFillBitrow(outrow, background, padleft, 0);
                
                if (padright > 0)            
                    padFillBitrow(outrow, background, padright,
                                  padleft + img[i].cols);
                
            }
        }
            
        if (startRow == 1)
            /* Top row already read for auto background color
               determination.  Write it out.
            */
            pbm_writepbmrow_packed(ofP, outrow, newcols, 0);
        
        for (row = startRow; row < img[i].rows; ++row) {
            pbm_readpbmrow_bitoffset(img[i].ifP, outrow, img[i].cols,
                                     img[i].format, padleft);
            pbm_writepbmrow_packed(ofP, outrow, newcols, 0);
        }

        backgroundPrev = background;
    }
    pbm_freerow_packed(outrow);
}
Exemple #5
0
static void
concatenateLeftRightPbm(FILE *             const ofP,
                        unsigned int       const nfiles,
                        unsigned int       const newcols,
                        unsigned int       const newrows,
                        enum justification const justification,
                        struct imgInfo     const img[],   
                        enum backcolor     const backcolor) {

    unsigned char * const outrow = pbm_allocrow_packed(newcols);
        /* We use just one outrow.  All padding and image data (with the
           exeption of following img2.proberow) goes directly into this
           packed PBM row. 
        */

    struct imgInfoPbm2 * img2;
        /* malloc'ed array, one element per image.  Shadows img[] */
    unsigned int row;

    getPbmImageInfo(img, nfiles, newrows, justification, backcolor, &img2);

    outrow[pbm_packed_bytes(newcols)-1] = 0x00;

    for (row = 0; row < newrows; ++row) {
        unsigned int i;

        for (i = 0; i < nfiles; ++i) {

            if ((row == 0 && img2[i].padtop > 0) ||
                row == img2[i].padtop + img[i].rows) {

                /* This row begins a run of padding, either above or below
                   file 'i', so set 'outrow' to padding.
                */
                padFillBitrow(outrow, img2[i].background, img[i].cols,
                              img2[i].offset);
            }

            if (row == img2[i].padtop && img2[i].proberow != NULL) {
                /* Top row has been read to proberow[] to determine
                   background.  Copy it to outrow[].
                */
                copyBitrow(img2[i].proberow, outrow,
                           img[i].cols, img2[i].offset);
            } else if (row >= img2[i].padtop &&
                       row < img2[i].padtop + img[i].rows) {
                pbm_readpbmrow_bitoffset(
                    img[i].ifP, outrow, img[i].cols, img[i].format,
                    img2[i].offset);
            } else {
                /* It's a row of padding, so outrow[] is already set
                   appropriately.
                */
            }
        }
        pbm_writepbmrow_packed(ofP, outrow, newcols, 0);
    }

    destroyPbmImg2(img2, nfiles);

    pbm_freerow_packed(outrow);
}
Exemple #6
0
static void
extractRowsPBM(const struct pam * const inpamP,
               const struct pam * const outpamP,
               int                const leftcol,
               int                const rightcol,
               int                const toprow,
               int                const bottomrow) {

    unsigned char * bitrow;
    int             readOffset, writeOffset;
    int             row;
    unsigned int    totalWidth;

    assert(leftcol <= rightcol);
    assert(toprow <= bottomrow);

    if (leftcol > 0) {
        totalWidth = MAX(rightcol+1, inpamP->width) + 7;
        if (totalWidth > INT_MAX)
            /* Prevent overflows in pbm_allocrow_packed() */
            pm_error("Specified right edge is too far "
                     "from the right end of input image");
        
        readOffset  = 0;
        writeOffset = leftcol;
    } else {
        totalWidth = -leftcol + MAX(rightcol+1, inpamP->width);
        if (totalWidth > INT_MAX)
            pm_error("Specified left/right edge is too far "
                     "from the left/right end of input image");
        
        readOffset = -leftcol;
        writeOffset = 0;
    }

    bitrow = pbm_allocrow_packed(totalWidth);

    if (toprow < 0 || leftcol < 0 || rightcol >= inpamP->width){
        makeBlackPBMRow(bitrow, totalWidth);
        if (toprow < 0) {
            int row;
            for (row=0; row < 0 - toprow; ++row)
                pbm_writepbmrow_packed(outpamP->file, bitrow,
                                       outpamP->width, 0);
        }
    }

    for (row = 0; row < inpamP->height; ++row){
        if (row >= toprow && row <= bottomrow) {
            pbm_readpbmrow_bitoffset(inpamP->file, bitrow, inpamP->width,
                                     inpamP->format, readOffset);

            pbm_writepbmrow_bitoffset(outpamP->file, bitrow, outpamP->width,
                                      0, writeOffset);
  
            if (rightcol >= inpamP->width)
                /* repair right padding */
                bitrow[writeOffset/8 + pbm_packed_bytes(outpamP->width) - 1] =
                    0xff * PBM_BLACK;
        } else
            pnm_readpamrow(inpamP, NULL);    /* read and discard */
    }

    if (bottomrow - (inpamP->height-1) > 0) {
        int row;
        makeBlackPBMRow(bitrow, outpamP->width);
        for (row = 0; row < bottomrow - (inpamP->height-1); ++row)
            pbm_writepbmrow_packed(outpamP->file, bitrow, outpamP->width, 0);
    }
    pbm_freerow_packed(bitrow);
}
static void
ReadMacPaintFile( FILE *  const ifP,
                  int  * outOfSyncP,
                  int  * pixelCntP ) {
/*---------------------------------------------------------------------------
  Unpack image data.  Compression method is called "Packbits".
  This run-length encoding scheme has also been adopted by
  Postscript and TIFF.  See source: converter/other/pnmtops.c

  Unpacked raster array is raw PBM.  No conversion is required.

  One source says flag byte should not be 0xFF (255), but we don't reject
  the value, for in practice, it is widely used.

  Sequences should never cross row borders.
  Violations of this rule are recorded in outOfSync.

  Note that pixelCnt counts bytes, not bits, so it is the number of pixels
  multiplied by 8.  This counter exists to detect corruptions.
---------------------------------------------------------------------------*/
    int           pixelCnt   = 0;   /* Initial value */
    int           outOfSync  = 0;   /* Initial value */
    unsigned int  flag;             /* Read from input */
    unsigned int  i;
    unsigned char * const bitrow = pbm_allocrow_packed(MACP_COLS);

    while ( pixelCnt < MACP_BYTES ) {
        flag = (unsigned int) readChar( ifP );    /* Flag (count) byte */
        if ( flag < 0x80 ) {
            /* Unpack next (flag + 1) chars as is */
            for ( i = 0; i <= flag; i++ )
                if( pixelCnt < MACP_BYTES) {
                  int const colChar = pixelCnt % MACP_COLCHARS;
                  pixelCnt++;
                  bitrow[colChar] = readChar( ifP );
                  if (colChar == MACP_COLCHARS-1)
                      pbm_writepbmrow_packed( stdout, bitrow, MACP_COLS, 0 );
                  if (colChar == 0 && i > 0 )
                      outOfSync++;
                }
        }
        else {
          /* Repeat next char (2's complement of flagCnt) times */
            unsigned int  const flagCnt = 256 - flag;
            unsigned char const ch = readChar( ifP );
            for ( i = 0; i <= flagCnt; i++ )
                if( pixelCnt < MACP_BYTES) {
                  int const colChar = pixelCnt % MACP_COLCHARS;
                  pixelCnt++;
                  bitrow[colChar] = ch;
                  if (colChar == MACP_COLCHARS-1)
                      pbm_writepbmrow_packed( stdout, bitrow, MACP_COLS, 0 );
                  if (colChar == 0 && i > 0 )
                      outOfSync++;
                }
        }
    }
    pbm_freerow_packed ( bitrow );
    *outOfSyncP  = outOfSync;
    *pixelCntP   = pixelCnt;
}