GP<JB2Image> erode8(const JB2Image *im) { int i; GP<JB2Image> newim = JB2Image::create(); newim->set_dimension(im->get_width(),im->get_height()); for(i=0; i<im->get_shape_count(); i++) { const JB2Shape &shape = im->get_shape(i); JB2Shape newshape; newshape.parent = shape.parent; if (shape.bits) newshape.bits = erode8(shape.bits); else newshape.bits = 0; newim->add_shape(newshape); } for(i=0; i<im->get_blit_count(); i++) { const JB2Blit* blit = im->get_blit(i); JB2Blit newblit; newblit.bottom = blit->bottom + 1; newblit.left = blit->left + 1; newblit.shapeno = blit->shapeno; newim->add_blit(newblit); } return newim; }
// -- Creates a JB2Image with the remaining components GP<JB2Image> CCImage::get_jb2image() const { GP<JB2Image> jimg = JB2Image::create(); jimg->set_dimension(width, height); if (runs.hbound() < 0) return jimg; if (ccs.hbound() < 0) G_THROW("Must first perform a cc analysis"); // Iterate over CCs for (int ccid=0; ccid<=ccs.hbound(); ccid++) { JB2Shape shape; JB2Blit blit; shape.parent = -1; shape.bits = get_bitmap_for_cc(ccid); shape.userdata = 0; if (ccid >= nregularccs) shape.userdata |= JB2SHAPE_SPECIAL; blit.shapeno = jimg->add_shape(shape); blit.left = ccs[ccid].bb.xmin; blit.bottom = ccs[ccid].bb.ymin; jimg->add_blit(blit); shape.bits->compress(); } // Return return jimg; }
GP<JB2Image> MMRDecoder::decode(GP<ByteStream> gbs) { ByteStream &inp=*gbs; // Read header int width, height, invert; const bool striped=decode_header(inp, width, height, invert); // Prepare image GP<JB2Image> jimg = JB2Image::create(); jimg->set_dimension(width, height); // Choose pertinent blocksize int blocksize = MIN(500,MAX(64,MAX(width/17,height/22))); int blocksperline = (width+blocksize-1)/blocksize; // Prepare decoder GP<MMRDecoder> gdcd=MMRDecoder::create(gbs, width, height, striped); MMRDecoder &dcd=*gdcd; // Loop on JB2 bands int line = height-1; while (line >= 0) { int bandline = MIN(blocksize-1,line); GPArray<GBitmap> blocks(0,blocksperline-1); // Loop on scanlines for(; bandline >= 0; bandline--,line--) { // Decode one scanline const unsigned short *s = dcd.scanruns(); if (s) { // Loop on blocks int x = 0; int b = 0; int firstx = 0; bool c = !!invert; while (x < width) { int xend = x + *s++; while (b<blocksperline) { int lastx = MIN(firstx+blocksize,width); if (c) { if (!blocks[b]) blocks[b] = GBitmap::create(bandline+1, lastx-firstx); unsigned char *bptr = (*blocks[b])[bandline] - firstx; int x1 = MAX(x,firstx); int x2 = MIN(xend,lastx); while (x1 < x2) bptr[x1++] = 1; } if (xend < lastx) break; firstx = lastx; b ++; } x = xend; c = !c; } } } // Insert blocks into JB2Image for (int b=0; b<blocksperline; b++) { JB2Shape shape; shape.bits = blocks[b]; if (shape.bits) { shape.parent = -1; shape.bits->compress(); JB2Blit blit; blit.left = b*blocksize; blit.bottom = line+1; blit.shapeno = jimg->add_shape(shape); jimg->add_blit(blit); } } } // Return return jimg; }