void readRaster(const TRasterPT<Pix> &ras, Tiio::Reader *reader, int x0, int y0, int x1, int y1, int inLx, int inLy, int shrink) { typedef typename pixel_traits<Pix>::buffer_type buffer_type; if (shrink == 1) { // Direct read ras->lock(); ptrdiff_t linePad = -x0 * ras->getPixelSize(); if (reader->getRowOrder() == Tiio::BOTTOM2TOP) { int start = reader->skipLines(y0); int stop = y1 + 1; for (int y = start; y < stop; ++y) if (y >= y0 && y <= y1) { buffer_type *line = (buffer_type *)(ras->getRawData(0, y - y0) + linePad); reader->readLine(line, x0, x1, 1); } } else // TOP2BOTTOM { reader->skipLines(inLy - y1 - 1); for (int y = y1; y >= y0; --y) { buffer_type *line = (buffer_type *)(ras->getRawData(0, y - y0) + linePad); reader->readLine(line, x0, x1, 1); } } ras->unlock(); } else readRaster_copyLines(ras, reader, x0, y0, x1, y1, inLx, inLy, shrink); }
void readRaster_copyLines(const TRasterPT<Pix> &ras, Tiio::Reader *reader, int x0, int y0, int x1, int y1, int inLx, int inLy, int shrink) { typedef typename pixel_traits<Pix>::buffer_type buffer_type; typedef typename pixel_traits<Pix>::rgbm_pixel_type rgbm_pixel_type; int linesToSkip = shrink - 1; buffer_type *lineBuffer = (buffer_type *)malloc(inLx * sizeof(rgbm_pixel_type)); if (!lineBuffer) return; rgbm_pixel_type *lineIn = (rgbm_pixel_type *)lineBuffer; if (reader->getRowOrder() == Tiio::BOTTOM2TOP) { int start = reader->skipLines(y0); int stop = y1 + 1; for (int y = start; y < stop; ++y) { reader->readLine(lineBuffer, x0, x1, shrink); if (y >= y0 && y <= y1 && (y - y0) % shrink == 0) { Pix *line = (Pix *)ras->getRawData(0, (y - y0) / shrink); copyLine<Pix>(lineIn, line, x0, ras->getLx(), shrink); } if (linesToSkip > 0 && y + linesToSkip < inLy) y += reader->skipLines(linesToSkip); } } else // TOP2BOTTOM { reader->skipLines(inLy - y1 - 1); for (int y = y1; y >= y0; --y) { reader->readLine(lineBuffer, x0, x1, shrink); if ((y - y0) % shrink == 0) { Pix *line = (Pix *)ras->getRawData(0, (y - y0) / shrink); copyLine<Pix>(lineIn, line, x0, ras->getLx(), shrink); } if (linesToSkip > 0 && y - linesToSkip > 0) y -= reader->skipLines(linesToSkip); } } free(lineBuffer); }
TRasterImageP Ffmpeg::getImage(int frameIndex) { QString ffmpegCachePath = getFfmpegCache().getQString(); QString tempPath = ffmpegCachePath + "//" + cleanPathSymbols(); std::string tmpPath = tempPath.toStdString(); // QString tempPath= m_path.getQString(); QString number = QString("%1").arg(frameIndex, 4, 10, QChar('0')); QString tempName = "In" + number + ".png"; tempName = tempPath + tempName; // for debugging std::string strPath = tempName.toStdString(); if (TSystem::doesExistFileOrLevel(TFilePath(tempName))) { QImage *temp = new QImage(tempName, "PNG"); if (temp) { QImage tempToo = temp->convertToFormat(QImage::Format_ARGB32); delete temp; const UCHAR *bits = tempToo.bits(); TRasterPT<TPixelRGBM32> ret; ret.create(m_lx, m_ly); ret->lock(); memcpy(ret->getRawData(), bits, m_lx * m_ly * 4); ret->unlock(); ret->yMirror(); return TRasterImageP(ret); } } else return TRasterImageP(); }
void blend(TToonzImageP ti, TRasterPT<PIXEL> rasOut, const std::vector<BlendParam> ¶ms) { assert(ti->getRaster()->getSize() == rasOut->getSize()); // Extract the interesting raster. It should be the savebox of passed cmap, // plus - if // some param has the 0 index as blending color - the intensity of that blend // param. unsigned int i, j; TRect saveBox(ti->getSavebox()); int enlargement = 0; for (i = 0; i < params.size(); ++i) for (j = 0; j < params[i].colorsIndexes.size(); ++j) if (params[i].colorsIndexes[j] == 0) enlargement = std::max(enlargement, tceil(params[i].intensity)); saveBox = saveBox.enlarge(enlargement); TRasterCM32P cmIn(ti->getRaster()->extract(saveBox)); TRasterPT<PIXEL> rasOutExtract = rasOut->extract(saveBox); // Ensure that cmIn and rasOut have the same size unsigned int lx = cmIn->getLx(), ly = cmIn->getLy(); // Build the pure colors infos SelectionRaster selectionRaster(cmIn); // Now, build a little group of BlurPatterns - and for each, one for passed // param. // A small number of patterns per param is needed to make the pattern look not // ever the same. const int blurPatternsPerParam = 10; std::vector<BlurPatternContainer> blurGroup(params.size()); for (i = 0; i < params.size(); ++i) { BlurPatternContainer &blurContainer = blurGroup[i]; blurContainer.reserve(blurPatternsPerParam); for (j = 0; j < blurPatternsPerParam; ++j) blurContainer.push_back(BlurPattern( params[i].intensity, params[i].smoothness, params[i].stopAtCountour)); } // Build the palette TPalette *palette = ti->getPalette(); std::vector<TPixel32> paletteColors; paletteColors.resize(palette->getStyleCount()); for (i = 0; i < paletteColors.size(); ++i) paletteColors[i] = premultiply(palette->getStyle(i)->getAverageColor()); // Build the 4 auxiliary rasters for the blending procedure: they are ink / // paint versus input / output in the blend. // The output raster is reused to spare some memory - it should be, say, the // inkLayer's second at the end of the overall // blending procedure. It could be the first, without the necessity of // clearing it before blending the layers, but things // get more complicated when PIXEL is TPixel64... RGBMRasterPair inkLayer, paintLayer; TRaster32P rasOut32P_1(lx, ly, lx, (TPixel32 *)rasOut->getRawData(), false); inkLayer.first = (params.size() % 2) ? rasOut32P_1 : TRaster32P(lx, ly); inkLayer.second = (params.size() % 2) ? TRaster32P(lx, ly) : rasOut32P_1; if (PIXEL::maxChannelValue >= TPixel64::maxChannelValue) { TRaster32P rasOut32P_2(lx, ly, lx, ((TPixel32 *)rasOut->getRawData()) + lx * ly, false); paintLayer.first = (params.size() % 2) ? rasOut32P_2 : TRaster32P(lx, ly); paintLayer.second = (params.size() % 2) ? TRaster32P(lx, ly) : rasOut32P_2; } else { paintLayer.first = TRaster32P(lx, ly); paintLayer.second = TRaster32P(lx, ly); } inkLayer.first->clear(); inkLayer.second->clear(); paintLayer.first->clear(); paintLayer.second->clear(); // Now, we have to perform the blur of each of the cm's pixels. cmIn->lock(); rasOut->lock(); inkLayer.first->lock(); inkLayer.second->lock(); paintLayer.first->lock(); paintLayer.second->lock(); // Convert the initial cmIn to fullcolor ink - paint layers buildLayers(cmIn, paletteColors, inkLayer.first, paintLayer.first); // Perform the blend on separated ink - paint layers for (i = 0; i < params.size(); ++i) { if (params[i].colorsIndexes.size() == 0) continue; selectionRaster.updateSelection(cmIn, params[i]); doBlend(cmIn, inkLayer, paintLayer, selectionRaster, blurGroup[i]); tswap(inkLayer.first, inkLayer.second); tswap(paintLayer.first, paintLayer.second); } // Release the unnecessary rasters inkLayer.second->unlock(); paintLayer.second->unlock(); inkLayer.second = TRaster32P(); paintLayer.second = TRaster32P(); // Clear rasOut - since it was reused to spare space... rasOut->clear(); // Add the ink & paint layers on the output raster double PIXELmaxChannelValue = PIXEL::maxChannelValue; double toPIXELFactor = PIXELmaxChannelValue / (double)TPixel32::maxChannelValue; double inkFactor, paintFactor; TPoint pos; PIXEL *outPix, *outBegin = (PIXEL *)rasOutExtract->getRawData(); TPixelCM32 *cmPix, *cmBegin = (TPixelCM32 *)cmIn->getRawData(); int wrap = rasOutExtract->getWrap(); TPixel32 *inkPix = (TPixel32 *)inkLayer.first->getRawData(); TPixel32 *paintPix = (TPixel32 *)paintLayer.first->getRawData(); for (i = 0; i < ly; ++i) { outPix = outBegin + wrap * i; cmPix = cmBegin + wrap * i; for (j = 0; j < lx; ++j, ++outPix, ++cmPix, ++inkPix, ++paintPix) { getFactors(cmPix->getTone(), inkFactor, paintFactor); outPix->r = tcrop( toPIXELFactor * (inkFactor * inkPix->r + paintFactor * paintPix->r), 0.0, PIXELmaxChannelValue); outPix->g = tcrop( toPIXELFactor * (inkFactor * inkPix->g + paintFactor * paintPix->g), 0.0, PIXELmaxChannelValue); outPix->b = tcrop( toPIXELFactor * (inkFactor * inkPix->b + paintFactor * paintPix->b), 0.0, PIXELmaxChannelValue); outPix->m = tcrop( toPIXELFactor * (inkFactor * inkPix->m + paintFactor * paintPix->m), 0.0, PIXELmaxChannelValue); } } inkLayer.first->unlock(); paintLayer.first->unlock(); cmIn->unlock(); rasOut->unlock(); // Destroy the auxiliary bitmaps selectionRaster.destroy(); }
void ropSharpen(const TRasterPT<T> &rin, TRasterPT<T> &rout, int sharpen_max_corr) { T *bufin, *east, *northeast, *southeast; T *bufout, *pixout; int lx, ly, wrapin, wrapout, x, y, count; int cntr_r, east_r, col_west_r, col_cntr_r, col_east_r; int cntr_g, east_g, col_west_g, col_cntr_g, col_east_g; int cntr_b, east_b, col_west_b, col_cntr_b, col_east_b; int cntr_m, east_m, col_west_m, col_cntr_m, col_east_m; int lapl, out; #define SET_PIXOUT(X) \ { \ lapl = (cntr_##X << 3) + cntr_##X - \ (col_west_##X + col_cntr_##X + col_east_##X); \ if (lapl < 0) { \ out = cntr_##X - ((256 * 4 - lapl * sharpen_max_corr) >> (8 + 3)); \ pixout->X = (out <= 0) ? 0 : out; \ } else { \ out = cntr_##X + ((256 * 4 + lapl * sharpen_max_corr) >> (8 + 3)); \ pixout->X = (out >= maxChanVal) ? maxChanVal : out; \ } \ } rin->lock(); rout->lock(); bufin = (T *)rin->getRawData(); bufout = (T *)rout->getRawData(); lx = std::min(rin->getLx(), rout->getLx()); ly = std::min(rin->getLy(), rout->getLy()); wrapin = rin->getWrap(); wrapout = rout->getWrap(); int maxChanVal = T::maxChannelValue; if (lx <= 1 || ly <= 1) { for (y = 0; y < ly; y++) for (x = 0; x < lx; x++) bufout[x + y * wrapout] = bufin[x + y * wrapin]; return; } east = bufin; northeast = east + wrapin; east_r = east->r; east_g = east->g; east_b = east->b; east_m = east->m; col_east_r = 2 * east_r + northeast->r; col_east_g = 2 * east_g + northeast->g; col_east_b = 2 * east_b + northeast->b; col_east_m = 2 * east_m + northeast->m; col_cntr_r = col_east_r; col_cntr_g = col_east_g; col_cntr_b = col_east_b; col_cntr_m = col_east_m; east++; northeast++; pixout = bufout; for (count = lx - 1; count > 0; count--, east++, northeast++, pixout++) { cntr_r = east_r; east_r = east->r; col_west_r = col_cntr_r; col_cntr_r = col_east_r; col_east_r = 2 * east_r + northeast->r; SET_PIXOUT(r) cntr_g = east_g; east_g = east->g; col_west_g = col_cntr_g; col_cntr_g = col_east_g; col_east_g = 2 * east_g + northeast->g; SET_PIXOUT(g) cntr_b = east_b; east_b = east->b; col_west_b = col_cntr_b; col_cntr_b = col_east_b; col_east_b = 2 * east_b + northeast->b; SET_PIXOUT(b) cntr_m = east_m; east_m = east->m; col_west_m = col_cntr_m; col_cntr_m = col_east_m; col_east_m = 2 * east_m + northeast->m; SET_PIXOUT(m) } cntr_r = east_r; col_west_r = col_cntr_r; col_cntr_r = col_east_r; SET_PIXOUT(r) cntr_g = east_g; col_west_g = col_cntr_g; col_cntr_g = col_east_g; SET_PIXOUT(g) cntr_b = east_b; col_west_b = col_cntr_b; col_cntr_b = col_east_b; SET_PIXOUT(b) cntr_m = east_m; col_west_m = col_cntr_m; col_cntr_m = col_east_m; SET_PIXOUT(m) for (y = 1; y < ly - 1; y++) { east = bufin + y * wrapin; northeast = east + wrapin; southeast = east - wrapin; east_r = east->r; east_g = east->g; east_b = east->b; east_m = east->m; col_east_r = east_r + northeast->r + southeast->r; col_east_g = east_g + northeast->g + southeast->g; col_east_b = east_b + northeast->b + southeast->b; col_east_m = east_m + northeast->m + southeast->m; col_cntr_r = col_east_r; col_cntr_g = col_east_g; col_cntr_b = col_east_b; col_cntr_m = col_east_m; east++; northeast++; southeast++; pixout = bufout + y * wrapout; for (count = lx - 1; count > 0; count--, east++, northeast++, southeast++, pixout++) { cntr_r = east_r; east_r = east->r; col_west_r = col_cntr_r; col_cntr_r = col_east_r; col_east_r = east_r + northeast->r + southeast->r; SET_PIXOUT(r) cntr_g = east_g; east_g = east->g; col_west_g = col_cntr_g; col_cntr_g = col_east_g; col_east_g = east_g + northeast->g + southeast->g; SET_PIXOUT(g) cntr_b = east_b; east_b = east->b; col_west_b = col_cntr_b; col_cntr_b = col_east_b; col_east_b = east_b + northeast->b + southeast->b; SET_PIXOUT(b) cntr_m = east_m; east_m = east->m; col_west_m = col_cntr_m; col_cntr_m = col_east_m; col_east_m = east_m + northeast->m + southeast->m; SET_PIXOUT(m) } cntr_r = east_r; col_west_r = col_cntr_r; col_cntr_r = col_east_r; SET_PIXOUT(r) cntr_g = east_g; col_west_g = col_cntr_g; col_cntr_g = col_east_g; SET_PIXOUT(g) cntr_b = east_b; col_west_b = col_cntr_b; col_cntr_b = col_east_b; SET_PIXOUT(b) cntr_m = east_m; col_west_m = col_cntr_m; col_cntr_m = col_east_m; SET_PIXOUT(m) } east = bufin + y * wrapin; southeast = east - wrapin; east_r = east->r; east_g = east->g; east_b = east->b; east_m = east->m; col_east_r = 2 * east_r + southeast->r; col_east_g = 2 * east_g + southeast->g; col_east_b = 2 * east_b + southeast->b; col_east_m = 2 * east_m + southeast->m; col_cntr_r = col_east_r; col_cntr_g = col_east_g; col_cntr_b = col_east_b; col_cntr_m = col_east_m; east++; southeast++; pixout = bufout + y * wrapout; for (count = lx - 1; count > 0; count--, east++, southeast++, pixout++) { cntr_r = east_r; east_r = east->r; col_west_r = col_cntr_r; col_cntr_r = col_east_r; col_east_r = 2 * east_r + southeast->r; SET_PIXOUT(r) cntr_g = east_g; east_g = east->g; col_west_g = col_cntr_g; col_cntr_g = col_east_g; col_east_g = 2 * east_g + southeast->g; SET_PIXOUT(g) cntr_b = east_b; east_b = east->b; col_west_b = col_cntr_b; col_cntr_b = col_east_b; col_east_b = 2 * east_b + southeast->b; SET_PIXOUT(b) cntr_m = east_m; east_m = east->m; col_west_m = col_cntr_m; col_cntr_m = col_east_m; col_east_m = 2 * east_m + southeast->m; SET_PIXOUT(m) } cntr_r = east_r; col_west_r = col_cntr_r; col_cntr_r = col_east_r; SET_PIXOUT(r) cntr_g = east_g; col_west_g = col_cntr_g; col_cntr_g = col_east_g; SET_PIXOUT(g) cntr_b = east_b; col_west_b = col_cntr_b; col_cntr_b = col_east_b; SET_PIXOUT(b) cntr_m = east_m; col_west_m = col_cntr_m; col_cntr_m = col_east_m; SET_PIXOUT(m) rin->unlock(); rout->unlock(); }