Imports the image from the TIFF descriptor.
595{
596 uint32_t &width = basicInfo.
width;
597 uint32_t &height = basicInfo.
height;
598 float &xres = basicInfo.
xres;
599 float &yres = basicInfo.
yres;
609 uint8_t &dstDepth = basicInfo.
dstDepth;
610
611
612 int32_t alphapos = -1;
613 bool hasPremultipliedAlpha = false;
614
615 dbgFile <<
"There are" << nbchannels <<
" channels and" << extrasamplescount
616 << " extra channels";
617 if (sampleinfo) {
618
619 for (uint16_t i = 0; i < extrasamplescount; i++) {
620 dbgFile <<
"sample" << i <<
"extra sample count"
621 << extrasamplescount << "color channel count"
623 << nbchannels << "sample info" << sampleinfo[i];
624 switch (sampleinfo[i]) {
625 case EXTRASAMPLE_ASSOCALPHA:
626
627
628 dbgPlugins <<
"Detected associated alpha @ " << i;
629 hasPremultipliedAlpha = true;
630 alphapos = static_cast<int32_t>(extrasamplescount
631 - 1U);
632 break;
633 case EXTRASAMPLE_UNASSALPHA:
634
635
636 alphapos = i;
637 break;
638 case EXTRASAMPLE_UNSPECIFIED:
639 default:
640 qWarning() << "Extra sample type not defined for this file, "
641 "assuming unassociated alpha.";
642 alphapos = i;
643 break;
644 }
645
646 if (sampleinfo[i] == EXTRASAMPLE_UNASSALPHA) {
647
648
649 alphapos = i;
650 }
651 }
652 }
653
654 dbgFile <<
"Alpha pos:" << alphapos;
655
656
658 char *text = nullptr;
659 if (TIFFGetField(image, TIFFTAG_ARTIST, &text) == 1) {
661 }
662 if (TIFFGetField(image, TIFFTAG_DOCUMENTNAME, &text) == 1) {
664 }
665 if (TIFFGetField(image, TIFFTAG_IMAGEDESCRIPTION, &text) == 1) {
667 }
668
669 uint16_t orientation = ORIENTATION_TOPLEFT;
670 if (TIFFGetField(image, TIFFTAG_ORIENTATION, &orientation) == 0) {
671 dbgFile <<
"Orientation not defined, assuming top left";
672 }
673
674 dbgFile <<
"Orientation:" << orientation;
675
676
677 uint32_t iptc_profile_size = 0;
678 uint32_t *iptc_profile_data = nullptr;
679 if (TIFFGetField(image,
680 TIFFTAG_RICHTIFFIPTC,
681 &iptc_profile_size,
682 &iptc_profile_data)
683 == 0) {
684 dbgFile <<
"IPTC metadata not found!";
685 }
686
687
688 uint32_t xmp_size = 0;
689 uint8_t *xmp_data = nullptr;
690 if (TIFFGetField(image, TIFFTAG_XMLPACKET, &xmp_size, &xmp_data) == 0) {
691 dbgFile <<
"XML metadata not found!";
692 }
693
694
695 uint16_t planarconfig = PLANARCONFIG_CONTIG;
696 if (TIFFGetField(image, TIFFTAG_PLANARCONFIG, &planarconfig) == 0) {
697 dbgFile <<
"Planar configuration is not defined";
699 }
700
703 static_cast<qint32>(width),
704 static_cast<qint32>(height),
705 cs,
706 "built image");
710
711
714 } else {
716 }
717 } else {
720 qint32 newwidth = (
m_image->
width() <
static_cast<qint32
>(width))
721 ? static_cast<qint32>(width)
723 qint32 newheight = (
m_image->
height() <
static_cast<qint32
>(height))
724 ? static_cast<qint32>(height)
727 }
728 }
731 std::unique_ptr<std::remove_pointer_t<tdata_t>, decltype(&_TIFFfree)> buf(
732 nullptr,
733 &_TIFFfree);
734
737 for (uint8_t *
p : *buf)
739 delete buf;
740 });
741
744
745
746 uint16_t nbcolorsamples = nbchannels - extrasamplescount;
747 const auto poses = [&]() -> std::array<quint8, 5> {
748 switch (color_type) {
749 case PHOTOMETRIC_MINISWHITE:
750 case PHOTOMETRIC_MINISBLACK:
751 return {0, 1};
752 case PHOTOMETRIC_CIELAB:
753 case PHOTOMETRIC_ICCLAB:
754 return {0, 1, 2, 3};
755 case PHOTOMETRIC_RGB:
756 if (sampletype == SAMPLEFORMAT_IEEEFP) {
757 return {0, 1, 2, 3};
758 } else {
759 return {2, 1, 0, 3};
760 }
761 case PHOTOMETRIC_SEPARATED:
762 return {0, 1, 2, 3, 4};
763 default:
764 return {};
765 }
766 }();
767
769 switch (color_type) {
770 case PHOTOMETRIC_MINISWHITE:
771 return makePostProcessor<KisTIFFPostProcessorInvert>(
772 nbcolorsamples,
773 colorSpaceIdTag);
774 case PHOTOMETRIC_MINISBLACK:
775 return makePostProcessor<KisTIFFPostProcessorDummy>(
776 nbcolorsamples,
777 colorSpaceIdTag);
778 case PHOTOMETRIC_CIELAB:
779 return makePostProcessor<KisTIFFPostProcessorCIELABtoICCLAB>(
780 nbcolorsamples,
781 colorSpaceIdTag);
782 case PHOTOMETRIC_ICCLAB:
783 case PHOTOMETRIC_RGB:
784 case PHOTOMETRIC_SEPARATED:
785 return makePostProcessor<KisTIFFPostProcessorDummy>(
786 nbcolorsamples,
787 colorSpaceIdTag);
788 default:
789 return {};
790 }
791 }();
792
793
795 uint16_t vsubsampling = 1;
796 uint16_t hsubsampling = 1;
797 if (color_type == PHOTOMETRIC_PALETTE) {
798 uint16_t *red =
799 nullptr;
800 uint16_t *green = nullptr;
801 uint16_t *blue = nullptr;
802 if ((TIFFGetField(image, TIFFTAG_COLORMAP, &red, &green, &blue)) == 0) {
803 dbgFile <<
"Indexed image does not define a palette";
805 }
806
807 tiffReader =
809 red,
810 green,
811 blue,
812 poses,
813 alphapos,
814 depth,
815 sampletype,
816 nbcolorsamples,
817 extrasamplescount,
818 hasPremultipliedAlpha,
819 transform,
820 postprocessor);
821 } else if (color_type == PHOTOMETRIC_YCBCR) {
822 TIFFGetFieldDefaulted(image,
823 TIFFTAG_YCBCRSUBSAMPLING,
824 &hsubsampling,
825 &vsubsampling);
826 lineSizeCoeffs[1] = hsubsampling;
827 lineSizeCoeffs[2] = hsubsampling;
828 dbgFile <<
"Subsampling" << 4 << hsubsampling << vsubsampling;
829 if (dstDepth == 8) {
832 static_cast<quint32
>(layer->
image()->
width()),
834 poses,
835 alphapos,
836 depth,
837 sampletype,
838 nbcolorsamples,
839 extrasamplescount,
840 hasPremultipliedAlpha,
841 transform,
842 postprocessor,
843 hsubsampling,
844 vsubsampling);
845 } else if (dstDepth == 16) {
846 if (sampletype == SAMPLEFORMAT_IEEEFP) {
847#ifdef HAVE_OPENEXR
850 static_cast<quint32
>(layer->
image()->
width()),
852 poses,
853 alphapos,
854 depth,
855 sampletype,
856 nbcolorsamples,
857 extrasamplescount,
858 hasPremultipliedAlpha,
859 transform,
860 postprocessor,
861 hsubsampling,
862 vsubsampling);
863#endif
864 } else {
865 tiffReader =
868 static_cast<quint32
>(layer->
image()->
width()),
870 poses,
871 alphapos,
872 depth,
873 sampletype,
874 nbcolorsamples,
875 extrasamplescount,
876 hasPremultipliedAlpha,
877 transform,
878 postprocessor,
879 hsubsampling,
880 vsubsampling);
881 }
882 } else if (dstDepth == 32) {
883 if (sampletype == SAMPLEFORMAT_IEEEFP) {
886 static_cast<quint32
>(layer->
image()->
width()),
888 poses,
889 alphapos,
890 depth,
891 sampletype,
892 nbcolorsamples,
893 extrasamplescount,
894 hasPremultipliedAlpha,
895 transform,
896 postprocessor,
897 hsubsampling,
898 vsubsampling);
899 } else {
900 tiffReader =
903 static_cast<quint32
>(layer->
image()->
width()),
905 poses,
906 alphapos,
907 depth,
908 sampletype,
909 nbcolorsamples,
910 extrasamplescount,
911 hasPremultipliedAlpha,
912 transform,
913 postprocessor,
914 hsubsampling,
915 vsubsampling);
916 }
917 }
918 } else if (dstDepth == 8) {
921 poses,
922 alphapos,
923 depth,
924 sampletype,
925 nbcolorsamples,
926 extrasamplescount,
927 hasPremultipliedAlpha,
928 transform,
929 postprocessor,
931 } else if (dstDepth == 16) {
932 if (sampletype == SAMPLEFORMAT_IEEEFP) {
933#ifdef HAVE_OPENEXR
936 poses,
937 alphapos,
938 depth,
939 sampletype,
940 nbcolorsamples,
941 extrasamplescount,
942 hasPremultipliedAlpha,
943 transform,
944 postprocessor,
945 1.0);
946#endif
947 } else {
950 poses,
951 alphapos,
952 depth,
953 sampletype,
954 nbcolorsamples,
955 extrasamplescount,
956 hasPremultipliedAlpha,
957 transform,
958 postprocessor,
960 }
961 } else if (dstDepth == 32) {
962 if (sampletype == SAMPLEFORMAT_IEEEFP) {
965 poses,
966 alphapos,
967 depth,
968 sampletype,
969 nbcolorsamples,
970 extrasamplescount,
971 hasPremultipliedAlpha,
972 transform,
973 postprocessor,
974 1.0f);
975 } else {
978 poses,
979 alphapos,
980 depth,
981 sampletype,
982 nbcolorsamples,
983 extrasamplescount,
984 hasPremultipliedAlpha,
985 transform,
986 postprocessor,
987 std::numeric_limits<uint32_t>::max());
988 }
989 }
990
991 if (!tiffReader) {
992 dbgFile <<
"Image has an invalid/unsupported color type: "
993 << color_type;
995 }
996
997 uint32_t compression = COMPRESSION_NONE;
998 TIFFGetFieldDefaulted(image, TIFFTAG_COMPRESSION, &compression, COMPRESSION_NONE);
999
1000#ifdef HAVE_JPEG_TURBO
1001 uint32_t hasSplitTables = 0;
1002 uint8_t *tables = nullptr;
1003 uint32_t sz = 0;
1005
1006 auto handle = [&]() -> std::unique_ptr<void, decltype(&tjDestroy)> {
1007 if (planarconfig == PLANARCONFIG_CONTIG
1008 && color_type == PHOTOMETRIC_YCBCR
1009 && compression == COMPRESSION_JPEG) {
1010 return {tjInitDecompress(), &tjDestroy};
1011 } else {
1012 return {nullptr, &tjDestroy};
1013 }
1014 }();
1015
1016 if (color_type == PHOTOMETRIC_YCBCR && compression == COMPRESSION_JPEG
1017 && hsubsampling != 1 && vsubsampling != 1) {
1018 dbgFile <<
"Setting up libjpeg-turbo for handling subsampled JPEG...";
1019 if (!TIFFGetFieldDefaulted(image,
1020 TIFFTAG_JPEGTABLESMODE,
1021 &hasSplitTables)) {
1022 errFile <<
"Error when detecting the JPEG coefficient "
1023 "table mode";
1025 }
1026 if (hasSplitTables) {
1027 if (!TIFFGetField(image, TIFFTAG_JPEGTABLES, &sz, &tables)) {
1028 errFile <<
"Unable to retrieve the JPEG abbreviated datastream";
1030 }
1031 }
1032
1033 {
1034 int width = 0;
1035 int height = 0;
1036
1037 if (hasSplitTables
1038 && tjDecompressHeader(handle.get(), tables, sz, &width, &height)
1039 != 0) {
1040 errFile << tjGetErrorStr2(handle.get());
1042 i18nc("TIFF errors",
1043 "This TIFF file is compressed with JPEG, but "
1044 "libjpeg-turbo could not load its coefficient "
1045 "quantization and/or Huffman coding tables. "
1046 "Please upgrade your version of libjpeg-turbo "
1047 "and try again."));
1049 }
1050 }
1051 }
1052#endif
1053
1054 if (TIFFIsTiled(image)) {
1056 uint32_t tileWidth = 0;
1057 uint32_t tileHeight = 0;
1060 TIFFGetField(image, TIFFTAG_TILEWIDTH, &tileWidth);
1061 TIFFGetField(image, TIFFTAG_TILELENGTH, &tileHeight);
1062 tmsize_t tileSize = TIFFTileSize(image);
1063
1064 if (planarconfig == PLANARCONFIG_CONTIG
1065 && !(color_type == PHOTOMETRIC_YCBCR
1066 && compression == COMPRESSION_JPEG && hsubsampling != 1
1067 && vsubsampling != 1)) {
1068 buf.reset(_TIFFmalloc(tileSize));
1069 if (depth < 16) {
1070 tiffstream =
1072 static_cast<uint8_t *>(buf.get()),
1073 depth,
1074 tileSize / tileHeight);
1075 } else if (depth >= 16 && depth < 32) {
1076 tiffstream =
1078 static_cast<uint8_t *>(buf.get()),
1079 depth,
1080 tileSize / tileHeight);
1081 } else {
1082 tiffstream =
1084 static_cast<uint8_t *>(buf.get()),
1085 depth,
1086 tileSize / tileHeight);
1087 }
1088 } else if (planarconfig == PLANARCONFIG_CONTIG
1089 && color_type == PHOTOMETRIC_YCBCR
1090 && compression == COMPRESSION_JPEG) {
1091#ifdef HAVE_JPEG_TURBO
1092 jpegBuf.resize(tileSize);
1093 ps_buf->resize(nbchannels);
1094 TIFFReadRawTile(image, 0, jpegBuf.data(), tileSize);
1095
1096 int width = tileWidth;
1097 int height = tileHeight;
1098 int jpegSubsamp = TJ_444;
1099 int jpegColorspace = TJCS_YCbCr;
1100
1101 if (tjDecompressHeader3(handle.get(),
1102 jpegBuf.data(),
1103 tileSize,
1104 &width,
1105 &height,
1106 &jpegSubsamp,
1107 &jpegColorspace)
1108 != 0) {
1109 errFile << tjGetErrorStr2(handle.get());
1111 }
1112
1114 for (uint32_t i = 0; i < nbchannels; i++) {
1115 const unsigned long uncompressedTileSize =
1116 tjPlaneSizeYUV(i, width, 0, height, jpegColorspace);
1118 uncompressedTileSize != (unsigned long)-1,
1120 dbgFile << QString(
"Uncompressed tile size (plane %1): %2")
1121 .arg(i)
1122 .arg(uncompressedTileSize)
1123 .toStdString()
1124 .c_str();
1125 tsize_t scanLineSize = uncompressedTileSize / tileHeight;
1126 dbgFile << QString(
"scan line size (plane %1): %2")
1127 .arg(i)
1128 .arg(scanLineSize)
1129 .toStdString()
1130 .c_str();
1131 (*ps_buf)[i] =
1132 static_cast<uint8_t *>(_TIFFmalloc(uncompressedTileSize));
1133 lineSizes[i] = scanLineSize;
1134 }
1135 tiffstream =
1137 ps_buf->data(),
1138 nbchannels,
1139 depth,
1140 lineSizes.data(),
1141 hsubsampling,
1142 vsubsampling);
1143#else
1145 i18nc("TIFF",
1146 "Subsampled YCbCr TIFF files compressed with JPEG cannot "
1147 "be loaded."));
1149#endif
1150 } else {
1151 ps_buf->resize(nbchannels);
1152 tsize_t scanLineSize = tileSize / tileHeight;
1153 dbgFile <<
" scanLineSize for each plan =" << scanLineSize;
1155 for (uint32_t i = 0; i < nbchannels; i++) {
1156 (*ps_buf)[i] = static_cast<uint8_t *>(_TIFFmalloc(tileSize));
1157 lineSizes[i] = scanLineSize / lineSizeCoeffs[i];
1158 }
1160 ps_buf->data(),
1161 nbchannels,
1162 depth,
1163 lineSizes.data());
1164 }
1165 dbgFile <<
"Scanline size =" << TIFFRasterScanlineSize(image)
1166 << " / tile size =" << TIFFTileSize(image)
1167 << " / tile width =" << tileWidth
1168 << " tileSize/tileHeight =" << tileSize / tileHeight;
1169
1170 dbgFile <<
" NbOfTiles =" << TIFFNumberOfTiles(image)
1171 << " tileWidth =" << tileWidth << " tileSize =" << tileSize;
1172
1173 for (y = 0;
y < height;
y += tileHeight) {
1174 for (x = 0;
x < width;
x += tileWidth) {
1175 dbgFile <<
"Reading tile x =" <<
x <<
" y =" <<
y;
1176#ifdef HAVE_JPEG_TURBO
1177 if (planarconfig == PLANARCONFIG_CONTIG
1178 && !(color_type == PHOTOMETRIC_YCBCR
1179 && compression == COMPRESSION_JPEG && hsubsampling != 1
1180 && vsubsampling != 1)) {
1181#else
1182 if (planarconfig == PLANARCONFIG_CONTIG) {
1183#endif
1184 TIFFReadTile(image, buf.get(), x, y, 0, (tsample_t)-1);
1185#ifdef HAVE_JPEG_TURBO
1186 } else if (planarconfig == PLANARCONFIG_CONTIG
1187 && (color_type == PHOTOMETRIC_YCBCR
1188 && compression == COMPRESSION_JPEG)) {
1189 uint32_t tile =
1190 TIFFComputeTile(image, x, y, 0, (tsample_t)-1);
1191 TIFFReadRawTile(image, tile, jpegBuf.data(), tileSize);
1192
1193 int width = tileWidth;
1194 int height = tileHeight;
1195 int jpegSubsamp = TJ_444;
1196 int jpegColorspace = TJCS_YCbCr;
1197
1198 if (tjDecompressHeader3(handle.get(),
1199 jpegBuf.data(),
1200 tileSize,
1201 &width,
1202 &height,
1203 &jpegSubsamp,
1204 &jpegColorspace)
1205 != 0) {
1206 errFile << tjGetErrorStr2(handle.get());
1208 }
1209
1210 if (tjDecompressToYUVPlanes(handle.get(),
1211 jpegBuf.data(),
1212 tileSize,
1213 ps_buf->data(),
1214 width,
1215 nullptr,
1216 height,
1217 0)
1218 != 0) {
1219 errFile << tjGetErrorStr2(handle.get());
1221 }
1222#endif
1223 } else {
1224 for (uint16_t i = 0; i < nbchannels; i++) {
1225 TIFFReadTile(image, (*ps_buf)[i], x, y, 0, i);
1226 }
1227 }
1228 uint32_t realTileWidth =
1229 (
x + tileWidth) < width ? tileWidth : width -
x;
1230 for (uint32_t yintile = 0;
1231 yintile < tileHeight &&
y + yintile < height;) {
1232 uint32_t linesread =
1233 tiffReader->copyDataToChannels(x,
1234 y + yintile,
1235 realTileWidth,
1236 tiffstream);
1237 yintile += linesread;
1238 tiffstream->moveToLine(yintile);
1239 }
1240 tiffstream->restart();
1241 }
1242 }
1243 } else {
1245 tsize_t stripsize = TIFFStripSize(image);
1246 uint32_t rowsPerStrip = 0;
1247 TIFFGetFieldDefaulted(image, TIFFTAG_ROWSPERSTRIP, &rowsPerStrip);
1248 dbgFile << rowsPerStrip <<
"" << height;
1249 rowsPerStrip =
1250 qMin(rowsPerStrip,
1251 height);
1252
1253 if (planarconfig == PLANARCONFIG_CONTIG
1254 && !(color_type == PHOTOMETRIC_YCBCR
1255 && compression == COMPRESSION_JPEG && hsubsampling != 1
1256 && vsubsampling != 1)) {
1257 buf.reset(_TIFFmalloc(stripsize));
1258 if (depth < 16) {
1259 tiffstream =
1261 static_cast<uint8_t *>(buf.get()),
1262 depth,
1263 stripsize / rowsPerStrip);
1264 } else if (depth < 32) {
1265 tiffstream =
1267 static_cast<uint8_t *>(buf.get()),
1268 depth,
1269 stripsize / rowsPerStrip);
1270 } else {
1271 tiffstream =
1273 static_cast<uint8_t *>(buf.get()),
1274 depth,
1275 stripsize / rowsPerStrip);
1276 }
1277 } else if (planarconfig == PLANARCONFIG_CONTIG
1278 && color_type == PHOTOMETRIC_YCBCR
1279 && compression == COMPRESSION_JPEG) {
1280#ifdef HAVE_JPEG_TURBO
1281 jpegBuf.resize(stripsize);
1282 ps_buf->resize(nbchannels);
1283 TIFFReadRawStrip(image, 0, jpegBuf.data(), stripsize);
1284
1285 int width = basicInfo.
width;
1286 int height = rowsPerStrip;
1287 int jpegSubsamp = TJ_444;
1288 int jpegColorspace = TJCS_YCbCr;
1289
1290 if (tjDecompressHeader3(handle.get(),
1291 jpegBuf.data(),
1292 stripsize,
1293 &width,
1294 &height,
1295 &jpegSubsamp,
1296 &jpegColorspace)
1297 != 0) {
1298 errFile << tjGetErrorStr2(handle.get());
1300 }
1301
1303 for (uint32_t i = 0; i < nbchannels; i++) {
1304 const unsigned long uncompressedStripsize =
1305 tjPlaneSizeYUV(i, width, 0, height, jpegColorspace);
1307 uncompressedStripsize != (unsigned long)-1,
1309 dbgFile << QString(
"Uncompressed strip size (plane %1): %2")
1310 .arg(i)
1311 .arg(uncompressedStripsize);
1312 tsize_t scanLineSize = uncompressedStripsize / rowsPerStrip;
1313 dbgFile << QString(
"scan line size (plane %1): %2")
1314 .arg(i)
1315 .arg(scanLineSize);
1316 (*ps_buf)[i] = static_cast<uint8_t*>(_TIFFmalloc(uncompressedStripsize));
1317 lineSizes[i] = scanLineSize;
1318 }
1320 ps_buf->data(),
1321 nbchannels,
1322 depth,
1323 lineSizes.data(),
1324 hsubsampling,
1325 vsubsampling);
1326#else
1328 i18nc("TIFF",
1329 "Subsampled YCbCr TIFF files compressed with JPEG cannot "
1330 "be loaded."));
1332#endif
1333 } else {
1334 ps_buf->resize(nbchannels);
1335 tsize_t scanLineSize = stripsize / rowsPerStrip;
1336 dbgFile <<
" scanLineSize for each plan =" << scanLineSize;
1338 for (uint32_t i = 0; i < nbchannels; i++) {
1339 (*ps_buf)[i] = static_cast<uint8_t*>(_TIFFmalloc(stripsize));
1340 lineSizes[i] = scanLineSize / lineSizeCoeffs[i];
1341 }
1343 ps_buf->data(),
1344 nbchannels,
1345 depth,
1346 lineSizes.data());
1347 }
1348
1349 dbgFile <<
"Scanline size =" << TIFFRasterScanlineSize(image)
1350 << " / strip size =" << TIFFStripSize(image)
1351 << " / rowsPerStrip =" << rowsPerStrip
1352 << " stripsize/rowsPerStrip =" << stripsize / rowsPerStrip;
1354 dbgFile <<
" NbOfStrips =" << TIFFNumberOfStrips(image)
1355 << " rowsPerStrip =" << rowsPerStrip
1356 << " stripsize =" << stripsize;
1357
1358 for (uint32_t strip = 0;
y < height; strip++) {
1359#ifdef HAVE_JPEG_TURBO
1360 if (planarconfig == PLANARCONFIG_CONTIG
1361 && !(color_type == PHOTOMETRIC_YCBCR
1362 && compression == COMPRESSION_JPEG && hsubsampling != 1
1363 && vsubsampling != 1)) {
1364#else
1365 if (planarconfig == PLANARCONFIG_CONTIG) {
1366#endif
1367 TIFFReadEncodedStrip(image,
1368 TIFFComputeStrip(image, y, 0),
1369 buf.get(),
1370 (tsize_t)-1);
1371#ifdef HAVE_JPEG_TURBO
1372 } else if (planarconfig == PLANARCONFIG_CONTIG
1373 && (color_type == PHOTOMETRIC_YCBCR
1374 && compression == COMPRESSION_JPEG)) {
1375 TIFFReadRawStrip(image, strip, jpegBuf.data(), stripsize);
1376
1377 int width = basicInfo.
width;
1378 int height = rowsPerStrip;
1379 int jpegSubsamp = TJ_444;
1380 int jpegColorspace = TJCS_YCbCr;
1381
1382 if (tjDecompressHeader3(handle.get(),
1383 jpegBuf.data(),
1384 stripsize,
1385 &width,
1386 &height,
1387 &jpegSubsamp,
1388 &jpegColorspace)
1389 != 0) {
1390 errFile << tjGetErrorStr2(handle.get());
1392 }
1393
1394 if (tjDecompressToYUVPlanes(
1395 handle.get(),
1396 jpegBuf.data(),
1397 stripsize,
1398 ps_buf->data(),
1399 width,
1400 nullptr,
1401 height,
1402 0)
1403 != 0) {
1404 errFile << tjGetErrorStr2(handle.get());
1406 }
1407#endif
1408 } else {
1409 for (uint16_t i = 0; i < nbchannels; i++) {
1410 TIFFReadEncodedStrip(image,
1411 TIFFComputeStrip(image, y, i),
1412 (*ps_buf)[i],
1413 (tsize_t)-1);
1414 }
1415 }
1416 for (uint32_t yinstrip = 0;
1417 yinstrip < rowsPerStrip &&
y < height;) {
1418 uint32_t linesread =
1419 tiffReader->copyDataToChannels(0, y, width, tiffstream);
1421 yinstrip += linesread;
1422 tiffstream->moveToLine(yinstrip);
1423 }
1424 tiffstream->restart();
1425 }
1426 }
1427 tiffReader->finalize();
1428 tiffReader.reset();
1429 tiffstream.reset();
1430 ps_buf.reset();
1431
1433
1436
1437
1438
1439 switch (orientation) {
1440 case ORIENTATION_TOPRIGHT:
1442 break;
1443 case ORIENTATION_BOTRIGHT:
1445 break;
1446 case ORIENTATION_BOTLEFT:
1448 break;
1449 case ORIENTATION_LEFTTOP:
1452 break;
1453 case ORIENTATION_RIGHTTOP:
1455 break;
1456 case ORIENTATION_RIGHTBOT:
1459 break;
1460 case ORIENTATION_LEFTBOT:
1462 break;
1463 default:
1464 break;
1465 }
1466
1467
1468 if (iptc_profile_size > 0 && iptc_profile_data != nullptr) {
1469 dbgFile <<
"Loading IPTC profile. Size: "
1470 << sizeof(uint32_t) * iptc_profile_size;
1471
1472
1473 if (TIFFIsByteSwapped(image) != 0) {
1474 TIFFSwabArrayOfLong(iptc_profile_data,
1475 iptc_profile_size / sizeof(uint32_t));
1476 }
1477
1480
1481
1482 QByteArray ba(reinterpret_cast<const char *>(iptc_profile_data),
1483 static_cast<int>(iptc_profile_size));
1484 QBuffer buf(&ba);
1486 }
1487
1488
1489 if (xmp_size > 0 && xmp_data != nullptr) {
1490 dbgFile <<
"Loading XMP data. Size: " << xmp_size;
1491
1494
1495
1496 QByteArray ba(reinterpret_cast<char *>(xmp_data),
1497 static_cast<int>(xmp_size));
1498 QBuffer buf(&ba);
1500 }
1501
1503}
constexpr qreal POINT_TO_CM(qreal px)
constexpr qreal POINT_TO_INCH(qreal px)
KisUndoStore * createUndoStore()
KoDocumentInfo * documentInfo() const
void setErrorMessage(const QString &errMsg)
void resizeImage(const QRect &newRect)
start asynchronous operation on resizing the image
QString nextLayerName(const QString &baseName="") const
void rotateImage(double radians)
start asynchronous operation on rotating the image
void setResolution(double xres, double yres)
virtual quint32 colorChannelCount() const =0
The class containing all meta information about a document.
void setAboutInfo(const QString &info, const QString &data)
void setAuthorInfo(const QString &info, const QString &data)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
const quint16 quint16_MAX
auto make_unique_with_deleter(T *data, Deleter d)
KisSharedPtr< KisNode > KisNodeSP
int depth(typename Forest< T >::const_child_iterator beginIt, typename Forest< T >::const_child_iterator endIt)
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
KisPaintDeviceSP paintDevice
QPair< QString, QString > colorSpaceIdTag
TiffResolution resolution
uint16_t extrasamplescount
KoColorTransformation * transform