Exemplo n.º 1
0
static void
doPartialBlockTop(const struct pam * const inpamP,
                  bit **             const inrow,
                  const bit *        const blockPartial[16],
                  unsigned int       const topOfFullBlock,
                  uint16_t **        const outplane) {
    
    if (topOfFullBlock > 0) {
        unsigned int colChar, row;
        unsigned int pad = 16 - topOfFullBlock;

        for (colChar=0; colChar < pbm_packed_bytes(inpamP->width); ++colChar)
            inrow[0][colChar] = 0x00;

        for (row = 0; row < topOfFullBlock; ++row){
            pbm_readpbmrow_packed(inpamP->file, inrow[row+pad],
                                  inpamP->width, inpamP->format);
            if (inpamP->width % 8 > 0){
                /* Clear partial byte at end of input row */
                int const lastByte = pbm_packed_bytes(inpamP->width) -1;

                inrow[row+pad][lastByte] >>= (8 - inpamP->width % 8);
                inrow[row+pad][lastByte] <<= (8 - inpamP->width % 8);
            }
        }
Exemplo n.º 2
0
bit
pbm_backgroundbitrow(unsigned const char * const packedBits,
                     unsigned int          const cols,
                     unsigned int          const offset) {
    /*----------------------------------------------------------------------------
      PBM version of pnm_backgroundxelrow() with additional offset parameter.
      When offset == 0, produces the same return value as does
      pnm_backgroundxelrow(promoted_bitrow, cols, ...)
    -----------------------------------------------------------------------------*/
    const unsigned char * const row = &packedBits[offset/8];
    unsigned int const rs = offset % 8;
    unsigned int const last = pbm_packed_bytes(cols + rs) - 1;

    unsigned int retval;

    bool const firstbit = (row[0] >> (7-rs)) & 0x01;
    bool const lastbit  = (row[last] >> (7- (cols+rs-1)%8)) & 0x01;

    if (firstbit == lastbit)
        retval = firstbit;
    else {
        if (bitpop(row, cols, rs) >= cols/2)
            retval = PBM_BLACK;
        else
            retval = PBM_WHITE;
    }
    return retval;
}
Exemplo n.º 3
0
static void
padFillBitrow(unsigned char * const destBitrow,
              unsigned char   const padColor,
              unsigned int    const cols,
              unsigned int    const offset) {
/*----------------------------------------------------------------------------
   Fill destBitrow, starting at offset, with padColor.  padColor is a
   byte -- 0x00 or 0xff -- not a single bit.
-----------------------------------------------------------------------------*/
    unsigned char * const dest = &destBitrow[offset/8];
    unsigned int const rs = offset % 8;
    unsigned int const trs = (cols + rs) % 8;
    unsigned int const colByteCnt = pbm_packed_bytes(cols + rs);
    unsigned int const last = colByteCnt - 1;

    unsigned char const origHead = dest[0];
    unsigned char const origEnd  = dest[last];

    unsigned int i;

    assert(colByteCnt > 0);

    for (i = 0; i < colByteCnt; ++i)
        dest[i] = padColor;

    if (rs > 0)
        dest[0] = LEFTBITS(origHead, rs) | RIGHTBITS(dest[0], 8-rs);

    if (trs > 0)
        dest[last] = LEFTBITS(dest[last], trs) | RIGHTBITS(origEnd, 8-trs);
}
Exemplo n.º 4
0
static int
bitpop(const unsigned char * const packedRow,
       unsigned int          const cols,
       unsigned int          const offset) {
    /*----------------------------------------------------------------------------
      Return the number of 1 bits in 'packedRow', ignoring 0 to 7 bits
      at the row start (= on the left edge), indicated by offset.
    -----------------------------------------------------------------------------*/
    unsigned int const fullLength = cols + offset;

    unsigned int sum;

    if (fullLength <= 8) {
        /* All bits are in a single byte */
        sum = bitpop8((packedRow[0] << offset ) & (0xff << (8 - cols)));
    } else {
        unsigned int const colByteCnt  = pbm_packed_bytes(fullLength);
        unsigned int const fullByteCnt = fullLength/8;

        unsigned int i;

        /* First byte, whether it is full or not */
        sum = bitpop8(packedRow[0] << offset );

        /* Second byte to last full byte */
        for (i = 1; i < fullByteCnt; ++i)
            sum += bitpop8(packedRow[i]);

        /* Partial byte at the right end */
        if (colByteCnt > fullByteCnt)
            sum += bitpop8(packedRow[i] >> (8 - fullLength%8));
    }

    return sum;
}
Exemplo n.º 5
0
static void
makeBlackPBMRow(unsigned char * const bitrow,
                unsigned int    const cols) {

    unsigned int const colByteCnt = pbm_packed_bytes(cols);

    unsigned int i;

    for (i = 0; i < colByteCnt; ++i)
        bitrow[i] = PBM_BLACK * 0xff;

    if (PBM_BLACK != 0 && cols % 8 > 0)
        bitrow[colByteCnt-1] <<= (8 - cols % 8);
}
Exemplo n.º 6
0
static void
fillRowPBM(unsigned char * const bitrow,
           unsigned int    const cols,
           unsigned int    const blackWhite) {
/*----------------------------------------------------------------------------
   Fill the packed PBM row buffer bitrow[] with 'cols' columns of
   black or white: black if 'blackWhite' is 1; white if it is '0'.
   'blackWhite' cannot be anything else.
-----------------------------------------------------------------------------*/
    unsigned int const colChars = pbm_packed_bytes(cols);
    unsigned int i;

    assert(blackWhite == 0 || blackWhite == 1);
    
    for (i = 0; i < colChars; ++i)
        bitrow[i] = blackWhite * 0xff;
        
    if (cols % 8 > 0)
        bitrow[colChars-1] <<= 8 - cols % 8;
}
Exemplo n.º 7
0
static void
copyBitrow(const unsigned char * const source,
           unsigned char *       const destBitrow,
           unsigned int          const cols,
           unsigned int          const offset) {
/*----------------------------------------------------------------------------
  Copy from source to destBitrow, without shifting.  Preserve
  surrounding image data.
-----------------------------------------------------------------------------*/
    unsigned char * const dest = & destBitrow[ offset/8 ];
        /* Copy destination, with leading full bytes ignored. */
    unsigned int const rs = offset % 8;
        /* The "little offset", as measured from start of dest.  Source
           is already shifted by this value.
        */
    unsigned int const trs = (cols + rs) % 8;
        /* The number of partial bits in the final char. */
    unsigned int const colByteCnt = pbm_packed_bytes(cols + rs);
        /* # bytes to process, including partial ones on both ends. */
    unsigned int const last = colByteCnt - 1;

    unsigned char const origHead = dest[0];
    unsigned char const origEnd  = dest[last];

    unsigned int i;

    assert(colByteCnt >= 1);

    for (i = 0; i < colByteCnt; ++i)
        dest[i] = source[i];

    if (rs > 0)
        dest[0] = LEFTBITS(origHead, rs) | RIGHTBITS(dest[0], 8-rs);

    if (trs > 0)
        dest[last] = LEFTBITS(dest[last], trs) | RIGHTBITS(origEnd, 8-trs);
}
Exemplo n.º 8
0
int
main(int argc, char* argv[]) {

    FILE* ifP;
    int rows, cols;
    int format;
    unsigned int row, idx, len;
    unsigned int h, v;
    unsigned char *bytes, *cprbytes;
    struct cmdlineInfo cmdline;
    
    pbm_init(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);

    ifP = pm_openr(cmdline.inputFileName);

    pbm_readpbminit(ifP, &cols, &rows, &format);

    bytes = malloc(24*pbm_packed_bytes(cols)+2);
    cprbytes = malloc(2*24*pbm_packed_bytes(cols));
    if (bytes == NULL || cprbytes == NULL)
        pm_error("Cannot allocate memory");

    h = v = 3600/cmdline.resolution;

    /* Set raster graphic mode. */
    printf("%c%c%c%c%c%c", esc, '(', 'G', 1, 0, 1);

    /* Set line spacing in units of 1/360 inches. */
    printf("%c%c%c", esc, '+', 24*h/10);

    /* Write out raster stripes 24 rows high. */
    for (row = 0; row < rows; row += 24) {
        unsigned int const linesThisStripe = (rows-row<24) ? rows%24 : 24;
        printf("%c%c%c%c%c%c%c%c", esc, '.', cmdline.compress, 
               v, h, linesThisStripe, 
               cols%256, cols/256);
        /* Read pbm rows, each padded to full byte */
        for (idx = 0; idx < 24 && row+idx < rows; ++idx)
            pbm_readpbmrow_packed(ifP,bytes+idx*pbm_packed_bytes(cols),
                                  cols,format);
        /* Write raster data. */
        if (cmdline.compress != 0) {
            /* compressed */
            len = enc_epson_rle(linesThisStripe * pbm_packed_bytes(cols), 
                                bytes, cprbytes);
            fwrite(cprbytes,len,1,stdout);
        } else
            /* uncompressed */
            fwrite(bytes, pbm_packed_bytes(cols), linesThisStripe, stdout);    

        if (rows-row >= 24) putchar('\n');
    }
    free(bytes); free(cprbytes);
    pm_close(ifP);

    /* Reset printer. */
    printf("%c%c", esc, '@');

    return 0;
}
Exemplo n.º 9
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);
}
Exemplo n.º 10
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);
}
Exemplo n.º 11
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);
}
Exemplo n.º 12
0
int
main(int argc, const char * argv[]) {

    FILE * ifP;
    int rows, cols;
    int format;
    unsigned int row;
    unsigned int idx;
    unsigned int outColByteCt;
    unsigned int stripeByteCt;
    unsigned int hres, vres;
    unsigned char * inBuff;
    unsigned char * bitrow[256];
    unsigned char * compressedData;
    struct CmdlineInfo cmdline;
    
    pm_proginit(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);

    ifP = pm_openr(cmdline.inputFileName);

    pbm_readpbminit(ifP, &cols, &rows, &format);

    if (cols / 256 > 127)  /* Limit in official Epson manual */
        pm_error("Image width is too large");

    outColByteCt = pbm_packed_bytes(cols);
    stripeByteCt = cmdline.stripeHeight * outColByteCt;

    MALLOCARRAY(inBuff, stripeByteCt);
    if (inBuff == NULL)
      pm_error("Out of memory trying to create input buffer of %u bytes",
               stripeByteCt);

    if (cmdline.compress != 0)
        pm_rlenc_allocoutbuf(&compressedData, stripeByteCt, PM_RLE_PACKBITS);
    else
        compressedData = NULL;

    for (idx = 0; idx <= cmdline.stripeHeight; ++idx)
        bitrow[idx]= &inBuff[idx * outColByteCt];

    hres = vres = 3600 / cmdline.resolution;
        /* Possible values for hres, vres: 20, 10, 5 */

    if (!cmdline.raw)
        writeSetup(hres);

    /* Write out raster stripes */

    for (row = 0; row < rows; row += cmdline.stripeHeight ) {
        unsigned int const rowsThisStripe =
            MIN(rows - row, cmdline.stripeHeight);
        unsigned int const outCols = outColByteCt * 8;

        if (rowsThisStripe > 0) {
            unsigned int idx;

            printf("%c%c%c%c%c%c%c%c", esc, '.', cmdline.compress, vres, hres,
                   cmdline.stripeHeight, outCols % 256, outCols / 256);

            /* Read pbm rows, each padded to full byte */

            for (idx = 0; idx < rowsThisStripe; ++idx) {
                pbm_readpbmrow_packed (ifP, bitrow[idx], cols, format);
                pbm_cleanrowend_packed(bitrow[idx], cols);
            }

            /* If at bottom pad with empty rows up to stripe height */
            if (rowsThisStripe < cmdline.stripeHeight )
                memset(bitrow[rowsThisStripe], 0,
                       (cmdline.stripeHeight - rowsThisStripe) * outColByteCt);

            /* Write raster data */
            if (cmdline.compress != 0) {  /* compressed */
                size_t compressedDataCt;

                pm_rlenc_compressbyte(inBuff, compressedData, PM_RLE_PACKBITS,
                                      stripeByteCt, &compressedDataCt);
                fwrite(compressedData, compressedDataCt, 1, stdout);
            } else                        /* uncompressed */
                fwrite(inBuff, stripeByteCt, 1, stdout);

            /* Emit newline to print the stripe */
            putchar('\n');
        }
    }

    free(inBuff); 
    free(compressedData);
    pm_close(ifP);

    /* Form feed */
    if (cmdline.formfeed)
        putchar('\f');

    if (!cmdline.raw) {
        /* Reset printer. a*/
        printf("%c%c", esc, '@');
    }

    return 0;
}