//----------------------------------------------------------------------------- // questa funzione viene chiamata dopo il fill rect delle aree, e colora gli // inchiostri di tipo "autoink" // che confinano con le aree appena fillate con il rect. rbefore e' il rect del // raster prima del rectfill. void fillautoInks(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore, TPalette *plt) { assert(plt); TRasterCM32P r = rin->extract(rect); assert(r->getSize() == rbefore->getSize()); int i, j; for (i = 0; i < r->getLy(); i++) { TPixelCM32 *pix = r->pixels(i); TPixelCM32 *pixb = rbefore->pixels(i); for (j = 0; j < r->getLx(); j++, pix++, pixb++) { int paint = pix->getPaint(); int tone = pix->getTone(); int ink = pix->getInk(); if (paint != pixb->getPaint() && tone > 0 && tone < 255 && ink != paint && plt->getStyle(ink)->getFlags() != 0) inkFill(rin, TPoint(j, i) + rect.getP00(), paint, 0, NULL, &rect); } } }
void Convert2Tlv::buildToonzRaster(TRasterCM32P &rout, const TRasterP &rin1, const TRasterP &rin2) { if (rin2) assert(rin1->getSize() == rin2->getSize()); rout->clear(); std::cout << " computing inks...\n"; TRaster32P r1 = (TRaster32P)rin1; TRasterGR8P r1gr = (TRasterGR8P)rin1; TRaster32P r2 = (TRaster32P)rin2; TRasterGR8P r2gr = (TRasterGR8P)rin2; TRasterP rU, rP; if (r1gr) { rU = r1gr; rP = r2; } else if (r2gr) { rU = r2gr; rP = r1; } else if (!r1) rU = r2; else if (!r2) rU = r1; else if (firstIsUnpainted(r1, r2)) { rU = r1; rP = r2; } else { rU = r2; rP = r1; } TRasterCM32P r; if (rout->getSize() != rU->getSize()) { int dx = rout->getLx() - rU->getLx(); int dy = rout->getLy() - rU->getLy(); assert(dx >= 0 && dy >= 0); r = rout->extract(dx / 2, dy / 2, dx / 2 + rU->getLx() - 1, dy / 2 + rU->getLy() - 1); } else r = rout; if ((TRasterGR8P)rU) buildInksFromGrayTones(r, rU); else if (m_isUnpaintedFromNAA) buildInksForNAAImage(r, (TRaster32P)rU); else { int maxMatte = getMaxMatte((TRaster32P)rU); if (maxMatte == -1) buildInksFromGrayTones(r, rU); else { if (maxMatte < 255) normalize(rU, maxMatte); buildInks(r, (TRaster32P)rU /*rP,*/); } } if (m_autoclose) TAutocloser(r, AutocloseDistance, AutocloseAngle, 1, AutocloseOpacity).exec(); if (rP) { std::cout << " computing paints...\n"; doFill(r, rP); } if (m_antialiasType == 2) //remove antialias removeAntialias(r); else if (m_antialiasType == 1) //add antialias { TRasterCM32P raux(r->getSize()); TRop::antialias(r, raux, 10, m_antialiasValue); rout = raux; } }
CleanupPreprocessedImage *TCleanupper::process( TRasterImageP &image, bool first_image, TRasterImageP &onlyResampledImage, bool isCameraTest, bool returnResampled, bool onlyForSwatch, TAffine *resampleAff) { TAffine aff; double blur; TDimension outDim(0, 0); TPointD outDpi; bool isSameDpi = false; bool autocentered = getResampleValues(image, aff, blur, outDim, outDpi, isCameraTest, isSameDpi); if (m_parameters->m_autocenterType != AUTOCENTER_NONE && !autocentered) DVGui::MsgBox(DVGui::WARNING, QObject::tr("The autocentering failed on the current drawing.")); bool fromGr8 = (bool)TRasterGR8P(image->getRaster()); bool toGr8 = (m_parameters->m_lineProcessingMode == lpGrey); // If necessary, perform auto-adjust if (!isCameraTest && m_parameters->m_lineProcessingMode != lpNone && toGr8 && m_parameters->m_autoAdjustMode != AUTO_ADJ_NONE && !onlyForSwatch) { static int ref_cum[256]; UCHAR lut[256]; int cum[256]; double x0_src_f, y0_src_f, x1_src_f, y1_src_f; int x0_src, y0_src, x1_src, y1_src; //cleanup_message("Autoadjusting... \n"); TAffine inv = aff.inv(); x0_src_f = affMV1(inv, 0, 0); y0_src_f = affMV2(inv, 0, 0); x1_src_f = affMV1(inv, outDim.lx - 1, outDim.ly - 1); y1_src_f = affMV2(inv, outDim.lx - 1, outDim.ly - 1); x0_src = tround(x0_src_f); y0_src = tround(y0_src_f); x1_src = tround(x1_src_f); y1_src = tround(y1_src_f); set_autoadjust_window(x0_src, y0_src, x1_src, y1_src); if (!TRasterGR8P(image->getRaster())) { //Auto-adjusting a 32-bit image. This means that a white background must be introduced first. TRaster32P ras32(image->getRaster()->clone()); TRop::addBackground(ras32, TPixel32::White); image = TRasterImageP(ras32); //old image is released here ras32 = TRaster32P(); TRasterGR8P rgr(image->getRaster()->getSize()); TRop::copy(rgr, image->getRaster()); //This is now legit. It was NOT before the clone, since the original could be cached. image->setRaster(rgr); } switch (m_parameters->m_autoAdjustMode) { case AUTO_ADJ_HISTOGRAM: { if (first_image) { build_gr_cum(image, ref_cum); } else { build_gr_cum(image, cum); build_gr_lut(ref_cum, cum, lut); apply_lut(image, lut); } } CASE AUTO_ADJ_HISTO_L : histo_l_algo(image, first_image); CASE AUTO_ADJ_BLACK_EQ : black_eq_algo(image); CASE AUTO_ADJ_NONE : DEFAULT : assert(false); } } fromGr8 = (bool)TRasterGR8P(image->getRaster()); //may have changed type due to auto-adjust assert(returnResampled || !onlyForSwatch); //if onlyForSwatch, then returnResampled // Allocate output colormap raster TRasterCM32P finalRas; if (!onlyForSwatch) { finalRas = TRasterCM32P(outDim); if (!finalRas) { TImageCache::instance()->outputMap(outDim.lx * outDim.ly * 4, "C:\\cachelog"); assert(!"failed finalRas allocation!"); return 0; } } // In case the input raster was a greymap, we cannot reutilize finalRas's buffer to transform the final // fullcolor pixels to colormap pixels directly (1 32-bit pixel would hold 4 8-bit pixels) - therefore, // a secondary greymap is allocated. //NOTE: This should be considered obsolete? By using TRop::resample( <TRaster32P& instance> , ...) we //should get the same effect!! TRasterP tmp_ras; if (returnResampled || (fromGr8 && toGr8)) { if (fromGr8 && toGr8) tmp_ras = TRasterGR8P(outDim); else tmp_ras = TRaster32P(outDim); if (!tmp_ras) { TImageCache::instance()->outputMap(outDim.lx * outDim.ly * 4, "C:\\cachelog"); assert(!"failed tmp_ras allocation!"); return 0; } } else //if finalRas is allocated, and the intermediate raster has to be 32-bit, we can perform pixel //conversion directly on the same output buffer tmp_ras = TRaster32P(outDim.lx, outDim.ly, outDim.lx, (TPixel32 *)finalRas->getRawData()); TRop::ResampleFilterType flt_type; if (isSameDpi) flt_type = TRop::ClosestPixel; //NearestNeighbor else if (isCameraTest) flt_type = TRop::Triangle; else flt_type = TRop::Hann2; TRop::resample(tmp_ras, image->getRaster(), aff, flt_type, blur); if ((TRaster32P)tmp_ras) //Add white background to deal with semitransparent pixels TRop::addBackground(tmp_ras, TPixel32::White); if (resampleAff) *resampleAff = aff; image->getRaster()->unlock(); image = TRasterImageP(); if (returnResampled) { onlyResampledImage = TRasterImageP(tmp_ras); onlyResampledImage->setDpi(outDpi.x, outDpi.y); } if (onlyForSwatch) return 0; assert(finalRas); // Copy current cleanup palette to parameters' colors m_parameters->m_colors.update(m_parameters->m_cleanupPalette.getPointer(), m_parameters->m_noAntialias); if (toGr8) { //No (color) processing. Not even thresholding. This just means that all the important //stuff here is made in the brightness/contrast stage... //NOTE: Most of the color processing should be DISABLED in this case!! tmp_ras->lock(); finalRas->lock(); assert(tmp_ras->getSize() == finalRas->getSize()); assert(tmp_ras->getLx() == tmp_ras->getWrap()); assert(finalRas->getLx() == finalRas->getWrap()); int pixCount = outDim.lx * outDim.ly; if (fromGr8) { UCHAR *rowin = tmp_ras->getRawData(); TUINT32 *rowout = reinterpret_cast<TUINT32 *>(finalRas->getRawData()); for (int i = 0; i < pixCount; i++) *rowout++ = *rowin++; //Direct copy for now... :( } else { TPixel32 *rowin = reinterpret_cast<TPixel32 *>(tmp_ras->getRawData()); TUINT32 *rowout = reinterpret_cast<TUINT32 *>(finalRas->getRawData()); for (int i = 0; i < pixCount; i++) *rowout++ = TPixelGR8::from(*rowin++).value; } tmp_ras->unlock(); finalRas->unlock(); } else { //WARNING: finalRas and tmp_ras may share the SAME buffer! assert(TRaster32P(tmp_ras)); preprocessColors(finalRas, tmp_ras, m_parameters->m_colors); } TToonzImageP final; final = TToonzImageP(finalRas, finalRas->getBounds());
void TRop::over(TRasterP rout, const TRasterCM32P &rup, TPalette *palette, const TPoint &point, const TAffine &aff) { TRaster32P app(rup->getSize()); TRop::convert(app, rup, palette); TRop::over(rout, app, point, aff); }