Fix png and spritesheet render (depremultiply) by turtletooth (modified) (#1844)
* Fix png and spritesheet render (depremultiply) * move depremultiply in PngWriter
This commit is contained in:
parent
b08db1990c
commit
e6b1248e52
5 changed files with 82 additions and 19 deletions
|
@ -631,6 +631,7 @@ void TImageWriter::save(const TImageP &img) {
|
|||
writer->open(file, info);
|
||||
|
||||
ras->lock();
|
||||
|
||||
if (writer->getRowOrder() == Tiio::BOTTOM2TOP) {
|
||||
if (bpp == 1 || bpp == 8 || bpp == 24 || bpp == 32 || bpp == 16)
|
||||
for (int i = 0; i < ras->getLy(); i++)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "png.h"
|
||||
|
||||
#include "tpixel.h"
|
||||
#include "tpixelutils.h"
|
||||
|
||||
using namespace std;
|
||||
//------------------------------------------------------------
|
||||
|
@ -876,7 +877,11 @@ void PngWriter::writeLine(short *buffer) {
|
|||
tmp = (unsigned short *)malloc((m_info.m_lx + 1) * 3);
|
||||
// unsigned short tmp[10000];
|
||||
int k = 0;
|
||||
for (int j = 0; j < m_info.m_lx; j++) {
|
||||
for (int j = 0; j < m_info.m_lx; j++, pix++) {
|
||||
// depremultiply here
|
||||
TPixel64 depremult_pix(*pix);
|
||||
if (m_matte && depremult_pix.m != 0) depremult(depremult_pix);
|
||||
|
||||
#if defined(TNZ_MACHINE_CHANNEL_ORDER_MRGB) || \
|
||||
defined(TNZ_MACHINE_CHANNEL_ORDER_RGBM)
|
||||
tmp[k++] = mySwap(pix->r);
|
||||
|
@ -890,8 +895,8 @@ void PngWriter::writeLine(short *buffer) {
|
|||
#else
|
||||
#error "unknown channel order"
|
||||
#endif
|
||||
if (m_matte) tmp[k++] = mySwap(pix->m);
|
||||
++pix;
|
||||
if (m_matte)
|
||||
tmp[k++] = mySwap(pix->m); // ?? does it take care MRGB or MBGR case?
|
||||
}
|
||||
png_write_row(m_png_ptr, (unsigned char *)tmp);
|
||||
}
|
||||
|
@ -903,14 +908,43 @@ void PngWriter::writeLine(char *buffer) {
|
|||
// TBoolProperty* alphaProp =
|
||||
// (TBoolProperty*)(m_properties->getProperty("Alpha Channel"));
|
||||
if (m_matte || m_colormap) {
|
||||
png_bytep row_pointer = (unsigned char *)buffer;
|
||||
png_write_row(m_png_ptr, row_pointer);
|
||||
} else {
|
||||
unsigned char *tmp = 0;
|
||||
unsigned char *tmp = new unsigned char[(m_info.m_lx + 1) * 4];
|
||||
TPixel32 *pix = (TPixel32 *)buffer;
|
||||
tmp = (unsigned char *)malloc((m_info.m_lx + 1) * 3);
|
||||
int k = 0;
|
||||
for (int j = 0; j < m_info.m_lx; j++, pix++) {
|
||||
// depremultiply here
|
||||
TPixel32 depremult_pix(*pix);
|
||||
if (depremult_pix.m != 0) depremult(depremult_pix);
|
||||
#if defined(TNZ_MACHINE_CHANNEL_ORDER_MRGB)
|
||||
tmp[k++] = depremult_pix.m;
|
||||
tmp[k++] = depremult_pix.r;
|
||||
tmp[k++] = depremult_pix.g;
|
||||
tmp[k++] = depremult_pix.b;
|
||||
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_RGBM)
|
||||
tmp[k++] = depremult_pix.r;
|
||||
tmp[k++] = depremult_pix.g;
|
||||
tmp[k++] = depremult_pix.b;
|
||||
tmp[k++] = depremult_pix.m;
|
||||
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR)
|
||||
tmp[k++] = depremult_pix.m;
|
||||
tmp[k++] = depremult_pix.b;
|
||||
tmp[k++] = depremult_pix.g;
|
||||
tmp[k++] = depremult_pix.r;
|
||||
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM)
|
||||
tmp[k++] = depremult_pix.b;
|
||||
tmp[k++] = depremult_pix.g;
|
||||
tmp[k++] = depremult_pix.r;
|
||||
tmp[k++] = depremult_pix.m;
|
||||
#else
|
||||
#error "unknown channel order"
|
||||
#endif
|
||||
}
|
||||
png_write_row(m_png_ptr, tmp);
|
||||
delete[] tmp;
|
||||
} else {
|
||||
TPixel32 *pix = (TPixel32 *)buffer;
|
||||
unsigned char *tmp = new unsigned char[(m_info.m_lx + 1) * 3];
|
||||
|
||||
// unsigned char tmp[10000];
|
||||
int k = 0;
|
||||
for (int j = 0; j < m_info.m_lx; j++) {
|
||||
// tmp = (pix->r&0xe0)|((pix->g&0xe0)>>3) | ((pix->b&0xc0)>>6);
|
||||
|
@ -932,6 +966,7 @@ void PngWriter::writeLine(char *buffer) {
|
|||
++pix;
|
||||
}
|
||||
png_write_row(m_png_ptr, tmp);
|
||||
delete[] tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ TLevelWriterSprite::~TLevelWriterSprite() {
|
|||
totalHorizPadding = horizDim * horizPadding;
|
||||
spriteSheetWidth = horizDim * resizedWidth + totalHorizPadding;
|
||||
vertDim = horizDim;
|
||||
// Figure out if there is one row too many
|
||||
// Figure out if there is one row too many
|
||||
// (Such as 6 images needs 3 x 2 grid)
|
||||
if (vertDim * vertDim - vertDim >= m_imagesResized.size()) {
|
||||
vertDim = vertDim - 1;
|
||||
|
@ -130,8 +130,8 @@ TLevelWriterSprite::~TLevelWriterSprite() {
|
|||
}
|
||||
}
|
||||
if (m_format != "Individual") {
|
||||
QImage spriteSheet =
|
||||
QImage(spriteSheetWidth, spriteSheetHeight, QImage::Format_ARGB32);
|
||||
QImage spriteSheet = QImage(spriteSheetWidth, spriteSheetHeight,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
spriteSheet.fill(qRgba(0, 0, 0, 0));
|
||||
QPainter painter;
|
||||
painter.begin(&spriteSheet);
|
||||
|
@ -229,7 +229,8 @@ void TLevelWriterSprite::save(const TImageP &img, int frameIndex) {
|
|||
QByteArray ba = m_intermediateFormat.toUpper().toLatin1();
|
||||
const char *format = ba.data();
|
||||
|
||||
QImage *qi = new QImage((uint8_t *)buffer, m_lx, m_ly, QImage::Format_ARGB32);
|
||||
QImage *qi = new QImage((uint8_t *)buffer, m_lx, m_ly,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
int l = qi->width(), r = 0, t = qi->height(), b = 0;
|
||||
if (m_trim) {
|
||||
|
@ -269,7 +270,7 @@ void TLevelWriterSprite::save(const TImageP &img, int frameIndex) {
|
|||
if (t < m_top) m_top = t;
|
||||
if (b > m_bottom) m_bottom = b;
|
||||
}
|
||||
QImage *newQi = new QImage(m_lx, m_ly, QImage::Format_ARGB32);
|
||||
QImage *newQi = new QImage(m_lx, m_ly, QImage::Format_ARGB32_Premultiplied);
|
||||
newQi->fill(qRgba(0, 0, 0, 0));
|
||||
QPainter painter(newQi);
|
||||
painter.drawImage(QPoint(0, 0), *qi);
|
||||
|
|
|
@ -268,9 +268,9 @@ void FlipBook::addFreezeButtonToTitleBar() {
|
|||
TPanel *panel = qobject_cast<TPanel *>(parentWidget());
|
||||
if (panel) {
|
||||
TPanelTitleBar *titleBar = panel->getTitleBar();
|
||||
m_freezeButton = new TPanelTitleBarButton(titleBar, ":Resources/pane_freeze_off.svg",
|
||||
":Resources/pane_freeze_over.svg",
|
||||
":Resources/pane_freeze_on.svg");
|
||||
m_freezeButton = new TPanelTitleBarButton(
|
||||
titleBar, ":Resources/pane_freeze_off.svg",
|
||||
":Resources/pane_freeze_over.svg", ":Resources/pane_freeze_on.svg");
|
||||
m_freezeButton->setToolTip("Freeze");
|
||||
titleBar->add(QPoint(-55, 0), m_freezeButton);
|
||||
connect(m_freezeButton, SIGNAL(toggled(bool)), this, SLOT(freeze(bool)));
|
||||
|
@ -1136,6 +1136,15 @@ void FlipBook::setLevel(const TFilePath &fp, TPalette *palette, int from,
|
|||
Level levelToPush(level, fp, fromIndex, toIndex, step);
|
||||
levelToPush.m_randomAccessRead = randomAccessRead;
|
||||
levelToPush.m_incrementalIndexing = incrementalIndexing;
|
||||
|
||||
int formatIdx = Preferences::instance()->matchLevelFormat(fp);
|
||||
if (formatIdx >= 0 &&
|
||||
Preferences::instance()
|
||||
->levelFormat(formatIdx)
|
||||
.m_options.m_premultiply) {
|
||||
levelToPush.m_premultiply = true;
|
||||
}
|
||||
|
||||
m_levels.push_back(levelToPush);
|
||||
|
||||
// Get the frames count to be shown in this flipbook level
|
||||
|
@ -1498,7 +1507,7 @@ TImageP FlipBook::getCurrentImage(int frame) {
|
|||
|
||||
bool randomAccessRead = false;
|
||||
bool incrementalIndexing = false;
|
||||
|
||||
bool premultiply = false;
|
||||
if (m_xl) // is an xsheet level
|
||||
{
|
||||
if (m_xl->getFrameCount() <= 0) return 0;
|
||||
|
@ -1533,6 +1542,7 @@ TImageP FlipBook::getCurrentImage(int frame) {
|
|||
incrementalIndexing = m_levels[i].m_incrementalIndexing;
|
||||
levelName = m_levelNames[i];
|
||||
fid = m_levels[i].flipbookIndexToLevelFrame(frameIndex);
|
||||
premultiply = m_levels[i].m_premultiply;
|
||||
if (fid == TFrameId()) return 0;
|
||||
id = levelName.toStdString() + fid.expand(TFrameId::NO_PAD) +
|
||||
((m_isPreviewFx) ? "" : ::to_string(this));
|
||||
|
@ -1587,6 +1597,13 @@ TImageP FlipBook::getCurrentImage(int frame) {
|
|||
if (img) {
|
||||
TRasterImageP ri = ((TRasterImageP)img);
|
||||
TToonzImageP ti = ((TToonzImageP)img);
|
||||
if (premultiply) {
|
||||
if (ri)
|
||||
TRop::premultiply(ri->getRaster());
|
||||
else if (ti)
|
||||
TRop::premultiply(ti->getRaster());
|
||||
}
|
||||
|
||||
// se e' stata caricata una sottoimmagine alcuni formati in realta'
|
||||
// caricano tutto il raster e fanno extract, non si ha quindi alcun
|
||||
// risparmio di occupazione di memoria; alloco un raster grande
|
||||
|
|
|
@ -134,11 +134,20 @@ protected:
|
|||
, m_toIndex(toIndex)
|
||||
, m_step(step)
|
||||
, m_randomAccessRead(false)
|
||||
, m_incrementalIndexing(false) {}
|
||||
, m_incrementalIndexing(false)
|
||||
, m_premultiply(false) {}
|
||||
TLevelP m_level;
|
||||
int m_fromIndex, m_toIndex, m_step;
|
||||
bool m_incrementalIndexing;
|
||||
bool m_randomAccessRead;
|
||||
|
||||
// Specified if the level is needed to be premultiplied on display.
|
||||
// It will be true for the files of which the "premultiply" option is
|
||||
// activated in the Preferences > Loading > "Level Settings by File Format".
|
||||
// By default, PNG will be loaded with being premultiplied so that it will
|
||||
// be displayed properly.
|
||||
bool m_premultiply;
|
||||
|
||||
TFilePath m_fp;
|
||||
|
||||
TFrameId flipbookIndexToLevelFrame(int index);
|
||||
|
|
Loading…
Reference in a new issue