static TImageP renderVectorImage(TOfflineGL *glContext, const TVectorRenderData &rd, const TPointD &dpi, const TImageP &img, const TPixel32 &color) { glContext->clear(color); glContext->draw(img, rd); TRasterImageP rimg(glContext->getRaster()); rimg->setDpi(dpi.x, dpi.y); return rimg; }
void make_bpixmaps(void) // create scaled window button pixmaps { int wh = defaults::windowbuttonsize-4; QImage limg(qapp::get_cfile("button_left.xpm")); QImage rimg(qapp::get_cfile("button_right.xpm")); qapp::leftwinpix = new QPixmap(); qapp::rightwinpix = new QPixmap(); if(! limg.isNull()) qapp::leftwinpix->convertFromImage(limg.smoothScale(wh, wh)); if(! rimg.isNull()) qapp::rightwinpix->convertFromImage(rimg.smoothScale(wh, wh)); }
void make_bpixmaps(void) // create scaled window button pixmaps { int wh = defaults::windowbuttonsize-4; QImage limg(qapp::get_cfile("button_left.xpm")); QImage rimg(qapp::get_cfile("button_right.xpm")); qapp::leftwinpix = new QPixmap(); qapp::rightwinpix = new QPixmap(); if(! limg.isNull()) *qapp::leftwinpix = QPixmap::fromImage(limg.scaled(wh, wh, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); if(! rimg.isNull()) *qapp::rightwinpix = QPixmap::fromImage(rimg.scaled(wh, wh, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); }
// -- Compresses low color pixmap. void cpaldjvu(ByteStream *ibs, GURL &urlout, const cpaldjvuopts &opts) { GP<GPixmap> ginput=GPixmap::create(*ibs); int w = ginput->columns(); int h = ginput->rows(); int dpi = MAX(200, MIN(900, opts.dpi)); int largesize = MIN(500, MAX(64, dpi)); int smallsize = MAX(2, dpi/150); // Compute optimal palette and quantize input pixmap GP<DjVuPalette> gpal=DjVuPalette::create(); DjVuPalette &pal=*gpal; GPixel bgcolor; int bgindex = -1; if (! opts.bgwhite) { bgindex = pal.compute_pixmap_palette(*ginput, opts.ncolors); pal.index_to_color(bgindex, bgcolor); } else { bgcolor = GPixel::WHITE; pal.histogram_clear(); for (int j=0; j<h; j++) { const GPixel *p = (*ginput)[j]; for (int i=0; i<w; i++) if (p[i] != GPixel::WHITE) pal.histogram_add(p[i], 1); } pal.compute_palette(opts.ncolors); } if (opts.verbose) DjVuFormatErrorUTF8( "%s\t%d\t%d\t%d", ERR_MSG("cpaldjvu.quantizied"), w, h, pal.size()); if (opts.verbose && !opts.bgwhite) DjVuPrintErrorUTF8("cpaldjvu: background color is #%02x%02x%02x.\n", bgcolor.r, bgcolor.g, bgcolor.b); // Fill CCImage with color runs int xruncount=0,yruncount=0; CCImage rimg(w, h); int *line; GPBuffer<int> gline(line,w); int *prevline; GPBuffer<int> gprevline(prevline,w); for (int x=0;x<w;x++) { prevline[x]=bgindex; } for (int y=0; y<h; y++) { int x; const GPixel *row = (*ginput)[y]; for(x=0;x<w;x++) { line[x] = pal.color_to_index(row[x]); if (opts.bgwhite && row[x]==GPixel::WHITE) line[x] = bgindex; } for(x=0;x<w;) { int x1 = x; int index = line[x++]; while (x<w && line[x]==index) { x++; } if (index != bgindex) { xruncount++; rimg.add_single_run(y, x1, x-1, index); } } for(x=0;x<w;x++) if(prevline[x] != line[x]) yruncount++; gprevline.swap(gline); } ginput = 0; //save memory if (opts.verbose) DjVuFormatErrorUTF8( "%s\t%d", ERR_MSG("cpaldjvu.color_runs"), rimg.runs.size()); // Perform Color Connected Component Analysis rimg.make_ccids_by_analysis(); // Obtain ccids rimg.make_ccs_from_ccids(); // Compute cc descriptors if (opts.verbose) DjVuFormatErrorUTF8( "%s\t%d", ERR_MSG("cpaldjvu.ccs_before"), rimg.ccs.size()); rimg.merge_and_split_ccs(smallsize,largesize); // Eliminates gross ccs if (opts.verbose) DjVuFormatErrorUTF8( "%s\t%d", ERR_MSG("cpaldjvu.ccs_after"), rimg.ccs.size()); rimg.sort_in_reading_order(); // Sort cc descriptors // Create JB2Image and fill colordata GP<JB2Image> gjimg=JB2Image::create(); JB2Image &jimg=*gjimg; jimg.set_dimension(w, h); int nccs = rimg.ccs.size(); for (int ccid=0; ccid<nccs; ccid++) { JB2Shape shape; JB2Blit blit; shape.parent = -1; shape.userdata = 0; if (ccid >= rimg.nregularccs) shape.userdata |= JB2SHAPE_SPECIAL; shape.bits = rimg.get_bitmap_for_cc(ccid); shape.bits->compress(); CC& cc = rimg.ccs[ccid]; blit.shapeno = jimg.add_shape(shape); blit.left = cc.bb.xmin; blit.bottom = cc.bb.ymin; int blitno = jimg.add_blit(blit); pal.colordata.touch(blitno); pal.colordata[blitno] = cc.color; } // Organize JB2Image tune_jb2image_lossless(&jimg); if (opts.verbose) { int nshape=0, nrefine=0; for (int i=0; i<jimg.get_shape_count(); i++) { if (!jimg.get_shape(i).bits) continue; if (jimg.get_shape(i).parent >= 0) nrefine++; nshape++; } DjVuFormatErrorUTF8( "%s\t%d\t%d", ERR_MSG("cpaldjvu.cross_code"), nshape, nrefine); } // Create background image #ifdef BACKGROUND_SUBSAMPLING_FACTOR // -- we may create the background by masking and subsampling GP<GPixmap> ginputsub=GPixmap::create(); GPixmap &inputsub=*ginputsub; GP<GBitmap> mask = jimg.get_bitmap(BACKGROUND_SUBSAMPLING_FACTOR); inputsub.downsample(&input, BACKGROUND_SUBSAMPLING_FACTOR); GP<IW44Image> iwimage=IW44Image::create(inputsub, mask); #else // -- but who cares since the background is uniform. GP<GPixmap> ginputsub=GPixmap::create((h+11)/12, (w+11)/12, &bgcolor); GPixmap &inputsub=*ginputsub; GP<IW44Image> iwimage=IW44Image::create_encode(inputsub); #endif // Assemble DJVU file GP<ByteStream> obs=ByteStream::create(urlout, "wb"); GP<IFFByteStream> giff=IFFByteStream::create(obs); IFFByteStream &iff=*giff; // -- main composite chunk iff.put_chunk("FORM:DJVU", 1); // -- ``INFO'' chunk iff.put_chunk("INFO"); GP<DjVuInfo> ginfo=DjVuInfo::create(); DjVuInfo info=*ginfo; info.height = h; info.width = w; info.dpi = opts.dpi; info.encode(*iff.get_bytestream()); iff.close_chunk(); // -- ``Sjbz'' chunk iff.put_chunk("Sjbz"); jimg.encode(iff.get_bytestream()); iff.close_chunk(); // -- ``FGbz'' chunk iff.put_chunk("FGbz"); pal.encode(iff.get_bytestream()); iff.close_chunk(); // -- ``BG44'' chunk IWEncoderParms iwparms; #ifdef PROGRESSIVE_BACKGROUND // ----- we may use several chunks to enable progressive rendering ... iff.put_chunk("BG44"); iwparms.slices = 74; iwimage->encode_chunk(iff, iwparms); iff.close_chunk(); iff.put_chunk("BG44"); iwparms.slices = 87; iwimage->encode_chunk(iff, iwparms); iff.close_chunk(); #endif // ----- but who cares when the background is so small. iff.put_chunk("BG44"); iwparms.slices = 97; iwimage->encode_chunk(iff.get_bytestream(), iwparms); iff.close_chunk(); // -- terminate main composite chunk iff.close_chunk(); // Finished! }