コード例 #1
0
ファイル: pnmcat.c プロジェクト: chneukirchen/netpbm-mirror
static void
getPbmImageInfo(struct imgInfo        const img[],
                unsigned int          const nfiles,
                unsigned int          const newrows,
                enum justification    const justification,
                enum backcolor        const backcolor,
                struct imgInfoPbm2 ** const img2P) {
/*----------------------------------------------------------------------------
   Read the first row of each image in img[] and return that and additional
   information about images as *img2P.
-----------------------------------------------------------------------------*/
    struct imgInfoPbm2 * img2;
    unsigned int i;

    MALLOCARRAY_NOFAIL(img2, nfiles);

    for (i = 0; i < nfiles; ++i) {
        switch (justification) {
        case JUST_MIN:    img2[i].padtop = 0;                           break;
        case JUST_MAX:    img2[i].padtop = newrows - img[i].rows;       break;
        case JUST_CENTER: img2[i].padtop = (newrows - img[i].rows) / 2; break;
        }
        
        img2[i].offset = (i == 0) ? 0 : img2[i-1].offset + img[i-1].cols;
        
        if (img[i].rows == newrows)  /* no padding */
            img2[i].proberow = NULL;
        else {                   /* determine pad color for image i */
            switch (backcolor) {
            case BACK_AUTO: {
                bit bgBit;
                img2[i].proberow = pbm_allocrow_packed(img[i].cols+7);
                pbm_readpbmrow_bitoffset(
                    img[i].ifP, img2[i].proberow,
                    img[i].cols, img[i].format, img2[i].offset % 8);

                bgBit = pbm_backgroundbitrow(
                    img2[i].proberow, img[i].cols, img2[i].offset % 8);

                img2[i].background = bgBit == PBM_BLACK ? 0xff : 0x00;
            } break;
            case BACK_BLACK:
                img2[i].proberow   = NULL;
                img2[i].background = 0xff;
                break;
            case BACK_WHITE:
                img2[i].proberow   = NULL;
                img2[i].background = 0x00;
                break;
            }
        }
    }
    *img2P = img2;
}
コード例 #2
0
ファイル: pnmcrop.c プロジェクト: chneukirchen/netpbm-mirror
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);
}
コード例 #3
0
ファイル: pnmcat.c プロジェクト: chneukirchen/netpbm-mirror
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);
}
コード例 #4
0
ファイル: pnmcat.c プロジェクト: chneukirchen/netpbm-mirror
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);
}
コード例 #5
0
ファイル: pamcut.c プロジェクト: Eleanor66613/CS131
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);
}