diff --git a/toonz/sources/common/tsystem/tfilepath.cpp b/toonz/sources/common/tsystem/tfilepath.cpp index 0f28bb55..362b5c15 100644 --- a/toonz/sources/common/tsystem/tfilepath.cpp +++ b/toonz/sources/common/tsystem/tfilepath.cpp @@ -1,7 +1,7 @@ #ifdef _WIN32 -//#define UNICODE // per le funzioni di conversione da/a UNC +// #define UNICODE // per le funzioni di conversione da/a UNC #include #include @@ -279,8 +279,7 @@ void TFilePath::setPath(std::wstring path) { } } else if (isSlash(path[pos])) { int firstSlashPos = pos; - do - pos++; + do pos++; while (pos < length && isSlash(path[pos])); if (firstSlashPos == 0 && pos == 4) // Caso "\\\\MachineName" m_path.append(2, wslash); @@ -1066,9 +1065,9 @@ QString TFilePath::fidRegExpStr() { QString suffixLetter = (m_acceptNonAlphabetSuffix) ? "[^\\._ \\\\/:,;*?\"<>|0123456789]" : "[a-zA-Z]"; - QString countLetter = (m_letterCountForSuffix == 0) - ? "{0,}" - : (QString("{0,%1}").arg(m_letterCountForSuffix)); + QString countLetter = (m_letterCountForSuffix == 0) + ? "{0,}" + : (QString("{0,%1}").arg(m_letterCountForSuffix)); return QString("(\\d+)(%1%2)").arg(suffixLetter).arg(countLetter); // const QString fIdRegExp("(\\d+)([a-zA-Z]?)"); } @@ -1113,8 +1112,9 @@ TFilePath::TFilePathInfo TFilePath::analyzePath() const { // hogehoge.0001a.jpg // empty frame case : hogehoge..jpg - QRegExp rx("^" + levelNameRegExp + sepCharRegExp + "(?:" + fIdRegExp + ")?" + - "\\." + extensionRegExp + "$"); + // empty level name case : ..jpg .0001a.jpg + QRegExp rx("^(?:" + levelNameRegExp + ")?" + sepCharRegExp + + "(?:" + fIdRegExp + ")?" + "\\." + extensionRegExp + "$"); if (rx.indexIn(fileName) != -1) { assert(rx.captureCount() == 5); info.levelName = rx.cap(1); diff --git a/toonz/sources/image/CMakeLists.txt b/toonz/sources/image/CMakeLists.txt index 22de13f4..6cb955ae 100644 --- a/toonz/sources/image/CMakeLists.txt +++ b/toonz/sources/image/CMakeLists.txt @@ -63,6 +63,7 @@ if(NOT BUILD_TARGET_BSD) tif/tiio_tif.cpp tzp/tiio_plt.cpp tzp/tiio_tzp.cpp + tzp/toonzrle.cpp tzp/avl.c ) endif() diff --git a/toonz/sources/image/tzp/toonzrle.cpp b/toonz/sources/image/tzp/toonzrle.cpp new file mode 100644 index 00000000..adba2818 --- /dev/null +++ b/toonz/sources/image/tzp/toonzrle.cpp @@ -0,0 +1,1426 @@ + + +#include "tiffiop.h" +#include +#include "toonztags.h" +#include "tnztypes.h" + +#ifndef UCHAR +#define UCHAR unsigned char +#endif + +#ifndef USHORT +#define USHORT unsigned short +#endif + +#ifndef UINT +#define UINT TUINT32 +#endif + +extern "C" { +static int tif_toonz1_decode_cm24(UCHAR* buf_in, int* buf_in_len, + TUINT32* buf_out); + +static int tif_toonz1_decode_cm16(UCHAR* buf_in, int* buf_in_len, + USHORT* buf_out, int tone_bits, + int color_offs, int color_bits, + int pencil_offs, int pencil_bits, + USHORT offset_mask); +static int Toonz1Decode(TIFF* tif, tidataval_t* buffer, tsize_t bytes, + tsample_t s); + +static int TIFFInitToonz1(TIFF* tif, int) { + tif->tif_decoderow = Toonz1Decode; + tif->tif_decodestrip = 0; + tif->tif_decodetile = 0; + tif->tif_encoderow = 0; // Toonz1Encode; + tif->tif_encodestrip = 0; + tif->tif_encodetile = 0; + return 1; +} +//-------------------- DECODE + +static int Toonz1Decode(TIFF* tif, tidataval_t* buffer, tsize_t bytes, + tsample_t s) { + int enc, dec; + short bitspersample; + // USHORT *palette; + int tone_bits, color_offs, color_bits, pencil_offs, pencil_bits; + USHORT offset_mask; + + if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample)) assert(0); + enc = dec = 0; + switch (bitspersample) { + case 8: + assert(!"Not Implemented"); + /* +dec = tif_toonz1_decode_extra ((UCHAR *)tif->tif_rawcp, &enc, + (UCHAR *)buffer); +*/ + break; + + case 16: { + USHORT* palette; + USHORT paletteCount; + if (TIFFGetField(tif, TIFFTAG_TOONZPALETTE, &paletteCount, &palette)) { + tone_bits = palette[4]; + color_offs = palette[5]; + color_bits = palette[6]; + pencil_offs = palette[7]; + pencil_bits = palette[8]; + offset_mask = palette[9]; + } else { + tone_bits = 4; + color_offs = 4; + color_bits = 7; + pencil_offs = 11; + pencil_bits = 5; + offset_mask = 0; + } + dec = tif_toonz1_decode_cm16((UCHAR*)tif->tif_rawcp, &enc, (USHORT*)buffer, + tone_bits, color_offs, color_bits, pencil_offs, + pencil_bits, offset_mask); + } break; + + case 32: + dec = + tif_toonz1_decode_cm24((UCHAR*)tif->tif_rawcp, &enc, (TUINT32*)buffer); + break; + + default: + assert(0); + } + assert(enc); + assert(dec * bitspersample == bytes * 8); + tif->tif_rawcc += enc; + tif->tif_rawcp += enc; + + return 1; +} + +//-------------------- DECODE CM16 ---------------------------- + +static int tif_toonz1_decode_cm16(UCHAR* buf_in, int* buf_in_len, + USHORT* buf_out, int tone_bits, + int color_offs, int color_bits, + int pencil_offs, int pencil_bits, + USHORT offset_mask) + +{ + UCHAR* in; + USHORT* out; + int count, col_offs, pen_offs; + UINT inval, in0, in1, tmp, not_colmask, not_penmask; + UINT outval, maxtone, outval_maxtone; + +#define GET_IN0 (inval = *in++, in1 = inval & 0xF, in0 = inval >> 4) + + maxtone = (1U << tone_bits) - 1U; + col_offs = color_offs; + pen_offs = pencil_offs; + not_colmask = ~(((1U << color_bits) - 1U) << color_offs); + not_penmask = ~(((1U << pencil_bits) - 1U) << pencil_offs); + assert(maxtone <= 0xF); + outval = offset_mask; + outval_maxtone = outval | maxtone; + + in = buf_in; + out = buf_out; + + goto start_from_in0; + +count_out_and_start_from_in0: + outval_maxtone = outval | maxtone; + *out++ = (USHORT)outval_maxtone; + while (count--) *out++ = (USHORT)outval_maxtone; + +start_from_in0: + if (GET_IN0 == 0xF) { + switch (in1) { + case 0x0: + *out++ = (USHORT)(outval | maxtone); + goto start_from_in0; + break; + + case 0x1: + count = GET_IN0; + goto count_out_and_start_from_in1; + break; + + case 0x2: + count = *in++; + goto count_out_and_start_from_in0; + break; + + case 0x3: + count = *in++ << 4; + count += GET_IN0; + goto count_out_and_start_from_in1; + break; + + case 0x4: + count = *in++ << 8; + count += *in++; + goto count_out_and_start_from_in0; + break; + + case 0x5: + count = *in++ << 12; + count += *in++ << 4; + count += GET_IN0; + goto count_out_and_start_from_in1; + + break; + + case 0x6: + count = *in++ << 16; + count += *in++ << 8; + count += *in++; + goto count_out_and_start_from_in0; + + break; + + case 0x7: + count = *in++ << 20; + count += *in++ << 12; + count += *in++ << 4; + count += GET_IN0; + goto count_out_and_start_from_in1; + + break; + + case 0x8: + outval &= not_colmask; + goto start_from_in0; + + break; + + case 0x9: + outval &= not_penmask; + goto start_from_in0; + + break; + + case 0xA: + outval = outval & not_colmask | GET_IN0 << col_offs; + goto start_from_in1; + + break; + + case 0xB: + outval = outval & not_penmask | GET_IN0 << pen_offs; + goto start_from_in1; + + break; + + case 0xC: + outval = outval & not_colmask | *in++ << col_offs; + goto start_from_in0; + + break; + + case 0xD: + outval = outval & not_penmask | *in++ << pen_offs; + goto start_from_in0; + + break; + + case 0xE: + *out++ = (USHORT)(outval | maxtone); + goto end_rle_decoding; + + break; + + case 0xF: + switch (GET_IN0) { + case 0: + break; + case 1: + tmp = in1 << 12 | *in++ << 4; + *out++ = (USHORT)(tmp | GET_IN0); + break; + default: + goto rle_decoding_error; + } + goto end_rle_decoding; + + break; + default: + goto rle_decoding_error; + } + } else { + *out++ = (USHORT)(outval | in0); + goto start_from_in1; + } + +count_out_and_start_from_in1: + outval_maxtone = outval | maxtone; + *out++ = (USHORT)(outval_maxtone); + while (count--) *out++ = (USHORT)(outval_maxtone); + +start_from_in1: + if (in1 == 0xF) { + switch (GET_IN0) { + case 0x0: + *out++ = (USHORT)(outval | maxtone); + goto start_from_in1; + + break; + + case 0x1: + count = in1; + goto count_out_and_start_from_in0; + + break; + + case 0x2: + count = in1 << 4; + count += GET_IN0; + goto count_out_and_start_from_in1; + + break; + + case 0x3: + count = in1 << 8; + count += *in++; + goto count_out_and_start_from_in0; + + break; + + case 0x4: + count = in1 << 12; + count += *in++ << 4; + count += GET_IN0; + goto count_out_and_start_from_in1; + + break; + + case 0x5: + count = in1 << 16; + count += *in++ << 8; + count += *in++; + goto count_out_and_start_from_in0; + + break; + + case 0x6: + count = in1 << 20; + count += *in++ << 12; + count += *in++ << 4; + count += GET_IN0; + goto count_out_and_start_from_in1; + + break; + + case 0x7: + count = in1 << 24; + count += *in++ << 16; + count += *in++ << 8; + count += *in++; + goto count_out_and_start_from_in0; + + break; + + case 0x8: + outval &= not_colmask; + goto start_from_in1; + + break; + + case 0x9: + outval &= not_penmask; + goto start_from_in1; + + break; + + case 0xA: + outval = outval & not_colmask | in1 << col_offs; + goto start_from_in0; + + break; + + case 0xB: + outval = outval & not_penmask | in1 << pen_offs; + goto start_from_in0; + + break; + + case 0xC: + tmp = in1 << 4; + outval = outval & not_colmask | (tmp | GET_IN0) << col_offs; + goto start_from_in1; + + break; + + case 0xD: + tmp = in1 << 4; + outval = outval & not_penmask | (tmp | GET_IN0) << pen_offs; + goto start_from_in1; + + break; + + case 0xE: + *out++ = (USHORT)(outval | maxtone); + goto end_rle_decoding; + + break; + + case 0xF: + switch (in1) { + case 0: + break; + case 1: + tmp = *in++ << 8; + *out++ = (USHORT)(tmp | *in++); + break; + default: + goto rle_decoding_error; + } + goto end_rle_decoding; + + break; + default: + return 0; + } + } else { + *out++ = (USHORT)(outval | in1); + goto start_from_in0; + } + +end_rle_decoding: + if (buf_in_len) *buf_in_len = (int)(in - buf_in); + return (int)(out - buf_out); + +rle_decoding_error: + if (buf_in_len) *buf_in_len = 0; + return 0; +} + +//-------------------- DECODE CM24 ---------------------------- + +static int tif_toonz1_decode_cm24(UCHAR* buf_in, int* buf_in_len, + TUINT32* buf_out) { + UCHAR* in; + TUINT32* out; + int count; + TUINT32 inval, tmp; + TUINT32 outval, outval_maxtone; + const int col_offs = 8; + const int pen_offs = 16; + const int xub_offs = 24; + const TUINT32 not_colmask = 0xffff00ff; + const TUINT32 not_penmask = 0xff00ffff; + const TUINT32 not_xubmask = 0x00ffffff; + const TUINT32 maxtone = 0x000000ff; + + outval = 0; + outval_maxtone = outval | maxtone; + + in = buf_in; + out = buf_out; + + for (;;) { + inval = *in++; + switch (inval) { + case 0xF6: + outval = outval & not_xubmask | *in++ << xub_offs; + + break; + + case 0xF7: + count = *in++; + goto count_out; + + break; + + case 0xF8: + count = *in++ << 8; + count += *in++; + goto count_out; + + break; + + case 0xF9: + count = *in++ << 16; + count += *in++ << 8; + count += *in++; + goto count_out; + + break; + + case 0xFA: + outval &= not_colmask; + + break; + + case 0xFB: + outval &= not_penmask; + + break; + + case 0xFC: + outval = outval & not_colmask | *in++ << col_offs; + + break; + + case 0xFD: + outval = outval & not_penmask | *in++ << pen_offs; + + break; + + case 0xFE: + switch (*in++) { + case 0: + break; + case 1: + *out++ = outval | maxtone; + break; + + case 2: + tmp = *in++; + tmp = tmp << 8 | *in++; + tmp = tmp << 8 | *in++; + *out++ = tmp << 8 | *in++; + break; + + default: + goto rle_decoding_error; + } + goto end_rle_decoding; + + break; + + case 0xFF: + *out++ = outval | *in++; + + break; + + default: + *out++ = outval | inval; + } + continue; + + count_out: + outval_maxtone = outval | maxtone; + *out++ = outval_maxtone; + while (count--) *out++ = outval_maxtone; + } + +end_rle_decoding: + if (buf_in_len) *buf_in_len = (int)(in - buf_in); + return (int)(out - buf_out); + +rle_decoding_error: + if (buf_in_len) *buf_in_len = 0; + return 0; +} +} + +//============================================================================= + +namespace { + +class ToonzRleCodecRegisterer { + static TIFFCodec* m_codec; + +public: + ToonzRleCodecRegisterer() { + uint16 scheme = 32881; + const char* name = "TOONZ4RLE"; + m_codec = TIFFRegisterCODEC(scheme, name, &TIFFInitToonz1); + } + ~ToonzRleCodecRegisterer() { + TIFFUnRegisterCODEC(m_codec); + m_codec = 0; + } +}; + +TIFFCodec* ToonzRleCodecRegisterer::m_codec = 0; + +ToonzRleCodecRegisterer registerer; +} // namespace + +//============================================================================= + +#if 0 + +/* +Queste stanno qui piu' che altro per memoria... +*/ + +extern "C" { + + /*===========================================================================*/ + + /*---------------------------------------------------------------------------*/ + +#define GET_INVAL \ + { \ + inval = *in++; \ + remain--; \ + } +#define PUT_OUTVAL \ + { *out++ = (UCHAR)outval; } + +/*---------------------------------------------------------------------------*/ + + int tif_toonz1_safe_bytes_for_pixels(int n_pix, int pixbytes) + { + if (n_pix < 0) + return 0; + switch (pixbytes) + { + case 1: return 2 * n_pix + 1; + case 2: return 5 * n_pix + 2; /* == 2.5 * n_bytes + 2 */ + case 4: return 8 * n_pix + 6; /* == 2 * n_bytes + 6 */ + } + return 0; + } + + /*---------------------------------------------------------------------------*/ + + static int tif_toonz1_encode_cm16(USHORT* buf_in, int buf_in_len, + UCHAR* buf_out, + int tone_bits, + int color_offs, int color_bits, + int pencil_offs, int pencil_bits, + USHORT offset_mask) + { + int count, prevremain, remain; + UINT inval, outval; + UINT lastcol__, lastpen__, lastval, lastcolpen; + int col_offs, pen_offs; + UINT colpenmask, colmask, penmask, maxtone; + UINT incolpen, incol__, incol, inpen__, inpen, tone; + USHORT* in, save; + UCHAR* out; + + maxtone = (1U << tone_bits) - 1U; + col_offs = color_offs; + pen_offs = pencil_offs; + colmask = ((1U << color_bits) - 1U) << color_offs; + penmask = ((1U << pencil_bits) - 1U) << pencil_offs; + colpenmask = colmask | penmask; + + remain = buf_in_len; + lastcol__ = 0; + lastpen__ = 0; + lastval = offset_mask | maxtone; + lastcolpen = 0; + + in = buf_in; + out = buf_out; + + if (buf_in_len <= 1) + { + if (buf_in_len < 0) + return 0; + if (buf_in_len == 0) + { + outval = 0xFF; + PUT_OUTVAL + outval = 0x00; + PUT_OUTVAL + } + else + { + GET_INVAL + if (inval == (offset_mask | maxtone)) + { + outval = 0xFE; + PUT_OUTVAL + } + else + { + outval = 0xFF; + PUT_OUTVAL + outval = 0x10 | inval >> 12; + PUT_OUTVAL + outval = inval >> 4; + PUT_OUTVAL + outval = inval << 4; + PUT_OUTVAL + } + } + return out - buf_out; + } + + save = buf_in[buf_in_len - 1]; + buf_in[buf_in_len - 1] = buf_in[buf_in_len - 2] ^ colpenmask; + + GET_INVAL + + check_colpen_on_out0 : + incolpen = inval & colpenmask; + if (incolpen == lastcolpen) + goto check_tone_on_out0; + lastcolpen = incolpen; + if (!remain) + goto end_toonz1_encoding_on_out0; + + /*check_col_on_out0:*/ + incol__ = inval & colmask; + if (incol__ != lastcol__) + { + lastcol__ = incol__; + if (incol__ == 0) + { + outval = (0xF << 4) | 0x8; + PUT_OUTVAL + goto check_pen_on_out0; + } + else + { + incol = incol__ >> col_offs; + if (incol <= 0xF) + { + outval = (0xF << 4) | 0xA; + PUT_OUTVAL + outval = incol << 4; + goto check_pen_on_out1; + } + else + { + outval = (0xF << 4) | 0xC; + PUT_OUTVAL + outval = incol; + PUT_OUTVAL + goto check_pen_on_out0; + } + } + } + check_pen_on_out0: + inpen__ = inval & penmask; + if (inpen__ != lastpen__) + { + lastpen__ = inpen__; + if (inpen__ == 0) + { + outval = (0xF << 4) | 0x9; + PUT_OUTVAL + goto check_tone_on_out0; + } + else + { + inpen = inpen__ >> pen_offs; + if (inpen <= 0xF) + { + outval = (0xF << 4) | 0xB; + PUT_OUTVAL + outval = inpen << 4; + goto check_tone_on_out1; + } + else + { + outval = (0xF << 4) | 0xD; + PUT_OUTVAL + outval = inpen; + PUT_OUTVAL + goto check_tone_on_out0; + } + } + } + check_tone_on_out0: + tone = inval & maxtone; + if (tone == maxtone) + { + lastval = inval; + prevremain = remain; + do + GET_INVAL + while (inval == lastval); + count = prevremain - remain - 1; + if (count <= 0xF) + if (count == 0) + { + outval = (0xF << 4) | 0x0; + PUT_OUTVAL + goto check_colpen_on_out0; + } + else + { + outval = (0xF << 4) | 0x1; + PUT_OUTVAL + outval = count << 4; + goto check_colpen_on_out1; + } + else if (count <= 0xFF) + { + outval = (0xF << 4) | 0x2; + PUT_OUTVAL + outval = count; + PUT_OUTVAL + goto check_colpen_on_out0; + } + else if (count <= 0xFFF) + { + outval = (0xF << 4) | 0x3; + PUT_OUTVAL + outval = count >> 4; + PUT_OUTVAL + outval = count << 4; + goto check_colpen_on_out1; + } + else if (count <= 0xFFFF) + { + outval = (0xF << 4) | 0x4; + PUT_OUTVAL + outval = count >> 8; + PUT_OUTVAL + outval = count; + PUT_OUTVAL + goto check_colpen_on_out0; + } + else if (count <= 0xFFFFF) + { + outval = (0xF << 4) | 0x5; + PUT_OUTVAL + outval = count >> 12; + PUT_OUTVAL + outval = count >> 4; + PUT_OUTVAL + outval = count << 4; + goto check_colpen_on_out1; + } + else if (count <= 0xFFFFFF) + { + outval = (0xF << 4) | 0x6; + PUT_OUTVAL + outval = count >> 16; + PUT_OUTVAL + outval = count >> 8; + PUT_OUTVAL + outval = count; + PUT_OUTVAL + goto check_colpen_on_out0; + } + else if (count <= 0xFFFFFFF) + { + outval = (0xF << 4) | 0x7; + PUT_OUTVAL + outval = count >> 20; + PUT_OUTVAL + outval = count >> 12; + PUT_OUTVAL + outval = count >> 4; + PUT_OUTVAL + outval = count << 4; + goto check_colpen_on_out1; + } + else + { + buf_in[buf_in_len - 1] = save; + return 0; + } + } + else + { + outval = tone << 4; + GET_INVAL + /*goto check_colpen_on_out1;*/ + } + + check_colpen_on_out1: + incolpen = inval & colpenmask; + if (incolpen == lastcolpen) + goto check_tone_on_out1; + lastcolpen = incolpen; + if (!remain) + goto end_toonz1_encoding_on_out1; + + /*check_col_on_out1:*/ + incol__ = inval & colmask; + if (incol__ != lastcol__) + { + lastcol__ = incol__; + outval |= 0xF; + PUT_OUTVAL + if (incol__ == 0) + { + outval = 0x8 << 4; + goto check_pen_on_out1; + } + else + { + incol = incol__ >> col_offs; + if (incol <= 0xF) + { + outval = (0xA << 4) | incol; + PUT_OUTVAL + goto check_pen_on_out0; + } + else + { + outval = (0xC << 4) | (incol >> 4); + PUT_OUTVAL + outval = incol << 4; + goto check_pen_on_out1; + } + } + } + check_pen_on_out1: + inpen__ = inval & penmask; + if (inpen__ != lastpen__) + { + lastpen__ = inpen__; + outval |= 0xF; + PUT_OUTVAL + if (inpen__ == 0) + { + outval = 0x9 << 4; + goto check_tone_on_out1; + } + else + { + inpen = inpen__ >> pen_offs; + if (inpen <= 0xF) + { + outval = (0xB << 4) | inpen; + PUT_OUTVAL + goto check_tone_on_out0; + } + else + { + outval = (0xD << 4) | (inpen >> 4); + PUT_OUTVAL + outval = inpen << 4; + goto check_tone_on_out1; + } + } + } + check_tone_on_out1: + tone = inval & maxtone; + if (tone == maxtone) + { + lastval = inval; + prevremain = remain; + do + GET_INVAL + while (inval == lastval); + count = prevremain - remain - 1; + outval |= 0xF; + PUT_OUTVAL + if (count <= 0xF) + if (count == 0) + { + outval = 0x0 << 4; + goto check_colpen_on_out1; + } + else + { + outval = (0x1 << 4) | count; + PUT_OUTVAL + goto check_colpen_on_out0; + } + else if (count <= 0xFF) + { + outval = (0x2 << 4) | (count >> 4); + PUT_OUTVAL + outval = count << 4; + goto check_colpen_on_out1; + } + else if (count <= 0xFFF) + { + outval = (0x3 << 4) | (count >> 8); + PUT_OUTVAL + outval = count; + PUT_OUTVAL + goto check_colpen_on_out0; + } + else if (count <= 0xFFFF) + { + outval = (0x4 << 4) | (count >> 12); + PUT_OUTVAL + outval = count >> 4; + PUT_OUTVAL + outval = count << 4; + goto check_colpen_on_out1; + } + else if (count <= 0xFFFFF) + { + outval = (0x5 << 4) | (count >> 16); + PUT_OUTVAL + outval = count >> 8; + PUT_OUTVAL + outval = count; + PUT_OUTVAL + goto check_colpen_on_out0; + } + else if (count <= 0xFFFFFF) + { + outval = (0x6 << 4) | (count >> 20); + PUT_OUTVAL + outval = count >> 12; + PUT_OUTVAL + outval = count >> 4; + PUT_OUTVAL + outval = count << 4; + goto check_colpen_on_out1; + } + else if (count <= 0xFFFFFFF) + { + outval = (0x7 << 4) | (count >> 24); + PUT_OUTVAL + outval = count >> 16; + PUT_OUTVAL + outval = count >> 8; + PUT_OUTVAL + outval = count; + PUT_OUTVAL + goto check_colpen_on_out0; + } + else + { + buf_in[buf_in_len - 1] = save; + return 0; + } + } + else + { + outval |= tone; + PUT_OUTVAL + GET_INVAL + goto check_colpen_on_out0; + } + + end_toonz1_encoding_on_out0: + if (save == (in[-2] | maxtone)) + { + outval = 0xFE; + PUT_OUTVAL + } + else + { + outval = 0xFF; + PUT_OUTVAL + outval = 0x10 | save >> 12; + PUT_OUTVAL + outval = save >> 4; + PUT_OUTVAL + outval = save << 4; + PUT_OUTVAL + } + buf_in[buf_in_len - 1] = save; + return out - buf_out; + + end_toonz1_encoding_on_out1: + if (save == (in[-2] | maxtone)) + { + outval |= 0xF; + PUT_OUTVAL + outval = 0xE0; + PUT_OUTVAL + } + else + { + outval |= 0xF; + PUT_OUTVAL + outval = 0xF1; + PUT_OUTVAL + outval = save >> 8; + PUT_OUTVAL + outval = save; + PUT_OUTVAL + } + buf_in[buf_in_len - 1] = save; + return out - buf_out; + } + + /*---------------------------------------------------------------------------*/ + + static int tif_toonz1_encode_cm24(TUINT32* buf_in, int buf_in_len, + UCHAR* buf_out) + { + int count, prevremain, remain; + TUINT32 inval, outval; + TUINT32 lastcol__, lastpen__, lastxub__, lastval, lastenot; + TUINT32 inenot, incol__, incol, inpen__, inpen, inxub__, inxub, tone; + TUINT32* in, save; + UCHAR* out; + const int col_offs = 8; + const int pen_offs = 16; + const int xub_offs = 24; + const TUINT32 enotmask = 0xffffff00; + const TUINT32 colmask = 0x0000ff00; + const TUINT32 penmask = 0x00ff0000; + const TUINT32 xubmask = 0xff000000; + const TUINT32 maxtone = 0x000000ff; + + /* enot == ~tone , xub == extra upper byte */ + + remain = buf_in_len; + lastcol__ = 0; + lastpen__ = 0; + lastxub__ = 0; + lastval = maxtone; + lastenot = 0; + + in = buf_in; + out = buf_out; + + if (buf_in_len <= 1) + { + if (buf_in_len < 0) + return 0; + if (buf_in_len == 0) + { + outval = 0xFE; + PUT_OUTVAL + outval = 0x00; + PUT_OUTVAL + } + else + { + GET_INVAL + if (inval == maxtone) + { + outval = 0xFE; + PUT_OUTVAL + outval = 0x01; + PUT_OUTVAL + } + else + { + outval = 0xFE; + PUT_OUTVAL + outval = 0x02; + PUT_OUTVAL + outval = inval >> 24; + PUT_OUTVAL + outval = inval >> 16; + PUT_OUTVAL + outval = inval >> 8; + PUT_OUTVAL + outval = inval; + PUT_OUTVAL + } + } + return out - buf_out; + } + + save = buf_in[buf_in_len - 1]; + buf_in[buf_in_len - 1] = buf_in[buf_in_len - 2] ^ enotmask; + + GET_INVAL + + for (;;) + { + inenot = inval & enotmask; + if (inenot != lastenot) + { + lastenot = inenot; + if (!remain) + goto end_toonz1_encoding; + + incol__ = inval & colmask; + if (incol__ != lastcol__) + { + lastcol__ = incol__; + if (incol__ == 0) + { + outval = 0xFA; + PUT_OUTVAL + } + else + { + incol = incol__ >> col_offs; + outval = 0xFC; + PUT_OUTVAL + outval = incol; + PUT_OUTVAL + } + } + inpen__ = inval & penmask; + if (inpen__ != lastpen__) + { + lastpen__ = inpen__; + if (inpen__ == 0) + { + outval = 0xFB; + PUT_OUTVAL + } + else + { + inpen = inpen__ >> pen_offs; + outval = 0xFD; + PUT_OUTVAL + outval = inpen; + PUT_OUTVAL + } + } + inxub__ = inval & xubmask; + if (inxub__ != lastxub__) + { + lastxub__ = inxub__; + inxub = inxub__ >> xub_offs; + outval = 0xF6; + PUT_OUTVAL + outval = inxub; + PUT_OUTVAL + } + } + tone = inval & maxtone; + if (tone == maxtone) + { + lastval = inval; + prevremain = remain; + do + GET_INVAL + while (inval == lastval); + count = prevremain - remain - 1; + if (count <= 0xFF) + { + outval = 0xF7; + PUT_OUTVAL + outval = count; + PUT_OUTVAL + } + else if (count <= 0xFFFF) + { + outval = 0xF8; + PUT_OUTVAL + outval = count >> 8; + PUT_OUTVAL + outval = count; + PUT_OUTVAL + } + else + { + while (count > 0xFFFFFF) + { + outval = 0xF9; + PUT_OUTVAL + outval = 0xFF; + PUT_OUTVAL + outval = 0xFF; + PUT_OUTVAL + outval = 0xFF; + count -= 0xFFFFFF + 1; + } + outval = 0xF9; + PUT_OUTVAL + outval = count >> 16; + PUT_OUTVAL + outval = count >> 8; + PUT_OUTVAL + outval = count; + PUT_OUTVAL + } + } + else + { + if (tone < 0xF6) + { + outval = tone; + PUT_OUTVAL + } + else + { + outval = 0xFF; + PUT_OUTVAL + outval = tone; + PUT_OUTVAL + } + GET_INVAL + } + } + + end_toonz1_encoding: + if (save == (in[-2] | maxtone)) + { + outval = 0xFE; + PUT_OUTVAL + outval = 0x01; + PUT_OUTVAL + } + else + { + outval = 0xFE; + PUT_OUTVAL + outval = 0x02; + PUT_OUTVAL + outval = save >> 24; + PUT_OUTVAL + outval = save >> 16; + PUT_OUTVAL + outval = save >> 8; + PUT_OUTVAL + outval = save; + PUT_OUTVAL + } + buf_in[buf_in_len - 1] = save; + return out - buf_out; + } + + /*---------------------------------------------------------------------------*/ + + static int tif_toonz1_encode_extra(UCHAR* buf_in, int buf_in_len, + UCHAR* buf_out) + { + UCHAR* in, inval, lastval, save; + UCHAR* out; + int count, remain; + + remain = buf_in_len; + in = buf_in; + out = buf_out; + if (buf_in_len < 2) + { + if (!buf_in_len) + { + *out = 0; + return 1; + } + else + { + *out++ = 1; + *out++ = *in; + *out = 0; + return 3; + } + } + save = buf_in[buf_in_len - 1]; + buf_in[buf_in_len - 1] = buf_in[buf_in_len - 2] ^ 0xff; + + lastval = *buf_in; + count = 0; + for (;;) + { + GET_INVAL + if (inval == lastval) + count++; + else + { + while (count >> 15) + { + *out++ = 0xff; + *out++ = 0xff; + *out++ = lastval; + count -= 0x7fff; + } + if (count >> 7) + { + *out++ = 0x80 | count & 0x7f; + *out++ = count >> 7; + } + else + *out++ = count; + *out++ = lastval; + lastval = inval; + count = 1; + if (!remain) + break; + } + } + *out++ = 1; + *out++ = save; + *out++ = 0; + + buf_in[buf_in_len - 1] = save; + return out - buf_out; + } + + + static int tif_toonz1_decode_extra(UCHAR* buf_in, int* buf_in_len, + UCHAR* buf_out) + { + UCHAR* in, val; + UCHAR* out; + int count; + + in = buf_in; + out = buf_out; + for (;;) + { + count = (SCHAR)*in++; + if (count > 0) + { + val = *in++; + while (count--) + *out++ = val; + } + else if (count < 0) + { + count &= 0x7f; + count |= *in++ << 7; + val = *in++; + while (count--) + *out++ = val; + } + else + break; + } + if (buf_in_len) + *buf_in_len = in - buf_in; + return out - buf_out; + } + + /*---------------------------------------------------------------------------*/ + + + + /*---------------------------------------------------------------------------*/ + + static int + DECLARE4(Toonz1Encode, TIFF*, tif, u_char*, buffer, u_long, bytes, u_int, s) + { + int enc; + short bitspersample; + USHORT* palette; + int tone_bits, color_offs, color_bits, pencil_offs, pencil_bits; + USHORT offset_mask; + + if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample)) + assert(0); + enc = 0; + switch (bitspersample) + { + case 8: + enc = tif_toonz1_encode_extra((UCHAR*)buffer, (int)bytes, + (UCHAR*)tif->tif_rawcp); + break; + + case 16: + if (TIFFGetField(tif, TIFFTAG_TOONZPALETTE, &palette)) + { + tone_bits = palette[4]; + color_offs = palette[5]; color_bits = palette[6]; + pencil_offs = palette[7]; pencil_bits = palette[8]; + offset_mask = palette[9]; + } + else + { + tone_bits = 4; + color_offs = 4; color_bits = 7; + pencil_offs = 11; pencil_bits = 5; + offset_mask = 0; + } + enc = tif_toonz1_encode_cm16((USHORT*)buffer, (int)(bytes >> 1), + (UCHAR*)tif->tif_rawcp, + tone_bits, + color_offs, color_bits, + pencil_offs, pencil_bits, offset_mask); + break; + + case 32: + enc = tif_toonz1_encode_cm24((TUINT32*)buffer, (int)(bytes >> 2), + (UCHAR*)tif->tif_rawcp); + break; + + default: + assert(0); + } + assert(enc); + tif->tif_rawcc += enc; + tif->tif_rawcp += enc; + if (tif->tif_rawcc >= tif->tif_rawdatasize) + if (!TIFFFlushData1(tif)) + return -1; + + return 1; + } + + + +} +#endif \ No newline at end of file diff --git a/toonz/sources/include/tparamcontainer.h b/toonz/sources/include/tparamcontainer.h index 899a4c2e..1cfd3a4c 100644 --- a/toonz/sources/include/tparamcontainer.h +++ b/toonz/sources/include/tparamcontainer.h @@ -65,7 +65,7 @@ class TParamVarT final : public TParamVar { public: TParamVarT(std::string name, T *var = nullptr, TParamP pluginVar = 0, bool hidden = false, bool obsolete = false) - : TParamVar(name, hidden), m_var(var), m_pluginVar(pluginVar) {} + : TParamVar(name, hidden, obsolete), m_var(var), m_pluginVar(pluginVar) {} TParamVarT() = delete; void setParam(TParam *param) { if (m_var) @@ -80,7 +80,8 @@ public: return m_pluginVar.getPointer(); } TParamVar *clone() const { - return new TParamVarT(getName(), m_var, m_pluginVar, isHidden()); + return new TParamVarT(getName(), m_var, m_pluginVar, isHidden(), + isObsolete()); } }; diff --git a/toonz/sources/stdfx/igs_rotate_blur.cpp b/toonz/sources/stdfx/igs_rotate_blur.cpp index 3a4b51b2..4e0684ac 100644 --- a/toonz/sources/stdfx/igs_rotate_blur.cpp +++ b/toonz/sources/stdfx/igs_rotate_blur.cpp @@ -362,8 +362,8 @@ int igs::rotate_blur::reference_margin( const double blur_radius, /* ぼかしの始まる半径 */ const double spin_radius, /* ゼロ以上でspin指定となり、 かつぼかし強弱の一定になる半径となる */ - const int type // 0: Accelerator, 1: Uniform Angle, 2: Uniform Length -) { + const int type, // 0: Accelerator, 1: Uniform Angle, 2: Uniform Length + const double ellipse_aspect_ratio) { /* 強度のないとき、なにもしない */ if (degree <= 0.0) { return 0; @@ -402,5 +402,13 @@ int igs::rotate_blur::reference_margin( margin1 = margin2; } + // Consider ellipse deformation. + // Instead of precise computing, return the maximum possible value. + if (ellipse_aspect_ratio != 1.0) { + double axis_x = 2.0 * ellipse_aspect_ratio / (ellipse_aspect_ratio + 1.0); + double axis_y = axis_x / ellipse_aspect_ratio; + margin1 *= std::max(axis_x, axis_y); + } + return static_cast(ceil(margin1)); } diff --git a/toonz/sources/stdfx/igs_rotate_blur.h b/toonz/sources/stdfx/igs_rotate_blur.h index 4bb1d1b2..37e4c8fd 100644 --- a/toonz/sources/stdfx/igs_rotate_blur.h +++ b/toonz/sources/stdfx/igs_rotate_blur.h @@ -44,8 +44,8 @@ IGS_ROTATE_BLUR_EXPORT int reference_margin( const double blur_radius, /* ぼかしの始まる半径 */ const double spin_radius, /* ゼロ以上でspin指定となり、 かつぼかし強弱の一定になる半径となる */ - const int type // 0: Accelerator, 1: Uniform Angle, 2: Uniform Length -); + const int type, // 0: Accelerator, 1: Uniform Angle, 2: Uniform Length + const double ellipse_aspect_ratio = 1.0); } // namespace rotate_blur } // namespace igs diff --git a/toonz/sources/stdfx/ino_spin_blur.cpp b/toonz/sources/stdfx/ino_spin_blur.cpp index dc59acd2..74027b17 100644 --- a/toonz/sources/stdfx/ino_spin_blur.cpp +++ b/toonz/sources/stdfx/ino_spin_blur.cpp @@ -86,8 +86,8 @@ public: static_cast(ceil(bBox.getLy())), static_cast(ceil(bBox.getLx())), center, this->m_blur->getValue(frame), this->m_radius->getValue(frame) * scale, - ((0 < this->m_type->getValue()) ? 0.0 : (bBox.getLy() / 2.0)), - this->m_type->getValue()); + bBox.getLy() / 2.0, this->m_type->getValue(), + this->m_ellipse_aspect_ratio->getValue(frame)); } void get_render_enlarge(const double frame, const TAffine affine, TRectD &bBox) { diff --git a/toonz/sources/stdfx/iwa_bokeh_util.cpp b/toonz/sources/stdfx/iwa_bokeh_util.cpp index 0c48e870..1ba6fee1 100644 --- a/toonz/sources/stdfx/iwa_bokeh_util.cpp +++ b/toonz/sources/stdfx/iwa_bokeh_util.cpp @@ -163,9 +163,9 @@ void BokehUtils::MyThread::setLayerRaster(const RASTER srcRas, PIXEL* pix = srcRas->pixels(j); for (int i = 0; i < dim.lx; i++, pix++) { if (pix->m != 0) { - double val = (m_channel == Red) ? (double)pix->r - : (m_channel == Green) ? (double)pix->g - : (double)pix->b; + double val = (m_channel == Red) ? (double)pix->r + : (m_channel == Green) ? (double)pix->g + : (double)pix->b; // multiply the exposure by alpha channel value dstMem[j * dim.lx + i].r = valueToExposure(val / (double)PIXEL::maxChannelValue, @@ -264,9 +264,9 @@ void BokehUtils::MyThread::run() { std::pow(exposure / (*alp_p), m_layerHardness / m_masterHardness) * (*alp_p); - double* res = (m_channel == Red) ? (&((*res_p).x)) - : (m_channel == Green) ? (&((*res_p).y)) - : (&((*res_p).z)); + double* res = (m_channel == Red) ? (&((*res_p).x)) + : (m_channel == Green) ? (&((*res_p).y)) + : (&((*res_p).z)); // composite exposure if ((*alp_p) >= 1.0 || (*res) == 0.0) @@ -1280,22 +1280,26 @@ void BokehUtils::setOutputRaster(double4* src, const RASTER dstRas, outPix->r = (typename PIXEL::Channel)((val > (double)PIXEL::maxChannelValue) ? (double)PIXEL::maxChannelValue - : val); + : (val < 0.) ? 0. + : val); val = (*src_p).y * (double)PIXEL::maxChannelValue + 0.5; outPix->g = (typename PIXEL::Channel)((val > (double)PIXEL::maxChannelValue) ? (double)PIXEL::maxChannelValue - : val); + : (val < 0.) ? 0. + : val); val = (*src_p).z * (double)PIXEL::maxChannelValue + 0.5; outPix->b = (typename PIXEL::Channel)((val > (double)PIXEL::maxChannelValue) ? (double)PIXEL::maxChannelValue - : val); + : (val < 0.) ? 0. + : val); val = (*src_p).w * (double)PIXEL::maxChannelValue + 0.5; outPix->m = (typename PIXEL::Channel)((val > (double)PIXEL::maxChannelValue) ? (double)PIXEL::maxChannelValue - : val); + : (val < 0.) ? 0. + : val); } src_p += margin.x; } diff --git a/toonz/sources/stdfx/iwa_bokehfx.cpp b/toonz/sources/stdfx/iwa_bokehfx.cpp index 79848ba5..0a154e7a 100644 --- a/toonz/sources/stdfx/iwa_bokehfx.cpp +++ b/toonz/sources/stdfx/iwa_bokehfx.cpp @@ -163,9 +163,8 @@ void Iwa_BokehFx::doCompute(TTile& tile, double frame, QList layerValues; for (auto index : sourceIndices) { LayerValue layerValue; - layerValue.sourceTile = sourceTiles[index]; - layerValue.premultiply = - m_layerParams[index].m_premultiply->getValue() ? 1 : 0; + layerValue.sourceTile = sourceTiles[index]; + layerValue.premultiply = m_layerParams[index].m_premultiply->getValue(); layerValue.layerHardness = masterHardness; layerValue.depth_ref = 0; layerValue.irisSize = irisSizes.value(index); diff --git a/toonz/sources/stdfx/iwa_bokehreffx.cpp b/toonz/sources/stdfx/iwa_bokehreffx.cpp index a7007eb6..fe967eaf 100644 --- a/toonz/sources/stdfx/iwa_bokehreffx.cpp +++ b/toonz/sources/stdfx/iwa_bokehreffx.cpp @@ -212,7 +212,7 @@ void Iwa_BokehRefFx::doCompute(TTile& tile, double frame, } ctrls[1] = depth_buff; - layerValue.premultiply = 2; // auto + layerValue.premultiply = false; layerValue.layerHardness = m_hardness->getValue(frame); layerValue.depth_ref = 1; layerValue.distance = 0.5; diff --git a/toonz/sources/stdfx/iwa_soapbubblefx.cpp b/toonz/sources/stdfx/iwa_soapbubblefx.cpp index ecf1bd7a..eb189c81 100644 --- a/toonz/sources/stdfx/iwa_soapbubblefx.cpp +++ b/toonz/sources/stdfx/iwa_soapbubblefx.cpp @@ -60,7 +60,7 @@ static float* dt(float* f, int n, float a = 1.0f) { delete[] z; return d; } -} +} // namespace //------------------------------------ @@ -204,9 +204,10 @@ void Iwa_SoapBubbleFx::doCompute(TTile& tile, double frame, /* obtain shape image */ TTile shape_tile; { - TRaster32P tmp(1, 1); - m_shape->allocateAndCompute(shape_tile, bBox.getP00(), dim, tmp, frame, - settings); + TRenderSettings settings_aux(settings); + settings_aux.m_bpp = 32; + m_shape->allocateAndCompute(shape_tile, bBox.getP00(), dim, nullptr, + frame, settings_aux); } if (checkCancelAndReleaseRaster(allocatedRasList, tile, settings)) return; @@ -530,7 +531,7 @@ int Iwa_SoapBubbleFx::do_binarize(TRaster32P srcRas, USHORT* dst_p, float thres, } QList lut; - for (int i = 0; i < 65536; i++) lut.append(i); + for (int i = 0; i < 65536; i++) lut.append(i); tmp_p = dst_p; int regionCount = 0; for (int j = 0; j < dim.ly; j++) { @@ -569,7 +570,7 @@ int Iwa_SoapBubbleFx::do_binarize(TRaster32P srcRas, USHORT* dst_p, float thres, } else convIndex.append(i); } - for (int i = 0; i < convIndex.count(); i++) + for (int i = 0; i < convIndex.count(); i++) lut[convIndex.at(i)] = lut.at(lut.at(convIndex.at(i))); // apply lut @@ -577,7 +578,7 @@ int Iwa_SoapBubbleFx::do_binarize(TRaster32P srcRas, USHORT* dst_p, float thres, tmp_p = dst_p; for (int j = 0; j < dim.ly; j++) { for (int i = 0; i < dim.lx; i++, tmp_p++) { - (*tmp_p) = lut[*tmp_p]; + (*tmp_p) = lut[*tmp_p]; if (maxRegionIndex < (*tmp_p)) maxRegionIndex = (*tmp_p); } } @@ -789,14 +790,14 @@ void Iwa_SoapBubbleFx::calc_norm_angle(float* norm_angle_p, float* depth_map_p, float* dst_p = norm_angle_p; for (int j = 0; j < dim.ly; j++) { - int sample_y[2] = {j - sampleDistance, j + sampleDistance}; + int sample_y[2] = {j - sampleDistance, j + sampleDistance}; if (sample_y[0] < 0) sample_y[0] = 0; if (sample_y[1] >= dim.ly) sample_y[1] = dim.ly - 1; for (int i = 0; i < dim.lx; i++, norm_angle_p++) { int sample_x[2] = {i - sampleDistance, i + sampleDistance}; if (sample_x[1] >= dim.lx) sample_x[1] = dim.lx - 1; - if (sample_x[0] < 0) sample_x[0] = 0; + if (sample_x[0] < 0) sample_x[0] = 0; float gradient[2]; gradient[0] = diff --git a/toonz/sources/tcleanupper/tcleanupper.cpp b/toonz/sources/tcleanupper/tcleanupper.cpp index 818b29aa..9cf90155 100644 --- a/toonz/sources/tcleanupper/tcleanupper.cpp +++ b/toonz/sources/tcleanupper/tcleanupper.cpp @@ -22,6 +22,7 @@ #include "toonz/txshcolumn.h" #include "toonz/tlog.h" #include "toonz/imagestyles.h" +#include "toonz/filepathproperties.h" // TnzBase includes #include "tcli.h" @@ -596,6 +597,12 @@ int main(int argc, char *argv[]) { cout << "project:" << project->getName() << endl; + // update TFilePath condition on loading the current project + FilePathProperties *fpProp = project->getFilePathProperties(); + TFilePath::setFilePathProperties(fpProp->useStandard(), + fpProp->acceptNonAlphabetSuffix(), + fpProp->letterCountForSuffix()); + TFilePath fp = srcName; /*- CLNファイルを直接指定した場合 -*/ diff --git a/toonz/sources/tcomposer/tcomposer.cpp b/toonz/sources/tcomposer/tcomposer.cpp index bca06e0b..1b93b2b0 100644 --- a/toonz/sources/tcomposer/tcomposer.cpp +++ b/toonz/sources/tcomposer/tcomposer.cpp @@ -33,6 +33,7 @@ #include "toonz/levelset.h" #include "toonz/txshsimplelevel.h" #include "toonz/levelproperties.h" +#include "toonz/filepathproperties.h" // TnzSound includes #include "tnzsound.h" @@ -50,7 +51,7 @@ #include "tunit.h" #include "tenv.h" #include "tpassivecachemanager.h" -//#include "tcacheresourcepool.h" +// #include "tcacheresourcepool.h" // TnzCore includes #include "tsystem.h" @@ -798,7 +799,7 @@ int main(int argc, char *argv[]) { loadShaderInterfaces(ToonzFolder::getLibraryFolder() + TFilePath("shaders")); - //#endif + // #endif //--------------------------------------------------------- @@ -828,6 +829,12 @@ int main(int argc, char *argv[]) { m_userLog->info(msg); // pm->setCurrentProject(project, false); // false => temporaneamente + // update TFilePath condition on loading the current project + FilePathProperties *fpProp = project->getFilePathProperties(); + TFilePath::setFilePathProperties(fpProp->useStandard(), + fpProp->acceptNonAlphabetSuffix(), + fpProp->letterCountForSuffix()); + Sw1.start(); if (!TSystem::doesExistFileOrLevel(srcFilePath)) return -2; @@ -927,13 +934,10 @@ int main(int argc, char *argv[]) { const int threadCounts[3] = {1, procCount / 2, procCount}; if (nthreads.isSelected()) { QString threadCountStr = QString::fromStdString(nthreads.getValue()); - threadCount = (threadCountStr == "single") - ? threadCounts[0] - : (threadCountStr == "half") - ? threadCounts[1] - : (threadCountStr == "all") - ? threadCounts[2] - : threadCountStr.toInt(); + threadCount = (threadCountStr == "single") ? threadCounts[0] + : (threadCountStr == "half") ? threadCounts[1] + : (threadCountStr == "all") ? threadCounts[2] + : threadCountStr.toInt(); if (threadCount <= 0) { cout << "Qualifier 'nthreads': bad input" << endl; @@ -953,15 +957,11 @@ int main(int argc, char *argv[]) { TOutputProperties::MediumVal, TOutputProperties::SmallVal}; if (tileSize.isSelected()) { QString tileSizeStr = QString::fromStdString(tileSize.getValue()); - maxTileSize = (tileSizeStr == "none") - ? maxTileSizes[0] - : (tileSizeStr == "large") - ? maxTileSizes[1] - : (tileSizeStr == "medium") - ? maxTileSizes[2] - : (tileSizeStr == "small") - ? maxTileSizes[3] - : tileSizeStr.toInt(); + maxTileSize = (tileSizeStr == "none") ? maxTileSizes[0] + : (tileSizeStr == "large") ? maxTileSizes[1] + : (tileSizeStr == "medium") ? maxTileSizes[2] + : (tileSizeStr == "small") ? maxTileSizes[3] + : tileSizeStr.toInt(); if (maxTileSize <= 0) { cout << "Qualifier 'maxtilesize': bad input" << endl; diff --git a/toonz/sources/toonz/levelsettingspopup.cpp b/toonz/sources/toonz/levelsettingspopup.cpp index daa61b96..911d5abe 100644 --- a/toonz/sources/toonz/levelsettingspopup.cpp +++ b/toonz/sources/toonz/levelsettingspopup.cpp @@ -761,7 +761,7 @@ LevelSettingsValues LevelSettingsPopup::getValues(TXshLevelP level) { values.doAntialias = (sl->getProperties()->antialiasSoftness() > 0) ? Qt::Checked : Qt::Unchecked; - values.softness = sl->getProperties()->antialiasSoftness(); + values.softness = sl->getProperties()->antialiasSoftness(); } } @@ -1475,6 +1475,7 @@ void LevelSettingsPopup::onSubsamplingChanged() { return; } + bool somethingChanged = false; TUndoManager::manager()->beginBlock(); QSetIterator levelItr(m_selectedLevels); while (levelItr.hasNext()) { @@ -1491,8 +1492,10 @@ void LevelSettingsPopup::onSubsamplingChanged() { TUndoManager::manager()->add(new LevelSettingsUndo( levelP.getPointer(), LevelSettingsUndo::Subsampling, oldSubsampling, subsampling)); + somethingChanged = true; } TUndoManager::manager()->endBlock(); + if (!somethingChanged) return; TApp::instance()->getCurrentScene()->setDirtyFlag(true); TApp::instance() diff --git a/toonz/sources/toonz/previewfxmanager.cpp b/toonz/sources/toonz/previewfxmanager.cpp index ccffbfbc..169204a0 100644 --- a/toonz/sources/toonz/previewfxmanager.cpp +++ b/toonz/sources/toonz/previewfxmanager.cpp @@ -1456,6 +1456,7 @@ void PreviewFxManager::onLevelChanged() { // Build the level name as an alias keyword. All cache images associated // with an alias containing the level name will be updated. TXshLevel *xl = TApp::instance()->getCurrentLevel()->getLevel(); + if (!xl) return; std::string aliasKeyword; TFilePath fp = xl->getPath(); aliasKeyword = ::to_string(fp.withType("")); diff --git a/toonz/sources/toonz/xshrowviewer.cpp b/toonz/sources/toonz/xshrowviewer.cpp index 56a25159..52d4ea82 100644 --- a/toonz/sources/toonz/xshrowviewer.cpp +++ b/toonz/sources/toonz/xshrowviewer.cpp @@ -721,8 +721,8 @@ void RowArea::drawShiftTraceMarker(QPainter &p) { QPoint frameAdj = m_viewer->getFrameZoomAdjustment(); int frameAdj_i = (m_viewer->orientation()->isVerticalTimeline()) - ? frameAdj.y() - : frameAdj.x(); + ? frameAdj.y() + : frameAdj.x(); // get onion colors TPixel frontPixel, backPixel; @@ -1113,7 +1113,8 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) { return; } - m_row = m_viewer->xyToPosition(pos).frame(); + m_row = std::max(0, m_viewer->xyToPosition(pos).frame()); + int x = pos.x(); if ((event->buttons() & Qt::LeftButton) != 0 && diff --git a/toonz/sources/toonzlib/outputproperties.cpp b/toonz/sources/toonzlib/outputproperties.cpp index a0a34730..6568f8ff 100644 --- a/toonz/sources/toonzlib/outputproperties.cpp +++ b/toonz/sources/toonzlib/outputproperties.cpp @@ -164,6 +164,8 @@ TPropertyGroup *TOutputProperties::getFileFormatProperties(std::string ext) { TPropertyGroup *ret = Tiio::makeWriterProperties(ext); m_formatProperties[ext] = ret; return ret; + } else if (ext == "mov" || ext == "3gp") { + return it->second; } else { // Try to merge settings instead of overriding them TPropertyGroup *ret = Tiio::makeWriterProperties(ext); diff --git a/toonz/sources/toonzlib/tscenehandle.cpp b/toonz/sources/toonzlib/tscenehandle.cpp index 3606dfe4..5bd94169 100644 --- a/toonz/sources/toonzlib/tscenehandle.cpp +++ b/toonz/sources/toonzlib/tscenehandle.cpp @@ -1,4 +1,4 @@ - +#include #include "toonz/tscenehandle.h" @@ -24,7 +24,22 @@ ToonzScene *TSceneHandle::getScene() const { return m_scene; } void TSceneHandle::setScene(ToonzScene *scene) { if (m_scene == scene) return; emit sceneSwitching(); - delete m_scene; + ToonzScene *oldscene = m_scene; m_scene = scene; if (m_scene) emit sceneSwitched(); + + // Prevent memory corruption caused by delayed signals writing into the + // discarded old scene while that memory was freed. + // That made OT had a chance of crashing when project or scene changed rapidly. + // Note: This is not the best solution but "it just works" + if (oldscene) { + QTimer *delayedTimer = new QTimer(this); + delayedTimer->setSingleShot(true); + + connect(delayedTimer, &QTimer::timeout, [=]() { + delete oldscene; + delayedTimer->deleteLater(); + }); + delayedTimer->start(3000); // 1 sec was enough, but... dunno about toasters + } } diff --git a/toonz/sources/toonzqt/styleselection.cpp b/toonz/sources/toonzqt/styleselection.cpp index af753573..03392420 100644 --- a/toonz/sources/toonzqt/styleselection.cpp +++ b/toonz/sources/toonzqt/styleselection.cpp @@ -570,7 +570,7 @@ void TStyleSelection::selectNone() { //------------------------------------------------------------------- bool TStyleSelection::isEmpty() const { - return m_pageIndex < 0 && m_styleIndicesInPage.empty(); + return m_pageIndex < 0 || m_styleIndicesInPage.empty(); } //-------------------------------------------------------------------