void JB2Dict::JB2Codec::code_bitmap_by_cross_coding (GBitmap &bm, GP<GBitmap> &cbm, const int libno) { // Make sure bitmaps will not be disturbed GP<GBitmap> copycbm=GBitmap::create(); if (cbm->monitor()) { // Perform a copy when the bitmap is explicitely shared GMonitorLock lock2(cbm->monitor()); copycbm->init(*cbm); cbm = copycbm; } GMonitorLock lock1(bm.monitor()); // Center bitmaps const int cw = cbm->columns(); const int dw = bm.columns(); const int dh = bm.rows(); const LibRect &l = libinfo[libno]; const int xd2c = (dw/2 - dw + 1) - ((l.right - l.left + 1)/2 - l.right); const int yd2c = (dh/2 - dh + 1) - ((l.top - l.bottom + 1)/2 - l.top); // Ensure borders are adequate bm.minborder(2); cbm->minborder(2-xd2c); cbm->minborder(2+dw+xd2c-cw); // Initialize row pointers const int dy = dh - 1; const int cy = dy + yd2c; #ifndef NDEBUG bm.check_border(); cbm->check_border(); #endif code_bitmap_by_cross_coding (bm,*cbm, xd2c, dw, dy, cy, bm[dy+1], bm[dy], (*cbm)[cy+1] + xd2c, (*cbm)[cy ] + xd2c, (*cbm)[cy-1] + xd2c); }
void JB2Dict::JB2Codec::code_bitmap_directly (GBitmap &bm) { // Make sure bitmap will not be disturbed GMonitorLock lock(bm.monitor()); // ensure borders are adequate bm.minborder(3); // initialize row pointers int dy = bm.rows() - 1; code_bitmap_directly(bm,bm.columns(),dy,bm[dy+2],bm[dy+1],bm[dy]); }
void JB2Dict::JB2Codec::LibRect::compute_bounding_box(const GBitmap &bm) { // First lock the stuff. GMonitorLock lock(bm.monitor()); // Get size const int w = bm.columns(); const int h = bm.rows(); const int s = bm.rowsize(); // Right border for(right=w-1;right >= 0;--right) { unsigned char const *p = bm[0] + right; unsigned char const * const pe = p+(s*h); for (;(p<pe)&&(!*p);p+=s) continue; if (p<pe) break; } // Top border for(top=h-1;top >= 0;--top) { unsigned char const *p = bm[top]; unsigned char const * const pe = p+w; for (;(p<pe)&&(!*p); ++p) continue; if (p<pe) break; } // Left border for (left=0;left <= right;++left) { unsigned char const *p = bm[0] + left; unsigned char const * const pe=p+(s*h); for (;(p<pe)&&(!*p);p+=s) continue; if (p<pe) break; } // Bottom border for(bottom=0;bottom <= top;++bottom) { unsigned char const *p = bm[bottom]; unsigned char const * const pe = p+w; for (;(p<pe)&&(!*p); ++p) continue; if (p<pe) break; } }
void GBitmap::init(const GBitmap &ref, int aborder) { GMonitorLock lock(monitor()); if (this != &ref) { GMonitorLock lock(ref.monitor()); init(ref.nrows, ref.ncolumns, aborder); grays = ref.grays; unsigned char *row = bytes_data+border; for (int n=0; n<nrows; n++, row+=bytes_per_row) memcpy( (void*)row, (void*)ref[n], ncolumns ); } else if (aborder > border) { minborder(aborder); } }
void GBitmap::init(const GBitmap &ref, const GRect &rect, int border) { GMonitorLock lock(monitor()); // test bitmap physical equality if (this == &ref) { GBitmap tmp; tmp.grays = grays; tmp.border = border; tmp.bytes_per_row = bytes_per_row; tmp.ncolumns = ncolumns; tmp.nrows = nrows; tmp.bytes = bytes; tmp.gbytes_data.swap(gbytes_data); tmp.grle.swap(grle); bytes = 0 ; init(tmp, rect, border); } else { GMonitorLock lock(ref.monitor()); // create empty bitmap init(rect.height(), rect.width(), border); grays = ref.grays; // compute destination rectangle GRect rect2(0, 0, ref.columns(), ref.rows() ); rect2.intersect(rect2, rect); rect2.translate(-rect.xmin, -rect.ymin); // copy bits if (! rect2.isempty()) { for (int y=rect2.ymin; y<rect2.ymax; y++) { unsigned char *dst = (*this)[y]; const unsigned char *src = ref[y+rect.ymin] + rect.xmin; for (int x=rect2.xmin; x<rect2.xmax; x++) dst[x] = src[x]; } } } }