void UndoManager::getSnapshot(int index, DImg* const img) const { DImg data = d->undoCache->getData(index); // Pass ownership of buffer. If data is null, img will be null img->putImageData(data.width(), data.height(), data.sixteenBit(), data.hasAlpha(), data.bits(), true); }
bool UndoCache::putData(int level, const DImg& img) const { QFile file(d->cacheFile(level)); KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(d->cacheDir); unsigned long fspace = (unsigned long)(info.available()/1024.0/1024.0); kDebug() << "Free space available in Editor cache [" << d->cacheDir << "] in Mbytes: " << fspace; if (file.exists() || !file.open(QIODevice::WriteOnly) || fspace < 1024) // Check if free space is over 1 Gb to put data in cache. { return false; } QDataStream ds(&file); ds << img.width(); ds << img.height(); ds << img.sixteenBit(); ds << img.hasAlpha(); QByteArray ba((const char*)img.bits(), img.numBytes()); ds << ba; file.close(); d->cachedLevels << level; return true; }
void BorderFilter::solid2(DImg& src, DImg& dest, const DColor& fg, int borderWidth) { dest = DImg(src.width() + borderWidth * 2, src.height() + borderWidth * 2, src.sixteenBit(), src.hasAlpha()); dest.fill(fg); dest.bitBltImage(&src, borderWidth, borderWidth); }
void BorderFilter::solid(DImg& src, DImg& dest, const DColor& fg, int borderWidth) { if (d->settings.orgWidth > d->settings.orgHeight) { int height = src.height() + borderWidth * 2; dest = DImg((int)(height * d->orgRatio), height, src.sixteenBit(), src.hasAlpha()); dest.fill(fg); dest.bitBltImage(&src, (dest.width() - src.width()) / 2, borderWidth); } else { int width = src.width() + borderWidth * 2; dest = DImg(width, (int)(width / d->orgRatio), src.sixteenBit(), src.hasAlpha()); dest.fill(fg); dest.bitBltImage(&src, borderWidth, (dest.height() - src.height()) / 2); } }
void BorderFilter::bevel2(DImg& src, DImg& dest, const DColor& topColor, const DColor& btmColor, int borderWidth) { int x, y; int wc; dest = DImg(src.width() + borderWidth * 2, src.height() + borderWidth * 2, src.sixteenBit(), src.hasAlpha()); // top for (y = 0, wc = (int)dest.width() - 1; y < borderWidth; ++y, --wc) { for (x = 0; x < wc; ++x) { dest.setPixelColor(x, y, topColor); } for (; x < (int)dest.width(); ++x) { dest.setPixelColor(x, y, btmColor); } } // left and right for (; y < (int)dest.height() - borderWidth; ++y) { for (x = 0; x < borderWidth; ++x) { dest.setPixelColor(x, y, topColor); } for (x = (int)dest.width() - 1; x > (int)dest.width() - borderWidth - 1; --x) { dest.setPixelColor(x, y, btmColor); } } // bottom for (wc = borderWidth; y < (int)dest.height(); ++y, --wc) { for (x = 0; x < wc; ++x) { dest.setPixelColor(x, y, topColor); } for (; x < (int)dest.width(); ++x) { dest.setPixelColor(x, y, btmColor); } } dest.bitBltImage(&src, borderWidth, borderWidth); }
void BorderFilter::pattern(DImg& src, DImg& dest, int borderWidth, const DColor& firstColor, const DColor& secondColor, int firstWidth, int secondWidth) { // Original image with the first solid border around. DImg tmp; solid(src, tmp, firstColor, firstWidth); // Border tiled image using pattern with second solid border around. int width, height; if (d->settings.orgWidth > d->settings.orgHeight) { height = tmp.height() + borderWidth * 2; width = (int)(height * d->orgRatio); } else { width = tmp.width() + borderWidth * 2; height = (int)(width / d->orgRatio); } DImg tmp2(width, height, tmp.sixteenBit(), tmp.hasAlpha()); qCDebug(DIGIKAM_DIMG_LOG) << "Border File:" << d->settings.borderPath; DImg border(d->settings.borderPath); if (border.isNull()) { return; } border.convertToDepthOfImage(&tmp2); for (int x = 0 ; x < width ; x += border.width()) { for (int y = 0 ; y < height ; y += border.height()) { tmp2.bitBltImage(&border, x, y); } } solid(tmp2, dest, secondColor, secondWidth); // Merge both images to one. if (d->settings.orgWidth > d->settings.orgHeight) { dest.bitBltImage(&tmp, (dest.width() - tmp.width()) / 2, borderWidth); } else { dest.bitBltImage(&tmp, borderWidth, (dest.height() - tmp.height()) / 2); } }
void ImageIface::setSelection(const QString& caller, const FilterAction& action, const DImg& img) { if (img.hasAlpha() != originalHasAlpha() || img.sixteenBit() != originalSixteenBit() || img.size() != selectionRect().size() ) { kDebug() << "Properties of image to overwrite selection differs than original image"; return; } if (img.isNull()) { kDebug() << "No image data to handle"; return; } d->core->putImgSelection(caller, action, img); }
void BorderFilter::pattern2(DImg& src, DImg& dest, int borderWidth, const DColor& firstColor, const DColor& secondColor, int firstWidth, int secondWidth) { // Border tile. int w = d->settings.orgWidth + borderWidth * 2; int h = d->settings.orgHeight + borderWidth * 2; qCDebug(DIGIKAM_DIMG_LOG) << "Border File:" << d->settings.borderPath; DImg border(d->settings.borderPath); if (border.isNull()) { return; } DImg borderImg(w, h, src.sixteenBit(), src.hasAlpha()); border.convertToDepthOfImage(&borderImg); for (int x = 0 ; x < w ; x += border.width()) { for (int y = 0 ; y < h ; y += border.height()) { borderImg.bitBltImage(&border, x, y); } } // First line around the pattern tile. DImg tmp = borderImg.smoothScale(src.width() + borderWidth * 2, src.height() + borderWidth * 2); solid2(tmp, dest, firstColor, firstWidth); // Second line around original image. tmp.reset(); solid2(src, tmp, secondColor, secondWidth); // Copy original image. dest.bitBltImage(&tmp, borderWidth, borderWidth); }
void ImageIface::setPreview(const DImg& img) { if (img.hasAlpha() != previewHasAlpha() || img.sixteenBit() != previewSixteenBit() ) { kDebug() << "Properties of image differs than preview"; return; } uchar* const data = img.bits(); if (!data) { kDebug() << "No preview image data to handle"; return; } d->targetPreviewImage.detach(); d->targetPreviewImage.putImageData(data); }
void RawImport::setPreviewImage() { // Preserve metadata from loaded image, and take post-processed image data d->postProcessedImage = d->previewWidget->demosaicedImage().copyMetaData(); DImg data = filter()->getTargetImage(); d->postProcessedImage.putImageData(data.width(), data.height(), data.sixteenBit(), data.hasAlpha(), data.stripImageData(), false); d->previewWidget->setPostProcessedImage(d->postProcessedImage); d->settingsBox->setPostProcessedImage(d->postProcessedImage); EditorToolIface::editorToolIface()->setToolStopProgress(); setBusy(false); }
bool UndoManager::putImageDataAndHistory(DImg* const img, int stepsBack) const { if (stepsBack <= 0 || stepsBack > d->undoActions.size()) { return false; } /* * We need to find a snapshot, for the state the given number of steps back. * 0 steps back is the current state of the EditorCore. * 1 step back is the snapshot of the last undo action, at d->undoActions.size() - 1. * The next problem is that if the corresponding action is reversible, * we do not have a snapshot, but need to walk forward to the first snapshot (or current * state), then apply the reversible steps. */ int step = d->undoActions.size() - stepsBack; int snapshot; for (snapshot = step; snapshot < d->undoActions.size(); ++snapshot) { if (dynamic_cast<UndoActionIrreversible*>(d->undoActions.at(snapshot))) { break; } } if (snapshot == step) { getSnapshot(step, img); } else { DImg reverting; // Get closest available snapshot if (snapshot < d->undoActions.size()) { getSnapshot(snapshot, &reverting); } else { reverting = d->core->getImg()->copyImageData(); } // revert reversible actions, until reaching desired step for (; snapshot > step; snapshot--) { UndoActionReversible* const reversible = dynamic_cast<UndoActionReversible*>(d->undoActions.at(snapshot - 1)); if (!reversible) // would be a bug { continue; } reversible->getReverseFilter().apply(reverting); } img->putImageData(reverting.width(), reverting.height(), reverting.sixteenBit(), reverting.hasAlpha(), reverting.stripImageData(), false); } // adjust history UndoAction* const action = d->undoActions.at(step); UndoMetadataContainer dataBeforeStep = action->getMetadata(); dataBeforeStep.toImage(*img); return true; }
void BorderFilter::bevel(DImg& src, DImg& dest, const DColor& topColor, const DColor& btmColor, int borderWidth) { int width, height; if (d->settings.orgWidth > d->settings.orgHeight) { height = src.height() + borderWidth * 2; width = (int)(height * d->orgRatio); } else { width = src.width() + borderWidth * 2; height = (int)(width / d->orgRatio); } dest = DImg(width, height, src.sixteenBit(), src.hasAlpha()); dest.fill(topColor); QPolygon btTriangle(3); btTriangle.setPoint(0, width, 0); btTriangle.setPoint(1, 0, height); btTriangle.setPoint(2, width, height); QRegion btRegion(btTriangle); // paint upper right corner QPoint upperRightCorner((width - ((width - src.width()) / 2) - 2), ((0 + (height - src.height())) / 2 + 2) ); for (int x = upperRightCorner.x(); x < width; ++x) { for (int y = 0; y < upperRightCorner.y(); ++y) { if (btRegion.contains(QPoint(x, y))) { dest.setPixelColor(x, y, btmColor); } } } // paint right border for (int x = upperRightCorner.x(); x < width; ++x) { for (int y = upperRightCorner.y(); y < height; ++y) { dest.setPixelColor(x, y, btmColor); } } // paint lower left corner QPoint lowerLeftCorner((0 + ((width - src.width()) / 2) + 2), (height - ((height - src.height()) / 2) - 2) ); for (int x = 0; x < lowerLeftCorner.x(); ++x) { for (int y = lowerLeftCorner.y(); y < height; ++y) { if (btRegion.contains(QPoint(x, y))) { dest.setPixelColor(x, y, btmColor); } } } // paint bottom border for (int x = lowerLeftCorner.x(); x < width; ++x) { for (int y = lowerLeftCorner.y(); y < height; ++y) { dest.setPixelColor(x, y, btmColor); } } if (d->settings.orgWidth > d->settings.orgHeight) { dest.bitBltImage(&src, (dest.width() - src.width()) / 2, borderWidth); } else { dest.bitBltImage(&src, borderWidth, (dest.height() - src.height()) / 2); } }