From fc98b31c3ec83acf778c30c0cd34d178c9d0a54b Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Thu, 29 Feb 2024 12:24:01 +0300 Subject: [PATCH 01/56] Partially backport C API removal in imgproc module to reduce conflicts with 5.x --- modules/highgui/src/window_wayland.cpp | 22 +++++++++++----------- modules/imgproc/src/approx.cpp | 20 ++++++++++---------- modules/imgproc/src/contours.cpp | 2 +- modules/imgproc/src/distransform.cpp | 24 ++++++++++++------------ modules/imgproc/src/drawing.cpp | 4 ++-- modules/imgproc/src/emd.cpp | 6 +++--- modules/imgproc/src/histogram.cpp | 2 +- modules/imgproc/src/imgwarp.cpp | 24 ++++++++++++------------ modules/imgproc/src/thresh.cpp | 12 ++++++------ modules/imgproc/test/test_convhull.cpp | 4 ++-- modules/imgproc/test/test_drawing.cpp | 4 ++-- modules/imgproc/test/test_imgwarp.cpp | 14 +++++++------- modules/imgproc/test/test_thresh.cpp | 18 +++++++++--------- 13 files changed, 78 insertions(+), 78 deletions(-) diff --git a/modules/highgui/src/window_wayland.cpp b/modules/highgui/src/window_wayland.cpp index 0d7c9788a1..be5eb243b7 100644 --- a/modules/highgui/src/window_wayland.cpp +++ b/modules/highgui/src/window_wayland.cpp @@ -1442,18 +1442,18 @@ cv::Rect cv_wl_titlebar::draw(void *data, cv::Size const &size, bool force) { cv::putText( buf_, window_->get_title(), origin, title_.face, title_.scale, - CV_RGB(0xff, 0xff, 0xff), title_.thickness, CV_AA + CV_RGB(0xff, 0xff, 0xff), title_.thickness, cv::LINE_AA ); } buf_(cv::Rect(btn_min_.tl(), cv::Size(titlebar_min_width, size.height))) = bg_color_; - cv::line(buf_, btn_cls.tl(), btn_cls.br(), line_color_, 1, CV_AA); + cv::line(buf_, btn_cls.tl(), btn_cls.br(), line_color_, 1, cv::LINE_AA); cv::line(buf_, btn_cls.tl() + cv::Point(btn_cls.width, 0), btn_cls.br() - cv::Point(btn_cls.width, 0), - line_color_, 1, CV_AA); - cv::rectangle(buf_, btn_max.tl(), btn_max.br(), line_color_, 1, CV_AA); + line_color_, 1, cv::LINE_AA); + cv::rectangle(buf_, btn_max.tl(), btn_max.br(), line_color_, 1, cv::LINE_AA); cv::line(buf_, cv::Point(btn_min_.x + 8, btn_min_.height / 2), - cv::Point(btn_min_.x + btn_min_.width - 8, btn_min_.height / 2), line_color_, 1, CV_AA); - cv::line(buf_, cv::Point(0, 0), cv::Point(buf_.size().width, 0), border_color_, 1, CV_AA); + cv::Point(btn_min_.x + btn_min_.width - 8, btn_min_.height / 2), line_color_, 1, cv::LINE_AA); + cv::line(buf_, cv::Point(0, 0), cv::Point(buf_.size().width, 0), border_color_, 1, cv::LINE_AA); write_mat_to_xrgb8888(buf_, data); last_size_ = size; @@ -1657,12 +1657,12 @@ cv::Rect cv_wl_trackbar::draw(void *data, cv::Size const &size, bool force) { data_, (name_ + ": " + std::to_string(slider_.value)), bar_.text_orig, bar_.fontface, bar_.fontscale, - CV_RGB(0x00, 0x00, 0x00), bar_.font_thickness, CV_AA); + CV_RGB(0x00, 0x00, 0x00), bar_.font_thickness, cv::LINE_AA); - cv::line(data_, bar_.left, bar_.right, color_.bg, bar_.thickness + 3, CV_AA); - cv::line(data_, bar_.left, bar_.right, color_.fg, bar_.thickness, CV_AA); - cv::circle(data_, slider_.pos, slider_.radius, color_.fg, -1, CV_AA); - cv::circle(data_, slider_.pos, slider_.radius, color_.bg, 1, CV_AA); + cv::line(data_, bar_.left, bar_.right, color_.bg, bar_.thickness + 3, cv::LINE_AA); + cv::line(data_, bar_.left, bar_.right, color_.fg, bar_.thickness, cv::LINE_AA); + cv::circle(data_, slider_.pos, slider_.radius, color_.fg, -1, cv::LINE_AA); + cv::circle(data_, slider_.pos, slider_.radius, color_.bg, 1, cv::LINE_AA); write_mat_to_xrgb8888(data_, data); damage = cv::Rect(cv::Point(0, 0), size); diff --git a/modules/imgproc/src/approx.cpp b/modules/imgproc/src/approx.cpp index efbc6d33a5..df1570c38d 100644 --- a/modules/imgproc/src/approx.cpp +++ b/modules/imgproc/src/approx.cpp @@ -103,9 +103,9 @@ CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, /* calc 1-curvature */ s = abs_diff[reader.code - prev_code + 7]; - if( method <= CV_CHAIN_APPROX_SIMPLE ) + if( method <= cv::CHAIN_APPROX_SIMPLE ) { - if( method == CV_CHAIN_APPROX_NONE || s != 0 ) + if( method == cv::CHAIN_APPROX_NONE || s != 0 ) { CV_WRITE_SEQ_ELEM( pt, writer ); } @@ -121,7 +121,7 @@ CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, //CV_Assert( pt.x == chain->origin.x && pt.y == chain->origin.y ); - if( method <= CV_CHAIN_APPROX_SIMPLE ) + if( method <= cv::CHAIN_APPROX_SIMPLE ) return cvEndWriteSeq( &writer ); current->next = 0; @@ -176,7 +176,7 @@ CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, current->k = --k; /* determine cosine curvature if it should be used */ - if( method == CV_CHAIN_APPROX_TC89_KCOS ) + if( method == cv::CHAIN_APPROX_TC89_KCOS ) { /* calc k-cosine curvature */ for( j = k, s = 0; j > 0; j-- ) @@ -288,7 +288,7 @@ CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, } while( current != 0 ); - if( method == CV_CHAIN_APPROX_TC89_KCOS ) + if( method == cv::CHAIN_APPROX_TC89_KCOS ) goto copy_vect; /* Pass 4. @@ -390,7 +390,7 @@ cvApproxChains( CvSeq* src_seq, if( !src_seq || !storage ) CV_Error( CV_StsNullPtr, "" ); - if( method > CV_CHAIN_APPROX_TC89_KCOS || method <= 0 || minimal_perimeter < 0 ) + if( method > cv::CHAIN_APPROX_TC89_KCOS || method <= 0 || minimal_perimeter < 0 ) CV_Error( CV_StsOutOfRange, "" ); while( src_seq != 0 ) @@ -403,10 +403,10 @@ cvApproxChains( CvSeq* src_seq, switch( method ) { - case CV_CHAIN_APPROX_NONE: - case CV_CHAIN_APPROX_SIMPLE: - case CV_CHAIN_APPROX_TC89_L1: - case CV_CHAIN_APPROX_TC89_KCOS: + case cv::CHAIN_APPROX_NONE: + case cv::CHAIN_APPROX_SIMPLE: + case cv::CHAIN_APPROX_TC89_L1: + case cv::CHAIN_APPROX_TC89_KCOS: contour = icvApproximateChainTC89( (CvChain *) src_seq, sizeof( CvContour ), storage, method ); break; default: diff --git a/modules/imgproc/src/contours.cpp b/modules/imgproc/src/contours.cpp index e06e014e17..2e0d14e4c7 100644 --- a/modules/imgproc/src/contours.cpp +++ b/modules/imgproc/src/contours.cpp @@ -301,7 +301,7 @@ cvStartFindContours_Impl( void* _img, CvMemStorage* storage, /* converts all pixels to 0 or 1 */ if( CV_MAT_TYPE(mat->type) != CV_32S ) - cvThreshold( mat, mat, 0, 1, CV_THRESH_BINARY ); + cvThreshold( mat, mat, 0, 1, cv::THRESH_BINARY ); return scanner; } diff --git a/modules/imgproc/src/distransform.cpp b/modules/imgproc/src/distransform.cpp index 52167b2264..c2bdb62948 100644 --- a/modules/imgproc/src/distransform.cpp +++ b/modules/imgproc/src/distransform.cpp @@ -760,18 +760,18 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe _labels.create(src.size(), CV_32S); labels = _labels.getMat(); - maskSize = CV_DIST_MASK_5; + maskSize = cv::DIST_MASK_5; } float _mask[5] = {0}; - if( maskSize != CV_DIST_MASK_3 && maskSize != CV_DIST_MASK_5 && maskSize != CV_DIST_MASK_PRECISE ) + if( maskSize != cv::DIST_MASK_3 && maskSize != cv::DIST_MASK_5 && maskSize != cv::DIST_MASK_PRECISE ) CV_Error( CV_StsBadSize, "Mask size should be 3 or 5 or 0 (precise)" ); - if ((distType == CV_DIST_C || distType == CV_DIST_L1) && !need_labels) - maskSize = CV_DIST_MASK_3; + if ((distType == cv::DIST_C || distType == cv::DIST_L1) && !need_labels) + maskSize = cv::DIST_MASK_3; - if( maskSize == CV_DIST_MASK_PRECISE ) + if( maskSize == cv::DIST_MASK_PRECISE ) { #ifdef HAVE_IPP @@ -809,19 +809,19 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe return; } - CV_Assert( distType == CV_DIST_C || distType == CV_DIST_L1 || distType == CV_DIST_L2 ); + CV_Assert( distType == cv::DIST_C || distType == cv::DIST_L1 || distType == cv::DIST_L2 ); - getDistanceTransformMask( (distType == CV_DIST_C ? 0 : - distType == CV_DIST_L1 ? 1 : 2) + maskSize*10, _mask ); + getDistanceTransformMask( (distType == cv::DIST_C ? 0 : + distType == cv::DIST_L1 ? 1 : 2) + maskSize*10, _mask ); Size size = src.size(); - int border = maskSize == CV_DIST_MASK_3 ? 1 : 2; + int border = maskSize == cv::DIST_MASK_3 ? 1 : 2; Mat temp; if( !need_labels ) { - if( maskSize == CV_DIST_MASK_3 ) + if( maskSize == cv::DIST_MASK_3 ) { #if defined (HAVE_IPP) && (IPP_VERSION_X100 >= 700) bool has_int_overflow = (int64)src.cols * src.rows >= INT_MAX; @@ -864,7 +864,7 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe { labels.setTo(Scalar::all(0)); - if( labelType == CV_DIST_LABEL_CCOMP ) + if( labelType == cv::DIST_LABEL_CCOMP ) { Mat zpix = src == 0; connectedComponents(zpix, labels, 8, CV_32S, CCL_WU); @@ -893,7 +893,7 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, { CV_INSTRUMENT_REGION(); - if (distanceType == CV_DIST_L1 && dstType==CV_8U) + if (distanceType == cv::DIST_L1 && dstType==CV_8U) distanceTransform_L1_8U(_src, _dst); else distanceTransform(_src, _dst, noArray(), distanceType, maskSize, DIST_LABEL_PIXEL); diff --git a/modules/imgproc/src/drawing.cpp b/modules/imgproc/src/drawing.cpp index d69007a320..019c6e537e 100644 --- a/modules/imgproc/src/drawing.cpp +++ b/modules/imgproc/src/drawing.cpp @@ -1359,7 +1359,7 @@ FillEdgeCollection( Mat& img, std::vector& edges, const void* color, i int pix_size = (int)img.elemSize(); int delta; - if (line_type < CV_AA) + if (line_type < cv::LINE_AA) delta = 0; else delta = XY_ONE - 1; @@ -2310,7 +2310,7 @@ void putText( InputOutputArray _img, const String& text, Point org, int base_line = -(ascii[0] & 15); int hscale = cvRound(fontScale*XY_ONE), vscale = hscale; - if( line_type == CV_AA && img.depth() != CV_8U ) + if( line_type == cv::LINE_AA && img.depth() != CV_8U ) line_type = 8; if( bottomLeftOrigin ) diff --git a/modules/imgproc/src/emd.cpp b/modules/imgproc/src/emd.cpp index 3e065b0404..eb86460535 100644 --- a/modules/imgproc/src/emd.cpp +++ b/modules/imgproc/src/emd.cpp @@ -232,13 +232,13 @@ CV_IMPL float cvCalcEMD2( const CvArr* signature_arr1, user_param = (void *) (size_t)dims; switch (dist_type) { - case CV_DIST_L1: + case cv::DIST_L1: dist_func = icvDistL1; break; - case CV_DIST_L2: + case cv::DIST_L2: dist_func = icvDistL2; break; - case CV_DIST_C: + case cv::DIST_C: dist_func = icvDistC; break; default: diff --git a/modules/imgproc/src/histogram.cpp b/modules/imgproc/src/histogram.cpp index 7a52d0f3fe..499dd6e983 100644 --- a/modules/imgproc/src/histogram.cpp +++ b/modules/imgproc/src/histogram.cpp @@ -2471,7 +2471,7 @@ cvThreshHist( CvHistogram* hist, double thresh ) { CvMat mat; cvGetMat( hist->bins, &mat, 0, 1 ); - cvThreshold( &mat, &mat, thresh, 0, CV_THRESH_TOZERO ); + cvThreshold( &mat, &mat, thresh, 0, cv::THRESH_TOZERO ); } else { diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 567f890906..7a9ed3033e 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -1449,7 +1449,7 @@ static bool ocl_linearPolar(InputArray _src, OutputArray _dst, size_t h = dsize.height; String buildOptions; unsigned mem_size = 32; - if (flags & CV_WARP_INVERSE_MAP) + if (flags & cv::WARP_INVERSE_MAP) { buildOptions = "-D InverseMap"; } @@ -1464,7 +1464,7 @@ static bool ocl_linearPolar(InputArray _src, OutputArray _dst, ocl::KernelArg ocl_cp_sp = ocl::KernelArg::PtrReadWrite(cp_sp); ocl::KernelArg ocl_r = ocl::KernelArg::PtrReadWrite(r); - if (!(flags & CV_WARP_INVERSE_MAP)) + if (!(flags & cv::WARP_INVERSE_MAP)) { @@ -1495,7 +1495,7 @@ static bool ocl_linearPolar(InputArray _src, OutputArray _dst, size_t globalThreads[2] = { (size_t)dsize.width , (size_t)dsize.height }; size_t localThreads[2] = { mem_size , mem_size }; k.run(2, globalThreads, localThreads, false); - remap(src, _dst, mapx, mapy, flags & cv::INTER_MAX, (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT); + remap(src, _dst, mapx, mapy, flags & cv::INTER_MAX, (flags & cv::WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT); return true; } static bool ocl_logPolar(InputArray _src, OutputArray _dst, @@ -1518,7 +1518,7 @@ static bool ocl_logPolar(InputArray _src, OutputArray _dst, size_t h = dsize.height; String buildOptions; unsigned mem_size = 32; - if (flags & CV_WARP_INVERSE_MAP) + if (flags & cv::WARP_INVERSE_MAP) { buildOptions = "-D InverseMap"; } @@ -1535,7 +1535,7 @@ static bool ocl_logPolar(InputArray _src, OutputArray _dst, ocl::KernelArg ocl_cp_sp = ocl::KernelArg::PtrReadWrite(cp_sp); ocl::KernelArg ocl_r = ocl::KernelArg::PtrReadWrite(r); - if (!(flags & CV_WARP_INVERSE_MAP)) + if (!(flags & cv::WARP_INVERSE_MAP)) { @@ -1566,7 +1566,7 @@ static bool ocl_logPolar(InputArray _src, OutputArray _dst, size_t globalThreads[2] = { (size_t)dsize.width , (size_t)dsize.height }; size_t localThreads[2] = { mem_size , mem_size }; k.run(2, globalThreads, localThreads, false); - remap(src, _dst, mapx, mapy, flags & cv::INTER_MAX, (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT); + remap(src, _dst, mapx, mapy, flags & cv::INTER_MAX, (flags & cv::WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT); return true; } #endif @@ -3635,7 +3635,7 @@ cvWarpAffine( const CvArr* srcarr, CvArr* dstarr, const CvMat* marr, cv::Mat matrix = cv::cvarrToMat(marr); CV_Assert( src.type() == dst.type() ); cv::warpAffine( src, dst, matrix, dst.size(), flags, - (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT, + (flags & cv::WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT, fillval ); } @@ -3647,7 +3647,7 @@ cvWarpPerspective( const CvArr* srcarr, CvArr* dstarr, const CvMat* marr, cv::Mat matrix = cv::cvarrToMat(marr); CV_Assert( src.type() == dst.type() ); cv::warpPerspective( src, dst, matrix, dst.size(), flags, - (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT, + (flags & cv::WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT, fillval ); } @@ -3660,7 +3660,7 @@ cvRemap( const CvArr* srcarr, CvArr* dstarr, cv::Mat mapx = cv::cvarrToMat(_mapx), mapy = cv::cvarrToMat(_mapy); CV_Assert( src.type() == dst.type() && dst.size() == mapx.size() ); cv::remap( src, dst, mapx, mapy, flags & cv::INTER_MAX, - (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT, + (flags & cv::WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT, fillval ); CV_Assert( dst0.data == dst.data ); } @@ -3744,7 +3744,7 @@ void cv::warpPolar(InputArray _src, OutputArray _dst, Size dsize, mapy.create(dsize, CV_32F); bool semiLog = (flags & WARP_POLAR_LOG) != 0; - if (!(flags & CV_WARP_INVERSE_MAP)) + if (!(flags & cv::WARP_INVERSE_MAP)) { CV_Assert(!dsize.empty()); double Kangle = CV_2PI / dsize.height; @@ -3784,7 +3784,7 @@ void cv::warpPolar(InputArray _src, OutputArray _dst, Size dsize, my[rho] = (float)y; } } - remap(_src, _dst, mapx, mapy, flags & cv::INTER_MAX, (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT); + remap(_src, _dst, mapx, mapy, flags & cv::INTER_MAX, (flags & cv::WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT); } else { @@ -3837,7 +3837,7 @@ void cv::warpPolar(InputArray _src, OutputArray _dst, Size dsize, } } remap(src, _dst, mapx, mapy, flags & cv::INTER_MAX, - (flags & CV_WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT); + (flags & cv::WARP_FILL_OUTLIERS) ? cv::BORDER_CONSTANT : cv::BORDER_TRANSPARENT); } } diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index 4622691e68..8259902ed7 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -1545,18 +1545,18 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m ocl_threshold(_src, _dst, thresh, maxval, type), thresh) Mat src = _src.getMat(); - int automatic_thresh = (type & ~CV_THRESH_MASK); + int automatic_thresh = (type & ~cv::THRESH_MASK); type &= THRESH_MASK; - CV_Assert( automatic_thresh != (CV_THRESH_OTSU | CV_THRESH_TRIANGLE) ); - if( automatic_thresh == CV_THRESH_OTSU ) + CV_Assert( automatic_thresh != (cv::THRESH_OTSU | cv::THRESH_TRIANGLE) ); + if( automatic_thresh == cv::THRESH_OTSU ) { int src_type = src.type(); CV_CheckType(src_type, src_type == CV_8UC1 || src_type == CV_16UC1, "THRESH_OTSU mode"); thresh = src.type() == CV_8UC1 ? getThreshVal_Otsu_8u( src ) : getThreshVal_Otsu_16u( src ); } - else if( automatic_thresh == CV_THRESH_TRIANGLE ) + else if( automatic_thresh == cv::THRESH_TRIANGLE ) { CV_Assert( src.type() == CV_8UC1 ); thresh = getThreshVal_Triangle_8u( src ); @@ -1711,10 +1711,10 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, int idelta = type == THRESH_BINARY ? cvCeil(delta) : cvFloor(delta); uchar tab[768]; - if( type == CV_THRESH_BINARY ) + if( type == cv::THRESH_BINARY ) for( i = 0; i < 768; i++ ) tab[i] = (uchar)(i - 255 > -idelta ? imaxval : 0); - else if( type == CV_THRESH_BINARY_INV ) + else if( type == cv::THRESH_BINARY_INV ) for( i = 0; i < 768; i++ ) tab[i] = (uchar)(i - 255 <= -idelta ? imaxval : 0); else diff --git a/modules/imgproc/test/test_convhull.cpp b/modules/imgproc/test/test_convhull.cpp index 70251e3a25..2501a38075 100644 --- a/modules/imgproc/test/test_convhull.cpp +++ b/modules/imgproc/test/test_convhull.cpp @@ -747,7 +747,7 @@ int CV_MinAreaRectTest::validate_test_results( int test_case_idx ) cvCircle(img,cvPoint(cvRound(p[i].x*a+b),cvRound(p[i].y*c+d)), 3, CV_RGB(0,255,0), -1 ); for( i = 0; i < n; i++ ) bp[i] = cvPoint(cvRound(box_pt[i].x*a+b),cvRound(box_pt[i].y*c+d)); - cvPolyLine( img, &bpp, &n, 1, 1, CV_RGB(255,255,0), 1, CV_AA, 0 ); + cvPolyLine( img, &bpp, &n, 1, 1, CV_RGB(255,255,0), 1, cv::LINE_AA, 0 ); cvShowImage( "test", img ); cvWaitKey(); cvReleaseImage(&img); @@ -857,7 +857,7 @@ int CV_MinTriangleTest::validate_test_results( int test_case_idx ) cvCircle(img,cvPoint(cvRound(p[i].x*a+b),cvRound(p[i].y*c+d)), 3, CV_RGB(0,255,0), -1 ); for( i = 0; i < n; i++ ) bp[i] = cvPoint(cvRound(triangle[i].x*a+b),cvRound(triangle[i].y*c+d)); - cvPolyLine( img, &bpp, &n, 1, 1, CV_RGB(255,255,0), 1, CV_AA, 0 ); + cvPolyLine( img, &bpp, &n, 1, 1, CV_RGB(255,255,0), 1, cv::LINE_AA, 0 ); cvShowImage( "test", img ); cvWaitKey(); cvReleaseImage(&img); diff --git a/modules/imgproc/test/test_drawing.cpp b/modules/imgproc/test/test_drawing.cpp index 02095cd6b7..cdd2a01b4b 100644 --- a/modules/imgproc/test/test_drawing.cpp +++ b/modules/imgproc/test/test_drawing.cpp @@ -742,7 +742,7 @@ TEST(Drawing, fillpoly_fully) t1.x = (t1.x + offset.x) << (xy_shift - shift); t1.y = (t1.y + delta) >> shift; - if (lineType < CV_AA) + if (lineType < cv::LINE_AA) { t0.x = (t0.x + (xy_one >> 1)) >> xy_shift; t1.x = (t1.x + (xy_one >> 1)) >> xy_shift; @@ -831,7 +831,7 @@ PARAM_TEST_CASE(FillPolyFully, unsigned, unsigned, int, int, Point, cv::LineType t1.x = (t1.x + offset.x) << (xy_shift - shift); t1.y = (t1.y + delta) >> shift; - if (lineType < CV_AA) + if (lineType < cv::LINE_AA) { t0.x = (t0.x + (xy_one >> 1)) >> xy_shift; t1.x = (t1.x + (xy_one >> 1)) >> xy_shift; diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index 737128aa55..e8840d231b 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1615,11 +1615,11 @@ TEST(Imgproc_linearPolar, identity) { linearPolar(src, dst, Point2f((N-1) * 0.5f, (N-1) * 0.5f), N * 0.5f, - CV_WARP_FILL_OUTLIERS | CV_INTER_LINEAR | CV_WARP_INVERSE_MAP); + cv::WARP_FILL_OUTLIERS | CV_INTER_LINEAR | cv::WARP_INVERSE_MAP); linearPolar(dst, src, Point2f((N-1) * 0.5f, (N-1) * 0.5f), N * 0.5f, - CV_WARP_FILL_OUTLIERS | CV_INTER_LINEAR); + cv::WARP_FILL_OUTLIERS | CV_INTER_LINEAR); double psnr = cvtest::PSNR(in(roi), src(roi)); EXPECT_LE(25, psnr) << "iteration=" << i; @@ -1656,11 +1656,11 @@ TEST(Imgproc_logPolar, identity) { logPolar(src, dst, Point2f((N-1) * 0.5f, (N-1) * 0.5f), M, - CV_WARP_FILL_OUTLIERS | CV_INTER_LINEAR | CV_WARP_INVERSE_MAP); + cv::WARP_FILL_OUTLIERS | CV_INTER_LINEAR | cv::WARP_INVERSE_MAP); logPolar(dst, src, Point2f((N-1) * 0.5f, (N-1) * 0.5f), M, - CV_WARP_FILL_OUTLIERS | CV_INTER_LINEAR); + cv::WARP_FILL_OUTLIERS | CV_INTER_LINEAR); double psnr = cvtest::PSNR(in(roi), src(roi)); EXPECT_LE(25, psnr) << "iteration=" << i; @@ -1692,11 +1692,11 @@ TEST(Imgproc_warpPolar, identity) Rect roi = Rect(0, 0, in.cols - ((N + 19) / 20), in.rows); Point2f center = Point2f((N - 1) * 0.5f, (N - 1) * 0.5f); double radius = N * 0.5; - int flags = CV_WARP_FILL_OUTLIERS | CV_INTER_LINEAR; + int flags = cv::WARP_FILL_OUTLIERS | CV_INTER_LINEAR; // test linearPolar for (int ki = 1; ki <= 5; ki++) { - warpPolar(src, dst, src.size(), center, radius, flags + WARP_POLAR_LINEAR + CV_WARP_INVERSE_MAP); + warpPolar(src, dst, src.size(), center, radius, flags + WARP_POLAR_LINEAR + cv::WARP_INVERSE_MAP); warpPolar(dst, src, src.size(), center, radius, flags + WARP_POLAR_LINEAR); double psnr = cv::PSNR(in(roi), src(roi)); @@ -1706,7 +1706,7 @@ TEST(Imgproc_warpPolar, identity) src = in.clone(); for (int ki = 1; ki <= 5; ki++) { - warpPolar(src, dst, src.size(),center, radius, flags + WARP_POLAR_LOG + CV_WARP_INVERSE_MAP ); + warpPolar(src, dst, src.size(),center, radius, flags + WARP_POLAR_LOG + cv::WARP_INVERSE_MAP ); warpPolar(dst, src, src.size(),center, radius, flags + WARP_POLAR_LOG); double psnr = cv::PSNR(in(roi), src(roi)); diff --git a/modules/imgproc/test/test_thresh.cpp b/modules/imgproc/test/test_thresh.cpp index 510560fd05..3eb096a655 100644 --- a/modules/imgproc/test/test_thresh.cpp +++ b/modules/imgproc/test/test_thresh.cpp @@ -63,7 +63,7 @@ protected: CV_ThreshTest::CV_ThreshTest(int test_type) { - CV_Assert( (test_type & CV_THRESH_MASK) == 0 ); + CV_Assert( (test_type & cv::THRESH_MASK) == 0 ); test_array[INPUT].push_back(NULL); test_array[OUTPUT].push_back(NULL); test_array[REF_OUTPUT].push_back(NULL); @@ -84,7 +84,7 @@ void CV_ThreshTest::get_test_array_types_and_sizes( int test_case_idx, cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types ); depth = depth == 0 ? CV_8U : depth == 1 ? CV_16S : depth == 2 ? CV_16U : depth == 3 ? CV_32F : CV_64F; - if ( extra_type == CV_THRESH_OTSU ) + if ( extra_type == cv::THRESH_OTSU ) { depth = cvtest::randInt(rng) % 2 == 0 ? CV_8U : CV_16U; cn = 1; @@ -197,7 +197,7 @@ static void test_threshold( const Mat& _src, Mat& _dst, int width_n = _src.cols*cn, height = _src.rows; int ithresh = cvFloor(thresh); int imaxval, ithresh2; - if (extra_type == CV_THRESH_OTSU) + if (extra_type == cv::THRESH_OTSU) { thresh = compute_otsu_thresh(_src); ithresh = cvFloor(thresh); @@ -228,7 +228,7 @@ static void test_threshold( const Mat& _src, Mat& _dst, switch( thresh_type ) { - case CV_THRESH_BINARY: + case cv::THRESH_BINARY: for( i = 0; i < height; i++ ) { if( depth == CV_8U ) @@ -268,7 +268,7 @@ static void test_threshold( const Mat& _src, Mat& _dst, } } break; - case CV_THRESH_BINARY_INV: + case cv::THRESH_BINARY_INV: for( i = 0; i < height; i++ ) { if( depth == CV_8U ) @@ -308,7 +308,7 @@ static void test_threshold( const Mat& _src, Mat& _dst, } } break; - case CV_THRESH_TRUNC: + case cv::THRESH_TRUNC: for( i = 0; i < height; i++ ) { if( depth == CV_8U ) @@ -363,7 +363,7 @@ static void test_threshold( const Mat& _src, Mat& _dst, } } break; - case CV_THRESH_TOZERO: + case cv::THRESH_TOZERO: for( i = 0; i < height; i++ ) { if( depth == CV_8U ) @@ -418,7 +418,7 @@ static void test_threshold( const Mat& _src, Mat& _dst, } } break; - case CV_THRESH_TOZERO_INV: + case cv::THRESH_TOZERO_INV: for( i = 0; i < height; i++ ) { if( depth == CV_8U ) @@ -486,7 +486,7 @@ void CV_ThreshTest::prepare_to_validation( int /*test_case_idx*/ ) } TEST(Imgproc_Threshold, accuracy) { CV_ThreshTest test; test.safe_run(); } -TEST(Imgproc_Threshold, accuracyOtsu) { CV_ThreshTest test(CV_THRESH_OTSU); test.safe_run(); } +TEST(Imgproc_Threshold, accuracyOtsu) { CV_ThreshTest test(cv::THRESH_OTSU); test.safe_run(); } BIGDATA_TEST(Imgproc_Threshold, huge) { From e8582f2cf8b7d11d8ff384bad6f8b3776085f098 Mon Sep 17 00:00:00 2001 From: CSBVision Date: Fri, 1 Mar 2024 13:33:11 +0100 Subject: [PATCH 02/56] Update net_impl.cpp See issue #25112 --- modules/dnn/src/net.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/dnn/src/net.cpp b/modules/dnn/src/net.cpp index 3b200a108e..30894d0c24 100644 --- a/modules/dnn/src/net.cpp +++ b/modules/dnn/src/net.cpp @@ -13,6 +13,7 @@ CV__DNN_INLINE_NS_BEGIN Net::Net() : impl(makePtr()) { + setPreferableBackend(DNN_BACKEND_DEFAULT); } Net::~Net() From 52e280e94bece930b160b037d5e6553e6a6f66c9 Mon Sep 17 00:00:00 2001 From: Tomoaki Teshima Date: Sat, 2 Mar 2024 19:08:20 +0900 Subject: [PATCH 03/56] suppress warning ARM64 + Visual Studio build * follow the message --- modules/core/include/opencv2/core/hal/intrin_neon.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/include/opencv2/core/hal/intrin_neon.hpp b/modules/core/include/opencv2/core/hal/intrin_neon.hpp index ee9934135a..9218e88687 100644 --- a/modules/core/include/opencv2/core/hal/intrin_neon.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_neon.hpp @@ -1642,7 +1642,7 @@ inline int v_signmask(const v_uint64x2& a) #if CV_NEON_AARCH64 const int64x2_t signPosition = {0,1}; uint64x2_t v0 = vshlq_u64(vshrq_n_u64(a.val, 63), signPosition); - uint64_t t0 = vaddvq_u64(v0); + int t0 = (int)vaddvq_u64(v0); return t0; #else // #if CV_NEON_AARCH64 int64x1_t m0 = vdup_n_s64(0); From 500c55a808ceaa2058e2d1c060c2269c40c0cc9a Mon Sep 17 00:00:00 2001 From: Yuya Unno Date: Sat, 2 Mar 2024 19:43:58 +0900 Subject: [PATCH 04/56] Merge pull request #25122 from unnonouno:pqueue Use std::priority_queue in inpaint function for performance improvement #25122 In `cv::inpaint` implementation, it uses a priority queue with O(n) time linear search. For large images it is very slow. I replaced it with C++'s standard library `std::priority_queue`, that uses O(log(n)) algorithm. In my use case, it is x10 faster than the original. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/photo/perf/perf_inpaint.cpp | 23 ++++++ modules/photo/src/inpaint.cpp | 124 +++++++--------------------- 2 files changed, 53 insertions(+), 94 deletions(-) diff --git a/modules/photo/perf/perf_inpaint.cpp b/modules/photo/perf/perf_inpaint.cpp index 4ebf86d582..972770234f 100644 --- a/modules/photo/perf/perf_inpaint.cpp +++ b/modules/photo/perf/perf_inpaint.cpp @@ -6,6 +6,7 @@ namespace opencv_test CV_ENUM(InpaintingMethod, INPAINT_NS, INPAINT_TELEA) typedef tuple InpaintArea_InpaintingMethod_t; typedef perf::TestBaseWithParam InpaintArea_InpaintingMethod; +typedef perf::TestBaseWithParam Perf_InpaintingMethod; PERF_TEST_P(InpaintArea_InpaintingMethod, inpaint, @@ -34,4 +35,26 @@ PERF_TEST_P(InpaintArea_InpaintingMethod, inpaint, SANITY_CHECK(inpaintedArea); } +PERF_TEST_P(Perf_InpaintingMethod, inpaintDots, InpaintingMethod::all()) +{ + Mat src = imread(getDataPath("gpu/hog/road.png")); + + int inpaintingMethod = GetParam(); + + Mat mask(src.size(), CV_8UC1, Scalar(0)); + Mat result(src.size(), src.type()); + + for (int i = 0; i < src.size().height; i += 16) { + for (int j = 0; j < src.size().width; j += 16) { + mask.at(i, j) = 255; + } + } + + declare.in(src, mask).out(result).time(120); + + TEST_CYCLE() inpaint(src, mask, result, 10.0, inpaintingMethod); + + SANITY_CHECK_NOTHING(); +} + } // namespace diff --git a/modules/photo/src/inpaint.cpp b/modules/photo/src/inpaint.cpp index b436168212..05d2d49dca 100644 --- a/modules/photo/src/inpaint.cpp +++ b/modules/photo/src/inpaint.cpp @@ -45,6 +45,8 @@ // // */ +#include + #include "precomp.hpp" #include "opencv2/imgproc/imgproc_c.h" #include "opencv2/photo/legacy/constants_c.h" @@ -71,8 +73,16 @@ typedef struct CvHeapElem { float T; int i,j; - struct CvHeapElem* prev; - struct CvHeapElem* next; + int order; // to keep insertion order + + bool operator > (const CvHeapElem& rhs) const { + if (T > rhs.T) { + return true; + } else if (T < rhs.T) { + return false; + } + return order > rhs.order; + } } CvHeapElem; @@ -84,42 +94,10 @@ private: CvPriorityQueueFloat& operator=(const CvPriorityQueueFloat &); // assign disabled protected: - CvHeapElem *mem,*empty,*head,*tail; - int num,in; + std::priority_queue,std::greater > queue; + int next_order; public: - bool Init( const CvMat* f ) - { - int i,j; - for( i = num = 0; i < f->rows; i++ ) - { - for( j = 0; j < f->cols; j++ ) - num += CV_MAT_ELEM(*f,uchar,i,j)!=0; - } - if (num<=0) return false; - mem = (CvHeapElem*)cvAlloc((num+2)*sizeof(CvHeapElem)); - if (mem==NULL) return false; - - head = mem; - head->i = head->j = -1; - head->prev = NULL; - head->next = mem+1; - head->T = -FLT_MAX; - empty = mem+1; - for (i=1; i<=num; i++) { - mem[i].prev = mem+i-1; - mem[i].next = mem+i+1; - mem[i].i = -1; - mem[i].T = FLT_MAX; - } - tail = mem+i; - tail->i = tail->j = -1; - tail->prev = mem+i-1; - tail->next = NULL; - tail->T = FLT_MAX; - return true; - } - bool Add(const CvMat* f) { int i,j; for (i=0; irows; i++) { @@ -133,71 +111,33 @@ public: } bool Push(int i, int j, float T) { - CvHeapElem *tmp=empty,*add=empty; - if (empty==tail) return false; - while (tmp->prev->T>T) tmp = tmp->prev; - if (tmp!=empty) { - add->prev->next = add->next; - add->next->prev = add->prev; - empty = add->next; - add->prev = tmp->prev; - add->next = tmp; - add->prev->next = add; - add->next->prev = add; - } else { - empty = empty->next; - } - add->i = i; - add->j = j; - add->T = T; - in++; - // printf("push i %3d j %3d T %12.4e in %4d\n",i,j,T,in); + queue.push({T, i, j, next_order}); + ++next_order; return true; } bool Pop(int *i, int *j) { - CvHeapElem *tmp=head->next; - if (empty==tmp) return false; - *i = tmp->i; - *j = tmp->j; - tmp->prev->next = tmp->next; - tmp->next->prev = tmp->prev; - tmp->prev = empty->prev; - tmp->next = empty; - tmp->prev->next = tmp; - tmp->next->prev = tmp; - empty = tmp; - in--; - // printf("pop i %3d j %3d T %12.4e in %4d\n",tmp->i,tmp->j,tmp->T,in); + if (queue.empty()) { + return false; + } + *i = queue.top().i; + *j = queue.top().j; + queue.pop(); return true; } bool Pop(int *i, int *j, float *T) { - CvHeapElem *tmp=head->next; - if (empty==tmp) return false; - *i = tmp->i; - *j = tmp->j; - *T = tmp->T; - tmp->prev->next = tmp->next; - tmp->next->prev = tmp->prev; - tmp->prev = empty->prev; - tmp->next = empty; - tmp->prev->next = tmp; - tmp->next->prev = tmp; - empty = tmp; - in--; - // printf("pop i %3d j %3d T %12.4e in %4d\n",tmp->i,tmp->j,tmp->T,in); + if (queue.empty()) { + return false; + } + *i = queue.top().i; + *j = queue.top().j; + *T = queue.top().T; + queue.pop(); return true; } - CvPriorityQueueFloat(void) { - num=in=0; - mem=empty=head=tail=NULL; - } - - ~CvPriorityQueueFloat(void) - { - cvFree( &mem ); + CvPriorityQueueFloat(void) : queue(), next_order() { } }; @@ -786,8 +726,6 @@ icvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_ cvSet(t,cvScalar(1.0e6f,0,0,0)); cv::dilate(cv::cvarrToMat(mask), cv::cvarrToMat(band), el_cross, cv::Point(1, 1)); Heap=cv::makePtr(); - if (!Heap->Init(band)) - return; cvSub(band,mask,band,NULL); SET_BORDER1_C1(band,uchar,0); if (!Heap->Add(band)) @@ -803,8 +741,6 @@ icvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_ cv::dilate(cv::cvarrToMat(mask), cv::cvarrToMat(out), el_range); cvSub(out,mask,out,NULL); Out=cv::makePtr(); - if (!Out->Init(out)) - return; if (!Out->Add(band)) return; cvSub(out,band,out,NULL); From f48c06c0d9e27c2ff1d746cb0ce3783403bc3741 Mon Sep 17 00:00:00 2001 From: Aman-Vishwakarma1729 Date: Sun, 3 Mar 2024 23:37:07 +0530 Subject: [PATCH 05/56] Space mistake in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e812c37393..8217dde158 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Please read the [contribution guidelines](https://github.com/opencv/opencv/wiki/ * [Submit your OpenCV-based project](https://form.jotform.com/233105358823151) for inclusion in Community Friday on opencv.org * [Subscribe to the OpenCV YouTube Channel](http://youtube.com/@opencvofficial) featuring OpenCV Live, an hour-long streaming show -* [Follow OpenCV on LinkedIn](http://linkedin.com/company/opencv/) for daily posts showing the state-of-the-art in computer vision &AI +* [Follow OpenCV on LinkedIn](http://linkedin.com/company/opencv/) for daily posts showing the state-of-the-art in computer vision & AI * [Apply to be an OpenCV Volunteer](https://form.jotform.com/232745316792159) to help organize events and online campaigns as well as amplify them * [Follow OpenCV on Mastodon](http://mastodon.social/@opencv) in the Fediverse * [Follow OpenCV on Twitter](https://twitter.com/opencvlive) From c346ee1c29afc423a9b89bdf8c0a6b858f742789 Mon Sep 17 00:00:00 2001 From: MaximSmolskiy Date: Sun, 3 Mar 2024 23:05:29 +0300 Subject: [PATCH 06/56] Improve contours approximations in ChessBoardDetector::generateQuads --- modules/calib3d/src/calibinit.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/modules/calib3d/src/calibinit.cpp b/modules/calib3d/src/calibinit.cpp index ea5e5023b9..7e9b87ba5d 100644 --- a/modules/calib3d/src/calibinit.cpp +++ b/modules/calib3d/src/calibinit.cpp @@ -1796,22 +1796,12 @@ void ChessBoardDetector::generateQuads(const cv::Mat& image_, int flags, int dil if (contour_rect.area() < min_area) continue; - std::vector approx_contour; + std::vector approx_contour = contour; const int min_approx_level = 1, max_approx_level = MAX_CONTOUR_APPROX; - for (int approx_level = min_approx_level; approx_level <= max_approx_level; approx_level++ ) + for (int approx_level = min_approx_level; approx_contour.size() > 4 && approx_level <= max_approx_level; approx_level++ ) { - approxPolyDP(contour, approx_contour, (float)approx_level, true); - if (approx_contour.size() == 4) - break; - - // we call this again on its own output, because sometimes - // approxPoly() does not simplify as much as it should. - std::vector approx_contour_tmp; - std::swap(approx_contour, approx_contour_tmp); - approxPolyDP(approx_contour_tmp, approx_contour, (float)approx_level, true); - if (approx_contour.size() == 4) - break; + approxPolyDP(approx_contour, approx_contour, (float)approx_level, true); } // reject non-quadrangles From 5fe3933346ef34105a15bf4497e5426e0b6f2247 Mon Sep 17 00:00:00 2001 From: Laurent Berger Date: Mon, 4 Mar 2024 07:36:53 +0100 Subject: [PATCH 07/56] Merge pull request #25120 from LaurentBerger:I25103 Fixed ReduceMean layer behaviour #25120 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake https://github.com/microsoft/onnxruntime/blob/a93c31e3c9971063d8dfe45a627a80cbdcf99ed9/onnxruntime/core/providers/cpu/reduction/reduction_ops.cc#L433-L443 --- modules/dnn/src/layers/reduce_layer.cpp | 5 +-- modules/dnn/test/test_layers.cpp | 44 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/modules/dnn/src/layers/reduce_layer.cpp b/modules/dnn/src/layers/reduce_layer.cpp index 30f8139c25..d9d8b111fd 100644 --- a/modules/dnn/src/layers/reduce_layer.cpp +++ b/modules/dnn/src/layers/reduce_layer.cpp @@ -380,9 +380,10 @@ public: if (unprojected_indices[j] < shape_src[unreduced_axes[j]]) { break; } - unprojected_indices[j] = 0; + unprojected_indices[j] -= shape_src[unreduced_axes[j]]; + current_step -= shape_src[unreduced_axes[j]] * steps_src[unreduced_axes[j]]; ++unprojected_indices[j - 1]; - current_step = steps_src[unreduced_axes[j - 1]]; + current_step += steps_src[unreduced_axes[j - 1]]; } } } diff --git a/modules/dnn/test/test_layers.cpp b/modules/dnn/test/test_layers.cpp index 81c66b970f..a0171c9d91 100644 --- a/modules/dnn/test/test_layers.cpp +++ b/modules/dnn/test/test_layers.cpp @@ -1795,6 +1795,50 @@ INSTANTIATE_TEST_CASE_P(/**/, Layer_Test_ShuffleChannel, Combine( /*group*/ Values(1, 2, 3, 6), dnnBackendsAndTargets(/*with IE*/ false) )); +TEST(Layer_Test_ReduceMean, accuracy_input_0) +{ + vector szData = { 2, 1, 2, 1 ,2 }; + std::vector initData = { 0, 1, 2, 3, 4, 5, 6, 7 }; + Mat inpInitA(szData, CV_32FC1, Mat(initData).data); + std::vector resAxes0 = { 2, 3, 4, 5 }; + std::vector resAxes1 = { 0, 1, 2, 3, 4, 5, 6, 7 }; + std::vector resAxes2 = { 1, 2, 5, 6 }; + std::vector resAxes3 = { 0, 1, 2, 3, 4, 5, 6, 7 }; + std::vector resAxes4 = { 0.5, 2.5, 4.5, 6.5 }; + std::vector < vector> resReduceMean = { resAxes0, resAxes1, resAxes2, resAxes3, resAxes4 }; + + + for (int i = 0; i < resReduceMean.size(); i++) + { + Net net; + LayerParams lp; + lp.set("keepdims", 0); + lp.type = "Reduce"; + lp.set("reduce", "MEAN"); + lp.name = "testReduceMean"; + lp.set("axes", i); + lp.blobs.push_back(inpInitA); + + net.addLayerToPrev(lp.name, lp.type, lp); + net.setInput(inpInitA); + net.setPreferableBackend(DNN_BACKEND_OPENCV); + + Mat output = net.forward(); + MatShape gt_shape; + for (int j = 0; j < szData.size(); j++) + { + if (i == j) continue; + gt_shape.push_back(szData[j]); + } + + EXPECT_EQ(gt_shape, shape(output)); + + Mat a = output.reshape(1, output.total()); + normAssert(a, Mat(resReduceMean[i])); + } +} + + // Check if relu is not fused to convolution if we requested it's output TEST(Layer_Test_Convolution, relu_fusion) { From daa8f7dfc62e3b6a93f5f2005f84b8482ebc5694 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Mon, 4 Mar 2024 15:51:05 +0300 Subject: [PATCH 08/56] Partially back-port #25075 to 4.x --- apps/traincascade/boost.cpp | 28 +- apps/traincascade/cascadeclassifier.cpp | 4 +- apps/traincascade/imagestorage.cpp | 8 +- apps/traincascade/old_ml_boost.cpp | 28 +- apps/traincascade/old_ml_data.cpp | 72 ++-- apps/traincascade/old_ml_inner_functions.cpp | 172 +++++----- apps/traincascade/old_ml_precomp.hpp | 22 +- apps/traincascade/old_ml_tree.cpp | 68 ++-- modules/calib3d/src/calibration.cpp | 140 ++++---- modules/calib3d/src/solvepnp.cpp | 2 +- modules/calib3d/src/triangulate.cpp | 34 +- .../test/test_cameracalibration_badarg.cpp | 48 +-- .../calib3d/test/test_undistort_badarg.cpp | 16 +- modules/core/src/alloc.cpp | 2 +- modules/core/src/arithm.cpp | 16 +- modules/core/src/array.cpp | 320 +++++++++--------- modules/core/src/batch_distance.cpp | 2 +- modules/core/src/command_line_parser.cpp | 6 +- modules/core/src/copy.cpp | 4 +- modules/core/src/datastructs.cpp | 214 ++++++------ modules/core/src/dxt.cpp | 4 +- modules/core/src/glob.cpp | 2 +- modules/core/src/lapack.cpp | 4 +- modules/core/src/mathfuncs.cpp | 2 +- modules/core/src/matmul.dispatch.cpp | 2 +- modules/core/src/matrix.cpp | 20 +- modules/core/src/matrix_c.cpp | 12 +- modules/core/src/matrix_expressions.cpp | 8 +- modules/core/src/matrix_operations.cpp | 2 +- modules/core/src/matrix_sparse.cpp | 6 +- modules/core/src/matrix_wrap.cpp | 8 +- modules/core/src/norm.cpp | 2 +- modules/core/src/rand.cpp | 2 +- modules/core/src/system.cpp | 106 +++--- modules/core/src/types.cpp | 2 +- modules/core/src/umatrix.cpp | 16 +- modules/core/test/test_arithm.cpp | 4 +- modules/core/test/test_dxt.cpp | 4 +- modules/core/test/test_mat.cpp | 2 +- modules/dnn/src/dnn_utils.cpp | 2 +- .../dnn/src/int8layers/convolution_layer.cpp | 2 +- .../src/layers/cpu_kernels/convolution.cpp | 2 +- modules/dnn/src/vkcom/src/context.cpp | 8 +- modules/dnn/src/vkcom/src/op_conv.cpp | 2 +- modules/dnn/src/vkcom/src/op_naryEltwise.cpp | 2 +- modules/dnn/src/vkcom/src/pipeline.cpp | 4 +- modules/highgui/src/window.cpp | 26 +- modules/highgui/src/window_QT.cpp | 72 ++-- modules/highgui/src/window_gtk.cpp | 26 +- modules/highgui/src/window_winrt.cpp | 34 +- modules/imgproc/src/approx.cpp | 30 +- .../imgproc/src/bilateral_filter.dispatch.cpp | 2 +- modules/imgproc/src/box_filter.simd.hpp | 6 +- modules/imgproc/src/canny.cpp | 2 +- modules/imgproc/src/clahe.cpp | 2 +- modules/imgproc/src/color.cpp | 4 +- modules/imgproc/src/color_yuv.simd.hpp | 8 +- modules/imgproc/src/connectedcomponents.cpp | 6 +- modules/imgproc/src/contours.cpp | 32 +- modules/imgproc/src/convhull.cpp | 28 +- modules/imgproc/src/demosaicing.cpp | 8 +- modules/imgproc/src/deriv.cpp | 2 +- modules/imgproc/src/distransform.cpp | 4 +- modules/imgproc/src/drawing.cpp | 2 +- modules/imgproc/src/emd.cpp | 36 +- modules/imgproc/src/filter.simd.hpp | 6 +- modules/imgproc/src/floodfill.cpp | 14 +- modules/imgproc/src/geometry.cpp | 2 +- modules/imgproc/src/grabcut.cpp | 14 +- modules/imgproc/src/histogram.cpp | 98 +++--- modules/imgproc/src/hough.cpp | 10 +- modules/imgproc/src/imgwarp.cpp | 16 +- modules/imgproc/src/linefit.cpp | 4 +- modules/imgproc/src/matchcontours.cpp | 2 +- modules/imgproc/src/median_blur.simd.hpp | 2 +- modules/imgproc/src/moments.cpp | 14 +- modules/imgproc/src/morph.dispatch.cpp | 6 +- modules/imgproc/src/morph.simd.hpp | 6 +- modules/imgproc/src/precomp.hpp | 2 +- modules/imgproc/src/pyramids.cpp | 10 +- modules/imgproc/src/resize.cpp | 2 +- modules/imgproc/src/rotcalipers.cpp | 2 +- modules/imgproc/src/samplers.cpp | 4 +- modules/imgproc/src/segmentation.cpp | 8 +- modules/imgproc/src/shapedescr.cpp | 16 +- modules/imgproc/src/smooth.dispatch.cpp | 2 +- modules/imgproc/src/subdivision2d.cpp | 10 +- modules/imgproc/src/templmatch.cpp | 4 +- modules/imgproc/src/thresh.cpp | 14 +- modules/imgproc/src/utils.cpp | 6 +- modules/imgproc/test/test_color.cpp | 2 +- modules/imgproc/test/test_filter.cpp | 2 +- modules/ml/src/ann_mlp.cpp | 20 +- modules/ml/src/boost.cpp | 4 +- modules/ml/src/data.cpp | 14 +- modules/ml/src/gbt.cpp | 14 +- modules/ml/src/inner_functions.cpp | 2 +- modules/ml/src/lr.cpp | 28 +- modules/ml/src/nbayes.cpp | 10 +- modules/ml/src/precomp.hpp | 10 +- modules/ml/src/rtrees.cpp | 2 +- modules/ml/src/svm.cpp | 46 +-- modules/ml/src/svmsgd.cpp | 8 +- modules/ml/src/testset.cpp | 6 +- modules/ml/src/tree.cpp | 4 +- modules/photo/src/inpaint.cpp | 6 +- modules/stitching/src/motion_estimators.cpp | 2 +- modules/ts/src/ts.cpp | 2 +- modules/videoio/src/cap_mjpeg_encoder.cpp | 4 +- modules/videoio/src/cap_msmf.cpp | 6 +- modules/videoio/src/cap_openni2.cpp | 16 +- 111 files changed, 1124 insertions(+), 1124 deletions(-) diff --git a/apps/traincascade/boost.cpp b/apps/traincascade/boost.cpp index d409216b8a..c1a451672a 100644 --- a/apps/traincascade/boost.cpp +++ b/apps/traincascade/boost.cpp @@ -86,10 +86,10 @@ static CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, b int* dsti; if( !CV_IS_MAT(idx_arr) ) - CV_ERROR( CV_StsBadArg, "Invalid index array" ); + CV_ERROR( cv::Error::StsBadArg, "Invalid index array" ); if( idx_arr->rows != 1 && idx_arr->cols != 1 ) - CV_ERROR( CV_StsBadSize, "the index array must be 1-dimensional" ); + CV_ERROR( cv::Error::StsBadSize, "the index array must be 1-dimensional" ); idx_total = idx_arr->rows + idx_arr->cols - 1; srcb = idx_arr->data.ptr; @@ -105,20 +105,20 @@ static CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, b // idx_arr is array of 1's and 0's - // i.e. it is a mask of the selected components if( idx_total != data_arr_size ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "Component mask should contain as many elements as the total number of input variables" ); for( i = 0; i < idx_total; i++ ) idx_selected += srcb[i*step] != 0; if( idx_selected == 0 ) - CV_ERROR( CV_StsOutOfRange, "No components/input_variables is selected!" ); + CV_ERROR( cv::Error::StsOutOfRange, "No components/input_variables is selected!" ); break; case CV_32SC1: // idx_arr is array of integer indices of selected components if( idx_total > data_arr_size ) - CV_ERROR( CV_StsOutOfRange, + CV_ERROR( cv::Error::StsOutOfRange, "index array may not contain more elements than the total number of input variables" ); idx_selected = idx_total; // check if sorted already @@ -134,7 +134,7 @@ static CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, b } break; default: - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported index array data type " + CV_ERROR( cv::Error::StsUnsupportedFormat, "Unsupported index array data type " "(it should be 8uC1, 8sC1 or 32sC1)" ); } @@ -156,13 +156,13 @@ static CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, b qsort( dsti, idx_total, sizeof(dsti[0]), icvCmpIntegers ); if( dsti[0] < 0 || dsti[idx_total-1] >= data_arr_size ) - CV_ERROR( CV_StsOutOfRange, "the index array elements are out of range" ); + CV_ERROR( cv::Error::StsOutOfRange, "the index array elements are out of range" ); if( check_for_duplicates ) { for( i = 1; i < idx_total; i++ ) if( dsti[i] <= dsti[i-1] ) - CV_ERROR( CV_StsBadArg, "There are duplicated index array elements" ); + CV_ERROR( cv::Error::StsBadArg, "There are duplicated index array elements" ); } } @@ -218,7 +218,7 @@ bool CvCascadeBoostParams::read( const FileNode &node ) !boostTypeStr.compare( CC_LOGIT_BOOST ) ? CvBoost::LOGIT : !boostTypeStr.compare( CC_GENTLE_BOOST ) ? CvBoost::GENTLE : -1; if (boost_type == -1) - CV_Error( CV_StsBadArg, "unsupported Boost type" ); + CV_Error( cv::Error::StsBadArg, "unsupported Boost type" ); node[CC_MINHITRATE] >> minHitRate; node[CC_MAXFALSEALARM] >> maxFalseAlarm; node[CC_TRIM_RATE] >> weight_trim_rate ; @@ -228,7 +228,7 @@ bool CvCascadeBoostParams::read( const FileNode &node ) maxFalseAlarm <= 0 || maxFalseAlarm > 1 || weight_trim_rate <= 0 || weight_trim_rate > 1 || max_depth <= 0 || weak_count <= 0 ) - CV_Error( CV_StsBadArg, "bad parameters range"); + CV_Error( cv::Error::StsBadArg, "bad parameters range"); return true; } @@ -309,7 +309,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id bool isMakeRootCopy = true; if( !data_root ) - CV_Error( CV_StsError, "No training data has been set" ); + CV_Error( cv::Error::StsError, "No training data has been set" ); if( _subsample_idx ) { @@ -547,7 +547,7 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat // TODO: check responses: elements must be 0 or 1 if( _precalcValBufSize < 0 || _precalcIdxBufSize < 0) - CV_Error( CV_StsOutOfRange, "_numPrecalcVal and _numPrecalcIdx must be positive or 0" ); + CV_Error( cv::Error::StsOutOfRange, "_numPrecalcVal and _numPrecalcIdx must be positive or 0" ); var_count = var_all = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize(); sample_count = _numSamples; @@ -602,7 +602,7 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat if ((uint64)effective_buf_width * (uint64)effective_buf_height != effective_buf_size) { - CV_Error(CV_StsBadArg, "The memory buffer cannot be allocated since its size exceeds integer fields limit"); + CV_Error(cv::Error::StsBadArg, "The memory buffer cannot be allocated since its size exceeds integer fields limit"); } if ( is_buf_16u ) @@ -914,7 +914,7 @@ CvDTreeNode* CvCascadeBoostTree::predict( int sampleIdx ) const { CvDTreeNode* node = root; if( !node ) - CV_Error( CV_StsError, "The tree has not been trained yet" ); + CV_Error( cv::Error::StsError, "The tree has not been trained yet" ); if ( ((CvCascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount() == 0 ) // ordered { diff --git a/apps/traincascade/cascadeclassifier.cpp b/apps/traincascade/cascadeclassifier.cpp index e364f2e3ed..6540c30e3a 100644 --- a/apps/traincascade/cascadeclassifier.cpp +++ b/apps/traincascade/cascadeclassifier.cpp @@ -142,7 +142,7 @@ bool CvCascadeClassifier::train( const string _cascadeDirName, double time = (double)getTickCount(); if( _cascadeDirName.empty() || _posFilename.empty() || _negFilename.empty() ) - CV_Error( CV_StsBadArg, "_cascadeDirName or _bgfileName or _vecFileName is NULL" ); + CV_Error( cv::Error::StsBadArg, "_cascadeDirName or _bgfileName or _vecFileName is NULL" ); string dirName; if (_cascadeDirName.find_last_of("/\\") == (_cascadeDirName.length() - 1) ) @@ -452,7 +452,7 @@ void CvCascadeClassifier::save( const string filename, bool baseFormat ) //char buf[256]; CvSeq* weak; if ( cascadeParams.featureType != CvFeatureParams::HAAR ) - CV_Error( CV_StsBadFunc, "old file format is used for Haar-like features only"); + CV_Error( cv::Error::StsBadFunc, "old file format is used for Haar-like features only"); fs << "{:" ICV_HAAR_TYPE_ID; fs << ICV_HAAR_SIZE_NAME << "[:" << cascadeParams.winSize.width << cascadeParams.winSize.height << "]"; diff --git a/apps/traincascade/imagestorage.cpp b/apps/traincascade/imagestorage.cpp index f220e5c2b3..a32824c317 100644 --- a/apps/traincascade/imagestorage.cpp +++ b/apps/traincascade/imagestorage.cpp @@ -138,7 +138,7 @@ bool CvCascadeImageReader::PosReader::create( const string _filename ) fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 || fread( &tmp, sizeof( tmp ), 1, file ) != 1 || fread( &tmp, sizeof( tmp ), 1, file ) != 1 ) - CV_Error_( CV_StsParseError, ("wrong file format for %s\n", _filename.c_str()) ); + CV_Error_( cv::Error::StsParseError, ("wrong file format for %s\n", _filename.c_str()) ); base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp ); if( feof( file ) ) return false; @@ -154,14 +154,14 @@ bool CvCascadeImageReader::PosReader::get( Mat &_img ) uchar tmp = 0; size_t elements_read = fread( &tmp, sizeof( tmp ), 1, file ); if( elements_read != 1 ) - CV_Error( CV_StsBadArg, "Can not get new positive sample. The most possible reason is " + CV_Error( cv::Error::StsBadArg, "Can not get new positive sample. The most possible reason is " "insufficient count of samples in given vec-file.\n"); elements_read = fread( vec, sizeof( vec[0] ), vecSize, file ); if( elements_read != (size_t)(vecSize) ) - CV_Error( CV_StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n"); + CV_Error( cv::Error::StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n"); if( feof( file ) || last++ >= count ) - CV_Error( CV_StsBadArg, "Can not get new positive sample. vec-file is over.\n"); + CV_Error( cv::Error::StsBadArg, "Can not get new positive sample. vec-file is over.\n"); for( int r = 0; r < _img.rows; r++ ) { diff --git a/apps/traincascade/old_ml_boost.cpp b/apps/traincascade/old_ml_boost.cpp index 2f53bd9031..3dbd0204b1 100644 --- a/apps/traincascade/old_ml_boost.cpp +++ b/apps/traincascade/old_ml_boost.cpp @@ -991,7 +991,7 @@ CvBoost::set_params( const CvBoostParams& _params ) params = _params; if( params.boost_type != DISCRETE && params.boost_type != REAL && params.boost_type != LOGIT && params.boost_type != GENTLE ) - CV_ERROR( CV_StsBadArg, "Unknown/unsupported boosting type" ); + CV_ERROR( cv::Error::StsBadArg, "Unknown/unsupported boosting type" ); params.weak_count = MAX( params.weak_count, 1 ); params.weight_trim_rate = MAX( params.weight_trim_rate, 0. ); @@ -1045,7 +1045,7 @@ CvBoost::train( const CvMat* _train_data, int _tflag, _sample_idx, _var_type, _missing_mask, _params, true, true ); if( data->get_num_classes() != 2 ) - CV_ERROR( CV_StsNotImplemented, + CV_ERROR( cv::Error::StsNotImplemented, "Boosted trees can only be used for 2-class classification." ); CV_CALL( storage = cvCreateMemStorage() ); weak = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvBoostTree*), storage ); @@ -1482,7 +1482,7 @@ CvBoost::get_active_vars( bool absolute_idx ) __BEGIN__; if( !weak ) - CV_ERROR( CV_StsError, "The boosted tree ensemble has not been trained yet" ); + CV_ERROR( cv::Error::StsError, "The boosted tree ensemble has not been trained yet" ); if( !active_vars || !active_vars_abs ) { @@ -1612,13 +1612,13 @@ CvBoost::predict( const CvMat* _sample, const CvMat* _missing, const float* sample_data; if( !weak ) - CV_Error( CV_StsError, "The boosted tree ensemble has not been trained yet" ); + CV_Error( cv::Error::StsError, "The boosted tree ensemble has not been trained yet" ); if( !CV_IS_MAT(_sample) || CV_MAT_TYPE(_sample->type) != CV_32FC1 || (_sample->cols != 1 && _sample->rows != 1) || (_sample->cols + _sample->rows - 1 != data->var_all && !raw_mode) || (active_vars && _sample->cols + _sample->rows - 1 != active_vars->cols && raw_mode) ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "the input sample must be 1d floating-point vector with the same " "number of elements as the total number of variables or " "as the number of variables used for training" ); @@ -1627,7 +1627,7 @@ CvBoost::predict( const CvMat* _sample, const CvMat* _missing, { if( !CV_IS_MAT(_missing) || !CV_IS_MASK_ARR(_missing) || !CV_ARE_SIZES_EQ(_missing, _sample) ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "the missing data mask must be 8-bit vector of the same size as input sample" ); } @@ -1644,7 +1644,7 @@ CvBoost::predict( const CvMat* _sample, const CvMat* _missing, CV_MAT_TYPE(weak_responses->type) != CV_32FC1 || (weak_responses->cols != 1 && weak_responses->rows != 1) || weak_responses->cols + weak_responses->rows - 1 != weak_count ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The output matrix of weak classifier responses must be valid " "floating-point vector of the same number of components as the length of input slice" ); wstep = CV_IS_MAT_CONT(weak_responses->type) ? 1 : weak_responses->step/sizeof(float); @@ -1700,7 +1700,7 @@ CvBoost::predict( const CvMat* _sample, const CvMat* _missing, c = a; int ival = cvRound(val); if ( (ival != val) && (!m) ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "one of input categorical variable is not an integer" ); while( a < b ) @@ -1735,7 +1735,7 @@ CvBoost::predict( const CvMat* _sample, const CvMat* _missing, else { if( !CV_IS_MAT_CONT(_sample->type & (_missing ? _missing->type : -1)) ) - CV_Error( CV_StsBadArg, "In raw mode the input vectors must be continuous" ); + CV_Error( cv::Error::StsBadArg, "In raw mode the input vectors must be continuous" ); } cvStartReadSeq( weak, &reader ); @@ -1951,7 +1951,7 @@ void CvBoost::read_params( cv::FileNode& fnode ) params.boost_type = temp.empty() ? -1 : (int)temp; if( params.boost_type < DISCRETE || params.boost_type > GENTLE ) - CV_ERROR( CV_StsBadArg, "Unknown boosting type" ); + CV_ERROR( cv::Error::StsBadArg, "Unknown boosting type" ); temp = fnode[ "splitting_criteria" ]; if( !temp.empty() && temp.isString() ) @@ -1966,7 +1966,7 @@ void CvBoost::read_params( cv::FileNode& fnode ) params.split_criteria = temp.empty() ? -1 : (int) temp; if( params.split_criteria < DEFAULT || params.boost_type > SQERR ) - CV_ERROR( CV_StsBadArg, "Unknown boosting type" ); + CV_ERROR( cv::Error::StsBadArg, "Unknown boosting type" ); params.weak_count = (int) fnode[ "ntrees" ]; params.weight_trim_rate = (double)fnode["weight_trimming_rate"]; @@ -1996,13 +1996,13 @@ CvBoost::read( cv::FileNode& node ) trees_fnode = node[ "trees" ]; if( trees_fnode.empty() || !trees_fnode.isSeq() ) - CV_ERROR( CV_StsParseError, " tag is missing" ); + CV_ERROR( cv::Error::StsParseError, " tag is missing" ); reader = trees_fnode.begin(); ntrees = (int) trees_fnode.size(); if( ntrees != params.weak_count ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "The number of trees stored does not match tag value" ); CV_CALL( storage = cvCreateMemStorage() ); @@ -2034,7 +2034,7 @@ CvBoost::write( cv::FileStorage& fs, const char* name ) const fs.startWriteStruct( name, cv::FileNode::MAP, CV_TYPE_NAME_ML_BOOSTING ); if( !weak ) - CV_ERROR( CV_StsBadArg, "The classifier has not been trained yet" ); + CV_ERROR( cv::Error::StsBadArg, "The classifier has not been trained yet" ); write_params( fs ); fs.startWriteStruct( "trees", cv::FileNode::SEQ ); diff --git a/apps/traincascade/old_ml_data.cpp b/apps/traincascade/old_ml_data.cpp index d221dcbf0f..3b0712def1 100644 --- a/apps/traincascade/old_ml_data.cpp +++ b/apps/traincascade/old_ml_data.cpp @@ -284,7 +284,7 @@ const CvMat* CvMLData::get_missing() const __BEGIN__; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); __END__; @@ -331,7 +331,7 @@ void CvMLData::set_delimiter(char ch) __BEGIN__; if (ch == miss_ch /*|| ch == flt_separator*/) - CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different"); + CV_ERROR(cv::Error::StsBadArg, "delimited, miss_character and flt_separator must be different"); delimiter = ch; @@ -349,7 +349,7 @@ void CvMLData::set_miss_ch(char ch) __BEGIN__; if (ch == delimiter/* || ch == flt_separator*/) - CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different"); + CV_ERROR(cv::Error::StsBadArg, "delimited, miss_character and flt_separator must be different"); miss_ch = ch; @@ -367,10 +367,10 @@ void CvMLData::set_response_idx( int idx ) __BEGIN__; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); if ( idx >= values->cols) - CV_ERROR( CV_StsBadArg, "idx value is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "idx value is not correct" ); if ( response_idx >= 0 ) chahge_var_idx( response_idx, true ); @@ -387,7 +387,7 @@ int CvMLData::get_response_idx() const __BEGIN__; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); __END__; return response_idx; } @@ -400,19 +400,19 @@ void CvMLData::change_var_type( int var_idx, int type ) int var_count = 0; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); var_count = values->cols; if ( var_idx < 0 || var_idx >= var_count) - CV_ERROR( CV_StsBadArg, "var_idx is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "var_idx is not correct" ); if ( type != CV_VAR_ORDERED && type != CV_VAR_CATEGORICAL) - CV_ERROR( CV_StsBadArg, "type is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "type is not correct" ); assert( var_types ); if ( var_types->data.ptr[var_idx] == CV_VAR_CATEGORICAL && type == CV_VAR_ORDERED) - CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); + CV_ERROR( cv::Error::StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); var_types->data.ptr[var_idx] = (uchar)type; __END__; @@ -428,7 +428,7 @@ void CvMLData::set_var_types( const char* str ) const char* ord = 0, *cat = 0; int var_count = 0, set_var_type_count = 0; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); var_count = values->cols; @@ -437,7 +437,7 @@ void CvMLData::set_var_types( const char* str ) ord = strstr( str, "ord" ); cat = strstr( str, "cat" ); if ( !ord && !cat ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); if ( !ord && strlen(cat) == 3 ) // str == "cat" { @@ -455,19 +455,19 @@ void CvMLData::set_var_types( const char* str ) { char* stopstring = NULL; if ( ord[3] != '[') - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); ord += 4; // pass "ord[" do { int b1 = (int)strtod( ord, &stopstring ); if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); ord = stopstring + 1; if ( (stopstring[0] == ',') || (stopstring[0] == ']')) { if ( var_types->data.ptr[b1] == CV_VAR_CATEGORICAL) - CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); + CV_ERROR( cv::Error::StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); var_types->data.ptr[b1] = CV_VAR_ORDERED; set_var_type_count++; } @@ -477,39 +477,39 @@ void CvMLData::set_var_types( const char* str ) { int b2 = (int)strtod( ord, &stopstring); if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); ord = stopstring + 1; for (int i = b1; i <= b2; i++) { if ( var_types->data.ptr[i] == CV_VAR_CATEGORICAL) - CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); + CV_ERROR( cv::Error::StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); var_types->data.ptr[i] = CV_VAR_ORDERED; } set_var_type_count += b2 - b1 + 1; } else - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); } } while (*stopstring != ']'); if ( stopstring[1] != '\0' && stopstring[1] != ',') - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); } if ( cat ) // parse cat str { char* stopstring = NULL; if ( cat[3] != '[') - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); cat += 4; // pass "cat[" do { int b1 = (int)strtod( cat, &stopstring ); if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); cat = stopstring + 1; if ( (stopstring[0] == ',') || (stopstring[0] == ']')) { @@ -522,25 +522,25 @@ void CvMLData::set_var_types( const char* str ) { int b2 = (int)strtod( cat, &stopstring); if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') ) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); cat = stopstring + 1; for (int i = b1; i <= b2; i++) var_types->data.ptr[i] = CV_VAR_CATEGORICAL; set_var_type_count += b2 - b1 + 1; } else - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); } } while (*stopstring != ']'); if ( stopstring[1] != '\0' && stopstring[1] != ',') - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); } if (set_var_type_count != var_count) - CV_ERROR( CV_StsBadArg, "types string is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "types string is not correct" ); __END__; } @@ -553,7 +553,7 @@ const CvMat* CvMLData::get_var_types() uchar *var_types_out_ptr = 0; int avcount, vt_size; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); assert( var_idx_mask ); @@ -597,7 +597,7 @@ const CvMat* CvMLData::get_responses() int var_count = 0; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); var_count = values->cols; if ( response_idx < 0 || response_idx >= var_count ) @@ -621,7 +621,7 @@ void CvMLData::set_train_test_split( const CvTrainTestSplit * spl) int sample_count = 0; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); sample_count = values->rows; @@ -631,14 +631,14 @@ void CvMLData::set_train_test_split( const CvTrainTestSplit * spl) { train_sample_count = spl->train_sample_part.count; if (train_sample_count > sample_count) - CV_ERROR( CV_StsBadArg, "train samples count is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "train samples count is not correct" ); train_sample_count = train_sample_count<=0 ? sample_count : train_sample_count; } else // dtype.train_sample_part_mode == CV_PORTION { train_sample_portion = spl->train_sample_part.portion; if ( train_sample_portion > 1) - CV_ERROR( CV_StsBadArg, "train samples count is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "train samples count is not correct" ); train_sample_portion = train_sample_portion <= FLT_EPSILON || 1 - train_sample_portion <= FLT_EPSILON ? 1 : train_sample_portion; train_sample_count = std::max(1, cvFloor( train_sample_portion * sample_count )); @@ -680,7 +680,7 @@ const CvMat* CvMLData::get_train_sample_idx() const __BEGIN__; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); __END__; return train_sample_idx; @@ -692,7 +692,7 @@ const CvMat* CvMLData::get_test_sample_idx() const __BEGIN__; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); __END__; return test_sample_idx; @@ -704,7 +704,7 @@ void CvMLData::mix_train_and_test_idx() __BEGIN__; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); __END__; if ( !sample_idx) @@ -731,7 +731,7 @@ const CvMat* CvMLData::get_var_idx() int avcount = 0; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); assert( var_idx_mask ); @@ -776,12 +776,12 @@ void CvMLData::change_var_idx( int vi, bool state ) int var_count = 0; if ( !values ) - CV_ERROR( CV_StsInternal, "data is empty" ); + CV_ERROR( cv::Error::StsInternal, "data is empty" ); var_count = values->cols; if ( vi < 0 || vi >= var_count) - CV_ERROR( CV_StsBadArg, "variable index is not correct" ); + CV_ERROR( cv::Error::StsBadArg, "variable index is not correct" ); assert( var_idx_mask ); var_idx_mask->data.ptr[vi] = state; diff --git a/apps/traincascade/old_ml_inner_functions.cpp b/apps/traincascade/old_ml_inner_functions.cpp index ef81da3548..719674f4be 100644 --- a/apps/traincascade/old_ml_inner_functions.cpp +++ b/apps/traincascade/old_ml_inner_functions.cpp @@ -67,7 +67,7 @@ void CvStatModel::save( const char* filename, const char* name ) const __BEGIN__; if( !fs.open( filename, cv::FileStorage::WRITE )) - CV_ERROR( CV_StsError, "Could not open the file storage. Check the path and permissions" ); + CV_ERROR( cv::Error::StsError, "Could not open the file storage. Check the path and permissions" ); write( fs, name ? name : default_model_name ); @@ -87,7 +87,7 @@ void CvStatModel::load( const char* filename, const char* name ) cv::FileNode model_node; if( !fs.open(filename, cv::FileStorage::READ) ) - CV_ERROR( CV_StsError, "Could not open the file storage. Check the path and permissions" ); + CV_ERROR( cv::Error::StsError, "Could not open the file storage. Check the path and permissions" ); if( name ) model_node = fs[ name ]; @@ -107,12 +107,12 @@ void CvStatModel::load( const char* filename, const char* name ) void CvStatModel::write( cv::FileStorage&, const char* ) const { - OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::write", "" ); + OPENCV_ERROR( cv::Error::StsNotImplemented, "CvStatModel::write", "" ); } void CvStatModel::read( const cv::FileNode& ) { - OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::read", "" ); + OPENCV_ERROR( cv::Error::StsNotImplemented, "CvStatModel::read", "" ); } CvMat* icvGenerateRandomClusterCenters ( int seed, const CvMat* data, @@ -134,7 +134,7 @@ CvMat* icvGenerateRandomClusterCenters ( int seed, const CvMat* data, { if( _centers && !ICV_IS_MAT_OF_TYPE (_centers, CV_32FC1) ) { - CV_ERROR(CV_StsBadArg,""); + CV_ERROR(cv::Error::StsBadArg,""); } else if( !_centers ) CV_CALL(centers = cvCreateMat (num_of_clusters, dim, CV_32FC1)); @@ -143,16 +143,16 @@ CvMat* icvGenerateRandomClusterCenters ( int seed, const CvMat* data, { if( _centers && !ICV_IS_MAT_OF_TYPE (_centers, CV_64FC1) ) { - CV_ERROR(CV_StsBadArg,""); + CV_ERROR(cv::Error::StsBadArg,""); } else if( !_centers ) CV_CALL(centers = cvCreateMat (num_of_clusters, dim, CV_64FC1)); } else - CV_ERROR (CV_StsBadArg,""); + CV_ERROR (cv::Error::StsBadArg,""); if( num_of_clusters < 1 ) - CV_ERROR (CV_StsBadArg,""); + CV_ERROR (cv::Error::StsBadArg,""); rng = cvRNG(seed); for (i = 0; i < dim; i++) @@ -208,10 +208,10 @@ cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_ int* dsti; if( !CV_IS_MAT(idx_arr) ) - CV_ERROR( CV_StsBadArg, "Invalid index array" ); + CV_ERROR( cv::Error::StsBadArg, "Invalid index array" ); if( idx_arr->rows != 1 && idx_arr->cols != 1 ) - CV_ERROR( CV_StsBadSize, "the index array must be 1-dimensional" ); + CV_ERROR( cv::Error::StsBadSize, "the index array must be 1-dimensional" ); idx_total = idx_arr->rows + idx_arr->cols - 1; srcb = idx_arr->data.ptr; @@ -227,20 +227,20 @@ cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_ // idx_arr is array of 1's and 0's - // i.e. it is a mask of the selected components if( idx_total != data_arr_size ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "Component mask should contain as many elements as the total number of input variables" ); for( i = 0; i < idx_total; i++ ) idx_selected += srcb[i*step] != 0; if( idx_selected == 0 ) - CV_ERROR( CV_StsOutOfRange, "No components/input_variables is selected!" ); + CV_ERROR( cv::Error::StsOutOfRange, "No components/input_variables is selected!" ); break; case CV_32SC1: // idx_arr is array of integer indices of selected components if( idx_total > data_arr_size ) - CV_ERROR( CV_StsOutOfRange, + CV_ERROR( cv::Error::StsOutOfRange, "index array may not contain more elements than the total number of input variables" ); idx_selected = idx_total; // check if sorted already @@ -256,7 +256,7 @@ cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_ } break; default: - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported index array data type " + CV_ERROR( cv::Error::StsUnsupportedFormat, "Unsupported index array data type " "(it should be 8uC1, 8sC1 or 32sC1)" ); } @@ -278,13 +278,13 @@ cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_ qsort( dsti, idx_total, sizeof(dsti[0]), icvCmpIntegers ); if( dsti[0] < 0 || dsti[idx_total-1] >= data_arr_size ) - CV_ERROR( CV_StsOutOfRange, "the index array elements are out of range" ); + CV_ERROR( cv::Error::StsOutOfRange, "the index array elements are out of range" ); if( check_for_duplicates ) { for( i = 1; i < idx_total; i++ ) if( dsti[i] <= dsti[i-1] ) - CV_ERROR( CV_StsBadArg, "There are duplicated index array elements" ); + CV_ERROR( cv::Error::StsBadArg, "There are duplicated index array elements" ); } } @@ -315,19 +315,19 @@ cvPreprocessVarType( const CvMat* var_type, const CvMat* var_idx, uchar* dst; if( !CV_IS_MAT(var_type) ) - CV_ERROR( var_type ? CV_StsBadArg : CV_StsNullPtr, "Invalid or absent var_type array" ); + CV_ERROR( var_type ? cv::Error::StsBadArg : cv::Error::StsNullPtr, "Invalid or absent var_type array" ); if( var_type->rows != 1 && var_type->cols != 1 ) - CV_ERROR( CV_StsBadSize, "var_type array must be 1-dimensional" ); + CV_ERROR( cv::Error::StsBadSize, "var_type array must be 1-dimensional" ); if( !CV_IS_MASK_ARR(var_type)) - CV_ERROR( CV_StsUnsupportedFormat, "type mask must be 8uC1 or 8sC1 array" ); + CV_ERROR( cv::Error::StsUnsupportedFormat, "type mask must be 8uC1 or 8sC1 array" ); tm_size = var_type->rows + var_type->cols - 1; tm_step = var_type->rows == 1 ? 1 : var_type->step/CV_ELEM_SIZE(var_type->type); if( /*tm_size != var_count &&*/ tm_size != var_count + 1 ) - CV_ERROR( CV_StsBadArg, + CV_ERROR( cv::Error::StsBadArg, "type mask must be of + 1 size" ); if( response_type && tm_size > var_count ) @@ -337,9 +337,9 @@ cvPreprocessVarType( const CvMat* var_type, const CvMat* var_idx, { if( !CV_IS_MAT(var_idx) || CV_MAT_TYPE(var_idx->type) != CV_32SC1 || (var_idx->rows != 1 && var_idx->cols != 1) || !CV_IS_MAT_CONT(var_idx->type) ) - CV_ERROR( CV_StsBadArg, "var index array should be continuous 1-dimensional integer vector" ); + CV_ERROR( cv::Error::StsBadArg, "var index array should be continuous 1-dimensional integer vector" ); if( var_idx->rows + var_idx->cols - 1 > var_count ) - CV_ERROR( CV_StsBadSize, "var index array is too large" ); + CV_ERROR( cv::Error::StsBadSize, "var index array is too large" ); //map = var_idx->data.i; var_count = var_idx->rows + var_idx->cols - 1; } @@ -376,18 +376,18 @@ cvPreprocessOrderedResponses( const CvMat* responses, const CvMat* sample_idx, i int sample_count = sample_all; if( !CV_IS_MAT(responses) ) - CV_ERROR( CV_StsBadArg, "Invalid response array" ); + CV_ERROR( cv::Error::StsBadArg, "Invalid response array" ); if( responses->rows != 1 && responses->cols != 1 ) - CV_ERROR( CV_StsBadSize, "Response array must be 1-dimensional" ); + CV_ERROR( cv::Error::StsBadSize, "Response array must be 1-dimensional" ); if( responses->rows + responses->cols - 1 != sample_count ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "Response array must contain as many elements as the total number of samples" ); r_type = CV_MAT_TYPE(responses->type); if( r_type != CV_32FC1 && r_type != CV_32SC1 ) - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported response type" ); + CV_ERROR( cv::Error::StsUnsupportedFormat, "Unsupported response type" ); r_step = responses->step ? responses->step / CV_ELEM_SIZE(responses->type) : 1; @@ -401,9 +401,9 @@ cvPreprocessOrderedResponses( const CvMat* responses, const CvMat* sample_idx, i { if( !CV_IS_MAT(sample_idx) || CV_MAT_TYPE(sample_idx->type) != CV_32SC1 || (sample_idx->rows != 1 && sample_idx->cols != 1) || !CV_IS_MAT_CONT(sample_idx->type) ) - CV_ERROR( CV_StsBadArg, "sample index array should be continuous 1-dimensional integer vector" ); + CV_ERROR( cv::Error::StsBadArg, "sample index array should be continuous 1-dimensional integer vector" ); if( sample_idx->rows + sample_idx->cols - 1 > sample_count ) - CV_ERROR( CV_StsBadSize, "sample index array is too large" ); + CV_ERROR( cv::Error::StsBadSize, "sample index array is too large" ); map = sample_idx->data.i; sample_count = sample_idx->rows + sample_idx->cols - 1; } @@ -466,18 +466,18 @@ cvPreprocessCategoricalResponses( const CvMat* responses, int sample_count = sample_all; if( !CV_IS_MAT(responses) ) - CV_ERROR( CV_StsBadArg, "Invalid response array" ); + CV_ERROR( cv::Error::StsBadArg, "Invalid response array" ); if( responses->rows != 1 && responses->cols != 1 ) - CV_ERROR( CV_StsBadSize, "Response array must be 1-dimensional" ); + CV_ERROR( cv::Error::StsBadSize, "Response array must be 1-dimensional" ); if( responses->rows + responses->cols - 1 != sample_count ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "Response array must contain as many elements as the total number of samples" ); r_type = CV_MAT_TYPE(responses->type); if( r_type != CV_32FC1 && r_type != CV_32SC1 ) - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported response type" ); + CV_ERROR( cv::Error::StsUnsupportedFormat, "Unsupported response type" ); r_step = responses->rows == 1 ? 1 : responses->step / CV_ELEM_SIZE(responses->type); @@ -485,9 +485,9 @@ cvPreprocessCategoricalResponses( const CvMat* responses, { if( !CV_IS_MAT(sample_idx) || CV_MAT_TYPE(sample_idx->type) != CV_32SC1 || (sample_idx->rows != 1 && sample_idx->cols != 1) || !CV_IS_MAT_CONT(sample_idx->type) ) - CV_ERROR( CV_StsBadArg, "sample index array should be continuous 1-dimensional integer vector" ); + CV_ERROR( cv::Error::StsBadArg, "sample index array should be continuous 1-dimensional integer vector" ); if( sample_idx->rows + sample_idx->cols - 1 > sample_count ) - CV_ERROR( CV_StsBadSize, "sample index array is too large" ); + CV_ERROR( cv::Error::StsBadSize, "sample index array is too large" ); map = sample_idx->data.i; sample_count = sample_idx->rows + sample_idx->cols - 1; } @@ -495,7 +495,7 @@ cvPreprocessCategoricalResponses( const CvMat* responses, CV_CALL( out_responses = cvCreateMat( 1, sample_count, CV_32SC1 )); if( !out_response_map ) - CV_ERROR( CV_StsNullPtr, "out_response_map pointer is NULL" ); + CV_ERROR( cv::Error::StsNullPtr, "out_response_map pointer is NULL" ); CV_CALL( response_ptr = (int**)cvAlloc( sample_count*sizeof(response_ptr[0]))); @@ -517,7 +517,7 @@ cvPreprocessCategoricalResponses( const CvMat* responses, { char buf[100]; snprintf( buf, sizeof(buf), "response #%d is not integral", idx ); - CV_ERROR( CV_StsBadArg, buf ); + CV_ERROR( cv::Error::StsBadArg, buf ); } dst[i] = ri; } @@ -531,7 +531,7 @@ cvPreprocessCategoricalResponses( const CvMat* responses, cls_count += *response_ptr[i] != *response_ptr[i-1]; if( cls_count < 2 ) - CV_ERROR( CV_StsBadArg, "There is only a single class" ); + CV_ERROR( cv::Error::StsBadArg, "There is only a single class" ); CV_CALL( *out_response_map = cvCreateMat( 1, cls_count, CV_32SC1 )); @@ -588,7 +588,7 @@ cvGetTrainSamples( const CvMat* train_data, int tflag, const int *s_idx, *v_idx; if( !CV_IS_MAT(train_data) ) - CV_ERROR( CV_StsBadArg, "Invalid or NULL training data matrix" ); + CV_ERROR( cv::Error::StsBadArg, "Invalid or NULL training data matrix" ); var_count = var_idx ? var_idx->cols + var_idx->rows - 1 : tflag == CV_ROW_SAMPLE ? train_data->cols : train_data->rows; @@ -659,18 +659,18 @@ cvCheckTrainData( const CvMat* train_data, int tflag, // check parameter types and sizes if( !CV_IS_MAT(train_data) || CV_MAT_TYPE(train_data->type) != CV_32FC1 ) - CV_ERROR( CV_StsBadArg, "train data must be floating-point matrix" ); + CV_ERROR( cv::Error::StsBadArg, "train data must be floating-point matrix" ); if( missing_mask ) { if( !CV_IS_MAT(missing_mask) || !CV_IS_MASK_ARR(missing_mask) || !CV_ARE_SIZES_EQ(train_data, missing_mask) ) - CV_ERROR( CV_StsBadArg, + CV_ERROR( cv::Error::StsBadArg, "missing value mask must be 8-bit matrix of the same size as training data" ); } if( tflag != CV_ROW_SAMPLE && tflag != CV_COL_SAMPLE ) - CV_ERROR( CV_StsBadArg, + CV_ERROR( cv::Error::StsBadArg, "Unknown training data layout (must be CV_ROW_SAMPLE or CV_COL_SAMPLE)" ); if( var_all ) @@ -736,7 +736,7 @@ cvPrepareTrainData( const char* /*funcname*/, __BEGIN__; if( !out_train_samples ) - CV_ERROR( CV_StsBadArg, "output pointer to train samples is NULL" ); + CV_ERROR( cv::Error::StsBadArg, "output pointer to train samples is NULL" ); CV_CALL( cvCheckTrainData( train_data, tflag, 0, &var_all, &sample_all )); @@ -748,7 +748,7 @@ cvPrepareTrainData( const char* /*funcname*/, if( responses ) { if( !out_responses ) - CV_ERROR( CV_StsNullPtr, "output response pointer is NULL" ); + CV_ERROR( cv::Error::StsNullPtr, "output response pointer is NULL" ); if( response_type == CV_VAR_NUMERICAL ) { @@ -841,10 +841,10 @@ cvSortSamplesByClasses( const float** samples, const CvMat* classes, int i, k = 0, sample_count; if( !samples || !classes || !class_ranges ) - CV_ERROR( CV_StsNullPtr, "INTERNAL ERROR: some of the args are NULL pointers" ); + CV_ERROR( cv::Error::StsNullPtr, "INTERNAL ERROR: some of the args are NULL pointers" ); if( classes->rows != 1 || CV_MAT_TYPE(classes->type) != CV_32SC1 ) - CV_ERROR( CV_StsBadArg, "classes array must be a single row of integers" ); + CV_ERROR( cv::Error::StsBadArg, "classes array must be a single row of integers" ); sample_count = classes->cols; CV_CALL( pairs = (CvSampleResponsePair*)cvAlloc( (sample_count+1)*sizeof(pairs[0]))); @@ -901,45 +901,45 @@ cvPreparePredictData( const CvArr* _sample, int dims_all, int vec_size; if( !is_sparse && !CV_IS_MAT(sample) ) - CV_ERROR( !sample ? CV_StsNullPtr : CV_StsBadArg, "The sample is not a valid vector" ); + CV_ERROR( !sample ? cv::Error::StsNullPtr : cv::Error::StsBadArg, "The sample is not a valid vector" ); if( cvGetElemType( sample ) != CV_32FC1 ) - CV_ERROR( CV_StsUnsupportedFormat, "Input sample must have 32fC1 type" ); + CV_ERROR( cv::Error::StsUnsupportedFormat, "Input sample must have 32fC1 type" ); CV_CALL( d = cvGetDims( sample, sizes )); if( !((is_sparse && d == 1) || (!is_sparse && d == 2 && (sample->rows == 1 || sample->cols == 1))) ) - CV_ERROR( CV_StsBadSize, "Input sample must be 1-dimensional vector" ); + CV_ERROR( cv::Error::StsBadSize, "Input sample must be 1-dimensional vector" ); if( d == 1 ) sizes[1] = 1; if( sizes[0] + sizes[1] - 1 != dims_all ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "The sample size is different from what has been used for training" ); if( !_row_sample ) - CV_ERROR( CV_StsNullPtr, "INTERNAL ERROR: The row_sample pointer is NULL" ); + CV_ERROR( cv::Error::StsNullPtr, "INTERNAL ERROR: The row_sample pointer is NULL" ); if( comp_idx && (!CV_IS_MAT(comp_idx) || comp_idx->rows != 1 || CV_MAT_TYPE(comp_idx->type) != CV_32SC1) ) - CV_ERROR( CV_StsBadArg, "INTERNAL ERROR: invalid comp_idx" ); + CV_ERROR( cv::Error::StsBadArg, "INTERNAL ERROR: invalid comp_idx" ); dims_selected = comp_idx ? comp_idx->cols : dims_all; if( prob ) { if( !CV_IS_MAT(prob) ) - CV_ERROR( CV_StsBadArg, "The output matrix of probabilities is invalid" ); + CV_ERROR( cv::Error::StsBadArg, "The output matrix of probabilities is invalid" ); if( (prob->rows != 1 && prob->cols != 1) || (CV_MAT_TYPE(prob->type) != CV_32FC1 && CV_MAT_TYPE(prob->type) != CV_64FC1) ) - CV_ERROR( CV_StsBadSize, + CV_ERROR( cv::Error::StsBadSize, "The matrix of probabilities must be 1-dimensional vector of 32fC1 type" ); if( prob->rows + prob->cols - 1 != class_count ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "The vector of probabilities must contain as many elements as " "the number of classes in the training set" ); } @@ -1071,7 +1071,7 @@ icvConvertDataToSparse( const uchar* src, int src_step, int src_type, dst_type = CV_MAT_TYPE(dst_type); if( CV_MAT_CN(src_type) != 1 || CV_MAT_CN(dst_type) != 1 ) - CV_ERROR( CV_StsUnsupportedFormat, "The function supports only single-channel arrays" ); + CV_ERROR( cv::Error::StsUnsupportedFormat, "The function supports only single-channel arrays" ); if( src_step == 0 ) src_step = CV_ELEM_SIZE(src_type); @@ -1134,7 +1134,7 @@ icvConvertDataToSparse( const uchar* src, int src_step, int src_type, ((float*)_dst)[j] = (float)((double*)src)[j]; } else - CV_ERROR( CV_StsUnsupportedFormat, "Unsupported combination of input and output vectors" ); + CV_ERROR( cv::Error::StsUnsupportedFormat, "Unsupported combination of input and output vectors" ); __END__; } @@ -1154,15 +1154,15 @@ cvWritebackLabels( const CvMat* labels, CvMat* dst_labels, int samples_selected = samples_all, dims_selected = dims_all; if( dst_labels && !CV_IS_MAT(dst_labels) ) - CV_ERROR( CV_StsBadArg, "Array of output labels is not a valid matrix" ); + CV_ERROR( cv::Error::StsBadArg, "Array of output labels is not a valid matrix" ); if( dst_centers ) if( !ICV_IS_MAT_OF_TYPE(dst_centers, CV_32FC1) && !ICV_IS_MAT_OF_TYPE(dst_centers, CV_64FC1) ) - CV_ERROR( CV_StsBadArg, "Array of cluster centers is not a valid matrix" ); + CV_ERROR( cv::Error::StsBadArg, "Array of cluster centers is not a valid matrix" ); if( dst_probs && !CV_IS_MAT(dst_probs) ) - CV_ERROR( CV_StsBadArg, "Probability matrix is not valid" ); + CV_ERROR( cv::Error::StsBadArg, "Probability matrix is not valid" ); if( sample_idx ) { @@ -1179,15 +1179,15 @@ cvWritebackLabels( const CvMat* labels, CvMat* dst_labels, if( dst_labels && (!labels || labels->data.ptr != dst_labels->data.ptr) ) { if( !labels ) - CV_ERROR( CV_StsNullPtr, "NULL labels" ); + CV_ERROR( cv::Error::StsNullPtr, "NULL labels" ); CV_ASSERT( labels->rows == 1 ); if( dst_labels->rows != 1 && dst_labels->cols != 1 ) - CV_ERROR( CV_StsBadSize, "Array of output labels should be 1d vector" ); + CV_ERROR( cv::Error::StsBadSize, "Array of output labels should be 1d vector" ); if( dst_labels->rows + dst_labels->cols - 1 != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "Size of vector of output labels is not equal to the total number of input samples" ); CV_ASSERT( labels->cols == samples_selected ); @@ -1202,13 +1202,13 @@ cvWritebackLabels( const CvMat* labels, CvMat* dst_labels, int i; if( !centers ) - CV_ERROR( CV_StsNullPtr, "NULL centers" ); + CV_ERROR( cv::Error::StsNullPtr, "NULL centers" ); if( centers->rows != dst_centers->rows ) - CV_ERROR( CV_StsUnmatchedSizes, "Invalid number of rows in matrix of output centers" ); + CV_ERROR( cv::Error::StsUnmatchedSizes, "Invalid number of rows in matrix of output centers" ); if( dst_centers->cols != dims_all ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "Number of columns in matrix of output centers is " "not equal to the total number of components in the input samples" ); @@ -1223,13 +1223,13 @@ cvWritebackLabels( const CvMat* labels, CvMat* dst_labels, if( dst_probs && (!probs || probs->data.ptr != dst_probs->data.ptr) ) { if( !probs ) - CV_ERROR( CV_StsNullPtr, "NULL probs" ); + CV_ERROR( cv::Error::StsNullPtr, "NULL probs" ); if( probs->cols != dst_probs->cols ) - CV_ERROR( CV_StsUnmatchedSizes, "Invalid number of columns in output probability matrix" ); + CV_ERROR( cv::Error::StsUnmatchedSizes, "Invalid number of columns in output probability matrix" ); if( dst_probs->rows != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "Number of rows in output probability matrix is " "not equal to the total number of input samples" ); @@ -1273,29 +1273,29 @@ cvStatModelMultiPredict( const CvStatModel* stat_model, CvMat* probs1 = probs ? &probs_part : 0; if( !CV_IS_STAT_MODEL(stat_model) ) - CV_ERROR( !stat_model ? CV_StsNullPtr : CV_StsBadArg, "Invalid statistical model" ); + CV_ERROR( !stat_model ? cv::Error::StsNullPtr : cv::Error::StsBadArg, "Invalid statistical model" ); if( !stat_model->predict ) - CV_ERROR( CV_StsNotImplemented, "There is no \"predict\" method" ); + CV_ERROR( cv::Error::StsNotImplemented, "There is no \"predict\" method" ); if( !predict_input || !predict_output ) - CV_ERROR( CV_StsNullPtr, "NULL input or output matrices" ); + CV_ERROR( cv::Error::StsNullPtr, "NULL input or output matrices" ); if( !is_sparse && !CV_IS_MAT(predict_input) ) - CV_ERROR( CV_StsBadArg, "predict_input should be a matrix or a sparse matrix" ); + CV_ERROR( cv::Error::StsBadArg, "predict_input should be a matrix or a sparse matrix" ); if( !CV_IS_MAT(predict_output) ) - CV_ERROR( CV_StsBadArg, "predict_output should be a matrix" ); + CV_ERROR( cv::Error::StsBadArg, "predict_output should be a matrix" ); type = cvGetElemType( predict_input ); if( type != CV_32FC1 || (CV_MAT_TYPE(predict_output->type) != CV_32FC1 && CV_MAT_TYPE(predict_output->type) != CV_32SC1 )) - CV_ERROR( CV_StsUnsupportedFormat, "The input or output matrix has unsupported format" ); + CV_ERROR( cv::Error::StsUnsupportedFormat, "The input or output matrix has unsupported format" ); CV_CALL( d = cvGetDims( predict_input, sizes )); if( d > 2 ) - CV_ERROR( CV_StsBadSize, "The input matrix should be 1- or 2-dimensional" ); + CV_ERROR( cv::Error::StsBadSize, "The input matrix should be 1- or 2-dimensional" ); if( !tflag ) { @@ -1311,30 +1311,30 @@ cvStatModelMultiPredict( const CvStatModel* stat_model, if( sample_idx ) { if( !CV_IS_MAT(sample_idx) ) - CV_ERROR( CV_StsBadArg, "Invalid sample_idx matrix" ); + CV_ERROR( cv::Error::StsBadArg, "Invalid sample_idx matrix" ); if( sample_idx->cols != 1 && sample_idx->rows != 1 ) - CV_ERROR( CV_StsBadSize, "sample_idx must be 1-dimensional matrix" ); + CV_ERROR( cv::Error::StsBadSize, "sample_idx must be 1-dimensional matrix" ); samples_selected = sample_idx->rows + sample_idx->cols - 1; if( CV_MAT_TYPE(sample_idx->type) == CV_32SC1 ) { if( samples_selected > samples_all ) - CV_ERROR( CV_StsBadSize, "sample_idx is too large vector" ); + CV_ERROR( cv::Error::StsBadSize, "sample_idx is too large vector" ); } else if( samples_selected != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, "sample_idx has incorrect size" ); + CV_ERROR( cv::Error::StsUnmatchedSizes, "sample_idx has incorrect size" ); sample_idx_step = sample_idx->step ? sample_idx->step / CV_ELEM_SIZE(sample_idx->type) : 1; } if( predict_output->rows != 1 && predict_output->cols != 1 ) - CV_ERROR( CV_StsBadSize, "predict_output should be a 1-dimensional matrix" ); + CV_ERROR( cv::Error::StsBadSize, "predict_output should be a 1-dimensional matrix" ); if( predict_output->rows + predict_output->cols - 1 != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, "predict_output and predict_input have uncoordinated sizes" ); + CV_ERROR( cv::Error::StsUnmatchedSizes, "predict_output and predict_input have uncoordinated sizes" ); predict_output_step = predict_output->step ? predict_output->step / CV_ELEM_SIZE(predict_output->type) : 1; @@ -1342,14 +1342,14 @@ cvStatModelMultiPredict( const CvStatModel* stat_model, if( probs ) { if( !CV_IS_MAT(probs) ) - CV_ERROR( CV_StsBadArg, "Invalid matrix of probabilities" ); + CV_ERROR( cv::Error::StsBadArg, "Invalid matrix of probabilities" ); if( probs->rows != samples_all ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "matrix of probabilities must have as many rows as the total number of samples" ); if( CV_MAT_TYPE(probs->type) != CV_32FC1 ) - CV_ERROR( CV_StsUnsupportedFormat, "matrix of probabilities must have 32fC1 type" ); + CV_ERROR( cv::Error::StsUnsupportedFormat, "matrix of probabilities must have 32fC1 type" ); } if( is_sparse ) @@ -1414,7 +1414,7 @@ cvStatModelMultiPredict( const CvStatModel* stat_model, { idx = sample_idx->data.i[i*sample_idx_step]; if( (unsigned)idx >= (unsigned)samples_all ) - CV_ERROR( CV_StsOutOfRange, "Some of sample_idx elements are out of range" ); + CV_ERROR( cv::Error::StsOutOfRange, "Some of sample_idx elements are out of range" ); } else if( CV_MAT_TYPE(sample_idx->type) == CV_8UC1 && sample_idx->data.ptr[i*sample_idx_step] == 0 ) @@ -1494,7 +1494,7 @@ void cvCombineResponseMaps (CvMat* _responses, (!ICV_IS_MAT_OF_TYPE (old_response_map, CV_32SC1)) || (!ICV_IS_MAT_OF_TYPE (new_response_map, CV_32SC1))) { - CV_ERROR (CV_StsBadArg, "Some of input arguments is not the CvMat") + CV_ERROR (cv::Error::StsBadArg, "Some of input arguments is not the CvMat") } // Prepare sorted responses. diff --git a/apps/traincascade/old_ml_precomp.hpp b/apps/traincascade/old_ml_precomp.hpp index 6702e5b59f..592739c65d 100644 --- a/apps/traincascade/old_ml_precomp.hpp +++ b/apps/traincascade/old_ml_precomp.hpp @@ -70,7 +70,7 @@ /* Convert matrix to vector */ #define ICV_MAT2VEC( mat, vdata, vstep, num ) \ if( MIN( (mat).rows, (mat).cols ) != 1 ) \ - CV_ERROR( CV_StsBadArg, "" ); \ + CV_ERROR( cv::Error::StsBadArg, "" ); \ (vdata) = ((mat).data.ptr); \ if( (mat).rows == 1 ) \ { \ @@ -142,7 +142,7 @@ #define ICV_TRAIN_DATA_REQUIRED( param, flags ) \ if( !ICV_IS_MAT_OF_TYPE( (param), CV_32FC1 ) ) \ { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ + CV_ERROR( cv::Error::StsBadArg, "Invalid " #param " parameter" ); \ } \ else \ { \ @@ -154,21 +154,21 @@ #define ICV_TRAIN_CLASSES_REQUIRED( param ) \ if( !ICV_IS_MAT_OF_TYPE( (param), CV_32FC1 ) ) \ { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ + CV_ERROR( cv::Error::StsBadArg, "Invalid " #param " parameter" ); \ } \ else \ { \ ICV_MAT2VEC( *(param), classes, clstep, ncl ); \ if( m != ncl ) \ { \ - CV_ERROR( CV_StsBadArg, "Unmatched sizes" ); \ + CV_ERROR( cv::Error::StsBadArg, "Unmatched sizes" ); \ } \ } #define ICV_ARG_NULL( param ) \ if( (param) != NULL ) \ { \ - CV_ERROR( CV_StsBadArg, #param " parameter must be NULL" ); \ + CV_ERROR( cv::Error::StsBadArg, #param " parameter must be NULL" ); \ } #define ICV_MISSED_MEASUREMENTS_OPTIONAL( param, flags ) \ @@ -176,14 +176,14 @@ { \ if( !ICV_IS_MAT_OF_TYPE( param, CV_8UC1 ) ) \ { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ + CV_ERROR( cv::Error::StsBadArg, "Invalid " #param " parameter" ); \ } \ else \ { \ ICV_RAWDATA( *(param), (flags), missed, msstep, mcstep, mm, mn ); \ if( mm != m || mn != n ) \ { \ - CV_ERROR( CV_StsBadArg, "Unmatched sizes" ); \ + CV_ERROR( cv::Error::StsBadArg, "Unmatched sizes" ); \ } \ } \ } @@ -193,13 +193,13 @@ { \ if( !ICV_IS_MAT_OF_TYPE( param, CV_32SC1 ) ) \ { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ + CV_ERROR( cv::Error::StsBadArg, "Invalid " #param " parameter" ); \ } \ else \ { \ ICV_MAT2VEC( *(param), cidx, cistep, k ); \ if( k > n ) \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ + CV_ERROR( cv::Error::StsBadArg, "Invalid " #param " parameter" ); \ } \ } @@ -208,13 +208,13 @@ { \ if( !ICV_IS_MAT_OF_TYPE( param, CV_32SC1 ) ) \ { \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ + CV_ERROR( cv::Error::StsBadArg, "Invalid " #param " parameter" ); \ } \ else \ { \ ICV_MAT2VEC( *sampleIdx, sidx, sistep, l ); \ if( l > m ) \ - CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \ + CV_ERROR( cv::Error::StsBadArg, "Invalid " #param " parameter" ); \ } \ } diff --git a/apps/traincascade/old_ml_tree.cpp b/apps/traincascade/old_ml_tree.cpp index 55052ed532..7085debd89 100644 --- a/apps/traincascade/old_ml_tree.cpp +++ b/apps/traincascade/old_ml_tree.cpp @@ -93,17 +93,17 @@ bool CvDTreeTrainData::set_params( const CvDTreeParams& _params ) params = _params; if( params.max_categories < 2 ) - CV_ERROR( CV_StsOutOfRange, "params.max_categories should be >= 2" ); + CV_ERROR( cv::Error::StsOutOfRange, "params.max_categories should be >= 2" ); params.max_categories = MIN( params.max_categories, 15 ); if( params.max_depth < 0 ) - CV_ERROR( CV_StsOutOfRange, "params.max_depth should be >= 0" ); + CV_ERROR( cv::Error::StsOutOfRange, "params.max_depth should be >= 0" ); params.max_depth = MIN( params.max_depth, 25 ); params.min_sample_count = MAX(params.min_sample_count,1); if( params.cv_folds < 0 ) - CV_ERROR( CV_StsOutOfRange, + CV_ERROR( cv::Error::StsOutOfRange, "params.cv_folds should be =0 (the tree is not pruned) " "or n>0 (tree is pruned using n-fold cross-validation)" ); @@ -111,7 +111,7 @@ bool CvDTreeTrainData::set_params( const CvDTreeParams& _params ) params.cv_folds = 0; if( params.regression_accuracy < 0 ) - CV_ERROR( CV_StsOutOfRange, "params.regression_accuracy should be >= 0" ); + CV_ERROR( cv::Error::StsOutOfRange, "params.regression_accuracy should be >= 0" ); ok = true; @@ -183,7 +183,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, cvNorm( data->var_type, var_type, CV_C ) < FLT_EPSILON && cvNorm( data->cat_count, cat_count, CV_C ) < FLT_EPSILON && cvNorm( data->cat_map, cat_map, CV_C ) < FLT_EPSILON) ) - CV_ERROR( CV_StsBadArg, + CV_ERROR( cv::Error::StsBadArg, "The new training data must have the same types and the input and output variables " "and the same categories for categorical variables" ); @@ -264,7 +264,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, CV_MAT_TYPE(_responses->type) != CV_32FC1) || (_responses->rows != 1 && _responses->cols != 1) || _responses->rows + _responses->cols - 1 != sample_all ) - CV_ERROR( CV_StsBadArg, "The array of _responses must be an integer or " + CV_ERROR( cv::Error::StsBadArg, "The array of _responses must be an integer or " "floating-point vector containing as many elements as " "the total number of samples in the training data matrix" ); @@ -317,7 +317,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if ((uint64)effective_buf_width * (uint64)effective_buf_height != effective_buf_size) { - CV_Error(CV_StsBadArg, "The memory buffer cannot be allocated since its size exceeds integer fields limit"); + CV_Error(cv::Error::StsBadArg, "The memory buffer cannot be allocated since its size exceeds integer fields limit"); } @@ -360,7 +360,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if( cv_n ) { if( sample_count < cv_n*MAX(params.min_sample_count,10) ) - CV_ERROR( CV_StsOutOfRange, + CV_ERROR( cv::Error::StsOutOfRange, "The many folds in cross-validation for such a small dataset" ); cv_size = cvAlign( cv_n*(sizeof(int) + sizeof(double)*2), sizeof(double) ); @@ -444,7 +444,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, { snprintf( err, sizeof(err), "%d-th value of %d-th (categorical) " "variable is not an integer", i, vi ); - CV_ERROR( CV_StsBadArg, err ); + CV_ERROR( cv::Error::StsBadArg, err ); } } @@ -452,7 +452,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, { snprintf( err, sizeof(err), "%d-th value of %d-th (categorical) " "variable is too large", i, vi ); - CV_ERROR( CV_StsBadArg, err ); + CV_ERROR( cv::Error::StsBadArg, err ); } num_valid++; } @@ -559,7 +559,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, { snprintf( err, sizeof(err), "%d-th value of %d-th (ordered) " "variable (=%g) is too large", i, vi, val ); - CV_ERROR( CV_StsBadArg, err ); + CV_ERROR( cv::Error::StsBadArg, err ); } num_valid++; } @@ -652,7 +652,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, { double val = have_priors ? params.priors[i] : 1.; if( val <= 0 ) - CV_ERROR( CV_StsOutOfRange, "Every class weight should be positive" ); + CV_ERROR( cv::Error::StsOutOfRange, "Every class weight should be positive" ); priors->data.db[i] = val; sum += val; } @@ -705,7 +705,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) __BEGIN__; if( !data_root ) - CV_ERROR( CV_StsError, "No training data has been set" ); + CV_ERROR( cv::Error::StsError, "No training data has been set" ); if( _subsample_idx ) { @@ -1396,7 +1396,7 @@ void CvDTreeTrainData::read_params( const cv::FileNode& node ) auto tmat = cvMat( tparams_node[ "priors" ].mat() ); priors = cvCloneMat( &tmat ); if( !CV_IS_MAT(priors) ) - CV_ERROR( CV_StsParseError, "priors must stored as a matrix" ); + CV_ERROR( cv::Error::StsParseError, "priors must stored as a matrix" ); priors_mult = cvCloneMat( priors ); } } @@ -1413,12 +1413,12 @@ void CvDTreeTrainData::read_params( const cv::FileNode& node ) (var_idx->cols != 1 && var_idx->rows != 1) || var_idx->cols + var_idx->rows - 1 != var_count || CV_MAT_TYPE(var_idx->type) != CV_32SC1 ) - CV_ERROR( CV_StsParseError, + CV_ERROR( cv::Error::StsParseError, "var_idx (if exist) must be valid 1d integer vector containing elements" ); for( vi = 0; vi < var_count; vi++ ) if( (unsigned)var_idx->data.i[vi] >= (unsigned)var_all ) - CV_ERROR( CV_StsOutOfRange, "some of var_idx elements are out of range" ); + CV_ERROR( cv::Error::StsOutOfRange, "some of var_idx elements are out of range" ); } ////// read var type @@ -1434,7 +1434,7 @@ void CvDTreeTrainData::read_params( const cv::FileNode& node ) { if( vartype_node.empty() || !vartype_node.isSeq() || vartype_node.size() != (size_t) var_count ) - CV_ERROR( CV_StsParseError, "var_type must exist and be a sequence of 0's and 1's" ); + CV_ERROR( cv::Error::StsParseError, "var_type must exist and be a sequence of 0's and 1's" ); reader = vartype_node.begin(); @@ -1442,7 +1442,7 @@ void CvDTreeTrainData::read_params( const cv::FileNode& node ) { cv::FileNode n = *reader; if( !n.isInt() || ((int) n & ~1) ) - CV_ERROR( CV_StsParseError, "var_type must exist and be a sequence of 0's and 1's" ); + CV_ERROR( cv::Error::StsParseError, "var_type must exist and be a sequence of 0's and 1's" ); var_type->data.i[vi] = (int) n ? cat_var_count++ : ord_var_count--; reader++; } @@ -1468,7 +1468,7 @@ void CvDTreeTrainData::read_params( const cv::FileNode& node ) cat_count->cols + cat_count->rows - 1 != cat_var_count + is_classifier || (cat_map->cols != 1 && cat_map->rows != 1) || CV_MAT_TYPE(cat_map->type) != CV_32SC1 ) - CV_ERROR( CV_StsParseError, + CV_ERROR( cv::Error::StsParseError, "Both cat_count and cat_map must exist and be valid 1d integer vectors of an appropriate size" ); ccount = cat_var_count + is_classifier; @@ -1481,13 +1481,13 @@ void CvDTreeTrainData::read_params( const cv::FileNode& node ) { int val = cat_count->data.i[vi]; if( val <= 0 ) - CV_ERROR( CV_StsOutOfRange, "some of cat_count elements are out of range" ); + CV_ERROR( cv::Error::StsOutOfRange, "some of cat_count elements are out of range" ); max_c_count = MAX( max_c_count, val ); cat_ofs->data.i[vi+1] = total_c_count += val; } if( cat_map->cols + cat_map->rows - 1 != total_c_count ) - CV_ERROR( CV_StsBadSize, + CV_ERROR( cv::Error::StsBadSize, "cat_map vector length is not equal to the total number of categories in all categorical vars" ); } @@ -3631,13 +3631,13 @@ CvDTreeNode* CvDTree::predict( const CvMat* _sample, CvDTreeNode* node = root; if( !node ) - CV_Error( CV_StsError, "The tree has not been trained yet" ); + CV_Error( cv::Error::StsError, "The tree has not been trained yet" ); if( !CV_IS_MAT(_sample) || CV_MAT_TYPE(_sample->type) != CV_32FC1 || (_sample->cols != 1 && _sample->rows != 1) || (_sample->cols + _sample->rows - 1 != data->var_all && !preprocessed_input) || (_sample->cols + _sample->rows - 1 != data->var_count && preprocessed_input) ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "the input sample must be 1d floating-point vector with the same " "number of elements as the total number of variables used for training" ); @@ -3656,7 +3656,7 @@ CvDTreeNode* CvDTree::predict( const CvMat* _sample, { if( !CV_IS_MAT(_missing) || !CV_IS_MASK_ARR(_missing) || !CV_ARE_SIZES_EQ(_missing, _sample) ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "the missing data mask must be 8-bit vector of the same size as input sample" ); m = _missing->data.ptr; mstep = CV_IS_MAT_CONT(_missing->type) ? 1 : _missing->step/sizeof(m[0]); @@ -3696,7 +3696,7 @@ CvDTreeNode* CvDTree::predict( const CvMat* _sample, int ival = cvRound(val); if( ival != val ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "one of input categorical variable is not an integer" ); while( a < b ) @@ -3936,11 +3936,11 @@ CvDTreeSplit* CvDTree::read_split( const cv::FileNode& fnode ) int vi, ci; if( fnode.empty() || !fnode.isMap() ) - CV_ERROR( CV_StsParseError, "some of the splits are not stored properly" ); + CV_ERROR( cv::Error::StsParseError, "some of the splits are not stored properly" ); vi = fnode[ "var" ].empty() ? -1 : (int) fnode[ "var" ]; if( (unsigned)vi >= (unsigned)data->var_count ) - CV_ERROR( CV_StsOutOfRange, "Split variable index is out of range" ); + CV_ERROR( cv::Error::StsOutOfRange, "Split variable index is out of range" ); ci = data->get_var_type(vi); if( ci >= 0 ) // split on categorical var @@ -3957,14 +3957,14 @@ CvDTreeSplit* CvDTree::read_split( const cv::FileNode& fnode ) } if( inseq.empty() || (!inseq.isSeq() && !inseq.isInt())) - CV_ERROR( CV_StsParseError, + CV_ERROR( cv::Error::StsParseError, "Either 'in' or 'not_in' tags should be inside a categorical split data" ); if( inseq.isInt() ) { val = (int) inseq; if( (unsigned)val >= (unsigned)n ) - CV_ERROR( CV_StsOutOfRange, "some of in/not_in elements are out of range" ); + CV_ERROR( cv::Error::StsOutOfRange, "some of in/not_in elements are out of range" ); split->subset[val >> 5] |= 1 << (val & 31); } @@ -3977,7 +3977,7 @@ CvDTreeSplit* CvDTree::read_split( const cv::FileNode& fnode ) cv::FileNode inode = *reader; val = (int) inode; if( !inode.isInt() || (unsigned)val >= (unsigned)n ) - CV_ERROR( CV_StsOutOfRange, "some of in/not_in elements are out of range" ); + CV_ERROR( cv::Error::StsOutOfRange, "some of in/not_in elements are out of range" ); split->subset[val >> 5] |= 1 << (val & 31); reader++; @@ -4025,12 +4025,12 @@ CvDTreeNode* CvDTree::read_node( const cv::FileNode& fnode, CvDTreeNode* parent int i, depth; if( fnode.empty() || !fnode.isMap() ) - CV_ERROR( CV_StsParseError, "some of the tree elements are not stored properly" ); + CV_ERROR( cv::Error::StsParseError, "some of the tree elements are not stored properly" ); CV_CALL( node = data->new_node( parent, 0, 0, 0 )); depth = fnode[ "depth" ].empty() ? -1 : (int) fnode[ "depth" ]; if( depth != node->depth ) - CV_ERROR( CV_StsParseError, "incorrect node depth" ); + CV_ERROR( cv::Error::StsParseError, "incorrect node depth" ); node->sample_count = (int) fnode[ "sample_count" ]; node->value = (double) fnode[ "value" ]; @@ -4051,7 +4051,7 @@ CvDTreeNode* CvDTree::read_node( const cv::FileNode& fnode, CvDTreeNode* parent CvDTreeSplit* last_split = 0; if( !splits.isSeq() ) - CV_ERROR( CV_StsParseError, "splits tag must stored as a sequence" ); + CV_ERROR( cv::Error::StsParseError, "splits tag must stored as a sequence" ); reader = splits.begin(); for( i = 0; i < (int) (*reader).size(); i++ ) @@ -4137,7 +4137,7 @@ void CvDTree::read( const cv::FileNode& node, CvDTreeTrainData* _data ) tree_nodes = node[ "nodes" ]; if( tree_nodes.empty() || !tree_nodes.isSeq() ) - CV_ERROR( CV_StsParseError, "nodes tag is missing" ); + CV_ERROR( cv::Error::StsParseError, "nodes tag is missing" ); pruned_tree_idx = node[ "best_tree_idx" ].empty() ? -1 : node[ "best_tree_idx" ]; read_tree_nodes( tree_nodes ); diff --git a/modules/calib3d/src/calibration.cpp b/modules/calib3d/src/calibration.cpp index d488e4569e..24d2875fdd 100644 --- a/modules/calib3d/src/calibration.cpp +++ b/modules/calib3d/src/calibration.cpp @@ -254,32 +254,32 @@ CV_IMPL int cvRodrigues2( const CvMat* src, CvMat* dst, CvMat* jacobian ) CvMat matJ = cvMat( 3, 9, CV_64F, J ); if( !CV_IS_MAT(src) ) - CV_Error( !src ? CV_StsNullPtr : CV_StsBadArg, "Input argument is not a valid matrix" ); + CV_Error( !src ? cv::Error::StsNullPtr : cv::Error::StsBadArg, "Input argument is not a valid matrix" ); if( !CV_IS_MAT(dst) ) - CV_Error( !dst ? CV_StsNullPtr : CV_StsBadArg, + CV_Error( !dst ? cv::Error::StsNullPtr : cv::Error::StsBadArg, "The first output argument is not a valid matrix" ); int depth = CV_MAT_DEPTH(src->type); int elem_size = CV_ELEM_SIZE(depth); if( depth != CV_32F && depth != CV_64F ) - CV_Error( CV_StsUnsupportedFormat, "The matrices must have 32f or 64f data type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The matrices must have 32f or 64f data type" ); if( !CV_ARE_DEPTHS_EQ(src, dst) ) - CV_Error( CV_StsUnmatchedFormats, "All the matrices must have the same data type" ); + CV_Error( cv::Error::StsUnmatchedFormats, "All the matrices must have the same data type" ); if( jacobian ) { if( !CV_IS_MAT(jacobian) ) - CV_Error( CV_StsBadArg, "Jacobian is not a valid matrix" ); + CV_Error( cv::Error::StsBadArg, "Jacobian is not a valid matrix" ); if( !CV_ARE_DEPTHS_EQ(src, jacobian) || CV_MAT_CN(jacobian->type) != 1 ) - CV_Error( CV_StsUnmatchedFormats, "Jacobian must have 32fC1 or 64fC1 datatype" ); + CV_Error( cv::Error::StsUnmatchedFormats, "Jacobian must have 32fC1 or 64fC1 datatype" ); if( (jacobian->rows != 9 || jacobian->cols != 3) && (jacobian->rows != 3 || jacobian->cols != 9)) - CV_Error( CV_StsBadSize, "Jacobian must be 3x9 or 9x3" ); + CV_Error( cv::Error::StsBadSize, "Jacobian must be 3x9 or 9x3" ); } if( src->cols == 1 || src->rows == 1 ) @@ -287,10 +287,10 @@ CV_IMPL int cvRodrigues2( const CvMat* src, CvMat* dst, CvMat* jacobian ) int step = src->rows > 1 ? src->step / elem_size : 1; if( src->rows + src->cols*CV_MAT_CN(src->type) - 1 != 3 ) - CV_Error( CV_StsBadSize, "Input matrix must be 1x3, 3x1 or 3x3" ); + CV_Error( cv::Error::StsBadSize, "Input matrix must be 1x3, 3x1 or 3x3" ); if( dst->rows != 3 || dst->cols != 3 || CV_MAT_CN(dst->type) != 1 ) - CV_Error( CV_StsBadSize, "Output matrix must be 3x3, single-channel floating point matrix" ); + CV_Error( cv::Error::StsBadSize, "Output matrix must be 3x3, single-channel floating point matrix" ); Point3d r; if( depth == CV_32F ) @@ -368,7 +368,7 @@ CV_IMPL int cvRodrigues2( const CvMat* src, CvMat* dst, CvMat* jacobian ) if( (dst->rows != 1 || dst->cols*CV_MAT_CN(dst->type) != 3) && (dst->rows != 3 || dst->cols != 1 || CV_MAT_CN(dst->type) != 1)) - CV_Error( CV_StsBadSize, "Output matrix must be 1x3 or 3x1" ); + CV_Error( cv::Error::StsBadSize, "Output matrix must be 1x3 or 3x1" ); Matx33d R = cvarrToMat(src); @@ -490,7 +490,7 @@ CV_IMPL int cvRodrigues2( const CvMat* src, CvMat* dst, CvMat* jacobian ) } else { - CV_Error(CV_StsBadSize, "Input matrix must be 1x3 or 3x1 for a rotation vector, or 3x3 for a rotation matrix"); + CV_Error(cv::Error::StsBadSize, "Input matrix must be 1x3 or 3x1 for a rotation vector, or 3x3 for a rotation matrix"); } if( jacobian ) @@ -553,13 +553,13 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, if( !CV_IS_MAT(objectPoints) || !CV_IS_MAT(r_vec) || !CV_IS_MAT(t_vec) || !CV_IS_MAT(A) || /*!CV_IS_MAT(distCoeffs) ||*/ !CV_IS_MAT(imagePoints) ) - CV_Error( CV_StsBadArg, "One of required arguments is not a valid matrix" ); + CV_Error( cv::Error::StsBadArg, "One of required arguments is not a valid matrix" ); int total = objectPoints->rows * objectPoints->cols * CV_MAT_CN(objectPoints->type); if(total % 3 != 0) { //we have stopped support of homogeneous coordinates because it cause ambiguity in interpretation of the input data - CV_Error( CV_StsBadArg, "Homogeneous coordinates are not supported" ); + CV_Error( cv::Error::StsBadArg, "Homogeneous coordinates are not supported" ); } count = total / 3; @@ -576,7 +576,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, { // matM = cvCreateMat( 1, count, CV_64FC3 ); // cvConvertPointsHomogeneous( objectPoints, matM ); - CV_Error( CV_StsBadArg, "Homogeneous coordinates are not supported" ); + CV_Error( cv::Error::StsBadArg, "Homogeneous coordinates are not supported" ); } if( CV_IS_CONT_MAT(imagePoints->type) && @@ -591,7 +591,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, else { // _m = cvCreateMat( 1, count, CV_64FC2 ); - CV_Error( CV_StsBadArg, "Homogeneous coordinates are not supported" ); + CV_Error( cv::Error::StsBadArg, "Homogeneous coordinates are not supported" ); } M = (CvPoint3D64f*)matM->data.db; @@ -601,7 +601,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, (((r_vec->rows != 1 && r_vec->cols != 1) || r_vec->rows*r_vec->cols*CV_MAT_CN(r_vec->type) != 3) && ((r_vec->rows != 3 && r_vec->cols != 3) || CV_MAT_CN(r_vec->type) != 1))) - CV_Error( CV_StsBadArg, "Rotation must be represented by 1x3 or 3x1 " + CV_Error( cv::Error::StsBadArg, "Rotation must be represented by 1x3 or 3x1 " "floating-point rotation vector, or 3x3 rotation matrix" ); if( r_vec->rows == 3 && r_vec->cols == 3 ) @@ -621,7 +621,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, if( (CV_MAT_DEPTH(t_vec->type) != CV_64F && CV_MAT_DEPTH(t_vec->type) != CV_32F) || (t_vec->rows != 1 && t_vec->cols != 1) || t_vec->rows*t_vec->cols*CV_MAT_CN(t_vec->type) != 3 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Translation vector must be 1x3 or 3x1 floating-point vector" ); _t = cvMat( t_vec->rows, t_vec->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(t_vec->type)), t ); @@ -629,7 +629,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, if( (CV_MAT_TYPE(A->type) != CV_64FC1 && CV_MAT_TYPE(A->type) != CV_32FC1) || A->rows != 3 || A->cols != 3 ) - CV_Error( CV_StsBadArg, "Intrinsic parameters must be 3x3 floating-point matrix" ); + CV_Error( cv::Error::StsBadArg, "Intrinsic parameters must be 3x3 floating-point matrix" ); cvConvert( A, &_a ); fx = a[0]; fy = a[4]; @@ -649,7 +649,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 8 && distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 12 && distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 14) ) - CV_Error( CV_StsBadArg, cvDistCoeffErr ); + CV_Error( cv::Error::StsBadArg, cvDistCoeffErr ); _k = cvMat( distCoeffs->rows, distCoeffs->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(distCoeffs->type)), k ); @@ -667,7 +667,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, (CV_MAT_TYPE(dpdr->type) != CV_32FC1 && CV_MAT_TYPE(dpdr->type) != CV_64FC1) || dpdr->rows != count*2 || dpdr->cols != 3 ) - CV_Error( CV_StsBadArg, "dp/drot must be 2Nx3 floating-point matrix" ); + CV_Error( cv::Error::StsBadArg, "dp/drot must be 2Nx3 floating-point matrix" ); if( CV_MAT_TYPE(dpdr->type) == CV_64FC1 ) { @@ -685,7 +685,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, (CV_MAT_TYPE(dpdt->type) != CV_32FC1 && CV_MAT_TYPE(dpdt->type) != CV_64FC1) || dpdt->rows != count*2 || dpdt->cols != 3 ) - CV_Error( CV_StsBadArg, "dp/dT must be 2Nx3 floating-point matrix" ); + CV_Error( cv::Error::StsBadArg, "dp/dT must be 2Nx3 floating-point matrix" ); if( CV_MAT_TYPE(dpdt->type) == CV_64FC1 ) { @@ -702,7 +702,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, if( !CV_IS_MAT(dpdf) || (CV_MAT_TYPE(dpdf->type) != CV_32FC1 && CV_MAT_TYPE(dpdf->type) != CV_64FC1) || dpdf->rows != count*2 || dpdf->cols != 2 ) - CV_Error( CV_StsBadArg, "dp/df must be 2Nx2 floating-point matrix" ); + CV_Error( cv::Error::StsBadArg, "dp/df must be 2Nx2 floating-point matrix" ); if( CV_MAT_TYPE(dpdf->type) == CV_64FC1 ) { @@ -719,7 +719,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, if( !CV_IS_MAT(dpdc) || (CV_MAT_TYPE(dpdc->type) != CV_32FC1 && CV_MAT_TYPE(dpdc->type) != CV_64FC1) || dpdc->rows != count*2 || dpdc->cols != 2 ) - CV_Error( CV_StsBadArg, "dp/dc must be 2Nx2 floating-point matrix" ); + CV_Error( cv::Error::StsBadArg, "dp/dc must be 2Nx2 floating-point matrix" ); if( CV_MAT_TYPE(dpdc->type) == CV_64FC1 ) { @@ -736,10 +736,10 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, if( !CV_IS_MAT(dpdk) || (CV_MAT_TYPE(dpdk->type) != CV_32FC1 && CV_MAT_TYPE(dpdk->type) != CV_64FC1) || dpdk->rows != count*2 || (dpdk->cols != 14 && dpdk->cols != 12 && dpdk->cols != 8 && dpdk->cols != 5 && dpdk->cols != 4 && dpdk->cols != 2) ) - CV_Error( CV_StsBadArg, "dp/df must be 2Nx14, 2Nx12, 2Nx8, 2Nx5, 2Nx4 or 2Nx2 floating-point matrix" ); + CV_Error( cv::Error::StsBadArg, "dp/df must be 2Nx14, 2Nx12, 2Nx8, 2Nx5, 2Nx4 or 2Nx2 floating-point matrix" ); if( !distCoeffs ) - CV_Error( CV_StsNullPtr, "distCoeffs is NULL while dpdk is not" ); + CV_Error( cv::Error::StsNullPtr, "distCoeffs is NULL while dpdk is not" ); if( CV_MAT_TYPE(dpdk->type) == CV_64FC1 ) { @@ -756,7 +756,7 @@ static void cvProjectPoints2Internal( const CvMat* objectPoints, if( !CV_IS_MAT( dpdo ) || ( CV_MAT_TYPE( dpdo->type ) != CV_32FC1 && CV_MAT_TYPE( dpdo->type ) != CV_64FC1 ) || dpdo->rows != count * 2 || dpdo->cols != count * 3 ) - CV_Error( CV_StsBadArg, "dp/do must be 2Nx3N floating-point matrix" ); + CV_Error( cv::Error::StsBadArg, "dp/do must be 2Nx3N floating-point matrix" ); if( CV_MAT_TYPE( dpdo->type ) == CV_64FC1 ) { @@ -1283,10 +1283,10 @@ CV_IMPL void cvInitIntrinsicParams2D( const CvMat* objectPoints, CV_MAT_TYPE(objectPoints->type) != CV_64FC3) || (CV_MAT_TYPE(imagePoints->type) != CV_32FC2 && CV_MAT_TYPE(imagePoints->type) != CV_64FC2) ) - CV_Error( CV_StsUnsupportedFormat, "Both object points and image points must be 2D" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Both object points and image points must be 2D" ); if( objectPoints->rows != 1 || imagePoints->rows != 1 ) - CV_Error( CV_StsBadSize, "object points and image points must be a single-row matrices" ); + CV_Error( cv::Error::StsBadSize, "object points and image points must be a single-row matrices" ); matA.reset(cvCreateMat( 2*nimages, 2, CV_64F )); _b.reset(cvCreateMat( 2*nimages, 1, CV_64F )); @@ -1395,27 +1395,27 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, // 0. check the parameters & allocate buffers if( !CV_IS_MAT(objectPoints) || !CV_IS_MAT(imagePoints) || !CV_IS_MAT(npoints) || !CV_IS_MAT(cameraMatrix) || !CV_IS_MAT(distCoeffs) ) - CV_Error( CV_StsBadArg, "One of required vector arguments is not a valid matrix" ); + CV_Error( cv::Error::StsBadArg, "One of required vector arguments is not a valid matrix" ); if( imageSize.width <= 0 || imageSize.height <= 0 ) - CV_Error( CV_StsOutOfRange, "image width and height must be positive" ); + CV_Error( cv::Error::StsOutOfRange, "image width and height must be positive" ); if( CV_MAT_TYPE(npoints->type) != CV_32SC1 || (npoints->rows != 1 && npoints->cols != 1) ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "the array of point counters must be 1-dimensional integer vector" ); if(flags & CALIB_TILTED_MODEL) { //when the tilted sensor model is used the distortion coefficients matrix must have 14 parameters if (distCoeffs->cols*distCoeffs->rows != 14) - CV_Error( CV_StsBadArg, "The tilted sensor model must have 14 parameters in the distortion matrix" ); + CV_Error( cv::Error::StsBadArg, "The tilted sensor model must have 14 parameters in the distortion matrix" ); } else { //when the thin prism model is used the distortion coefficients matrix must have 12 parameters if(flags & CALIB_THIN_PRISM_MODEL) if (distCoeffs->cols*distCoeffs->rows != 12) - CV_Error( CV_StsBadArg, "Thin prism model must have 12 parameters in the distortion matrix" ); + CV_Error( cv::Error::StsBadArg, "Thin prism model must have 12 parameters in the distortion matrix" ); } nimages = npoints->rows*npoints->cols; @@ -1428,7 +1428,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, (CV_MAT_DEPTH(rvecs->type) != CV_32F && CV_MAT_DEPTH(rvecs->type) != CV_64F) || ((rvecs->rows != nimages || (rvecs->cols*cn != 3 && rvecs->cols*cn != 9)) && (rvecs->rows != 1 || rvecs->cols != nimages || cn != 3)) ) - CV_Error( CV_StsBadArg, "the output array of rotation vectors must be 3-channel " + CV_Error( cv::Error::StsBadArg, "the output array of rotation vectors must be 3-channel " "1xn or nx1 array or 1-channel nx3 or nx9 array, where n is the number of views" ); } @@ -1439,7 +1439,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, (CV_MAT_DEPTH(tvecs->type) != CV_32F && CV_MAT_DEPTH(tvecs->type) != CV_64F) || ((tvecs->rows != nimages || tvecs->cols*cn != 3) && (tvecs->rows != 1 || tvecs->cols != nimages || cn != 3)) ) - CV_Error( CV_StsBadArg, "the output array of translation vectors must be 3-channel " + CV_Error( cv::Error::StsBadArg, "the output array of translation vectors must be 3-channel " "1xn or nx1 array or 1-channel nx3 array, where n is the number of views" ); } @@ -1454,7 +1454,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, (stdDevs->rows != 1 || stdDevs->cols != (nimages*6 + NINTRINSIC) || cn != 1)) ) #define STR__(x) #x #define STR_(x) STR__(x) - CV_Error( CV_StsBadArg, "the output array of standard deviations vectors must be 1-channel " + CV_Error( cv::Error::StsBadArg, "the output array of standard deviations vectors must be 1-channel " "1x(n*6 + NINTRINSIC) or (n*6 + NINTRINSIC)x1 array, where n is the number of views," " NINTRINSIC = " STR_(CV_CALIB_NINTRINSIC)); } @@ -1462,7 +1462,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, if( (CV_MAT_TYPE(cameraMatrix->type) != CV_32FC1 && CV_MAT_TYPE(cameraMatrix->type) != CV_64FC1) || cameraMatrix->rows != 3 || cameraMatrix->cols != 3 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Intrinsic parameters must be 3x3 floating-point matrix" ); if( (CV_MAT_TYPE(distCoeffs->type) != CV_32FC1 && @@ -1473,14 +1473,14 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, distCoeffs->cols*distCoeffs->rows != 8 && distCoeffs->cols*distCoeffs->rows != 12 && distCoeffs->cols*distCoeffs->rows != 14) ) - CV_Error( CV_StsBadArg, cvDistCoeffErr ); + CV_Error( cv::Error::StsBadArg, cvDistCoeffErr ); for( i = 0; i < nimages; i++ ) { ni = npoints->data.i[i*npstep]; if( ni < 4 ) { - CV_Error_( CV_StsOutOfRange, ("The number of points in the view #%d is < 4", i)); + CV_Error_( cv::Error::StsOutOfRange, ("The number of points in the view #%d is < 4", i)); } maxPoints = MAX( maxPoints, ni ); total += ni; @@ -1493,7 +1493,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, (CV_MAT_DEPTH(newObjPoints->type) != CV_32F && CV_MAT_DEPTH(newObjPoints->type) != CV_64F) || ((newObjPoints->rows != maxPoints || newObjPoints->cols*cn != 3) && (newObjPoints->rows != 1 || newObjPoints->cols != maxPoints || cn != 3)) ) - CV_Error( CV_StsBadArg, "the output array of refined object points must be 3-channel " + CV_Error( cv::Error::StsBadArg, "the output array of refined object points must be 3-channel " "1xn or nx1 array or 1-channel nx3 array, where n is the number of object points per view" ); } @@ -1504,7 +1504,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, (CV_MAT_DEPTH(stdDevs->type) != CV_32F && CV_MAT_DEPTH(stdDevs->type) != CV_64F) || ((stdDevs->rows != (nimages*6 + NINTRINSIC + maxPoints*3) || stdDevs->cols*cn != 1) && (stdDevs->rows != 1 || stdDevs->cols != (nimages*6 + NINTRINSIC + maxPoints*3) || cn != 1)) ) - CV_Error( CV_StsBadArg, "the output array of standard deviations vectors must be 1-channel " + CV_Error( cv::Error::StsBadArg, "the output array of standard deviations vectors must be 1-channel " "1x(n*6 + NINTRINSIC + m*3) or (n*6 + NINTRINSIC + m*3)x1 array, where n is the number of views," " NINTRINSIC = " STR_(CV_CALIB_NINTRINSIC) ", m is the number of object points per view"); } @@ -1544,15 +1544,15 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, { cvConvert( cameraMatrix, &matA ); if( A(0, 0) <= 0 || A(1, 1) <= 0 ) - CV_Error( CV_StsOutOfRange, "Focal length (fx and fy) must be positive" ); + CV_Error( cv::Error::StsOutOfRange, "Focal length (fx and fy) must be positive" ); if( A(0, 2) < 0 || A(0, 2) >= imageSize.width || A(1, 2) < 0 || A(1, 2) >= imageSize.height ) - CV_Error( CV_StsOutOfRange, "Principal point must be within the image" ); + CV_Error( cv::Error::StsOutOfRange, "Principal point must be within the image" ); if( fabs(A(0, 1)) > 1e-5 ) - CV_Error( CV_StsOutOfRange, "Non-zero skew is not supported by the function" ); + CV_Error( cv::Error::StsOutOfRange, "Non-zero skew is not supported by the function" ); if( fabs(A(1, 0)) > 1e-5 || fabs(A(2, 0)) > 1e-5 || fabs(A(2, 1)) > 1e-5 || fabs(A(2,2)-1) > 1e-5 ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "The intrinsic matrix must have [fx 0 cx; 0 fy cy; 0 0 1] shape" ); A(0, 1) = A(1, 0) = A(2, 0) = A(2, 1) = 0.; A(2, 2) = 1.; @@ -1562,7 +1562,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, aspectRatio = A(0, 0)/A(1, 1); if( aspectRatio < minValidAspectRatio || aspectRatio > maxValidAspectRatio ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "The specified aspect ratio (= cameraMatrix[0][0] / cameraMatrix[1][1]) is incorrect" ); } cvConvert( distCoeffs, &_k ); @@ -1572,7 +1572,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, Scalar mean, sdv; meanStdDev(matM, mean, sdv); if( fabs(mean[2]) > 1e-5 || fabs(sdv[2]) > 1e-5 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "For non-planar calibration rigs the initial intrinsic matrix must be specified" ); for( i = 0; i < total; i++ ) matM.at(i).z = 0.; @@ -1582,7 +1582,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, aspectRatio = cvmGet(cameraMatrix,0,0); aspectRatio /= cvmGet(cameraMatrix,1,1); if( aspectRatio < minValidAspectRatio || aspectRatio > maxValidAspectRatio ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "The specified aspect ratio (= cameraMatrix[0][0] / cameraMatrix[1][1]) is incorrect" ); } CvMat _matM = cvMat(matM), m = cvMat(_m); @@ -1673,7 +1673,7 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints, Mat mask = cvarrToMat(solver.mask); int nparams_nz = countNonZero(mask); if (nparams_nz >= 2 * total) - CV_Error_(CV_StsBadArg, + CV_Error_(cv::Error::StsBadArg, ("There should be less vars to optimize (having %d) than the number of residuals (%d = 2 per point)", nparams_nz, 2 * total)); // 2. initialize extrinsic parameters @@ -1889,10 +1889,10 @@ CV_IMPL double cvCalibrateCamera4( const CvMat* objectPoints, CvMat* rvecs, CvMat* tvecs, CvMat* newObjPoints, int flags, CvTermCriteria termCrit ) { if( !CV_IS_MAT(npoints) ) - CV_Error( CV_StsBadArg, "npoints is not a valid matrix" ); + CV_Error( cv::Error::StsBadArg, "npoints is not a valid matrix" ); if( CV_MAT_TYPE(npoints->type) != CV_32SC1 || (npoints->rows != 1 && npoints->cols != 1) ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "the array of point counters must be 1-dimensional integer vector" ); bool releaseObject = iFixedPoint > 0 && iFixedPoint < npoints->data.i[0] - 1; @@ -1903,7 +1903,7 @@ CV_IMPL double cvCalibrateCamera4( const CvMat* objectPoints, if( releaseObject ) { if( !CV_IS_MAT(objectPoints) ) - CV_Error( CV_StsBadArg, "objectPoints is not a valid matrix" ); + CV_Error( cv::Error::StsBadArg, "objectPoints is not a valid matrix" ); Mat matM; if(CV_MAT_CN(objectPoints->type) == 3) { matM = cvarrToMat(objectPoints); @@ -1917,14 +1917,14 @@ CV_IMPL double cvCalibrateCamera4( const CvMat* objectPoints, { if( npoints->data.i[i * npstep] != ni ) { - CV_Error( CV_StsBadArg, "All objectPoints[i].size() should be equal when " + CV_Error( cv::Error::StsBadArg, "All objectPoints[i].size() should be equal when " "object-releasing method is requested." ); } Mat ocmp = matM.colRange(ni * i, ni * i + ni) != matM.colRange(0, ni); ocmp = ocmp.reshape(1); if( countNonZero(ocmp) ) { - CV_Error( CV_StsBadArg, "All objectPoints[i] should be identical when object-releasing" + CV_Error( cv::Error::StsBadArg, "All objectPoints[i] should be identical when object-releasing" " method is requested." ); } } @@ -1941,10 +1941,10 @@ void cvCalibrationMatrixValues( const CvMat *calibMatr, CvSize imgSize, { /* Validate parameters. */ if(calibMatr == 0) - CV_Error(CV_StsNullPtr, "Some of parameters is a NULL pointer!"); + CV_Error(cv::Error::StsNullPtr, "Some of parameters is a NULL pointer!"); if(!CV_IS_MAT(calibMatr)) - CV_Error(CV_StsUnsupportedFormat, "Input parameters must be matrices!"); + CV_Error(cv::Error::StsUnsupportedFormat, "Input parameters must be matrices!"); double dummy = .0; Point2d pp; @@ -2023,7 +2023,7 @@ static double cvStereoCalibrateImpl( const CvMat* _objectPoints, const CvMat* _i (CV_MAT_DEPTH(rvecs->type) != CV_32F && CV_MAT_DEPTH(rvecs->type) != CV_64F) || ((rvecs->rows != nimages || (rvecs->cols*cn != 3 && rvecs->cols*cn != 9)) && (rvecs->rows != 1 || rvecs->cols != nimages || cn != 3)) ) - CV_Error( CV_StsBadArg, "the output array of rotation vectors must be 3-channel " + CV_Error( cv::Error::StsBadArg, "the output array of rotation vectors must be 3-channel " "1xn or nx1 array or 1-channel nx3 or nx9 array, where n is the number of views" ); } @@ -2034,7 +2034,7 @@ static double cvStereoCalibrateImpl( const CvMat* _objectPoints, const CvMat* _i (CV_MAT_DEPTH(tvecs->type) != CV_32F && CV_MAT_DEPTH(tvecs->type) != CV_64F) || ((tvecs->rows != nimages || tvecs->cols*cn != 3) && (tvecs->rows != 1 || tvecs->cols != nimages || cn != 3)) ) - CV_Error( CV_StsBadArg, "the output array of translation vectors must be 3-channel " + CV_Error( cv::Error::StsBadArg, "the output array of translation vectors must be 3-channel " "1xn or nx1 array or 1-channel nx3 array, where n is the number of views" ); } @@ -3344,19 +3344,19 @@ cvDecomposeProjectionMatrix( const CvMat *projMatr, CvMat *calibMatr, /* Validate parameters. */ if(projMatr == 0 || calibMatr == 0 || rotMatr == 0 || posVect == 0) - CV_Error(CV_StsNullPtr, "Some of parameters is a NULL pointer!"); + CV_Error(cv::Error::StsNullPtr, "Some of parameters is a NULL pointer!"); if(!CV_IS_MAT(projMatr) || !CV_IS_MAT(calibMatr) || !CV_IS_MAT(rotMatr) || !CV_IS_MAT(posVect)) - CV_Error(CV_StsUnsupportedFormat, "Input parameters must be matrices!"); + CV_Error(cv::Error::StsUnsupportedFormat, "Input parameters must be matrices!"); if(projMatr->cols != 4 || projMatr->rows != 3) - CV_Error(CV_StsUnmatchedSizes, "Size of projection matrix must be 3x4!"); + CV_Error(cv::Error::StsUnmatchedSizes, "Size of projection matrix must be 3x4!"); if(calibMatr->cols != 3 || calibMatr->rows != 3 || rotMatr->cols != 3 || rotMatr->rows != 3) - CV_Error(CV_StsUnmatchedSizes, "Size of calibration and rotation matrices must be 3x3!"); + CV_Error(cv::Error::StsUnmatchedSizes, "Size of calibration and rotation matrices must be 3x3!"); if(posVect->cols != 1 || posVect->rows != 4) - CV_Error(CV_StsUnmatchedSizes, "Size of position vector must be 4x1!"); + CV_Error(cv::Error::StsUnmatchedSizes, "Size of position vector must be 4x1!"); /* Compute position vector. */ cvSetZero(&tmpProjMatr); // Add zero row to make matrix square. @@ -3402,17 +3402,17 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints, { Mat objectPoint = objectPoints.getMat(i); if (objectPoint.empty()) - CV_Error(CV_StsBadSize, "objectPoints should not contain empty vector of vectors of points"); + CV_Error(cv::Error::StsBadSize, "objectPoints should not contain empty vector of vectors of points"); int numberOfObjectPoints = objectPoint.checkVector(3, CV_32F); if (numberOfObjectPoints <= 0) - CV_Error(CV_StsUnsupportedFormat, "objectPoints should contain vector of vectors of points of type Point3f"); + CV_Error(cv::Error::StsUnsupportedFormat, "objectPoints should contain vector of vectors of points of type Point3f"); Mat imagePoint1 = imagePoints1.getMat(i); if (imagePoint1.empty()) - CV_Error(CV_StsBadSize, "imagePoints1 should not contain empty vector of vectors of points"); + CV_Error(cv::Error::StsBadSize, "imagePoints1 should not contain empty vector of vectors of points"); int numberOfImagePoints = imagePoint1.checkVector(2, CV_32F); if (numberOfImagePoints <= 0) - CV_Error(CV_StsUnsupportedFormat, "imagePoints1 should contain vector of vectors of points of type Point2f"); + CV_Error(cv::Error::StsUnsupportedFormat, "imagePoints1 should contain vector of vectors of points of type Point2f"); CV_CheckEQ(numberOfObjectPoints, numberOfImagePoints, "Number of object and image points must be equal"); total += numberOfObjectPoints; @@ -3467,14 +3467,14 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints, { if( npoints.at(i) != ni ) { - CV_Error( CV_StsBadArg, "All objectPoints[i].size() should be equal when " + CV_Error( cv::Error::StsBadArg, "All objectPoints[i].size() should be equal when " "object-releasing method is requested." ); } Mat ocmp = objPtMat.colRange(ni * i, ni * i + ni) != objPtMat.colRange(0, ni); ocmp = ocmp.reshape(1); if( countNonZero(ocmp) ) { - CV_Error( CV_StsBadArg, "All objectPoints[i] should be identical when object-releasing" + CV_Error( cv::Error::StsBadArg, "All objectPoints[i] should be identical when object-releasing" " method is requested." ); } } @@ -3884,7 +3884,7 @@ void cv::calibrationMatrixValues( InputArray _cameraMatrix, Size imageSize, CV_INSTRUMENT_REGION(); if(_cameraMatrix.size() != Size(3, 3)) - CV_Error(CV_StsUnmatchedSizes, "Size of cameraMatrix must be 3x3!"); + CV_Error(cv::Error::StsUnmatchedSizes, "Size of cameraMatrix must be 3x3!"); Matx33d K = _cameraMatrix.getMat(); diff --git a/modules/calib3d/src/solvepnp.cpp b/modules/calib3d/src/solvepnp.cpp index 54e23ca9f8..771abff483 100644 --- a/modules/calib3d/src/solvepnp.cpp +++ b/modules/calib3d/src/solvepnp.cpp @@ -1041,7 +1041,7 @@ int solvePnPGeneric( InputArray _opoints, InputArray _ipoints, vec_tvecs.push_back(tvec); }*/ else - CV_Error(CV_StsBadArg, "The flags argument must be one of SOLVEPNP_ITERATIVE, SOLVEPNP_P3P, " + CV_Error(cv::Error::StsBadArg, "The flags argument must be one of SOLVEPNP_ITERATIVE, SOLVEPNP_P3P, " "SOLVEPNP_EPNP, SOLVEPNP_DLS, SOLVEPNP_UPNP, SOLVEPNP_AP3P, SOLVEPNP_IPPE, SOLVEPNP_IPPE_SQUARE or SOLVEPNP_SQPNP"); CV_Assert(vec_rvecs.size() == vec_tvecs.size()); diff --git a/modules/calib3d/src/triangulate.cpp b/modules/calib3d/src/triangulate.cpp index cded42232a..671659c84b 100644 --- a/modules/calib3d/src/triangulate.cpp +++ b/modules/calib3d/src/triangulate.cpp @@ -56,30 +56,30 @@ icvTriangulatePoints(CvMat* projMatr1, CvMat* projMatr2, CvMat* projPoints1, CvM if( projMatr1 == 0 || projMatr2 == 0 || projPoints1 == 0 || projPoints2 == 0 || points4D == 0) - CV_Error( CV_StsNullPtr, "Some of parameters is a NULL pointer" ); + CV_Error( cv::Error::StsNullPtr, "Some of parameters is a NULL pointer" ); if( !CV_IS_MAT(projMatr1) || !CV_IS_MAT(projMatr2) || !CV_IS_MAT(projPoints1) || !CV_IS_MAT(projPoints2) || !CV_IS_MAT(points4D) ) - CV_Error( CV_StsUnsupportedFormat, "Input parameters must be matrices" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Input parameters must be matrices" ); int numPoints = projPoints1->cols; if( numPoints < 1 ) - CV_Error( CV_StsOutOfRange, "Number of points must be more than zero" ); + CV_Error( cv::Error::StsOutOfRange, "Number of points must be more than zero" ); if( projPoints2->cols != numPoints || points4D->cols != numPoints ) - CV_Error( CV_StsUnmatchedSizes, "Number of points must be the same" ); + CV_Error( cv::Error::StsUnmatchedSizes, "Number of points must be the same" ); if( projPoints1->rows != 2 || projPoints2->rows != 2) - CV_Error( CV_StsUnmatchedSizes, "Number of proj points coordinates must be == 2" ); + CV_Error( cv::Error::StsUnmatchedSizes, "Number of proj points coordinates must be == 2" ); if( points4D->rows != 4 ) - CV_Error( CV_StsUnmatchedSizes, "Number of world points coordinates must be == 4" ); + CV_Error( cv::Error::StsUnmatchedSizes, "Number of world points coordinates must be == 4" ); if( projMatr1->cols != 4 || projMatr1->rows != 3 || projMatr2->cols != 4 || projMatr2->rows != 3) - CV_Error( CV_StsUnmatchedSizes, "Size of projection matrices must be 3x4" ); + CV_Error( cv::Error::StsUnmatchedSizes, "Size of projection matrices must be 3x4" ); // preallocate SVD matrices on stack cv::Matx matrA; @@ -147,30 +147,30 @@ icvCorrectMatches(CvMat *F_, CvMat *points1_, CvMat *points2_, CvMat *new_points cv::Ptr F; if (!CV_IS_MAT(F_) || !CV_IS_MAT(points1_) || !CV_IS_MAT(points2_) ) - CV_Error( CV_StsUnsupportedFormat, "Input parameters must be matrices" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Input parameters must be matrices" ); if (!( F_->cols == 3 && F_->rows == 3)) - CV_Error( CV_StsUnmatchedSizes, "The fundamental matrix must be a 3x3 matrix"); + CV_Error( cv::Error::StsUnmatchedSizes, "The fundamental matrix must be a 3x3 matrix"); if (!(((F_->type & CV_MAT_TYPE_MASK) >> 3) == 0 )) - CV_Error( CV_StsUnsupportedFormat, "The fundamental matrix must be a single-channel matrix" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The fundamental matrix must be a single-channel matrix" ); if (!(points1_->rows == 1 && points2_->rows == 1 && points1_->cols == points2_->cols)) - CV_Error( CV_StsUnmatchedSizes, "The point-matrices must have one row, and an equal number of columns" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The point-matrices must have one row, and an equal number of columns" ); if (((points1_->type & CV_MAT_TYPE_MASK) >> 3) != 1 ) - CV_Error( CV_StsUnmatchedSizes, "The first set of points must contain two channels; one for x and one for y" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The first set of points must contain two channels; one for x and one for y" ); if (((points2_->type & CV_MAT_TYPE_MASK) >> 3) != 1 ) - CV_Error( CV_StsUnmatchedSizes, "The second set of points must contain two channels; one for x and one for y" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The second set of points must contain two channels; one for x and one for y" ); if (new_points1 != NULL) { CV_Assert(CV_IS_MAT(new_points1)); if (new_points1->cols != points1_->cols || new_points1->rows != 1) - CV_Error( CV_StsUnmatchedSizes, "The first output matrix must have the same dimensions as the input matrices" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The first output matrix must have the same dimensions as the input matrices" ); if (CV_MAT_CN(new_points1->type) != 2) - CV_Error( CV_StsUnsupportedFormat, "The first output matrix must have two channels; one for x and one for y" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The first output matrix must have two channels; one for x and one for y" ); } if (new_points2 != NULL) { CV_Assert(CV_IS_MAT(new_points2)); if (new_points2->cols != points2_->cols || new_points2->rows != 1) - CV_Error( CV_StsUnmatchedSizes, "The second output matrix must have the same dimensions as the input matrices" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The second output matrix must have the same dimensions as the input matrices" ); if (CV_MAT_CN(new_points2->type) != 2) - CV_Error( CV_StsUnsupportedFormat, "The second output matrix must have two channels; one for x and one for y" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The second output matrix must have two channels; one for x and one for y" ); } // Make sure F uses double precision diff --git a/modules/calib3d/test/test_cameracalibration_badarg.cpp b/modules/calib3d/test/test_cameracalibration_badarg.cpp index 240bdbb1b3..046fc1d530 100644 --- a/modules/calib3d/test/test_cameracalibration_badarg.cpp +++ b/modules/calib3d/test/test_cameracalibration_badarg.cpp @@ -149,49 +149,49 @@ void CV_CameraCalibrationBadArgTest::run( int /* start_from */ ) caller.initArgs(); caller.objPts_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "None passed in objPts", caller); + errors += run_test_case( cv::Error::StsBadArg, "None passed in objPts", caller); caller.initArgs(); caller.imgPts_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "None passed in imgPts", caller ); + errors += run_test_case( cv::Error::StsBadArg, "None passed in imgPts", caller ); caller.initArgs(); caller.cameraMatrix_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero passed in cameraMatrix", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero passed in cameraMatrix", caller ); caller.initArgs(); caller.distCoeffs_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero passed in distCoeffs", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero passed in distCoeffs", caller ); caller.initArgs(); caller.imageSize.width = -1; - errors += run_test_case( CV_StsOutOfRange, "Bad image width", caller ); + errors += run_test_case( cv::Error::StsOutOfRange, "Bad image width", caller ); caller.initArgs(); caller.imageSize.height = -1; - errors += run_test_case( CV_StsOutOfRange, "Bad image height", caller ); + errors += run_test_case( cv::Error::StsOutOfRange, "Bad image height", caller ); caller.initArgs(); caller.imgPts[0].clear(); - errors += run_test_case( CV_StsBadSize, "Bad imgpts[0]", caller ); + errors += run_test_case( cv::Error::StsBadSize, "Bad imgpts[0]", caller ); caller.imgPts[0] = caller.imgPts[1]; caller.initArgs(); caller.objPts[1].clear(); - errors += run_test_case( CV_StsBadSize, "Bad objpts[1]", caller ); + errors += run_test_case( cv::Error::StsBadSize, "Bad objpts[1]", caller ); caller.objPts[1] = caller.objPts[0]; caller.initArgs(); Mat badCM = Mat::zeros(4, 4, CV_64F); caller.cameraMatrix_arg = badCM; caller.flags = CALIB_USE_INTRINSIC_GUESS; - errors += run_test_case( CV_StsBadArg, "Bad camearaMatrix header", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad camearaMatrix header", caller ); caller.initArgs(); Mat badDC = Mat::zeros(10, 10, CV_64F); caller.distCoeffs_arg = badDC; caller.flags = CALIB_USE_INTRINSIC_GUESS; - errors += run_test_case( CV_StsBadArg, "Bad camearaMatrix header", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad camearaMatrix header", caller ); if (errors) ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); @@ -244,15 +244,15 @@ protected: caller.initArgs(); caller.src_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Src is empty matrix", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Src is empty matrix", caller ); caller.initArgs(); caller.src = Mat::zeros(3, 1, CV_8U); - errors += run_test_case( CV_StsUnsupportedFormat, "Bad src formart", caller ); + errors += run_test_case( cv::Error::StsUnsupportedFormat, "Bad src formart", caller ); caller.initArgs(); caller.src = Mat::zeros(1, 1, CV_32F); - errors += run_test_case( CV_StsBadSize, "Bad src size", caller ); + errors += run_test_case( cv::Error::StsBadSize, "Bad src size", caller ); if (errors) ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); @@ -331,57 +331,57 @@ protected: caller.initArgs(); caller.objectPoints_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero objectPoints", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero objectPoints", caller ); caller.initArgs(); caller.rvec_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero r_vec", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero r_vec", caller ); caller.initArgs(); caller.tvec_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero t_vec", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero t_vec", caller ); caller.initArgs(); caller.A_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero camMat", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero camMat", caller ); caller.initArgs(); caller.imagePoints_arg = noArray(); - errors += run_test_case( CV_StsBadArg, "Zero imagePoints", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Zero imagePoints", caller ); Mat save_rvec = caller.r_vec; caller.initArgs(); caller.r_vec.create(2, 2, CV_32F); - errors += run_test_case( CV_StsBadArg, "Bad rvec format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad rvec format", caller ); caller.initArgs(); caller.r_vec.create(1, 3, CV_8U); - errors += run_test_case( CV_StsBadArg, "Bad rvec format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad rvec format", caller ); caller.r_vec = save_rvec; /****************************/ Mat save_tvec = caller.t_vec; caller.initArgs(); caller.t_vec.create(3, 3, CV_32F); - errors += run_test_case( CV_StsBadArg, "Bad tvec format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad tvec format", caller ); caller.initArgs(); caller.t_vec.create(1, 3, CV_8U); - errors += run_test_case( CV_StsBadArg, "Bad tvec format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad tvec format", caller ); caller.t_vec = save_tvec; /****************************/ Mat save_A = caller.A; caller.initArgs(); caller.A.create(2, 2, CV_32F); - errors += run_test_case( CV_StsBadArg, "Bad A format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad A format", caller ); caller.A = save_A; /****************************/ Mat save_DC = caller.distCoeffs; caller.initArgs(); caller.distCoeffs.create(3, 3, CV_32F); - errors += run_test_case( CV_StsBadArg, "Bad distCoeffs format", caller ); + errors += run_test_case( cv::Error::StsBadArg, "Bad distCoeffs format", caller ); caller.distCoeffs = save_DC; if (errors) diff --git a/modules/calib3d/test/test_undistort_badarg.cpp b/modules/calib3d/test/test_undistort_badarg.cpp index 0ba13f1212..71bb21a0bd 100644 --- a/modules/calib3d/test/test_undistort_badarg.cpp +++ b/modules/calib3d/test/test_undistort_badarg.cpp @@ -106,15 +106,15 @@ void CV_UndistortPointsBadArgTest::run(int) src_points = cv::cvarrToMat(&_src_points_orig); src_points.create(2, 2, CV_32FC2); - errcount += run_test_case( CV_StsAssert, "Invalid input data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid input data matrix size" ); src_points = cv::cvarrToMat(&_src_points_orig); src_points.create(1, 4, CV_64FC2); - errcount += run_test_case( CV_StsAssert, "Invalid input data matrix type" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid input data matrix type" ); src_points = cv::cvarrToMat(&_src_points_orig); src_points = cv::Mat(); - errcount += run_test_case( CV_StsBadArg, "Input data matrix is not continuous" ); + errcount += run_test_case( cv::Error::StsBadArg, "Input data matrix is not continuous" ); src_points = cv::cvarrToMat(&_src_points_orig); //------------ @@ -181,19 +181,19 @@ void CV_InitUndistortRectifyMapBadArgTest::run(int) mapy = cv::cvarrToMat(&_mapy_orig); mat_type = CV_64F; - errcount += run_test_case( CV_StsAssert, "Invalid map matrix type" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid map matrix type" ); mat_type = mat_type_orig; camera_mat.create(3, 2, CV_32F); - errcount += run_test_case( CV_StsAssert, "Invalid camera data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid camera data matrix size" ); camera_mat = cv::cvarrToMat(&_camera_mat_orig); R.create(4, 3, CV_32F); - errcount += run_test_case( CV_StsAssert, "Invalid R data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid R data matrix size" ); R = cv::cvarrToMat(&_R_orig); distortion_coeffs.create(6, 1, CV_32F); - errcount += run_test_case( CV_StsAssert, "Invalid distortion coefficients data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid distortion coefficients data matrix size" ); distortion_coeffs = cv::cvarrToMat(&_distortion_coeffs_orig); //------------ @@ -256,7 +256,7 @@ void CV_UndistortBadArgTest::run(int) dst = cv::cvarrToMat(&_dst_orig); camera_mat.create(5, 5, CV_64F); - errcount += run_test_case( CV_StsAssert, "Invalid camera data matrix size" ); + errcount += run_test_case( cv::Error::StsAssert, "Invalid camera data matrix size" ); //------------ ts->set_failed_test_info(errcount > 0 ? cvtest::TS::FAIL_BAD_ARG_CHECK : cvtest::TS::OK); diff --git a/modules/core/src/alloc.cpp b/modules/core/src/alloc.cpp index cb2db71e2c..f6abeeb098 100644 --- a/modules/core/src/alloc.cpp +++ b/modules/core/src/alloc.cpp @@ -70,7 +70,7 @@ namespace cv { static void* OutOfMemoryError(size_t size) { - CV_Error_(CV_StsNoMem, ("Failed to allocate %llu bytes", (unsigned long long)size)); + CV_Error_(cv::Error::StsNoMem, ("Failed to allocate %llu bytes", (unsigned long long)size)); } CV_EXPORTS cv::utils::AllocatorStatisticsInterface& getAllocatorStatistics(); diff --git a/modules/core/src/arithm.cpp b/modules/core/src/arithm.cpp index 9de474b402..9e690fef2f 100644 --- a/modules/core/src/arithm.cpp +++ b/modules/core/src/arithm.cpp @@ -209,7 +209,7 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst, swap(sz1, sz2); } else if( !checkScalar(*psrc2, type1, kind2, kind1) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The operation is neither 'array op array' (where arrays have the same size and type), " "nor 'array op scalar', nor 'scalar op array'" ); haveScalar = true; @@ -644,7 +644,7 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, oclop = OCL_OP_RDIV_SCALE; } else if( !checkScalar(*psrc2, type1, kind2, kind1) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The operation is neither 'array op array' " "(where arrays have the same size and the same number of channels), " "nor 'array op scalar', nor 'scalar op array'" ); @@ -669,7 +669,7 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, else { if( !haveScalar && type1 != type2 ) - CV_Error(CV_StsBadArg, + CV_Error(cv::Error::StsBadArg, "When the input arrays in add/subtract/multiply/divide functions have different types, " "the output array type must be explicitly specified"); dtype = type1; @@ -1206,7 +1206,7 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op) return; } else if(is_src1_scalar == is_src2_scalar) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The operation is neither 'array op array' (where arrays have the same size and the same type), " "nor 'array op scalar', nor 'scalar op array'" ); haveScalar = true; @@ -1615,7 +1615,7 @@ static bool ocl_inRange( InputArray _src, InputArray _lowerb, ssize != lsize || stype != ltype ) { if( !checkScalar(_lowerb, stype, lkind, skind) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The lower boundary is neither an array of the same size and same type as src, nor a scalar"); lbScalar = true; } @@ -1624,7 +1624,7 @@ static bool ocl_inRange( InputArray _src, InputArray _lowerb, ssize != usize || stype != utype ) { if( !checkScalar(_upperb, stype, ukind, skind) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The upper boundary is neither an array of the same size and same type as src, nor a scalar"); ubScalar = true; } @@ -1738,7 +1738,7 @@ void cv::inRange(InputArray _src, InputArray _lowerb, src.size != lb.size || src.type() != lb.type() ) { if( !checkScalar(lb, src.type(), lkind, skind) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The lower boundary is neither an array of the same size and same type as src, nor a scalar"); lbScalar = true; } @@ -1747,7 +1747,7 @@ void cv::inRange(InputArray _src, InputArray _lowerb, src.size != ub.size || src.type() != ub.type() ) { if( !checkScalar(ub, src.type(), ukind, skind) ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The upper boundary is neither an array of the same size and same type as src, nor a scalar"); ubScalar = true; } diff --git a/modules/core/src/array.cpp b/modules/core/src/array.cpp index 1eef447d0c..252ac13ca0 100644 --- a/modules/core/src/array.cpp +++ b/modules/core/src/array.cpp @@ -79,7 +79,7 @@ cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader, (createROI != 0) + (cloneImage != 0); if( count != 0 && count != 5 ) - CV_Error( CV_StsBadArg, "Either all the pointers should be null or " + CV_Error( cv::Error::StsBadArg, "Either all the pointers should be null or " "they all should be non-null" ); CvIPL.createHeader = createHeader; @@ -118,11 +118,11 @@ cvCreateMatHeader( int rows, int cols, int type ) type = CV_MAT_TYPE(type); if( rows < 0 || cols < 0 ) - CV_Error( CV_StsBadSize, "Non-positive width or height" ); + CV_Error( cv::Error::StsBadSize, "Non-positive width or height" ); int min_step = CV_ELEM_SIZE(type); if( min_step <= 0 ) - CV_Error( CV_StsUnsupportedFormat, "Invalid matrix type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Invalid matrix type" ); min_step *= cols; CvMat* arr = (CvMat*)cvAlloc( sizeof(*arr)); @@ -146,13 +146,13 @@ cvInitMatHeader( CvMat* arr, int rows, int cols, int type, void* data, int step ) { if( !arr ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX ) - CV_Error( CV_BadNumChannels, "" ); + CV_Error( cv::Error::BadNumChannels, "" ); if( rows < 0 || cols < 0 ) - CV_Error( CV_StsBadSize, "Non-positive cols or rows" ); + CV_Error( cv::Error::StsBadSize, "Non-positive cols or rows" ); type = CV_MAT_TYPE( type ); arr->type = type | CV_MAT_MAGIC_VAL; @@ -168,7 +168,7 @@ cvInitMatHeader( CvMat* arr, int rows, int cols, if( step != CV_AUTOSTEP && step != 0 ) { if( step < min_step ) - CV_Error( CV_BadStep, "" ); + CV_Error( cv::Error::BadStep, "" ); arr->step = step; } else @@ -196,7 +196,7 @@ cvReleaseMat( CvMat** array ) CvMat* arr = *array; if( !CV_IS_MAT_HDR_Z(arr) && !CV_IS_MATND_HDR(arr) ) - CV_Error( CV_StsBadFlag, "" ); + CV_Error( cv::Error::StsBadFlag, "" ); *array = 0; @@ -211,7 +211,7 @@ CV_IMPL CvMat* cvCloneMat( const CvMat* src ) { if( !CV_IS_MAT_HDR( src )) - CV_Error( CV_StsBadArg, "Bad CvMat header" ); + CV_Error( cv::Error::StsBadArg, "Bad CvMat header" ); CvMat* dst = cvCreateMatHeader( src->rows, src->cols, src->type ); @@ -237,25 +237,25 @@ cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int64 step = CV_ELEM_SIZE(type); if( !mat ) - CV_Error( CV_StsNullPtr, "NULL matrix header pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL matrix header pointer" ); if( step == 0 ) - CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "invalid array data type" ); if( !sizes ) - CV_Error( CV_StsNullPtr, "NULL pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL pointer" ); if( dims <= 0 || dims > CV_MAX_DIM ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "non-positive or too large number of dimensions" ); for( int i = dims - 1; i >= 0; i-- ) { if( sizes[i] < 0 ) - CV_Error( CV_StsBadSize, "one of dimension sizes is non-positive" ); + CV_Error( cv::Error::StsBadSize, "one of dimension sizes is non-positive" ); mat->dim[i].size = sizes[i]; if( step > INT_MAX ) - CV_Error( CV_StsOutOfRange, "The array is too big" ); + CV_Error( cv::Error::StsOutOfRange, "The array is too big" ); mat->dim[i].step = (int)step; step *= sizes[i]; } @@ -285,7 +285,7 @@ CV_IMPL CvMatND* cvCreateMatNDHeader( int dims, const int* sizes, int type ) { if( dims <= 0 || dims > CV_MAX_DIM ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "non-positive or too large number of dimensions" ); CvMatND* arr = (CvMatND*)cvAlloc( sizeof(*arr) ); @@ -301,7 +301,7 @@ CV_IMPL CvMatND* cvCloneMatND( const CvMatND* src ) { if( !CV_IS_MATND_HDR( src )) - CV_Error( CV_StsBadArg, "Bad CvMatND header" ); + CV_Error( cv::Error::StsBadArg, "Bad CvMatND header" ); CV_Assert( src->dims <= CV_MAX_DIM ); int sizes[CV_MAX_DIM]; @@ -335,12 +335,12 @@ cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi ) *coi = 0; if( !matnd || !arr ) - CV_Error( CV_StsNullPtr, "NULL array pointer is passed" ); + CV_Error( cv::Error::StsNullPtr, "NULL array pointer is passed" ); if( CV_IS_MATND_HDR(arr)) { if( !((CvMatND*)arr)->data.ptr ) - CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" ); + CV_Error( cv::Error::StsNullPtr, "The matrix has NULL data pointer" ); result = (CvMatND*)arr; } @@ -352,10 +352,10 @@ cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi ) mat = cvGetMat( mat, &stub, coi ); if( !CV_IS_MAT_HDR( mat )) - CV_Error( CV_StsBadArg, "Unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "Unrecognized or unsupported array type" ); if( !mat->data.ptr ) - CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" ); + CV_Error( cv::Error::StsNullPtr, "Input array has NULL data pointer" ); matnd->data.ptr = mat->data.ptr; matnd->refcount = 0; @@ -393,16 +393,16 @@ cvInitNArrayIterator( int count, CvArr** arrs, CvMatND* hdr0 = 0; if( count < 1 || count > CV_MAX_ARR ) - CV_Error( CV_StsOutOfRange, "Incorrect number of arrays" ); + CV_Error( cv::Error::StsOutOfRange, "Incorrect number of arrays" ); if( !arrs || !stubs ) - CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" ); + CV_Error( cv::Error::StsNullPtr, "Some of required array pointers is NULL" ); if( !iterator ) - CV_Error( CV_StsNullPtr, "Iterator pointer is NULL" ); + CV_Error( cv::Error::StsNullPtr, "Iterator pointer is NULL" ); if (mask) - CV_Error( CV_StsBadArg, "Iterator with mask is not supported" ); + CV_Error( cv::Error::StsBadArg, "Iterator with mask is not supported" ); for( i = 0; i < count; i++ ) { @@ -410,7 +410,7 @@ cvInitNArrayIterator( int count, CvArr** arrs, CvMatND* hdr; if( !arr ) - CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" ); + CV_Error( cv::Error::StsNullPtr, "Some of required array pointers is NULL" ); if( CV_IS_MATND( arr )) hdr = (CvMatND*)arr; @@ -419,7 +419,7 @@ cvInitNArrayIterator( int count, CvArr** arrs, int coi = 0; hdr = cvGetMatND( arr, stubs + i, &coi ); if( coi != 0 ) - CV_Error( CV_BadCOI, "COI set is not allowed here" ); + CV_Error( cv::Error::BadCOI, "COI set is not allowed here" ); } iterator->hdr[i] = hdr; @@ -427,24 +427,24 @@ cvInitNArrayIterator( int count, CvArr** arrs, if( i > 0 ) { if( hdr->dims != hdr0->dims ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "Number of dimensions is the same for all arrays" ); switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK)) { case 0: if( !CV_ARE_TYPES_EQ( hdr, hdr0 )) - CV_Error( CV_StsUnmatchedFormats, + CV_Error( cv::Error::StsUnmatchedFormats, "Data type is not the same for all arrays" ); break; case CV_NO_DEPTH_CHECK: if( !CV_ARE_CNS_EQ( hdr, hdr0 )) - CV_Error( CV_StsUnmatchedFormats, + CV_Error( cv::Error::StsUnmatchedFormats, "Number of channels is not the same for all arrays" ); break; case CV_NO_CN_CHECK: if( !CV_ARE_CNS_EQ( hdr, hdr0 )) - CV_Error( CV_StsUnmatchedFormats, + CV_Error( cv::Error::StsUnmatchedFormats, "Depth is not the same for all arrays" ); break; } @@ -453,7 +453,7 @@ cvInitNArrayIterator( int count, CvArr** arrs, { for( j = 0; j < hdr->dims; j++ ) if( hdr->dim[j].size != hdr0->dim[j].size ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "Dimension sizes are the same for all arrays" ); } } @@ -536,18 +536,18 @@ cvCreateSparseMat( int dims, const int* sizes, int type ) CvMemStorage* storage; if( pix_size == 0 ) - CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "invalid array data type" ); if( dims <= 0 || dims > CV_MAX_DIM ) - CV_Error( CV_StsOutOfRange, "bad number of dimensions" ); + CV_Error( cv::Error::StsOutOfRange, "bad number of dimensions" ); if( !sizes ) - CV_Error( CV_StsNullPtr, "NULL pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL pointer" ); for( i = 0; i < dims; i++ ) { if( sizes[i] <= 0 ) - CV_Error( CV_StsBadSize, "one of dimension sizes is non-positive" ); + CV_Error( cv::Error::StsBadSize, "one of dimension sizes is non-positive" ); } CvSparseMat* arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0])); @@ -587,7 +587,7 @@ cvReleaseSparseMat( CvSparseMat** array ) CvSparseMat* arr = *array; if( !CV_IS_SPARSE_MAT_HDR(arr) ) - CV_Error( CV_StsBadFlag, "" ); + CV_Error( cv::Error::StsBadFlag, "" ); *array = 0; @@ -604,7 +604,7 @@ CV_IMPL CvSparseMat* cvCloneSparseMat( const CvSparseMat* src ) { if( !CV_IS_SPARSE_MAT_HDR(src) ) - CV_Error( CV_StsBadArg, "Invalid sparse array header" ); + CV_Error( cv::Error::StsBadArg, "Invalid sparse array header" ); CvSparseMat* dst = cvCreateSparseMat( src->dims, src->size, src->type ); cvCopy( src, dst ); @@ -619,10 +619,10 @@ cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator ) int idx; if( !CV_IS_SPARSE_MAT( mat )) - CV_Error( CV_StsBadArg, "Invalid sparse matrix header" ); + CV_Error( cv::Error::StsBadArg, "Invalid sparse matrix header" ); if( !iterator ) - CV_Error( CV_StsNullPtr, "NULL iterator pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL iterator pointer" ); iterator->mat = (CvSparseMat*)mat; iterator->node = 0; @@ -656,7 +656,7 @@ icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type, { int t = idx[i]; if( (unsigned)t >= (unsigned)mat->size[i] ) - CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "One of indices is out of range" ); hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; } } @@ -750,7 +750,7 @@ icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval ) { int t = idx[i]; if( (unsigned)t >= (unsigned)mat->size[i] ) - CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "One of indices is out of range" ); hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; } } @@ -805,7 +805,7 @@ cvCreateData( CvArr* arr ) return; if( mat->data.ptr != 0 ) - CV_Error( CV_StsError, "Data is already allocated" ); + CV_Error( cv::Error::StsError, "Data is already allocated" ); if( step == 0 ) step = CV_ELEM_SIZE(mat->type)*mat->cols; @@ -813,7 +813,7 @@ cvCreateData( CvArr* arr ) int64 _total_size = (int64)step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN; total_size = (size_t)_total_size; if(_total_size != (int64)total_size) - CV_Error(CV_StsNoMem, "Too big buffer is allocated" ); + CV_Error(cv::Error::StsNoMem, "Too big buffer is allocated" ); mat->refcount = (int*)cvAlloc( (size_t)total_size ); mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN ); *mat->refcount = 1; @@ -823,13 +823,13 @@ cvCreateData( CvArr* arr ) IplImage* img = (IplImage*)arr; if( img->imageData != 0 ) - CV_Error( CV_StsError, "Data is already allocated" ); + CV_Error( cv::Error::StsError, "Data is already allocated" ); if( !CvIPL.allocateData ) { const int64 imageSize_tmp = (int64)img->widthStep*(int64)img->height; if( (int64)img->imageSize != imageSize_tmp ) - CV_Error( CV_StsNoMem, "Overflow for imageSize" ); + CV_Error( cv::Error::StsNoMem, "Overflow for imageSize" ); img->imageData = img->imageDataOrigin = (char*)cvAlloc( (size_t)img->imageSize ); } @@ -859,7 +859,7 @@ cvCreateData( CvArr* arr ) return; if( mat->data.ptr != 0 ) - CV_Error( CV_StsError, "Data is already allocated" ); + CV_Error( cv::Error::StsError, "Data is already allocated" ); if( CV_IS_MAT_CONT( mat->type )) { @@ -884,7 +884,7 @@ cvCreateData( CvArr* arr ) *mat->refcount = 1; } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } @@ -908,7 +908,7 @@ cvSetData( CvArr* arr, void* data, int step ) if( step != CV_AUTOSTEP && step != 0 ) { if( step < min_step && data != 0 ) - CV_Error( CV_BadStep, "" ); + CV_Error( cv::Error::BadStep, "" ); mat->step = step; } else @@ -929,7 +929,7 @@ cvSetData( CvArr* arr, void* data, int step ) if( step != CV_AUTOSTEP && img->height > 1 ) { if( step < min_step && data != 0 ) - CV_Error( CV_BadStep, "" ); + CV_Error( cv::Error::BadStep, "" ); img->widthStep = step; } else @@ -940,7 +940,7 @@ cvSetData( CvArr* arr, void* data, int step ) const int64 imageSize_tmp = (int64)img->widthStep*(int64)img->height; img->imageSize = (int)imageSize_tmp; if( (int64)img->imageSize != imageSize_tmp ) - CV_Error( CV_StsNoMem, "Overflow for imageSize" ); + CV_Error( cv::Error::StsNoMem, "Overflow for imageSize" ); img->imageData = img->imageDataOrigin = (char*)data; if( (((int)(size_t)data | step) & 7) == 0 && @@ -956,7 +956,7 @@ cvSetData( CvArr* arr, void* data, int step ) int64 cur_step; if( step != CV_AUTOSTEP ) - CV_Error( CV_BadStep, + CV_Error( cv::Error::BadStep, "For multidimensional array only CV_AUTOSTEP is allowed here" ); mat->data.ptr = (uchar*)data; @@ -965,13 +965,13 @@ cvSetData( CvArr* arr, void* data, int step ) for( i = mat->dims - 1; i >= 0; i-- ) { if( cur_step > INT_MAX ) - CV_Error( CV_StsOutOfRange, "The array is too big" ); + CV_Error( cv::Error::StsOutOfRange, "The array is too big" ); mat->dim[i].step = (int)cur_step; cur_step *= mat->dim[i].size; } } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } @@ -1000,7 +1000,7 @@ cvReleaseData( CvArr* arr ) } } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } @@ -1048,7 +1048,7 @@ cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size ) CvMatND* mat = (CvMatND*)arr; if( !CV_IS_MAT_CONT( mat->type )) - CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); + CV_Error( cv::Error::StsBadArg, "Only continuous nD arrays are supported here" ); if( data ) *data = mat->data.ptr; @@ -1077,7 +1077,7 @@ cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size ) } } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } @@ -1093,7 +1093,7 @@ cvGetElemType( const CvArr* arr ) type = CV_MAKETYPE( IPL2CV_DEPTH(img->depth), img->nChannels ); } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); return type; } @@ -1147,7 +1147,7 @@ cvGetDims( const CvArr* arr, int* sizes ) memcpy( sizes, mat->size, dims*sizeof(sizes[0])); } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); return dims; } @@ -1172,7 +1172,7 @@ cvGetDimSize( const CvArr* arr, int index ) size = mat->cols; break; default: - CV_Error( CV_StsOutOfRange, "bad dimension index" ); + CV_Error( cv::Error::StsOutOfRange, "bad dimension index" ); } } else if( CV_IS_IMAGE( arr )) @@ -1188,7 +1188,7 @@ cvGetDimSize( const CvArr* arr, int index ) size = !img->roi ? img->width : img->roi->width; break; default: - CV_Error( CV_StsOutOfRange, "bad dimension index" ); + CV_Error( cv::Error::StsOutOfRange, "bad dimension index" ); } } else if( CV_IS_MATND_HDR( arr )) @@ -1196,7 +1196,7 @@ cvGetDimSize( const CvArr* arr, int index ) CvMatND* mat = (CvMatND*)arr; if( (unsigned)index >= (unsigned)mat->dims ) - CV_Error( CV_StsOutOfRange, "bad dimension index" ); + CV_Error( cv::Error::StsOutOfRange, "bad dimension index" ); size = mat->dim[index].size; } @@ -1205,12 +1205,12 @@ cvGetDimSize( const CvArr* arr, int index ) CvSparseMat* mat = (CvSparseMat*)arr; if( (unsigned)index >= (unsigned)mat->dims ) - CV_Error( CV_StsOutOfRange, "bad dimension index" ); + CV_Error( cv::Error::StsOutOfRange, "bad dimension index" ); size = mat->size[index]; } else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); return size; } @@ -1245,7 +1245,7 @@ cvGetSize( const CvArr* arr ) } } else - CV_Error( CV_StsBadArg, "Array should be CvMat or IplImage" ); + CV_Error( cv::Error::StsBadArg, "Array should be CvMat or IplImage" ); return size; } @@ -1262,14 +1262,14 @@ cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect ) mat = cvGetMat( mat, &stub ); if( !submat ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( (rect.x|rect.y|rect.width|rect.height) < 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); if( rect.x + rect.width > mat->cols || rect.y + rect.height > mat->rows ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); { /* @@ -1307,11 +1307,11 @@ cvGetRows( const CvArr* arr, CvMat* submat, mat = cvGetMat( mat, &stub ); if( !submat ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( (unsigned)start_row >= (unsigned)mat->rows || (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); { /* @@ -1359,12 +1359,12 @@ cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col ) mat = cvGetMat( mat, &stub ); if( !submat ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cols = mat->cols; if( (unsigned)start_col >= (unsigned)cols || (unsigned)end_col > (unsigned)cols ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); { /* @@ -1401,7 +1401,7 @@ cvGetDiag( const CvArr* arr, CvMat* submat, int diag ) mat = cvGetMat( mat, &stub ); if( !submat ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); pix_size = CV_ELEM_SIZE(mat->type); @@ -1419,7 +1419,7 @@ cvGetDiag( const CvArr* arr, CvMat* submat, int diag ) len = mat->cols - diag; if( len <= 0 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); len = CV_IMIN( len, mat->rows ); submat->data.ptr = mat->data.ptr + diag*pix_size; @@ -1429,7 +1429,7 @@ cvGetDiag( const CvArr* arr, CvMat* submat, int diag ) len = mat->rows + diag; if( len <= 0 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); len = CV_IMIN( len, mat->cols ); submat->data.ptr = mat->data.ptr - diag*mat->step; @@ -1464,7 +1464,7 @@ cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_1 CV_Assert( scalar && data ); if( (unsigned)(cn - 1) >= 4 ) - CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); + CV_Error( cv::Error::StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); switch( depth ) { @@ -1510,7 +1510,7 @@ cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_1 break; default: CV_Assert(0); - CV_Error( CV_BadDepth, "" ); + CV_Error( cv::Error::BadDepth, "" ); } if( extend_to_12 ) @@ -1537,7 +1537,7 @@ cvRawDataToScalar( const void* data, int flags, CvScalar* scalar ) CV_Assert( scalar && data ); if( (unsigned)(cn - 1) >= 4 ) - CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); + CV_Error( cv::Error::StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); memset( scalar->val, 0, sizeof(scalar->val)); @@ -1573,7 +1573,7 @@ cvRawDataToScalar( const void* data, int flags, CvScalar* scalar ) break; default: CV_Assert(0); - CV_Error( CV_BadDepth, "" ); + CV_Error( cv::Error::BadDepth, "" ); } } @@ -1660,7 +1660,7 @@ cvPtr1D( const CvArr* arr, int idx, int* _type ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); if( CV_IS_MAT_CONT(mat->type)) { @@ -1697,7 +1697,7 @@ cvPtr1D( const CvArr* arr, int idx, int* _type ) size *= mat->dim[j].size; if((unsigned)idx >= (unsigned)size ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); if( CV_IS_MAT_CONT(mat->type)) { @@ -1741,7 +1741,7 @@ cvPtr1D( const CvArr* arr, int idx, int* _type ) } else { - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } return ptr; @@ -1760,7 +1760,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); if( _type ) @@ -1790,7 +1790,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) { int coi = img->roi->coi; if( !coi ) - CV_Error( CV_BadCOI, + CV_Error( cv::Error::BadCOI, "COI must be non-null in case of planar images" ); ptr += (coi - 1)*img->imageSize; } @@ -1803,7 +1803,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) if( (unsigned)y >= (unsigned)height || (unsigned)x >= (unsigned)width ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr += y*img->widthStep + x*pix_size; @@ -1811,7 +1811,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) { int type = IPL2CV_DEPTH(img->depth); if( type < 0 || (unsigned)(img->nChannels - 1) > 3 ) - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); *_type = CV_MAKETYPE( type, img->nChannels ); } @@ -1823,7 +1823,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) if( mat->dims != 2 || (unsigned)y >= (unsigned)(mat->dim[0].size) || (unsigned)x >= (unsigned)(mat->dim[1].size) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step; if( _type ) @@ -1837,7 +1837,7 @@ cvPtr2D( const CvArr* arr, int y, int x, int* _type ) } else { - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } return ptr; @@ -1857,7 +1857,7 @@ cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type ) (unsigned)z >= (unsigned)(mat->dim[0].size) || (unsigned)y >= (unsigned)(mat->dim[1].size) || (unsigned)x >= (unsigned)(mat->dim[2].size) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)z*mat->dim[0].step + (size_t)y*mat->dim[1].step + x*mat->dim[2].step; @@ -1872,7 +1872,7 @@ cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type ) } else { - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); } return ptr; @@ -1886,7 +1886,7 @@ cvPtrND( const CvArr* arr, const int* idx, int* _type, { uchar* ptr = 0; if( !idx ) - CV_Error( CV_StsNullPtr, "NULL pointer to indices" ); + CV_Error( cv::Error::StsNullPtr, "NULL pointer to indices" ); if( CV_IS_SPARSE_MAT( arr )) ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, @@ -1900,7 +1900,7 @@ cvPtrND( const CvArr* arr, const int* idx, int* _type, for( i = 0; i < mat->dims; i++ ) { if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr += (size_t)idx[i]*mat->dim[i].step; } @@ -1910,7 +1910,7 @@ cvPtrND( const CvArr* arr, const int* idx, int* _type, else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) ) ptr = cvPtr2D( arr, idx[0], idx[1], _type ); else - CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadArg, "unrecognized or unsupported array type" ); return ptr; } @@ -1935,7 +1935,7 @@ cvGet1D( const CvArr* arr, int idx ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)idx*pix_size; } @@ -1965,7 +1965,7 @@ cvGet2D( const CvArr* arr, int y, int x ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); @@ -2046,7 +2046,7 @@ cvGetReal1D( const CvArr* arr, int idx ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)idx*pix_size; } @@ -2058,7 +2058,7 @@ cvGetReal1D( const CvArr* arr, int idx ) if( ptr ) { if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvGetReal* support only single-channel arrays" ); value = icvGetReal( ptr, type ); } @@ -2080,7 +2080,7 @@ cvGetReal2D( const CvArr* arr, int y, int x ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); @@ -2096,7 +2096,7 @@ cvGetReal2D( const CvArr* arr, int y, int x ) if( ptr ) { if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvGetReal* support only single-channel arrays" ); value = icvGetReal( ptr, type ); } @@ -2124,7 +2124,7 @@ cvGetReal3D( const CvArr* arr, int z, int y, int x ) if( ptr ) { if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvGetReal* support only single-channel arrays" ); value = icvGetReal( ptr, type ); } @@ -2149,7 +2149,7 @@ cvGetRealND( const CvArr* arr, const int* idx ) if( ptr ) { if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvGetReal* support only single-channel arrays" ); value = icvGetReal( ptr, type ); } @@ -2176,7 +2176,7 @@ cvSet1D( CvArr* arr, int idx, CvScalar scalar ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)idx*pix_size; } @@ -2202,7 +2202,7 @@ cvSet2D( CvArr* arr, int y, int x, CvScalar scalar ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); @@ -2268,7 +2268,7 @@ cvSetReal1D( CvArr* arr, int idx, double value ) // that the index is within the matrix if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); ptr = mat->data.ptr + (size_t)idx*pix_size; } @@ -2278,7 +2278,7 @@ cvSetReal1D( CvArr* arr, int idx, double value ) ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 ); if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvSetReal* support only single-channel arrays" ); if( ptr ) icvSetReal( value, ptr, type ); @@ -2297,7 +2297,7 @@ cvSetReal2D( CvArr* arr, int y, int x, double value ) if( (unsigned)y >= (unsigned)(mat->rows) || (unsigned)x >= (unsigned)(mat->cols) ) - CV_Error( CV_StsOutOfRange, "index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "index is out of range" ); type = CV_MAT_TYPE(mat->type); ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); @@ -2312,7 +2312,7 @@ cvSetReal2D( CvArr* arr, int y, int x, double value ) ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); } if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvSetReal* support only single-channel arrays" ); if( ptr ) icvSetReal( value, ptr, type ); @@ -2333,7 +2333,7 @@ cvSetReal3D( CvArr* arr, int z, int y, int x, double value ) ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); } if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvSetReal* support only single-channel arrays" ); if( ptr ) icvSetReal( value, ptr, type ); @@ -2352,7 +2352,7 @@ cvSetRealND( CvArr* arr, const int* idx, double value ) ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); if( CV_MAT_CN( type ) > 1 ) - CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); + CV_Error( cv::Error::BadNumChannels, "cvSetReal* support only single-channel arrays" ); if( ptr ) icvSetReal( value, ptr, type ); @@ -2389,12 +2389,12 @@ cvGetMat( const CvArr* array, CvMat* mat, int coi = 0; if( !mat || !src ) - CV_Error( CV_StsNullPtr, "NULL array pointer is passed" ); + CV_Error( cv::Error::StsNullPtr, "NULL array pointer is passed" ); if( CV_IS_MAT_HDR(src)) { if( !src->data.ptr ) - CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" ); + CV_Error( cv::Error::StsNullPtr, "The matrix has NULL data pointer" ); result = (CvMat*)src; } @@ -2404,11 +2404,11 @@ cvGetMat( const CvArr* array, CvMat* mat, int depth, order; if( img->imageData == 0 ) - CV_Error( CV_StsNullPtr, "The image has NULL data pointer" ); + CV_Error( cv::Error::StsNullPtr, "The image has NULL data pointer" ); depth = IPL2CV_DEPTH( img->depth ); if( depth < 0 ) - CV_Error( CV_BadDepth, "" ); + CV_Error( cv::Error::BadDepth, "" ); order = img->dataOrder & (img->nChannels > 1 ? -1 : 0); @@ -2419,7 +2419,7 @@ cvGetMat( const CvArr* array, CvMat* mat, int type = depth; if( img->roi->coi == 0 ) - CV_Error( CV_StsBadFlag, + CV_Error( cv::Error::StsBadFlag, "Images with planar data layout should be used with COI selected" ); cvInitMatHeader( mat, img->roi->height, @@ -2435,7 +2435,7 @@ cvGetMat( const CvArr* array, CvMat* mat, coi = img->roi->coi; if( img->nChannels > CV_CN_MAX ) - CV_Error( CV_BadNumChannels, + CV_Error( cv::Error::BadNumChannels, "The image is interleaved and has over CV_CN_MAX channels" ); cvInitMatHeader( mat, img->roi->height, img->roi->width, @@ -2450,7 +2450,7 @@ cvGetMat( const CvArr* array, CvMat* mat, int type = CV_MAKETYPE( depth, img->nChannels ); if( order != IPL_DATA_ORDER_PIXEL ) - CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" ); + CV_Error( cv::Error::StsBadFlag, "Pixel order should be used with coi == 0" ); cvInitMatHeader( mat, img->height, img->width, type, img->imageData, img->widthStep ); @@ -2464,10 +2464,10 @@ cvGetMat( const CvArr* array, CvMat* mat, int size1 = matnd->dim[0].size, size2 = 1; if( !src->data.ptr ) - CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" ); + CV_Error( cv::Error::StsNullPtr, "Input array has NULL data pointer" ); if( !CV_IS_MAT_CONT( matnd->type )) - CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); + CV_Error( cv::Error::StsBadArg, "Only continuous nD arrays are supported here" ); if( matnd->dims > 2 ) { @@ -2491,7 +2491,7 @@ cvGetMat( const CvArr* array, CvMat* mat, result = mat; } else - CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" ); + CV_Error( cv::Error::StsBadFlag, "Unrecognized or unsupported array type" ); if( pCOI ) *pCOI = coi; @@ -2509,10 +2509,10 @@ cvReshapeMatND( const CvArr* arr, int dims, coi = 0; if( !arr || !_header ) - CV_Error( CV_StsNullPtr, "NULL pointer to array or destination header" ); + CV_Error( cv::Error::StsNullPtr, "NULL pointer to array or destination header" ); if( new_cn == 0 && new_dims == 0 ) - CV_Error( CV_StsBadArg, "None of array parameters is changed: dummy call?" ); + CV_Error( cv::Error::StsBadArg, "None of array parameters is changed: dummy call?" ); dims = cvGetDims( arr ); @@ -2528,9 +2528,9 @@ cvReshapeMatND( const CvArr* arr, else { if( new_dims <= 0 || new_dims > CV_MAX_DIM ) - CV_Error( CV_StsOutOfRange, "Non-positive or too large number of dimensions" ); + CV_Error( cv::Error::StsOutOfRange, "Non-positive or too large number of dimensions" ); if( !new_sizes ) - CV_Error( CV_StsNullPtr, "New dimension sizes are not specified" ); + CV_Error( cv::Error::StsNullPtr, "New dimension sizes are not specified" ); } if( new_dims <= 2 ) @@ -2542,7 +2542,7 @@ cvReshapeMatND( const CvArr* arr, int total_width, new_rows, cn; if( sizeof_header != sizeof(CvMat) && sizeof_header != sizeof(CvMatND) ) - CV_Error( CV_StsBadArg, "The output header should be CvMat or CvMatND" ); + CV_Error( cv::Error::StsBadArg, "The output header should be CvMat or CvMatND" ); if( mat == (CvMat*)_header ) { @@ -2575,13 +2575,13 @@ cvReshapeMatND( const CvArr* arr, int total_size = total_width * mat->rows; if( !CV_IS_MAT_CONT( mat->type )) - CV_Error( CV_BadStep, + CV_Error( cv::Error::BadStep, "The matrix is not continuous so the number of rows can not be changed" ); total_width = total_size / new_rows; if( total_width * new_rows != total_size ) - CV_Error( CV_StsBadArg, "The total number of matrix elements " + CV_Error( cv::Error::StsBadArg, "The total number of matrix elements " "is not divisible by the new number of rows" ); } @@ -2590,7 +2590,7 @@ cvReshapeMatND( const CvArr* arr, if( header.cols * new_cn != total_width || (new_sizes && header.cols != new_sizes[1]) ) - CV_Error( CV_StsBadArg, "The total matrix width is not " + CV_Error( cv::Error::StsBadArg, "The total matrix width is not " "divisible by the new number of columns" ); header.type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn); @@ -2614,12 +2614,12 @@ cvReshapeMatND( const CvArr* arr, CvMatND* header = (CvMatND*)_header; if( sizeof_header != sizeof(CvMatND)) - CV_Error( CV_StsBadSize, "The output header should be CvMatND" ); + CV_Error( cv::Error::StsBadSize, "The output header should be CvMatND" ); if( !new_sizes ) { if( !CV_IS_MATND( arr )) - CV_Error( CV_StsBadArg, "The input array must be CvMatND" ); + CV_Error( cv::Error::StsBadArg, "The input array must be CvMatND" ); { CvMatND* mat = (CvMatND*)arr; @@ -2628,7 +2628,7 @@ cvReshapeMatND( const CvArr* arr, int new_size = last_dim_size/new_cn; if( new_size*new_cn != last_dim_size ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The last dimension full size is not divisible by new number of channels"); if( mat != header ) @@ -2650,7 +2650,7 @@ cvReshapeMatND( const CvArr* arr, int step; if( new_cn != 0 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Simultaneous change of shape and number of channels is not supported. " "Do it by 2 separate calls" ); @@ -2661,7 +2661,7 @@ cvReshapeMatND( const CvArr* arr, } if( CV_IS_MAT_CONT( mat->type )) - CV_Error( CV_StsBadArg, "Non-continuous nD arrays are not supported" ); + CV_Error( cv::Error::StsBadArg, "Non-continuous nD arrays are not supported" ); size1 = mat->dim[0].size; for( i = 1; i < dims; i++ ) @@ -2671,13 +2671,13 @@ cvReshapeMatND( const CvArr* arr, for( i = 0; i < new_dims; i++ ) { if( new_sizes[i] <= 0 ) - CV_Error( CV_StsBadSize, + CV_Error( cv::Error::StsBadSize, "One of new dimension sizes is non-positive" ); size2 *= new_sizes[i]; } if( size1 != size2 ) - CV_Error( CV_StsBadSize, + CV_Error( cv::Error::StsBadSize, "Number of elements in the original and reshaped array is different" ); if( header != mat ) @@ -2701,7 +2701,7 @@ cvReshapeMatND( const CvArr* arr, } if( coi ) - CV_Error( CV_BadCOI, "COI is not supported by this operation" ); + CV_Error( cv::Error::BadCOI, "COI is not supported by this operation" ); result = _header; return result; @@ -2717,20 +2717,20 @@ cvReshape( const CvArr* array, CvMat* header, int total_width, new_width; if( !header ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !CV_IS_MAT( mat )) { int coi = 0; mat = cvGetMat( mat, header, &coi, 1 ); if( coi ) - CV_Error( CV_BadCOI, "COI is not supported" ); + CV_Error( cv::Error::BadCOI, "COI is not supported" ); } if( new_cn == 0 ) new_cn = CV_MAT_CN(mat->type); else if( (unsigned)(new_cn - 1) > 3 ) - CV_Error( CV_BadNumChannels, "" ); + CV_Error( cv::Error::BadNumChannels, "" ); if( mat != header ) { @@ -2754,16 +2754,16 @@ cvReshape( const CvArr* array, CvMat* header, { int total_size = total_width * mat->rows; if( !CV_IS_MAT_CONT( mat->type )) - CV_Error( CV_BadStep, + CV_Error( cv::Error::BadStep, "The matrix is not continuous, thus its number of rows can not be changed" ); if( (unsigned)new_rows > (unsigned)total_size ) - CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); + CV_Error( cv::Error::StsOutOfRange, "Bad new number of rows" ); total_width = total_size / new_rows; if( total_width * new_rows != total_size ) - CV_Error( CV_StsBadArg, "The total number of matrix elements " + CV_Error( cv::Error::StsBadArg, "The total number of matrix elements " "is not divisible by the new number of rows" ); header->rows = new_rows; @@ -2773,7 +2773,7 @@ cvReshape( const CvArr* array, CvMat* header, new_width = total_width / new_cn; if( new_width * new_cn != total_width ) - CV_Error( CV_BadNumChannels, + CV_Error( cv::Error::BadNumChannels, "The total width is not divisible by the new number of channels" ); header->cols = new_width; @@ -2792,17 +2792,17 @@ cvGetImage( const CvArr* array, IplImage* img ) const IplImage* src = (const IplImage*)array; if( !img ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !CV_IS_IMAGE_HDR(src) ) { const CvMat* mat = (const CvMat*)src; if( !CV_IS_MAT_HDR(mat)) - CV_Error( CV_StsBadFlag, "" ); + CV_Error( cv::Error::StsBadFlag, "" ); if( mat->data.ptr == 0 ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); int depth = cvIplDepth(mat->type); @@ -2942,7 +2942,7 @@ cvInitImageHeader( IplImage * image, CvSize size, int depth, depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S && depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) || channels < 0 ) - CV_Error( CV_BadDepth, "Unsupported format" ); + CV_Error( cv::Error::BadDepth, "Unsupported format" ); if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL ) CV_Error( CV_BadOrigin, "Bad input origin" ); @@ -2969,7 +2969,7 @@ cvInitImageHeader( IplImage * image, CvSize size, int depth, const int64 imageSize_tmp = (int64)image->widthStep*(int64)image->height; image->imageSize = (int)imageSize_tmp; if( (int64)image->imageSize != imageSize_tmp ) - CV_Error( CV_StsNoMem, "Overflow for imageSize" ); + CV_Error( cv::Error::StsNoMem, "Overflow for imageSize" ); return image; } @@ -2979,7 +2979,7 @@ CV_IMPL void cvReleaseImageHeader( IplImage** image ) { if( !image ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( *image ) { @@ -3003,7 +3003,7 @@ CV_IMPL void cvReleaseImage( IplImage ** image ) { if( !image ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( *image ) { @@ -3077,7 +3077,7 @@ cvGetImageROI( const IplImage* img ) { CvRect rect = {0, 0, 0, 0}; if( !img ) - CV_Error( CV_StsNullPtr, "Null pointer to image" ); + CV_Error( cv::Error::StsNullPtr, "Null pointer to image" ); if( img->roi ) rect = cvRect( img->roi->xOffset, img->roi->yOffset, @@ -3096,7 +3096,7 @@ cvSetImageCOI( IplImage* image, int coi ) CV_Error( CV_HeaderIsNull, "" ); if( (unsigned)coi > (unsigned)(image->nChannels) ) - CV_Error( CV_BadCOI, "" ); + CV_Error( cv::Error::BadCOI, "" ); if( image->roi || coi != 0 ) { @@ -3128,7 +3128,7 @@ cvCloneImage( const IplImage* src ) IplImage* dst = 0; if( !CV_IS_IMAGE_HDR( src )) - CV_Error( CV_StsBadArg, "Bad image header" ); + CV_Error( cv::Error::StsBadArg, "Bad image header" ); if( !CvIPL.cloneImage ) { @@ -3174,13 +3174,13 @@ cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, crit.epsilon = (float)default_eps; if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Unknown type of term criteria" ); if( (criteria.type & CV_TERMCRIT_ITER) != 0 ) { if( criteria.max_iter <= 0 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Iterations flag is set and maximum number of iterations is <= 0" ); crit.max_iter = criteria.max_iter; } @@ -3188,13 +3188,13 @@ cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, if( (criteria.type & CV_TERMCRIT_EPS) != 0 ) { if( criteria.epsilon < 0 ) - CV_Error( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" ); + CV_Error( cv::Error::StsBadArg, "Accuracy flag is set and epsilon is < 0" ); crit.epsilon = criteria.epsilon; } if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Neither accuracy nor maximum iterations " "number flags are set in criteria type" ); @@ -3221,7 +3221,7 @@ CV_IMPL void cvRelease( void** struct_ptr ) { if( !struct_ptr ) - CV_Error( CV_StsNullPtr, "NULL double pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL double pointer" ); if( *struct_ptr ) { @@ -3230,7 +3230,7 @@ cvRelease( void** struct_ptr ) else if( CV_IS_IMAGE(*struct_ptr)) cvReleaseImage((IplImage**)struct_ptr); else - CV_Error( CV_StsError, "Unknown object type" ); + CV_Error( cv::Error::StsError, "Unknown object type" ); } } @@ -3238,14 +3238,14 @@ void* cvClone( const void* struct_ptr ) { void* ptr = 0; if( !struct_ptr ) - CV_Error( CV_StsNullPtr, "NULL structure pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL structure pointer" ); if( CV_IS_MAT(struct_ptr) ) ptr = cvCloneMat((const CvMat*)struct_ptr); else if( CV_IS_IMAGE(struct_ptr)) ptr = cvCloneImage((const IplImage*)struct_ptr); else - CV_Error( CV_StsError, "Unknown object type" ); + CV_Error( cv::Error::StsError, "Unknown object type" ); return ptr; } diff --git a/modules/core/src/batch_distance.cpp b/modules/core/src/batch_distance.cpp index 1ce2edb769..4210c672b9 100644 --- a/modules/core/src/batch_distance.cpp +++ b/modules/core/src/batch_distance.cpp @@ -377,7 +377,7 @@ void cv::batchDistance( InputArray _src1, InputArray _src2, } if( func == 0 ) - CV_Error_(CV_StsUnsupportedFormat, + CV_Error_(cv::Error::StsUnsupportedFormat, ("The combination of type=%d, dtype=%d and normType=%d is not supported", type, dtype, normType)); diff --git a/modules/core/src/command_line_parser.cpp b/modules/core/src/command_line_parser.cpp index af97232db6..a83cb3166d 100644 --- a/modules/core/src/command_line_parser.cpp +++ b/modules/core/src/command_line_parser.cpp @@ -464,7 +464,7 @@ std::vector CommandLineParser::Impl::split_range_string(const String& _s { if (begin == true) { - throw cv::Exception(CV_StsParseError, + throw cv::Exception(cv::Error::StsParseError, String("error in split_range_string(") + str + String(", ") @@ -484,7 +484,7 @@ std::vector CommandLineParser::Impl::split_range_string(const String& _s { if (begin == false) { - throw cv::Exception(CV_StsParseError, + throw cv::Exception(cv::Error::StsParseError, String("error in split_range_string(") + str + String(", ") @@ -508,7 +508,7 @@ std::vector CommandLineParser::Impl::split_range_string(const String& _s if (begin == true) { - throw cv::Exception(CV_StsParseError, + throw cv::Exception(cv::Error::StsParseError, String("error in split_range_string(") + str + String(", ") diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index d641c6f497..f4c98b49c0 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -96,7 +96,7 @@ void scalarToRawData(const Scalar& s, void* _buf, int type, int unroll_to) scalarToRawData_(s, (float16_t*)_buf, cn, unroll_to); break; default: - CV_Error(CV_StsUnsupportedFormat,""); + CV_Error(cv::Error::StsUnsupportedFormat,""); } } @@ -788,7 +788,7 @@ int cv::borderInterpolate( int p, int len, int borderType ) else if( borderType == BORDER_CONSTANT ) p = -1; else - CV_Error( CV_StsBadArg, "Unknown/unsupported border type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported border type" ); return p; } diff --git a/modules/core/src/datastructs.cpp b/modules/core/src/datastructs.cpp index 80b02283dc..17da7119a3 100644 --- a/modules/core/src/datastructs.cpp +++ b/modules/core/src/datastructs.cpp @@ -91,7 +91,7 @@ static void icvInitMemStorage( CvMemStorage* storage, int block_size ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( block_size <= 0 ) block_size = CV_STORAGE_BLOCK_SIZE; @@ -120,7 +120,7 @@ CV_IMPL CvMemStorage * cvCreateChildMemStorage( CvMemStorage * parent ) { if( !parent ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvMemStorage* storage = cvCreateMemStorage(parent->block_size); storage->parent = parent; @@ -137,7 +137,7 @@ icvDestroyMemStorage( CvMemStorage* storage ) CvMemBlock *dst_top = 0; if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( storage->parent ) dst_top = storage->parent->top; @@ -180,7 +180,7 @@ CV_IMPL void cvReleaseMemStorage( CvMemStorage** storage ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvMemStorage* st = *storage; *storage = 0; @@ -197,7 +197,7 @@ CV_IMPL void cvClearMemStorage( CvMemStorage * storage ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( storage->parent ) icvDestroyMemStorage( storage ); @@ -215,7 +215,7 @@ static void icvGoNextMemBlock( CvMemStorage * storage ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !storage->top || !storage->top->next ) { @@ -273,7 +273,7 @@ CV_IMPL void cvSaveMemStoragePos( const CvMemStorage * storage, CvMemStoragePos * pos ) { if( !storage || !pos ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); pos->top = storage->top; pos->free_space = storage->free_space; @@ -285,9 +285,9 @@ CV_IMPL void cvRestoreMemStoragePos( CvMemStorage * storage, CvMemStoragePos * pos ) { if( !storage || !pos ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( pos->free_space > storage->block_size ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); /* // this breaks icvGoNextMemBlock, so comment it off for now @@ -324,10 +324,10 @@ cvMemStorageAlloc( CvMemStorage* storage, size_t size ) { schar *ptr = 0; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); if( size > INT_MAX ) - CV_Error( CV_StsOutOfRange, "Too large memory block is requested" ); + CV_Error( cv::Error::StsOutOfRange, "Too large memory block is requested" ); CV_Assert( storage->free_space % CV_STRUCT_ALIGN == 0 ); @@ -335,7 +335,7 @@ cvMemStorageAlloc( CvMemStorage* storage, size_t size ) { size_t max_free_space = cvAlignLeft(storage->block_size - sizeof(CvMemBlock), CV_STRUCT_ALIGN); if( max_free_space < size ) - CV_Error( CV_StsOutOfRange, "requested size is negative or too big" ); + CV_Error( cv::Error::StsOutOfRange, "requested size is negative or too big" ); icvGoNextMemBlock( storage ); } @@ -374,9 +374,9 @@ cvCreateSeq( int seq_flags, size_t header_size, size_t elem_size, CvMemStorage* CvSeq *seq = 0; if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( header_size < sizeof( CvSeq ) || elem_size <= 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); /* allocate sequence header */ seq = (CvSeq*)cvMemStorageAlloc( storage, header_size ); @@ -390,7 +390,7 @@ cvCreateSeq( int seq_flags, size_t header_size, size_t elem_size, CvMemStorage* if( elemtype != CV_SEQ_ELTYPE_GENERIC && elemtype != CV_SEQ_ELTYPE_PTR && typesize != 0 && typesize != (int)elem_size ) - CV_Error( CV_StsBadSize, + CV_Error( cv::Error::StsBadSize, "Specified element size doesn't match to the size of the specified element type " "(try to use 0 for element type)" ); } @@ -412,9 +412,9 @@ cvSetSeqBlockSize( CvSeq *seq, int delta_elements ) int useful_block_size; if( !seq || !seq->storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( delta_elements < 0 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); useful_block_size = cvAlignLeft(seq->storage->block_size - sizeof(CvMemBlock) - sizeof(CvSeqBlock), CV_STRUCT_ALIGN); @@ -429,7 +429,7 @@ cvSetSeqBlockSize( CvSeq *seq, int delta_elements ) { delta_elements = useful_block_size / elem_size; if( delta_elements == 0 ) - CV_Error( CV_StsOutOfRange, "Storage block size is too small " + CV_Error( cv::Error::StsOutOfRange, "Storage block size is too small " "to fit the sequence elements" ); } @@ -487,7 +487,7 @@ cvSeqElemIdx( const CvSeq* seq, const void* _element, CvSeqBlock** _block ) CvSeqBlock *block; if( !seq || !element ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); block = first_block = seq->first; elem_size = seq->elem_size; @@ -548,7 +548,7 @@ cvCvtSeqToArray( const CvSeq *seq, void *array, CvSlice slice ) char *dst = (char*)array; if( !seq || !array ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; total = cvSliceLength( slice, seq )*elem_size; @@ -587,10 +587,10 @@ cvMakeSeqHeaderForArray( int seq_flags, int header_size, int elem_size, CvSeq* result = 0; if( elem_size <= 0 || header_size < (int)sizeof( CvSeq ) || total < 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); if( !seq || ((!array || !block) && total > 0) ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); memset( seq, 0, header_size ); @@ -602,7 +602,7 @@ cvMakeSeqHeaderForArray( int seq_flags, int header_size, int elem_size, if( elemtype != CV_SEQ_ELTYPE_GENERIC && typesize != 0 && typesize != elem_size ) - CV_Error( CV_StsBadSize, + CV_Error( cv::Error::StsBadSize, "Element size doesn't match to the size of predefined element type " "(try to use 0 for sequence element type)" ); } @@ -634,7 +634,7 @@ icvGrowSeq( CvSeq *seq, int in_front_of ) CvSeqBlock *block; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); block = seq->free_blocks; if( !block ) @@ -647,7 +647,7 @@ icvGrowSeq( CvSeq *seq, int in_front_of ) cvSetSeqBlockSize( seq, delta_elems*2 ); if( !storage ) - CV_Error( CV_StsNullPtr, "The sequence has NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "The sequence has NULL storage pointer" ); /* If there is a free space just after last allocated block and it is big enough then enlarge the last block. @@ -817,7 +817,7 @@ CV_IMPL void cvStartAppendToSeq( CvSeq *seq, CvSeqWriter * writer ) { if( !seq || !writer ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); memset( writer, 0, sizeof( *writer )); writer->header_size = sizeof( CvSeqWriter ); @@ -835,7 +835,7 @@ cvStartWriteSeq( int seq_flags, int header_size, int elem_size, CvMemStorage * storage, CvSeqWriter * writer ) { if( !storage || !writer ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvSeq* seq = cvCreateSeq( seq_flags, header_size, elem_size, storage ); cvStartAppendToSeq( seq, writer ); @@ -847,7 +847,7 @@ CV_IMPL void cvFlushSeqWriter( CvSeqWriter * writer ) { if( !writer ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvSeq* seq = writer->seq; seq->ptr = writer->ptr; @@ -878,7 +878,7 @@ CV_IMPL CvSeq * cvEndWriteSeq( CvSeqWriter * writer ) { if( !writer ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cvFlushSeqWriter( writer ); CvSeq* seq = writer->seq; @@ -909,7 +909,7 @@ CV_IMPL void cvCreateSeqBlock( CvSeqWriter * writer ) { if( !writer || !writer->seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvSeq* seq = writer->seq; @@ -942,7 +942,7 @@ cvStartReadSeq( const CvSeq *seq, CvSeqReader * reader, int reverse ) } if( !seq || !reader ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); reader->header_size = sizeof( CvSeqReader ); reader->seq = (CvSeq*)seq; @@ -992,7 +992,7 @@ cvChangeSeqBlock( void* _reader, int direction ) CvSeqReader* reader = (CvSeqReader*)_reader; if( !reader ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( direction > 0 ) { @@ -1017,7 +1017,7 @@ cvGetSeqReaderPos( CvSeqReader* reader ) int index = -1; if( !reader || !reader->ptr ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = reader->seq->elem_size; if( elem_size <= ICV_SHIFT_TAB_MAX && (index = icvPower2ShiftTab[elem_size - 1]) >= 0 ) @@ -1042,7 +1042,7 @@ cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative ) int elem_size, count, total; if( !reader || !reader->seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); total = reader->seq->total; elem_size = reader->seq->elem_size; @@ -1052,14 +1052,14 @@ cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative ) if( index < 0 ) { if( index < -total ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); index += total; } else if( index >= total ) { index -= total; if( index >= total ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); } block = reader->seq->first; @@ -1135,7 +1135,7 @@ cvSeqPush( CvSeq *seq, const void *element ) size_t elem_size; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; ptr = seq->ptr; @@ -1166,9 +1166,9 @@ cvSeqPop( CvSeq *seq, void *element ) int elem_size; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( seq->total <= 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); elem_size = seq->elem_size; seq->ptr = ptr = seq->ptr - elem_size; @@ -1195,7 +1195,7 @@ cvSeqPushFront( CvSeq *seq, const void *element ) CvSeqBlock *block; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; block = seq->first; @@ -1228,9 +1228,9 @@ cvSeqPopFront( CvSeq *seq, void *element ) CvSeqBlock *block; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( seq->total <= 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); elem_size = seq->elem_size; block = seq->first; @@ -1257,14 +1257,14 @@ cvSeqInsert( CvSeq *seq, int before_index, const void *element ) schar* ret_ptr = 0; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); total = seq->total; before_index += before_index < 0 ? total : 0; before_index -= before_index > total ? total : 0; if( (unsigned)before_index > (unsigned)total ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); if( before_index == total ) { @@ -1375,7 +1375,7 @@ cvSeqRemove( CvSeq *seq, int index ) int total, front = 0; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); total = seq->total; @@ -1383,7 +1383,7 @@ cvSeqRemove( CvSeq *seq, int index ) index -= index >= total ? total : 0; if( (unsigned) index >= (unsigned) total ) - CV_Error( CV_StsOutOfRange, "Invalid index" ); + CV_Error( cv::Error::StsOutOfRange, "Invalid index" ); if( index == total - 1 ) { @@ -1456,9 +1456,9 @@ cvSeqPushMulti( CvSeq *seq, const void *_elements, int count, int front ) char *elements = (char *) _elements; if( !seq ) - CV_Error( CV_StsNullPtr, "NULL sequence pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL sequence pointer" ); if( count < 0 ) - CV_Error( CV_StsBadSize, "number of removed elements is negative" ); + CV_Error( cv::Error::StsBadSize, "number of removed elements is negative" ); int elem_size = seq->elem_size; @@ -1525,9 +1525,9 @@ cvSeqPopMulti( CvSeq *seq, void *_elements, int count, int front ) char *elements = (char *) _elements; if( !seq ) - CV_Error( CV_StsNullPtr, "NULL sequence pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL sequence pointer" ); if( count < 0 ) - CV_Error( CV_StsBadSize, "number of removed elements is negative" ); + CV_Error( cv::Error::StsBadSize, "number of removed elements is negative" ); count = MIN( count, seq->total ); @@ -1593,7 +1593,7 @@ CV_IMPL void cvClearSeq( CvSeq *seq ) { if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cvSeqPopMulti( seq, 0, seq->total ); } @@ -1607,13 +1607,13 @@ cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage, int copy_dat CvSeqBlock *block, *first_block = 0, *last_block = 0; if( !CV_IS_SEQ(seq) ) - CV_Error( CV_StsBadArg, "Invalid sequence header" ); + CV_Error( cv::Error::StsBadArg, "Invalid sequence header" ); if( !storage ) { storage = seq->storage; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); } elem_size = seq->elem_size; @@ -1624,7 +1624,7 @@ cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage, int copy_dat slice.start_index -= seq->total; if( (unsigned)length > (unsigned)seq->total || ((unsigned)slice.start_index >= (unsigned)seq->total && length != 0) ) - CV_Error( CV_StsOutOfRange, "Bad sequence slice" ); + CV_Error( cv::Error::StsOutOfRange, "Bad sequence slice" ); subseq = cvCreateSeq( seq->flags, seq->header_size, elem_size, storage ); @@ -1680,7 +1680,7 @@ cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ) int total, length; if( !CV_IS_SEQ(seq) ) - CV_Error( CV_StsBadArg, "Invalid sequence header" ); + CV_Error( cv::Error::StsBadArg, "Invalid sequence header" ); length = cvSliceLength( slice, seq ); total = seq->total; @@ -1691,7 +1691,7 @@ cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ) slice.start_index -= total; if( (unsigned)slice.start_index >= (unsigned)total ) - CV_Error( CV_StsOutOfRange, "start slice index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "start slice index is out of range" ); slice.end_index = slice.start_index + length; @@ -1757,16 +1757,16 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr ) CvSeqBlock block; if( !CV_IS_SEQ(seq) ) - CV_Error( CV_StsBadArg, "Invalid destination sequence header" ); + CV_Error( cv::Error::StsBadArg, "Invalid destination sequence header" ); if( !CV_IS_SEQ(from)) { CvMat* mat = (CvMat*)from; if( !CV_IS_MAT(mat)) - CV_Error( CV_StsBadArg, "Source is not a sequence nor matrix" ); + CV_Error( cv::Error::StsBadArg, "Source is not a sequence nor matrix" ); if( !CV_IS_MAT_CONT(mat->type) || (mat->rows != 1 && mat->cols != 1) ) - CV_Error( CV_StsBadArg, "The source array must be 1d continuous vector" ); + CV_Error( cv::Error::StsBadArg, "The source array must be 1d continuous vector" ); from = cvMakeSeqHeaderForArray( CV_SEQ_KIND_GENERIC, sizeof(from_header), CV_ELEM_SIZE(mat->type), @@ -1775,7 +1775,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr ) } if( seq->elem_size != from->elem_size ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "Source and destination sequence element sizes are different." ); from_total = from->total; @@ -1788,7 +1788,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr ) index -= index > total ? total : 0; if( (unsigned)index > (unsigned)total ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); elem_size = seq->elem_size; @@ -1918,10 +1918,10 @@ cvSeqSort( CvSeq* seq, CvCmpFunc cmp_func, void* aux ) stack[48]; if( !CV_IS_SEQ(seq) ) - CV_Error( !seq ? CV_StsNullPtr : CV_StsBadArg, "Bad input sequence" ); + CV_Error( !seq ? cv::Error::StsNullPtr : cv::Error::StsBadArg, "Bad input sequence" ); if( !cmp_func ) - CV_Error( CV_StsNullPtr, "Null compare function" ); + CV_Error( cv::Error::StsNullPtr, "Null compare function" ); if( seq->total <= 1 ) return; @@ -2195,10 +2195,10 @@ cvSeqSearch( CvSeq* seq, const void* _elem, CvCmpFunc cmp_func, *_idx = idx; if( !CV_IS_SEQ(seq) ) - CV_Error( !seq ? CV_StsNullPtr : CV_StsBadArg, "Bad input sequence" ); + CV_Error( !seq ? cv::Error::StsNullPtr : cv::Error::StsBadArg, "Bad input sequence" ); if( !elem ) - CV_Error( CV_StsNullPtr, "Null element pointer" ); + CV_Error( cv::Error::StsNullPtr, "Null element pointer" ); int elem_size = seq->elem_size; int total = seq->total; @@ -2256,7 +2256,7 @@ cvSeqSearch( CvSeq* seq, const void* _elem, CvCmpFunc cmp_func, else { if( !cmp_func ) - CV_Error( CV_StsNullPtr, "Null compare function" ); + CV_Error( cv::Error::StsNullPtr, "Null compare function" ); i = 0, j = total; @@ -2340,16 +2340,16 @@ cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, CvSeq** labels, int is_set; if( !labels ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !seq || !is_equal ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !storage ) storage = seq->storage; if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); is_set = CV_IS_SET(seq); @@ -2483,11 +2483,11 @@ CV_IMPL CvSet* cvCreateSet( int set_flags, int header_size, int elem_size, CvMemStorage * storage ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( header_size < (int)sizeof( CvSet ) || elem_size < (int)sizeof(void*)*2 || (elem_size & (sizeof(void*)-1)) != 0 ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); CvSet* set = (CvSet*) cvCreateSeq( set_flags, header_size, elem_size, storage ); set->flags = (set->flags & ~CV_MAGIC_MASK) | CV_SET_MAGIC_VAL; @@ -2504,7 +2504,7 @@ cvSetAdd( CvSet* set, CvSetElem* element, CvSetElem** inserted_element ) CvSetElem *free_elem; if( !set ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !(set->free_elems) ) { @@ -2552,7 +2552,7 @@ cvSetRemove( CvSet* set, int index ) if( elem ) cvSetRemoveByPtr( set, elem ); else if( !set ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); } @@ -2583,7 +2583,7 @@ cvCreateGraph( int graph_type, int header_size, || edge_size < (int) sizeof( CvGraphEdge ) || vtx_size < (int) sizeof( CvGraphVtx ) ){ - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); } vertices = cvCreateSet( graph_type, header_size, vtx_size, storage ); @@ -2602,7 +2602,7 @@ CV_IMPL void cvClearGraph( CvGraph * graph ) { if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cvClearSet( graph->edges ); cvClearSet( (CvSet*)graph ); @@ -2617,7 +2617,7 @@ cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* _vertex, CvGraphVtx** _inserted int index = -1; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); vertex = (CvGraphVtx*)cvSetNew((CvSet*)graph); if( vertex ) @@ -2642,10 +2642,10 @@ cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ) int count = -1; if( !graph || !vtx ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( !CV_IS_SET_ELEM(vtx)) - CV_Error( CV_StsBadArg, "The vertex does not belong to the graph" ); + CV_Error( cv::Error::StsBadArg, "The vertex does not belong to the graph" ); count = graph->edges->active_count; for( ;; ) @@ -2670,11 +2670,11 @@ cvGraphRemoveVtx( CvGraph* graph, int index ) CvGraphVtx *vtx = 0; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); vtx = cvGetGraphVtx( graph, index ); if( !vtx ) - CV_Error( CV_StsBadArg, "The vertex is not found" ); + CV_Error( cv::Error::StsBadArg, "The vertex is not found" ); count = graph->edges->active_count; for( ;; ) @@ -2702,7 +2702,7 @@ cvFindGraphEdgeByPtr( const CvGraph* graph, int ofs = 0; if( !graph || !start_vtx || !end_vtx ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( start_vtx == end_vtx ) return 0; @@ -2735,7 +2735,7 @@ cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ) CvGraphVtx *end_vtx; if( !graph ) - CV_Error( CV_StsNullPtr, "graph pointer is NULL" ); + CV_Error( cv::Error::StsNullPtr, "graph pointer is NULL" ); start_vtx = cvGetGraphVtx( graph, start_idx ); end_vtx = cvGetGraphVtx( graph, end_idx ); @@ -2759,7 +2759,7 @@ cvGraphAddEdgeByPtr( CvGraph* graph, int delta; if( !graph ) - CV_Error( CV_StsNullPtr, "graph pointer is NULL" ); + CV_Error( cv::Error::StsNullPtr, "graph pointer is NULL" ); if( !CV_IS_GRAPH_ORIENTED( graph ) && (start_vtx->flags & CV_SET_ELEM_IDX_MASK) > (end_vtx->flags & CV_SET_ELEM_IDX_MASK) ) @@ -2778,7 +2778,7 @@ cvGraphAddEdgeByPtr( CvGraph* graph, } if( start_vtx == end_vtx ) - CV_Error( start_vtx ? CV_StsBadArg : CV_StsNullPtr, + CV_Error( start_vtx ? cv::Error::StsBadArg : cv::Error::StsNullPtr, "vertex pointers coincide (or set to NULL)" ); edge = (CvGraphEdge*)cvSetNew( (CvSet*)(graph->edges) ); @@ -2826,7 +2826,7 @@ cvGraphAddEdge( CvGraph* graph, CvGraphVtx *end_vtx; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); start_vtx = cvGetGraphVtx( graph, start_idx ); end_vtx = cvGetGraphVtx( graph, end_idx ); @@ -2843,7 +2843,7 @@ cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_v CvGraphEdge *edge, *next_edge, *prev_edge; if( !graph || !start_vtx || !end_vtx ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( start_vtx == end_vtx ) return; @@ -2902,7 +2902,7 @@ cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ) CvGraphVtx *end_vtx; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); start_vtx = cvGetGraphVtx( graph, start_idx ); end_vtx = cvGetGraphVtx( graph, end_idx ); @@ -2919,7 +2919,7 @@ cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vertex ) int count; if( !graph || !vertex ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); for( edge = vertex->first, count = 0; edge; ) { @@ -2940,11 +2940,11 @@ cvGraphVtxDegree( const CvGraph* graph, int vtx_idx ) int count; if( !graph ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); vertex = cvGetGraphVtx( graph, vtx_idx ); if( !vertex ) - CV_Error( CV_StsObjectNotFound, "" ); + CV_Error( cv::Error::StsObjectNotFound, "" ); for( edge = vertex->first, count = 0; edge; ) { @@ -2971,13 +2971,13 @@ icvSeqElemsClearFlags( CvSeq* seq, int offset, int clear_mask ) int i, total, elem_size; if( !seq ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; total = seq->total; if( (unsigned)offset > (unsigned)elem_size ) - CV_Error( CV_StsBadArg, "" ); + CV_Error( cv::Error::StsBadArg, "" ); cvStartReadSeq( seq, &reader ); @@ -3001,14 +3001,14 @@ icvSeqFindNextElem( CvSeq* seq, int offset, int mask, int total, elem_size, index; if( !seq || !start_index ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); elem_size = seq->elem_size; total = seq->total; index = *start_index; if( (unsigned)offset > (unsigned)elem_size ) - CV_Error( CV_StsBadArg, "" ); + CV_Error( cv::Error::StsBadArg, "" ); if( total == 0 ) return 0; @@ -3048,7 +3048,7 @@ CV_IMPL CvGraphScanner* cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx, int mask ) { if( !graph ) - CV_Error( CV_StsNullPtr, "Null graph pointer" ); + CV_Error( cv::Error::StsNullPtr, "Null graph pointer" ); CV_Assert( graph->storage != 0 ); @@ -3082,7 +3082,7 @@ CV_IMPL void cvReleaseGraphScanner( CvGraphScanner** scanner ) { if( !scanner ) - CV_Error( CV_StsNullPtr, "Null double pointer to graph scanner" ); + CV_Error( cv::Error::StsNullPtr, "Null double pointer to graph scanner" ); if( *scanner ) { @@ -3103,7 +3103,7 @@ cvNextGraphItem( CvGraphScanner* scanner ) CvGraphItem item; if( !scanner || !(scanner->stack)) - CV_Error( CV_StsNullPtr, "Null graph scanner" ); + CV_Error( cv::Error::StsNullPtr, "Null graph scanner" ); dst = scanner->dst; vtx = scanner->vtx; @@ -3259,13 +3259,13 @@ cvCloneGraph( const CvGraph* graph, CvMemStorage* storage ) CvSeqReader reader; if( !CV_IS_GRAPH(graph)) - CV_Error( CV_StsBadArg, "Invalid graph pointer" ); + CV_Error( cv::Error::StsBadArg, "Invalid graph pointer" ); if( !storage ) storage = graph->storage; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); vtx_size = graph->elem_size; edge_size = graph->edges->elem_size; @@ -3343,7 +3343,7 @@ cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage ) CvTreeNodeIterator iterator; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); allseq = cvCreateSeq( 0, header_size, sizeof(first), storage ); @@ -3389,7 +3389,7 @@ cvInsertNodeIntoTree( void* _node, void* _parent, void* _frame ) CvTreeNode* parent = (CvTreeNode*)_parent; if( !node || !parent ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); node->v_prev = _parent != _frame ? parent : 0; node->h_next = parent->v_next; @@ -3410,10 +3410,10 @@ cvRemoveNodeFromTree( void* _node, void* _frame ) CvTreeNode* frame = (CvTreeNode*)_frame; if( !node ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( node == frame ) - CV_Error( CV_StsBadArg, "frame node could not be deleted" ); + CV_Error( cv::Error::StsBadArg, "frame node could not be deleted" ); if( node->h_next ) node->h_next->h_prev = node->h_prev; @@ -3440,10 +3440,10 @@ cvInitTreeNodeIterator( CvTreeNodeIterator* treeIterator, const void* first, int max_level ) { if( !treeIterator || !first ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( max_level < 0 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); treeIterator->node = (void*)first; treeIterator->level = 0; @@ -3459,7 +3459,7 @@ cvNextTreeNode( CvTreeNodeIterator* treeIterator ) int level; if( !treeIterator ) - CV_Error( CV_StsNullPtr, "NULL iterator pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL iterator pointer" ); prevNode = node = (CvTreeNode*)treeIterator->node; level = treeIterator->level; @@ -3500,7 +3500,7 @@ cvPrevTreeNode( CvTreeNodeIterator* treeIterator ) int level; if( !treeIterator ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); prevNode = node = (CvTreeNode*)treeIterator->node; level = treeIterator->level; diff --git a/modules/core/src/dxt.cpp b/modules/core/src/dxt.cpp index 6dca818b1c..d491be5cd1 100644 --- a/modules/core/src/dxt.cpp +++ b/modules/core/src/dxt.cpp @@ -3469,7 +3469,7 @@ Ptr DFT2D::create(int width, int height, int depth, { if(width == 1 && nonzero_rows > 0 ) { - CV_Error( CV_StsNotImplemented, + CV_Error( cv::Error::StsNotImplemented, "This mode (using nonzero_rows with a single-column matrix) breaks the function's logic, so it is prohibited.\n" "For fast convolution/correlation use 2-column matrix or single-row matrix instead" ); } @@ -4317,7 +4317,7 @@ public: if( len != prev_len ) { if( len > 1 && (len & 1) ) - CV_Error( CV_StsNotImplemented, "Odd-size DCT\'s are not implemented" ); + CV_Error( cv::Error::StsNotImplemented, "Odd-size DCT\'s are not implemented" ); opt.nf = DFTFactorize( len, opt.factors ); bool inplace_transform = opt.factors[0] == opt.factors[opt.nf-1]; diff --git a/modules/core/src/glob.cpp b/modules/core/src/glob.cpp index b7cf1bf236..03638d49b1 100644 --- a/modules/core/src/glob.cpp +++ b/modules/core/src/glob.cpp @@ -276,7 +276,7 @@ static void glob_rec(const cv::String& directory, const cv::String& wildchart, s } else { - CV_Error_(CV_StsObjectNotFound, ("could not open directory: %s", directory.c_str())); + CV_Error_(cv::Error::StsObjectNotFound, ("could not open directory: %s", directory.c_str())); } } #endif // OPENCV_HAVE_FILESYSTEM_SUPPORT diff --git a/modules/core/src/lapack.cpp b/modules/core/src/lapack.cpp index 12376c2508..83adeeabc3 100644 --- a/modules/core/src/lapack.cpp +++ b/modules/core/src/lapack.cpp @@ -1191,7 +1191,7 @@ bool solve( InputArray _src, InputArray _src2arg, OutputArray _dst, int method ) Mat dst = _dst.getMat(); if( m < n ) - CV_Error(CV_StsBadArg, "The function can not solve under-determined linear systems" ); + CV_Error(cv::Error::StsBadArg, "The function can not solve under-determined linear systems" ); if( m == n ) is_normal = false; @@ -1515,7 +1515,7 @@ void SVD::backSubst( InputArray _w, InputArray _u, InputArray _vt, vt.ptr(), vt.step, true, rhs.ptr(), rhs.step, nb, dst.ptr(), dst.step, buffer.data()); else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); } diff --git a/modules/core/src/mathfuncs.cpp b/modules/core/src/mathfuncs.cpp index 525d71ba09..04604e84c0 100644 --- a/modules/core/src/mathfuncs.cpp +++ b/modules/core/src/mathfuncs.cpp @@ -1566,7 +1566,7 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double ma { cv::String value_str; value_str << src(cv::Range(badPt.y, badPt.y + 1), cv::Range(badPt.x, badPt.x + 1)); - CV_Error_( CV_StsOutOfRange, + CV_Error_( cv::Error::StsOutOfRange, ("the value at (%d, %d)=%s is out of range [%f, %f)", badPt.x, badPt.y, value_str.c_str(), minVal, maxVal)); } return false; diff --git a/modules/core/src/matmul.dispatch.cpp b/modules/core/src/matmul.dispatch.cpp index a213ca06c7..a72301b4c3 100644 --- a/modules/core/src/matmul.dispatch.cpp +++ b/modules/core/src/matmul.dispatch.cpp @@ -921,7 +921,7 @@ void mulTransposed(InputArray _src, OutputArray _dst, bool ata, { MulTransposedFunc func = getMulTransposedFunc(stype, dtype, ata); if( !func ) - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); func( src, dst, delta, scale ); completeSymm( dst, false ); diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 513e13ea5f..0701542dfd 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -267,7 +267,7 @@ void setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool auto m.step.p[i] = total; uint64 total1 = (uint64)total*s; if( (uint64)total1 != (size_t)total1 ) - CV_Error( CV_StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" ); + CV_Error( cv::Error::StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" ); total = (size_t)total1; } } @@ -1072,9 +1072,9 @@ void Mat::push_back(const Mat& elems) bool eq = size == elems.size; size.p[0] = int(r); if( !eq ) - CV_Error(CV_StsUnmatchedSizes, "Pushed vector length is not equal to matrix row length"); + CV_Error(cv::Error::StsUnmatchedSizes, "Pushed vector length is not equal to matrix row length"); if( type() != elems.type() ) - CV_Error(CV_StsUnmatchedFormats, "Pushed vector type is not the same as matrix type"); + CV_Error(cv::Error::StsUnmatchedFormats, "Pushed vector type is not the same as matrix type"); if( isSubmatrix() || dataend + step.p[0]*delta > datalimit ) reserve( std::max(r + delta, (r*3+1)/2) ); @@ -1170,16 +1170,16 @@ Mat Mat::reshape(int new_cn, int new_rows) const { int total_size = total_width * rows; if( !isContinuous() ) - CV_Error( CV_BadStep, + CV_Error( cv::Error::BadStep, "The matrix is not continuous, thus its number of rows can not be changed" ); if( (unsigned)new_rows > (unsigned)total_size ) - CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); + CV_Error( cv::Error::StsOutOfRange, "Bad new number of rows" ); total_width = total_size / new_rows; if( total_width * new_rows != total_size ) - CV_Error( CV_StsBadArg, "The total number of matrix elements " + CV_Error( cv::Error::StsBadArg, "The total number of matrix elements " "is not divisible by the new number of rows" ); hdr.rows = new_rows; @@ -1189,7 +1189,7 @@ Mat Mat::reshape(int new_cn, int new_rows) const int new_width = total_width / new_cn; if( new_width * new_cn != total_width ) - CV_Error( CV_BadNumChannels, + CV_Error( cv::Error::BadNumChannels, "The total width is not divisible by the new number of channels" ); hdr.cols = new_width; @@ -1231,13 +1231,13 @@ Mat Mat::reshape(int _cn, int _newndims, const int* _newsz) const else if (i < dims) newsz_buf[i] = this->size[i]; else - CV_Error(CV_StsOutOfRange, "Copy dimension (which has zero size) is not present in source matrix"); + CV_Error(cv::Error::StsOutOfRange, "Copy dimension (which has zero size) is not present in source matrix"); total_elem1 *= (size_t)newsz_buf[i]; } if (total_elem1 != total_elem1_ref) - CV_Error(CV_StsUnmatchedSizes, "Requested and source matrices have different count of elements"); + CV_Error(cv::Error::StsUnmatchedSizes, "Requested and source matrices have different count of elements"); Mat hdr = *this; hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((_cn-1) << CV_CN_SHIFT); @@ -1246,7 +1246,7 @@ Mat Mat::reshape(int _cn, int _newndims, const int* _newsz) const return hdr; } - CV_Error(CV_StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet"); + CV_Error(cv::Error::StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet"); // TBD } diff --git a/modules/core/src/matrix_c.cpp b/modules/core/src/matrix_c.cpp index baa61bb66f..13c9c11dd4 100644 --- a/modules/core/src/matrix_c.cpp +++ b/modules/core/src/matrix_c.cpp @@ -163,7 +163,7 @@ Mat cvarrToMat(const CvArr* arr, bool copyData, { const IplImage* iplimg = (const IplImage*)arr; if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 ) - CV_Error(CV_BadCOI, "COI is not supported by the function"); + CV_Error(cv::Error::BadCOI, "COI is not supported by the function"); return iplImageToMat(iplimg, copyData); } if( CV_IS_SEQ(arr) ) @@ -187,7 +187,7 @@ Mat cvarrToMat(const CvArr* arr, bool copyData, cvCvtSeqToArray(seq, buf.ptr(), CV_WHOLE_SEQ); return buf; } - CV_Error(CV_StsBadArg, "Unknown array type"); + CV_Error(cv::Error::StsBadArg, "Unknown array type"); } void extractImageCOI(const CvArr* arr, OutputArray _ch, int coi) @@ -269,14 +269,14 @@ cvReduce( const CvArr* srcarr, CvArr* dstarr, int dim, int op ) dim = src.rows > dst.rows ? 0 : src.cols > dst.cols ? 1 : dst.cols == 1; if( dim > 1 ) - CV_Error( CV_StsOutOfRange, "The reduced dimensionality index is out of range" ); + CV_Error( cv::Error::StsOutOfRange, "The reduced dimensionality index is out of range" ); if( (dim == 0 && (dst.cols != src.cols || dst.rows != 1)) || (dim == 1 && (dst.rows != src.rows || dst.cols != 1)) ) - CV_Error( CV_StsBadSize, "The output array size is incorrect" ); + CV_Error( cv::Error::StsBadSize, "The output array size is incorrect" ); if( src.channels() != dst.channels() ) - CV_Error( CV_StsUnmatchedFormats, "Input and output arrays must have the same number of channels" ); + CV_Error( cv::Error::StsUnmatchedFormats, "Input and output arrays must have the same number of channels" ); cv::reduce(src, dst, dim, op, dst.type()); } @@ -333,7 +333,7 @@ cvRange( CvArr* arr, double start, double end ) fdata[j] = (float)val; } else - CV_Error( CV_StsUnsupportedFormat, "The function only supports 32sC1 and 32fC1 datatypes" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The function only supports 32sC1 and 32fC1 datatypes" ); return arr; } diff --git a/modules/core/src/matrix_expressions.cpp b/modules/core/src/matrix_expressions.cpp index 44ac8f1713..dd39d50a01 100644 --- a/modules/core/src/matrix_expressions.cpp +++ b/modules/core/src/matrix_expressions.cpp @@ -21,7 +21,7 @@ static void checkOperandsExist(const Mat& a) { if (a.empty()) { - CV_Error(CV_StsBadArg, "Matrix operand is an empty matrix."); + CV_Error(cv::Error::StsBadArg, "Matrix operand is an empty matrix."); } } @@ -29,7 +29,7 @@ static void checkOperandsExist(const Mat& a, const Mat& b) { if (a.empty() || b.empty()) { - CV_Error(CV_StsBadArg, "One or more matrix operands are empty."); + CV_Error(cv::Error::StsBadArg, "One or more matrix operands are empty."); } } @@ -1456,7 +1456,7 @@ void MatOp_Bin::assign(const MatExpr& e, Mat& m, int _type) const else if( e.flags == 'a' && !e.b.data ) cv::absdiff(e.a, e.s, dst); else - CV_Error(CV_StsError, "Unknown operation"); + CV_Error(cv::Error::StsError, "Unknown operation"); if( dst.data != m.data ) dst.convertTo(m, _type); @@ -1691,7 +1691,7 @@ void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int _type) const else if( e.flags == '1' ) m = Scalar(e.alpha); else - CV_Error(CV_StsError, "Invalid matrix initializer type"); + CV_Error(cv::Error::StsError, "Invalid matrix initializer type"); } void MatOp_Initializer::multiply(const MatExpr& e, double s, MatExpr& res) const diff --git a/modules/core/src/matrix_operations.cpp b/modules/core/src/matrix_operations.cpp index 94e0c2b50b..8bb8c66e5c 100644 --- a/modules/core/src/matrix_operations.cpp +++ b/modules/core/src/matrix_operations.cpp @@ -954,7 +954,7 @@ void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype) } if( !func ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "Unsupported combination of input and output array formats" ); func( src, temp ); diff --git a/modules/core/src/matrix_sparse.cpp b/modules/core/src/matrix_sparse.cpp index 173f9ea8f6..7a02e5961d 100644 --- a/modules/core/src/matrix_sparse.cpp +++ b/modules/core/src/matrix_sparse.cpp @@ -758,7 +758,7 @@ double norm( const SparseMat& src, int normType ) } } else - CV_Error( CV_StsUnsupportedFormat, "Only 32f and 64f are supported" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Only 32f and 64f are supported" ); if( normType == NORM_L2 ) result = std::sqrt(result); @@ -821,7 +821,7 @@ void minMaxLoc( const SparseMat& src, double* _minval, double* _maxval, int* _mi *_maxval = maxval; } else - CV_Error( CV_StsUnsupportedFormat, "Only 32f and 64f are supported" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Only 32f and 64f are supported" ); if( _minidx && minidx ) for( i = 0; i < d; i++ ) @@ -843,7 +843,7 @@ void normalize( const SparseMat& src, SparseMat& dst, double a, int norm_type ) scale = scale > DBL_EPSILON ? a/scale : 0.; } else - CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported norm type" ); src.convertTo( dst, -1, scale ); } diff --git a/modules/core/src/matrix_wrap.cpp b/modules/core/src/matrix_wrap.cpp index fa9a23ee2a..238fc642fd 100644 --- a/modules/core/src/matrix_wrap.cpp +++ b/modules/core/src/matrix_wrap.cpp @@ -948,7 +948,7 @@ bool _InputArray::isContinuous(int i) const if( k == CUDA_GPU_MAT ) return i < 0 ? ((const cuda::GpuMat*)obj)->isContinuous() : true; - CV_Error(CV_StsNotImplemented, "Unknown/unsupported array type"); + CV_Error(cv::Error::StsNotImplemented, "Unknown/unsupported array type"); } bool _InputArray::isSubmatrix(int i) const @@ -986,7 +986,7 @@ bool _InputArray::isSubmatrix(int i) const return vv[i].isSubmatrix(); } - CV_Error(CV_StsNotImplemented, ""); + CV_Error(cv::Error::StsNotImplemented, ""); } size_t _InputArray::offset(int i) const @@ -1466,14 +1466,14 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i, ((std::vector >*)v)->resize(len); break; default: - CV_Error_(CV_StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz)); + CV_Error_(cv::Error::StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz)); } return; } if( k == NONE ) { - CV_Error(CV_StsNullPtr, "create() called for the missing output array" ); + CV_Error(cv::Error::StsNullPtr, "create() called for the missing output array" ); } if( k == STD_VECTOR_MAT ) diff --git a/modules/core/src/norm.cpp b/modules/core/src/norm.cpp index be68efddf0..31178dbcda 100644 --- a/modules/core/src/norm.cpp +++ b/modules/core/src/norm.cpp @@ -1392,7 +1392,7 @@ void normalize(InputArray _src, InputOutputArray _dst, double a, double b, shift = 0; } else - CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported norm type" ); CV_OCL_RUN(_dst.isUMat(), ocl_normalize(_src, _dst, _mask, rtype, scale, shift)) diff --git a/modules/core/src/rand.cpp b/modules/core/src/rand.cpp index 0647c95486..e39acce529 100644 --- a/modules/core/src/rand.cpp +++ b/modules/core/src/rand.cpp @@ -574,7 +574,7 @@ void RNG::fill( InputOutputArray _mat, int disttype, CV_Assert( scaleFunc != 0 ); } else - CV_Error( CV_StsBadArg, "Unknown distribution type" ); + CV_Error( cv::Error::StsBadArg, "Unknown distribution type" ); const Mat* arrays[] = {&mat, 0}; uchar* ptr; diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index 934c3b458c..c02944079e 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -1377,38 +1377,38 @@ CV_IMPL const char* cvErrorStr( int status ) switch (status) { - case CV_StsOk : return "No Error"; - case CV_StsBackTrace : return "Backtrace"; - case CV_StsError : return "Unspecified error"; - case CV_StsInternal : return "Internal error"; - case CV_StsNoMem : return "Insufficient memory"; - case CV_StsBadArg : return "Bad argument"; - case CV_StsNoConv : return "Iterations do not converge"; - case CV_StsAutoTrace : return "Autotrace call"; - case CV_StsBadSize : return "Incorrect size of input array"; - case CV_StsNullPtr : return "Null pointer"; - case CV_StsDivByZero : return "Division by zero occurred"; - case CV_BadStep : return "Image step is wrong"; - case CV_StsInplaceNotSupported : return "Inplace operation is not supported"; - case CV_StsObjectNotFound : return "Requested object was not found"; - case CV_BadDepth : return "Input image depth is not supported by function"; - case CV_StsUnmatchedFormats : return "Formats of input arguments do not match"; - case CV_StsUnmatchedSizes : return "Sizes of input arguments do not match"; - case CV_StsOutOfRange : return "One of the arguments\' values is out of range"; - case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats"; - case CV_BadCOI : return "Input COI is not supported"; - case CV_BadNumChannels : return "Bad number of channels"; - case CV_StsBadFlag : return "Bad flag (parameter or structure field)"; - case CV_StsBadPoint : return "Bad parameter of type CvPoint"; - case CV_StsBadMask : return "Bad type of mask argument"; - case CV_StsParseError : return "Parsing error"; - case CV_StsNotImplemented : return "The function/feature is not implemented"; - case CV_StsBadMemBlock : return "Memory block has been corrupted"; - case CV_StsAssert : return "Assertion failed"; - case CV_GpuNotSupported : return "No CUDA support"; - case CV_GpuApiCallError : return "Gpu API call"; - case CV_OpenGlNotSupported : return "No OpenGL support"; - case CV_OpenGlApiCallError : return "OpenGL API call"; + case cv::Error::StsOk : return "No Error"; + case cv::Error::StsBackTrace : return "Backtrace"; + case cv::Error::StsError : return "Unspecified error"; + case cv::Error::StsInternal : return "Internal error"; + case cv::Error::StsNoMem : return "Insufficient memory"; + case cv::Error::StsBadArg : return "Bad argument"; + case cv::Error::StsNoConv : return "Iterations do not converge"; + case cv::Error::StsAutoTrace : return "Autotrace call"; + case cv::Error::StsBadSize : return "Incorrect size of input array"; + case cv::Error::StsNullPtr : return "Null pointer"; + case cv::Error::StsDivByZero : return "Division by zero occurred"; + case cv::Error::BadStep : return "Image step is wrong"; + case cv::Error::StsInplaceNotSupported : return "Inplace operation is not supported"; + case cv::Error::StsObjectNotFound : return "Requested object was not found"; + case cv::Error::BadDepth : return "Input image depth is not supported by function"; + case cv::Error::StsUnmatchedFormats : return "Formats of input arguments do not match"; + case cv::Error::StsUnmatchedSizes : return "Sizes of input arguments do not match"; + case cv::Error::StsOutOfRange : return "One of the arguments\' values is out of range"; + case cv::Error::StsUnsupportedFormat : return "Unsupported format or combination of formats"; + case cv::Error::BadCOI : return "Input COI is not supported"; + case cv::Error::BadNumChannels : return "Bad number of channels"; + case cv::Error::StsBadFlag : return "Bad flag (parameter or structure field)"; + case cv::Error::StsBadPoint : return "Bad parameter of type CvPoint"; + case cv::Error::StsBadMask : return "Bad type of mask argument"; + case cv::Error::StsParseError : return "Parsing error"; + case cv::Error::StsNotImplemented : return "The function/feature is not implemented"; + case cv::Error::StsBadMemBlock : return "Memory block has been corrupted"; + case cv::Error::StsAssert : return "Assertion failed"; + case cv::Error::GpuNotSupported : return "No CUDA support"; + case cv::Error::GpuApiCallError : return "Gpu API call"; + case cv::Error::OpenGlNotSupported : return "No OpenGL support"; + case cv::Error::OpenGlApiCallError : return "OpenGL API call"; }; snprintf(buf, sizeof(buf), "Unknown %s code %d", status >= 0 ? "status":"error", status); @@ -1448,29 +1448,29 @@ cvErrorFromIppStatus( int status ) { switch (status) { - case CV_BADSIZE_ERR: return CV_StsBadSize; - case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock; - case CV_NULLPTR_ERR: return CV_StsNullPtr; - case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero; - case CV_BADSTEP_ERR: return CV_BadStep; - case CV_OUTOFMEM_ERR: return CV_StsNoMem; - case CV_BADARG_ERR: return CV_StsBadArg; - case CV_NOTDEFINED_ERR: return CV_StsError; - case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported; - case CV_NOTFOUND_ERR: return CV_StsObjectNotFound; - case CV_BADCONVERGENCE_ERR: return CV_StsNoConv; - case CV_BADDEPTH_ERR: return CV_BadDepth; - case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats; - case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI; - case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels; - case CV_BADFLAG_ERR: return CV_StsBadFlag; - case CV_BADRANGE_ERR: return CV_StsBadArg; - case CV_BADCOEF_ERR: return CV_StsBadArg; - case CV_BADFACTOR_ERR: return CV_StsBadArg; - case CV_BADPOINT_ERR: return CV_StsBadPoint; + case CV_BADSIZE_ERR: return cv::Error::StsBadSize; + case CV_BADMEMBLOCK_ERR: return cv::Error::StsBadMemBlock; + case CV_NULLPTR_ERR: return cv::Error::StsNullPtr; + case CV_DIV_BY_ZERO_ERR: return cv::Error::StsDivByZero; + case CV_BADSTEP_ERR: return cv::Error::BadStep; + case CV_OUTOFMEM_ERR: return cv::Error::StsNoMem; + case CV_BADARG_ERR: return cv::Error::StsBadArg; + case CV_NOTDEFINED_ERR: return cv::Error::StsError; + case CV_INPLACE_NOT_SUPPORTED_ERR: return cv::Error::StsInplaceNotSupported; + case CV_NOTFOUND_ERR: return cv::Error::StsObjectNotFound; + case CV_BADCONVERGENCE_ERR: return cv::Error::StsNoConv; + case CV_BADDEPTH_ERR: return cv::Error::BadDepth; + case CV_UNMATCHED_FORMATS_ERR: return cv::Error::StsUnmatchedFormats; + case CV_UNSUPPORTED_COI_ERR: return cv::Error::BadCOI; + case CV_UNSUPPORTED_CHANNELS_ERR: return cv::Error::BadNumChannels; + case CV_BADFLAG_ERR: return cv::Error::StsBadFlag; + case CV_BADRANGE_ERR: return cv::Error::StsBadArg; + case CV_BADCOEF_ERR: return cv::Error::StsBadArg; + case CV_BADFACTOR_ERR: return cv::Error::StsBadArg; + case CV_BADPOINT_ERR: return cv::Error::StsBadPoint; default: - return CV_StsError; + return cv::Error::StsError; } } diff --git a/modules/core/src/types.cpp b/modules/core/src/types.cpp index 43e25ef045..ccf3109989 100644 --- a/modules/core/src/types.cpp +++ b/modules/core/src/types.cpp @@ -83,7 +83,7 @@ void KeyPoint::convert(const std::vector& keypoints, std::vector (unsigned)total_size ) - CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); + CV_Error( cv::Error::StsOutOfRange, "Bad new number of rows" ); total_width = total_size / new_rows; if( total_width * new_rows != total_size ) - CV_Error( CV_StsBadArg, "The total number of matrix elements " + CV_Error( cv::Error::StsBadArg, "The total number of matrix elements " "is not divisible by the new number of rows" ); hdr.rows = new_rows; @@ -984,7 +984,7 @@ UMat UMat::reshape(int new_cn, int new_rows) const int new_width = total_width / new_cn; if( new_width * new_cn != total_width ) - CV_Error( CV_BadNumChannels, + CV_Error( cv::Error::BadNumChannels, "The total width is not divisible by the new number of channels" ); hdr.cols = new_width; @@ -1050,13 +1050,13 @@ UMat UMat::reshape(int _cn, int _newndims, const int* _newsz) const else if (i < dims) newsz_buf[i] = this->size[i]; else - CV_Error(CV_StsOutOfRange, "Copy dimension (which has zero size) is not present in source matrix"); + CV_Error(cv::Error::StsOutOfRange, "Copy dimension (which has zero size) is not present in source matrix"); total_elem1 *= (size_t)newsz_buf[i]; } if (total_elem1 != total_elem1_ref) - CV_Error(CV_StsUnmatchedSizes, "Requested and source matrices have different count of elements"); + CV_Error(cv::Error::StsUnmatchedSizes, "Requested and source matrices have different count of elements"); UMat hdr = *this; hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((_cn-1) << CV_CN_SHIFT); @@ -1065,7 +1065,7 @@ UMat UMat::reshape(int _cn, int _newndims, const int* _newsz) const return hdr; } - CV_Error(CV_StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet"); + CV_Error(cv::Error::StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet"); } Mat UMat::getMat(AccessFlag accessFlags) const diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index f26e47bc03..499c766a84 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -593,7 +593,7 @@ static void inRange(const Mat& src, const Mat& lb, const Mat& rb, Mat& dst) inRange_((const double*)sptr, (const double*)aptr, (const double*)bptr, dptr, total, cn); break; default: - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } } } @@ -642,7 +642,7 @@ static void inRangeS(const Mat& src, const Scalar& lb, const Scalar& rb, Mat& ds inRangeS_((const double*)sptr, lbuf.d, rbuf.d, dptr, total, cn); break; default: - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } } } diff --git a/modules/core/test/test_dxt.cpp b/modules/core/test/test_dxt.cpp index 05d1f3062c..b2305fef9a 100644 --- a/modules/core/test/test_dxt.cpp +++ b/modules/core/test/test_dxt.cpp @@ -97,7 +97,7 @@ static void DFT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat( } } else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } @@ -878,7 +878,7 @@ protected: { cout << "actual:\n" << dst << endl << endl; cout << "reference:\n" << dstz << endl << endl; - CV_Error(CV_StsError, ""); + CV_Error(cv::Error::StsError, ""); } } } diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index 4b6dcb8fcf..23a00a7eff 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -598,7 +598,7 @@ static void setValue(SparseMat& M, const int* idx, double value, RNG& rng) else if( M.type() == CV_64F ) *(double*)ptr = value; else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } #if defined(__GNUC__) && (__GNUC__ == 11 || __GNUC__ == 12 || __GNUC__ == 13) diff --git a/modules/dnn/src/dnn_utils.cpp b/modules/dnn/src/dnn_utils.cpp index 99b4e77e11..3ef75fad36 100644 --- a/modules/dnn/src/dnn_utils.cpp +++ b/modules/dnn/src/dnn_utils.cpp @@ -438,7 +438,7 @@ void Image2BlobParams::blobRectsToImageRects(const std::vector &rBlob, std } } else - CV_Error(CV_StsBadArg, "Unknown padding mode"); + CV_Error(cv::Error::StsBadArg, "Unknown padding mode"); } } diff --git a/modules/dnn/src/int8layers/convolution_layer.cpp b/modules/dnn/src/int8layers/convolution_layer.cpp index 6121e971a2..a5a98c9764 100644 --- a/modules/dnn/src/int8layers/convolution_layer.cpp +++ b/modules/dnn/src/int8layers/convolution_layer.cpp @@ -548,7 +548,7 @@ public: { // for Conv1d if (group != 1) - CV_Error( CV_StsNotImplemented, " Grouped Conv1d or Depth-Wise Conv1d are not supported by " + CV_Error( cv::Error::StsNotImplemented, " Grouped Conv1d or Depth-Wise Conv1d are not supported by " "TimVX Backend. Please try OpenCV Backend."); tvConv = graph->CreateOperation( tvConvWeightShape[2], tvPadType, (uint32_t)kernel_size[0], diff --git a/modules/dnn/src/layers/cpu_kernels/convolution.cpp b/modules/dnn/src/layers/cpu_kernels/convolution.cpp index c5258ccd91..6ae304f29d 100644 --- a/modules/dnn/src/layers/cpu_kernels/convolution.cpp +++ b/modules/dnn/src/layers/cpu_kernels/convolution.cpp @@ -450,7 +450,7 @@ Ptr initFastConv( } } else - CV_Error(CV_StsUnsupportedFormat, "Unknown convolution type."); + CV_Error(cv::Error::StsUnsupportedFormat, "Unknown convolution type."); // store bias; append some zero's to make sure that // we can always read MR elements starting from any valid index diff --git a/modules/dnn/src/vkcom/src/context.cpp b/modules/dnn/src/vkcom/src/context.cpp index 2cb355a247..4432d58aa0 100644 --- a/modules/dnn/src/vkcom/src/context.cpp +++ b/modules/dnn/src/vkcom/src/context.cpp @@ -225,7 +225,7 @@ void Context::createInstance() if (result != VK_SUCCESS) { - CV_Error(CV_StsError, "Vulkan: vkEnumerateInstanceLayerProperties failed!"); + CV_Error(cv::Error::StsError, "Vulkan: vkEnumerateInstanceLayerProperties failed!"); return; } @@ -234,7 +234,7 @@ void Context::createInstance() if (result != VK_SUCCESS) { - CV_Error(CV_StsError, "Vulkan: vkEnumerateInstanceLayerProperties failed!"); + CV_Error(cv::Error::StsError, "Vulkan: vkEnumerateInstanceLayerProperties failed!"); return; } @@ -388,7 +388,7 @@ Context::Context() vkEnumeratePhysicalDevices(kInstance, &deviceCount, NULL); if (deviceCount == 0) { - CV_Error(CV_StsError, "Vulkan Backend: could not find a device with vulkan support!"); + CV_Error(cv::Error::StsError, "Vulkan Backend: could not find a device with vulkan support!"); } std::vector devices(deviceCount); @@ -442,7 +442,7 @@ Context::Context() if (!cmdPoolPtr) cmdPoolPtr = CommandPool::create(kQueue, kQueueFamilyIndex); else - CV_Error(CV_StsError, "cmdPoolPtr has been created before!!"); + CV_Error(cv::Error::StsError, "cmdPoolPtr has been created before!!"); pipelineFactoryPtr = PipelineFactory::create(); } diff --git a/modules/dnn/src/vkcom/src/op_conv.cpp b/modules/dnn/src/vkcom/src/op_conv.cpp index 9c84ffccdf..22aa537111 100644 --- a/modules/dnn/src/vkcom/src/op_conv.cpp +++ b/modules/dnn/src/vkcom/src/op_conv.cpp @@ -244,7 +244,7 @@ bool OpConv::computeGroupCount() group_z_ = 1; } else - CV_Error(CV_StsNotImplemented, "shader type is not supported at compute GroupCount."); + CV_Error(cv::Error::StsNotImplemented, "shader type is not supported at compute GroupCount."); CV_Assert(group_x_ <= MAX_GROUP_COUNT_X); CV_Assert(group_y_ <= MAX_GROUP_COUNT_Y); diff --git a/modules/dnn/src/vkcom/src/op_naryEltwise.cpp b/modules/dnn/src/vkcom/src/op_naryEltwise.cpp index 812ca097b3..bcc5cd7e2e 100644 --- a/modules/dnn/src/vkcom/src/op_naryEltwise.cpp +++ b/modules/dnn/src/vkcom/src/op_naryEltwise.cpp @@ -182,7 +182,7 @@ bool OpNary::computeGroupCount() } else { - CV_Error(CV_StsNotImplemented, "shader type is not supported at compute GroupCount."); + CV_Error(cv::Error::StsNotImplemented, "shader type is not supported at compute GroupCount."); } CV_Assert(group_x_ <= MAX_GROUP_COUNT_X); diff --git a/modules/dnn/src/vkcom/src/pipeline.cpp b/modules/dnn/src/vkcom/src/pipeline.cpp index ea29d8824a..240102fba4 100644 --- a/modules/dnn/src/vkcom/src/pipeline.cpp +++ b/modules/dnn/src/vkcom/src/pipeline.cpp @@ -279,7 +279,7 @@ Ptr PipelineFactory::getPipeline(const std::string& key, const std::ve // retrieve spv from SPVMaps with given key auto iterSPV = SPVMaps.find(key); if (iterSPV == SPVMaps.end()) - CV_Error(CV_StsError, "Can not create SPV with the given name:"+key+"!"); + CV_Error(cv::Error::StsError, "Can not create SPV with the given name:"+key+"!"); const uint32_t* spv = iterSPV->second.first; size_t length = iterSPV->second.second; @@ -292,7 +292,7 @@ Ptr PipelineFactory::getPipeline(const std::string& key, const std::ve } else { - CV_Error(CV_StsError, "Can not Created the VkPipeline "+key); + CV_Error(cv::Error::StsError, "Can not Created the VkPipeline "+key); } return pipeline; diff --git a/modules/highgui/src/window.cpp b/modules/highgui/src/window.cpp index 2e528fe8e5..fef71f2b31 100644 --- a/modules/highgui/src/window.cpp +++ b/modules/highgui/src/window.cpp @@ -1097,17 +1097,17 @@ void cv::imshow(const String& winname, const ogl::Texture2D& _tex) CV_IMPL void cvSetOpenGlDrawCallback(const char*, CvOpenGlDrawCallback, void*) { - CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); + CV_Error(cv::Error::OpenGlNotSupported, "The library is compiled without OpenGL support"); } CV_IMPL void cvSetOpenGlContext(const char*) { - CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); + CV_Error(cv::Error::OpenGlNotSupported, "The library is compiled without OpenGL support"); } CV_IMPL void cvUpdateWindow(const char*) { - CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); + CV_Error(cv::Error::OpenGlNotSupported, "The library is compiled without OpenGL support"); } #endif // !HAVE_OPENGL @@ -1176,52 +1176,52 @@ static const char* NO_QT_ERR_MSG = "The library is compiled without QT support"; cv::QtFont cv::fontQt(const String&, int, Scalar, int, int, int) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::addText( const Mat&, const String&, Point, const QtFont&) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::addText(const Mat&, const String&, Point, const String&, int, Scalar, int, int, int) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::displayStatusBar(const String&, const String&, int) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::displayOverlay(const String&, const String&, int ) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } int cv::startLoop(int (*)(int argc, char *argv[]), int , char**) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::stopLoop() { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::saveWindowParameters(const String&) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } void cv::loadWindowParameters(const String&) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } int cv::createButton(const String&, ButtonCallback, void*, int , bool ) { - CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG); + CV_Error(cv::Error::StsNotImplemented, NO_QT_ERR_MSG); } #endif diff --git a/modules/highgui/src/window_QT.cpp b/modules/highgui/src/window_QT.cpp index c72163cd6b..65bcdb5239 100644 --- a/modules/highgui/src/window_QT.cpp +++ b/modules/highgui/src/window_QT.cpp @@ -147,7 +147,7 @@ CV_IMPL CvFont cvFontQt(const char* nameFont, int pointSize,CvScalar color,int w CV_IMPL void cvAddText(const CvArr* img, const char* text, CvPoint org, CvFont* font) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "putText", @@ -162,7 +162,7 @@ CV_IMPL void cvAddText(const CvArr* img, const char* text, CvPoint org, CvFont* double cvGetRatioWindow_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); double result = -1; QMetaObject::invokeMethod(guiMainThread, @@ -176,7 +176,7 @@ double cvGetRatioWindow_QT(const char* name) double cvGetPropVisible_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); double result = 0; @@ -193,7 +193,7 @@ void cvSetRatioWindow_QT(const char* name,double prop_value) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "setRatioWindow", @@ -205,7 +205,7 @@ void cvSetRatioWindow_QT(const char* name,double prop_value) double cvGetPropWindow_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); double result = -1; QMetaObject::invokeMethod(guiMainThread, @@ -221,7 +221,7 @@ double cvGetPropWindow_QT(const char* name) void cvSetPropWindow_QT(const char* name,double prop_value) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "setPropWindow", @@ -246,7 +246,7 @@ void setWindowTitle_QT(const String& winname, const String& title) void cvSetModeWindow_QT(const char* name, double prop_value) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "toggleFullScreen", @@ -258,7 +258,7 @@ void cvSetModeWindow_QT(const char* name, double prop_value) CvRect cvGetWindowRect_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); CvRect result = cvRect(-1, -1, -1, -1); @@ -274,7 +274,7 @@ CvRect cvGetWindowRect_QT(const char* name) double cvGetModeWindow_QT(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); double result = -1; @@ -291,7 +291,7 @@ double cvGetModeWindow_QT(const char* name) CV_IMPL void cvDisplayOverlay(const char* name, const char* text, int delayms) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "displayInfo", @@ -305,7 +305,7 @@ CV_IMPL void cvDisplayOverlay(const char* name, const char* text, int delayms) CV_IMPL void cvSaveWindowParameters(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "saveWindowParameters", @@ -317,7 +317,7 @@ CV_IMPL void cvSaveWindowParameters(const char* name) CV_IMPL void cvLoadWindowParameters(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "loadWindowParameters", @@ -329,7 +329,7 @@ CV_IMPL void cvLoadWindowParameters(const char* name) CV_IMPL void cvDisplayStatusBar(const char* name, const char* text, int delayms) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "displayStatusBar", @@ -492,7 +492,7 @@ static CvTrackbar* icvFindTrackBarByName(const char* name_trackbar, const char* QPointer w = icvFindWindowByName(nameWinQt); if (!w) - CV_Error(CV_StsNullPtr, "NULL window handler"); + CV_Error(cv::Error::StsNullPtr, "NULL window handler"); if (w->param_gui_mode == CV_GUI_NORMAL) return (CvTrackbar*) icvFindBarByName(w->myBarLayout, nameQt, type_CvTrackbar); @@ -575,7 +575,7 @@ CV_IMPL int cvNamedWindow(const char* name, int flags) CV_IMPL void cvDestroyWindow(const char* name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "destroyWindow", @@ -598,7 +598,7 @@ CV_IMPL void cvDestroyAllWindows() CV_IMPL void* cvGetWindowHandle(const char* name) { if (!name) - CV_Error( CV_StsNullPtr, "NULL name string" ); + CV_Error( cv::Error::StsNullPtr, "NULL name string" ); return (void*) icvFindWindowByName(QLatin1String(name)); } @@ -607,7 +607,7 @@ CV_IMPL void* cvGetWindowHandle(const char* name) CV_IMPL const char* cvGetWindowName(void* window_handle) { if( !window_handle ) - CV_Error( CV_StsNullPtr, "NULL window handler" ); + CV_Error( cv::Error::StsNullPtr, "NULL window handler" ); return ((CvWindow*)window_handle)->objectName().toLatin1().data(); } @@ -616,7 +616,7 @@ CV_IMPL const char* cvGetWindowName(void* window_handle) CV_IMPL void cvMoveWindow(const char* name, int x, int y) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "moveWindow", autoBlockingConnection(), @@ -628,7 +628,7 @@ CV_IMPL void cvMoveWindow(const char* name, int x, int y) CV_IMPL void cvResizeWindow(const char* name, int width, int height) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "resizeWindow", autoBlockingConnection(), @@ -641,7 +641,7 @@ CV_IMPL void cvResizeWindow(const char* name, int width, int height) CV_IMPL int cvCreateTrackbar2(const char* name_bar, const char* window_name, int* val, int count, CvTrackbarCallback2 on_notify, void* userdata) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "addSlider2", @@ -666,7 +666,7 @@ CV_IMPL int cvStartWindowThread() CV_IMPL int cvCreateTrackbar(const char* name_bar, const char* window_name, int* value, int count, CvTrackbarCallback on_change) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "addSlider", @@ -684,7 +684,7 @@ CV_IMPL int cvCreateTrackbar(const char* name_bar, const char* window_name, int* CV_IMPL int cvCreateButton(const char* button_name, CvButtonCallback on_change, void* userdata, int button_type, int initial_button_state) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); if (initial_button_state < 0 || initial_button_state > 1) return 0; @@ -750,7 +750,7 @@ CV_IMPL void cvSetMouseCallback(const char* window_name, CvMouseCallback on_mous QPointer w = icvFindWindowByName(QLatin1String(window_name)); if (!w) - CV_Error(CV_StsNullPtr, "NULL window handler"); + CV_Error(cv::Error::StsNullPtr, "NULL window handler"); w->setMouseCallBack(on_mouse, param); @@ -780,7 +780,7 @@ CV_IMPL void cvShowImage(const char* name, const CvArr* arr) CV_IMPL void cvSetOpenGlDrawCallback(const char* window_name, CvOpenGlDrawCallback callback, void* userdata) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "setOpenGlDrawCallback", @@ -794,7 +794,7 @@ CV_IMPL void cvSetOpenGlDrawCallback(const char* window_name, CvOpenGlDrawCallba CV_IMPL void cvSetOpenGlContext(const char* window_name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "setOpenGlContext", @@ -806,7 +806,7 @@ CV_IMPL void cvSetOpenGlContext(const char* window_name) CV_IMPL void cvUpdateWindow(const char* window_name) { if (!guiMainThread) - CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + CV_Error( cv::Error::StsNullPtr, "NULL guiReceiver (please create a window)" ); QMetaObject::invokeMethod(guiMainThread, "updateWindow", @@ -1036,7 +1036,7 @@ void GuiReceiver::toggleFullScreen(QString name, double arg2) void GuiReceiver::createWindow(QString name, int flags) { if (!qApp) - CV_Error(CV_StsNullPtr, "NULL session handler" ); + CV_Error(cv::Error::StsNullPtr, "NULL session handler" ); // Check the name in the storage if (icvFindWindowByName(name.toLatin1().data())) @@ -1127,7 +1127,7 @@ void GuiReceiver::destroyWindow(QString name) void GuiReceiver::destroyAllWindow() { if (!qApp) - CV_Error(CV_StsNullPtr, "NULL session handler" ); + CV_Error(cv::Error::StsNullPtr, "NULL session handler" ); if (multiThreads) { @@ -1256,7 +1256,7 @@ void GuiReceiver::addSlider2(QString bar_name, QString window_name, void* value, return; if (count <= 0) //count is the max value of the slider, so must be bigger than 0 - CV_Error(CV_StsNullPtr, "Max value of the slider must be bigger than 0" ); + CV_Error(cv::Error::StsNullPtr, "Max value of the slider must be bigger than 0" ); CvWindow::addSlider2(w, bar_name, (int*)value, count, (CvTrackbarCallback2) on_change, userdata); } @@ -1286,10 +1286,10 @@ void GuiReceiver::addSlider(QString bar_name, QString window_name, void* value, return; if (!value) - CV_Error(CV_StsNullPtr, "NULL value pointer" ); + CV_Error(cv::Error::StsNullPtr, "NULL value pointer" ); if (count <= 0) //count is the max value of the slider, so must be bigger than 0 - CV_Error(CV_StsNullPtr, "Max value of the slider must be bigger than 0" ); + CV_Error(cv::Error::StsNullPtr, "Max value of the slider must be bigger than 0" ); CvWindow::addSlider(w, bar_name, (int*)value, count, (CvTrackbarCallback) on_change); } @@ -1703,7 +1703,7 @@ CvWindow::CvWindow(QString name, int arg2) //3: my view #ifndef HAVE_QT_OPENGL if (arg2 & CV_WINDOW_OPENGL) - CV_Error( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); + CV_Error( cv::Error::OpenGlNotSupported, "Library was built without OpenGL support" ); mode_display = CV_MODE_NORMAL; #else mode_display = arg2 & CV_WINDOW_OPENGL ? CV_MODE_OPENGL : CV_MODE_NORMAL; @@ -2662,19 +2662,19 @@ void DefaultViewPort::startDisplayInfo(QString text, int delayms) void DefaultViewPort::setOpenGlDrawCallback(CvOpenGlDrawCallback /*callback*/, void* /*userdata*/) { - CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL"); + CV_Error(cv::Error::OpenGlNotSupported, "Window doesn't support OpenGL"); } void DefaultViewPort::makeCurrentOpenGlContext() { - CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL"); + CV_Error(cv::Error::OpenGlNotSupported, "Window doesn't support OpenGL"); } void DefaultViewPort::updateGl() { - CV_Error(CV_OpenGlNotSupported, "Window doesn't support OpenGL"); + CV_Error(cv::Error::OpenGlNotSupported, "Window doesn't support OpenGL"); } @@ -2777,7 +2777,7 @@ void DefaultViewPort::saveView() return; } - CV_Error(CV_StsNullPtr, "file extension not recognized, please choose between JPG, JPEG, BMP or PNG"); + CV_Error(cv::Error::StsNullPtr, "file extension not recognized, please choose between JPG, JPEG, BMP or PNG"); } } diff --git a/modules/highgui/src/window_gtk.cpp b/modules/highgui/src/window_gtk.cpp index ee590bd9c4..fa169f0bee 100644 --- a/modules/highgui/src/window_gtk.cpp +++ b/modules/highgui/src/window_gtk.cpp @@ -744,7 +744,7 @@ CvRect cvGetWindowRect_GTK(const char* name) CV_LOCK_MUTEX(); const auto window = icvFindWindowByName(name); if (!window) - CV_Error( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); return cvRect(getImageRect_(window)); } @@ -786,7 +786,7 @@ double cvGetModeWindow_GTK(const char* name)//YV CV_LOCK_MUTEX(); const auto window = icvFindWindowByName(name); if (!window) - CV_Error( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); double result = window->status; return result; @@ -801,7 +801,7 @@ void cvSetModeWindow_GTK( const char* name, double prop_value)//Yannick Verdie const auto window = icvFindWindowByName(name); if (!window) - CV_Error( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); setModeWindow_(window, (int)prop_value); } @@ -917,11 +917,11 @@ namespace // Try double-buffered visual glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE)); if (!glconfig) - CV_Error( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + CV_Error( cv::Error::OpenGlApiCallError, "Can't Create A GL Device Context" ); // Set OpenGL-capability to the widget if (!gtk_widget_set_gl_capability(window->widget, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE)) - CV_Error( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + CV_Error( cv::Error::OpenGlApiCallError, "Can't Create A GL Device Context" ); window->useGl = true; } @@ -932,7 +932,7 @@ namespace GdkGLDrawable* gldrawable = gtk_widget_get_gl_drawable(window->widget); if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) - CV_Error( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + CV_Error( cv::Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); glViewport(0, 0, gtk_widget_get_allocated_width(window->widget), gtk_widget_get_allocated_height(window->widget)); @@ -1050,7 +1050,7 @@ static std::shared_ptr namedWindow_(const std::string& name, int flags #ifndef HAVE_OPENGL if (flags & CV_WINDOW_OPENGL) - CV_Error( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); + CV_Error( cv::Error::OpenGlNotSupported, "Library was built without OpenGL support" ); #else if (flags & CV_WINDOW_OPENGL) createGlContext(window); @@ -1131,16 +1131,16 @@ CV_IMPL void cvSetOpenGlContext(const char* name) auto window = icvFindWindowByName(name); if (!window) - CV_Error( CV_StsNullPtr, "NULL window" ); + CV_Error( cv::Error::StsNullPtr, "NULL window" ); if (!window->useGl) - CV_Error( CV_OpenGlNotSupported, "Window doesn't support OpenGL" ); + CV_Error( cv::Error::OpenGlNotSupported, "Window doesn't support OpenGL" ); glcontext = gtk_widget_get_gl_context(window->widget); gldrawable = gtk_widget_get_gl_drawable(window->widget); if (!gdk_gl_drawable_make_current(gldrawable, glcontext)) - CV_Error( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + CV_Error( cv::Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); } CV_IMPL void cvUpdateWindow(const char* name) @@ -1168,7 +1168,7 @@ CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback call return; if (!window->useGl) - CV_Error( CV_OpenGlNotSupported, "Window was created without OpenGL context" ); + CV_Error( cv::Error::OpenGlNotSupported, "Window was created without OpenGL context" ); window->glDrawCallback = callback; window->glDrawData = userdata; @@ -1384,7 +1384,7 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, CV_Assert(trackbar_name && "NULL trackbar name"); if( count <= 0 ) - CV_Error( CV_StsOutOfRange, "Bad trackbar maximal value" ); + CV_Error( cv::Error::StsOutOfRange, "Bad trackbar maximal value" ); CV_LOCK_MUTEX(); @@ -1557,7 +1557,7 @@ CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_nam const auto trackbar = icvFindTrackbarByName(window, trackbar_name); if (!trackbar) { - CV_Error( CV_StsNullPtr, "No trackbar found" ); + CV_Error( cv::Error::StsNullPtr, "No trackbar found" ); } return setTrackbarPos_(trackbar, pos); diff --git a/modules/highgui/src/window_winrt.cpp b/modules/highgui/src/window_winrt.cpp index af771bd00b..93d14e3aef 100644 --- a/modules/highgui/src/window_winrt.cpp +++ b/modules/highgui/src/window_winrt.cpp @@ -36,7 +36,7 @@ #define CV_WINRT_NO_GUI_ERROR( funcname ) \ { \ - cvError( CV_StsNotImplemented, funcname, \ + cvError( cv::Error::StsNotImplemented, funcname, \ "The function is not implemented. ", \ __FILE__, __LINE__ ); \ } @@ -65,7 +65,7 @@ CV_IMPL void cvShowImage(const char* name, const CvArr* arr) CvMat stub, *image; if (!name) - CV_ERROR(CV_StsNullPtr, "NULL name"); + CV_ERROR(cv::Error::StsNullPtr, "NULL name"); CvWindow* window = HighguiBridge::getInstance().namedWindow(name); @@ -89,7 +89,7 @@ CV_IMPL int cvNamedWindow(const char* name, int flags) CV_FUNCNAME("cvNamedWindow"); if (!name) - CV_ERROR(CV_StsNullPtr, "NULL name"); + CV_ERROR(cv::Error::StsNullPtr, "NULL name"); HighguiBridge::getInstance().namedWindow(name); @@ -101,7 +101,7 @@ CV_IMPL void cvDestroyWindow(const char* name) CV_FUNCNAME("cvDestroyWindow"); if (!name) - CV_ERROR(CV_StsNullPtr, "NULL name string"); + CV_ERROR(cv::Error::StsNullPtr, "NULL name string"); HighguiBridge::getInstance().destroyWindow(name); } @@ -119,16 +119,16 @@ CV_IMPL int cvCreateTrackbar2(const char* trackbar_name, const char* window_name int pos = 0; if (!window_name || !trackbar_name) - CV_ERROR(CV_StsNullPtr, "NULL window or trackbar name"); + CV_ERROR(cv::Error::StsNullPtr, "NULL window or trackbar name"); if (count < 0) - CV_ERROR(CV_StsOutOfRange, "Bad trackbar max value"); + CV_ERROR(cv::Error::StsOutOfRange, "Bad trackbar max value"); CvWindow* window = HighguiBridge::getInstance().namedWindow(window_name); if (!window) { - CV_ERROR(CV_StsNullPtr, "NULL window"); + CV_ERROR(cv::Error::StsNullPtr, "NULL window"); } window->createSlider(trackbar_name, val, count, on_notify, userdata); @@ -143,7 +143,7 @@ CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name CvTrackbar* trackbar = 0; if (trackbar_name == 0 || window_name == 0) - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + CV_ERROR(cv::Error::StsNullPtr, "NULL trackbar or window name"); CvWindow* window = HighguiBridge::getInstance().findWindowByName(window_name); if (window) @@ -160,7 +160,7 @@ CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name if (maxval >= 0) { if (trackbar_name == 0 || window_name == 0) - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + CV_ERROR(cv::Error::StsNullPtr, "NULL trackbar or window name"); CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name); @@ -176,7 +176,7 @@ CV_IMPL void cvSetTrackbarMin(const char* trackbar_name, const char* window_name if (minval >= 0) { if (trackbar_name == 0 || window_name == 0) - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + CV_ERROR(cv::Error::StsNullPtr, "NULL trackbar or window name"); CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name); @@ -192,7 +192,7 @@ CV_IMPL int cvGetTrackbarPos(const char* trackbar_name, const char* window_name) CV_FUNCNAME("cvGetTrackbarPos"); if (trackbar_name == 0 || window_name == 0) - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + CV_ERROR(cv::Error::StsNullPtr, "NULL trackbar or window name"); CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name); @@ -229,7 +229,7 @@ CV_IMPL void cvSetMouseCallback(const char* window_name, CvMouseCallback on_mous CV_FUNCNAME("cvSetMouseCallback"); if (!window_name) - CV_ERROR(CV_StsNullPtr, "NULL window name"); + CV_ERROR(cv::Error::StsNullPtr, "NULL window name"); CvWindow* window = HighguiBridge::getInstance().findWindowByName(window_name); if (!window) @@ -253,19 +253,19 @@ CV_IMPL void cvResizeWindow(const char* name, int width, int height) CV_IMPL int cvInitSystem(int, char**) { CV_WINRT_NO_GUI_ERROR("cvInitSystem"); - return CV_StsNotImplemented; + return cv::Error::StsNotImplemented; } CV_IMPL void* cvGetWindowHandle(const char*) { CV_WINRT_NO_GUI_ERROR("cvGetWindowHandle"); - return (void*) CV_StsNotImplemented; + return (void*) cv::Error::StsNotImplemented; } CV_IMPL const char* cvGetWindowName(void*) { CV_WINRT_NO_GUI_ERROR("cvGetWindowName"); - return (const char*) CV_StsNotImplemented; + return (const char*) cv::Error::StsNotImplemented; } void cvSetModeWindow_WinRT(const char* name, double prop_value) { @@ -274,10 +274,10 @@ void cvSetModeWindow_WinRT(const char* name, double prop_value) { double cvGetModeWindow_WinRT(const char* name) { CV_WINRT_NO_GUI_ERROR("cvGetModeWindow"); - return CV_StsNotImplemented; + return cv::Error::StsNotImplemented; } CV_IMPL int cvStartWindowThread() { CV_WINRT_NO_GUI_ERROR("cvStartWindowThread"); - return CV_StsNotImplemented; + return cv::Error::StsNotImplemented; } diff --git a/modules/imgproc/src/approx.cpp b/modules/imgproc/src/approx.cpp index df1570c38d..f05a6bcf3c 100644 --- a/modules/imgproc/src/approx.cpp +++ b/modules/imgproc/src/approx.cpp @@ -389,9 +389,9 @@ cvApproxChains( CvSeq* src_seq, CvSeq *dst_seq = 0; if( !src_seq || !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( method > cv::CHAIN_APPROX_TC89_KCOS || method <= 0 || minimal_perimeter < 0 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); while( src_seq != 0 ) { @@ -410,7 +410,7 @@ cvApproxChains( CvSeq* src_seq, contour = icvApproximateChainTC89( (CvChain *) src_seq, sizeof( CvContour ), storage, method ); break; default: - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); } if( contour->total > 0 ) @@ -681,7 +681,7 @@ void cv::approxPolyDP( InputArray _curve, OutputArray _approxCurve, //from being used. if (epsilon < 0.0 || !(epsilon < 1e30)) { - CV_Error(CV_StsOutOfRange, "Epsilon not valid."); + CV_Error(cv::Error::StsOutOfRange, "Epsilon not valid."); } Mat curve = _curve.getMat(); @@ -704,7 +704,7 @@ void cv::approxPolyDP( InputArray _curve, OutputArray _approxCurve, else if( depth == CV_32F ) nout = approxPolyDP_(curve.ptr(), npoints, (Point2f*)buf, closed, epsilon, _stack); else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); Mat(nout, 1, CV_MAKETYPE(depth, 2), buf).copyTo(_approxCurve); } @@ -728,7 +728,7 @@ cvApproxPoly( const void* array, int header_size, { src_seq = (CvSeq*)array; if( !CV_IS_SEQ_POLYLINE( src_seq )) - CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + CV_Error( cv::Error::StsBadArg, "Unsupported sequence type" ); recursive = parameter2; @@ -743,10 +743,10 @@ cvApproxPoly( const void* array, int header_size, } if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer " ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer " ); if( header_size < 0 ) - CV_Error( CV_StsOutOfRange, "header_size is negative. " + CV_Error( cv::Error::StsOutOfRange, "header_size is negative. " "Pass 0 to make the destination header_size == input header_size" ); if( header_size == 0 ) @@ -756,12 +756,12 @@ cvApproxPoly( const void* array, int header_size, { if( CV_IS_SEQ_CHAIN( src_seq )) { - CV_Error( CV_StsBadArg, "Input curves are not polygonal. " + CV_Error( cv::Error::StsBadArg, "Input curves are not polygonal. " "Use cvApproxChains first" ); } else { - CV_Error( CV_StsBadArg, "Input curves have unknown type" ); + CV_Error( cv::Error::StsBadArg, "Input curves have unknown type" ); } } @@ -769,10 +769,10 @@ cvApproxPoly( const void* array, int header_size, header_size = src_seq->header_size; if( header_size < (int)sizeof(CvContour) ) - CV_Error( CV_StsBadSize, "New header size must be non-less than sizeof(CvContour)" ); + CV_Error( cv::Error::StsBadSize, "New header size must be non-less than sizeof(CvContour)" ); if( method != CV_POLY_APPROX_DP ) - CV_Error( CV_StsOutOfRange, "Unknown approximation method" ); + CV_Error( cv::Error::StsOutOfRange, "Unknown approximation method" ); while( src_seq != 0 ) { @@ -782,7 +782,7 @@ cvApproxPoly( const void* array, int header_size, { case CV_POLY_APPROX_DP: if( parameter < 0 ) - CV_Error( CV_StsOutOfRange, "Accuracy must be non-negative" ); + CV_Error( cv::Error::StsOutOfRange, "Accuracy must be non-negative" ); CV_Assert( CV_SEQ_ELTYPE(src_seq) == CV_32SC2 || CV_SEQ_ELTYPE(src_seq) == CV_32FC2 ); @@ -804,7 +804,7 @@ cvApproxPoly( const void* array, int header_size, nout = cv::approxPolyDP_((cv::Point2f*)src, npoints, (cv::Point2f*)dst, closed, parameter, stack); else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); contour = cvCreateSeq( src_seq->flags, header_size, src_seq->elem_size, storage ); @@ -812,7 +812,7 @@ cvApproxPoly( const void* array, int header_size, } break; default: - CV_Error( CV_StsBadArg, "Invalid approximation method" ); + CV_Error( cv::Error::StsBadArg, "Invalid approximation method" ); } CV_Assert( contour ); diff --git a/modules/imgproc/src/bilateral_filter.dispatch.cpp b/modules/imgproc/src/bilateral_filter.dispatch.cpp index e2a9dcba39..501af5b244 100644 --- a/modules/imgproc/src/bilateral_filter.dispatch.cpp +++ b/modules/imgproc/src/bilateral_filter.dispatch.cpp @@ -422,7 +422,7 @@ void bilateralFilter( InputArray _src, OutputArray _dst, int d, else if( src.depth() == CV_32F ) bilateralFilter_32f( src, dst, d, sigmaColor, sigmaSpace, borderType ); else - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "Bilateral filtering is only implemented for 8u and 32f images" ); } diff --git a/modules/imgproc/src/box_filter.simd.hpp b/modules/imgproc/src/box_filter.simd.hpp index f7c8f66a35..ac0b0f1b56 100644 --- a/modules/imgproc/src/box_filter.simd.hpp +++ b/modules/imgproc/src/box_filter.simd.hpp @@ -1200,7 +1200,7 @@ Ptr getRowSumFilter(int srcType, int sumType, int ksize, int anch if( sdepth == CV_64F && ddepth == CV_64F ) return makePtr >(ksize, anchor); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of source format (=%d), and buffer format (=%d)", srcType, sumType)); } @@ -1241,7 +1241,7 @@ Ptr getColumnSumFilter(int sumType, int dstType, int ksize, in if( ddepth == CV_64F && sdepth == CV_64F ) return makePtr >(ksize, anchor, scale); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of sum format (=%d), and destination format (=%d)", sumType, dstType)); } @@ -1339,7 +1339,7 @@ Ptr getSqrRowSumFilter(int srcType, int sumType, int ksize, int a if( sdepth == CV_64F && ddepth == CV_64F ) return makePtr >(ksize, anchor); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of source format (=%d), and buffer format (=%d)", srcType, sumType)); } diff --git a/modules/imgproc/src/canny.cpp b/modules/imgproc/src/canny.cpp index 2fed0ba0c2..c322959441 100644 --- a/modules/imgproc/src/canny.cpp +++ b/modules/imgproc/src/canny.cpp @@ -844,7 +844,7 @@ void Canny( InputArray _src, OutputArray _dst, } if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7))) - CV_Error(CV_StsBadFlag, "Aperture size should be odd between 3 and 7"); + CV_Error(cv::Error::StsBadFlag, "Aperture size should be odd between 3 and 7"); if (aperture_size == 7) { diff --git a/modules/imgproc/src/clahe.cpp b/modules/imgproc/src/clahe.cpp index 677b6a0738..b787378ee3 100644 --- a/modules/imgproc/src/clahe.cpp +++ b/modules/imgproc/src/clahe.cpp @@ -415,7 +415,7 @@ namespace else if (_src.type() == CV_16UC1) calcLutBody = cv::makePtr >(srcForLut, lut_, tileSize, tilesX_, clipLimit, lutScale); else - CV_Error( CV_StsBadArg, "Unsupported type" ); + CV_Error( cv::Error::StsBadArg, "Unsupported type" ); cv::parallel_for_(cv::Range(0, tilesX_ * tilesY_), *calcLutBody); diff --git a/modules/imgproc/src/color.cpp b/modules/imgproc/src/color.cpp index 4eaa051e24..dde8e1344c 100644 --- a/modules/imgproc/src/color.cpp +++ b/modules/imgproc/src/color.cpp @@ -177,7 +177,7 @@ void cvtColorTwoPlane( InputArray _ysrc, InputArray _uvsrc, OutputArray _dst, in case COLOR_YUV2BGRA_NV21: case COLOR_YUV2RGBA_NV21: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV12: break; default: - CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); return; } @@ -379,7 +379,7 @@ void cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) cvtColormRGBA2RGBA(_src, _dst); break; default: - CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); } } } //namespace cv diff --git a/modules/imgproc/src/color_yuv.simd.hpp b/modules/imgproc/src/color_yuv.simd.hpp index 03f1b653e5..f80b3d931c 100644 --- a/modules/imgproc/src/color_yuv.simd.hpp +++ b/modules/imgproc/src/color_yuv.simd.hpp @@ -2029,7 +2029,7 @@ void cvtTwoPlaneYUVtoBGR(const uchar * y_data, size_t y_step, const uchar * uv_d case 401: cvtPtr = cvtYUV420sp2RGB<0, 1, 4>; break; case 420: cvtPtr = cvtYUV420sp2RGB<2, 0, 4>; break; case 421: cvtPtr = cvtYUV420sp2RGB<2, 1, 4>; break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + default: CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); break; }; cvtPtr(dst_data, dst_step, dst_width, dst_height, y_data, y_step, uv_data, uv_step); @@ -2069,7 +2069,7 @@ void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step, case 32: cvtPtr = cvtYUV420p2RGB<2, 3>; break; case 40: cvtPtr = cvtYUV420p2RGB<0, 4>; break; case 42: cvtPtr = cvtYUV420p2RGB<2, 4>; break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + default: CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); break; }; cvtPtr(dst_data, dst_step, dst_width, dst_height, src_step, src_data, u, v, ustepIdx, vstepIdx); @@ -2139,7 +2139,7 @@ void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step, case 4200: cvtPtr = cvtYUV422toRGB<2,0,0,4>; break; case 4201: cvtPtr = cvtYUV422toRGB<2,0,1,4>; break; case 4210: cvtPtr = cvtYUV422toRGB<2,1,0,4>; break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + default: CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); break; }; cvtPtr(dst_data, dst_step, src_data, src_step, width, height); @@ -2168,7 +2168,7 @@ void cvtOnePlaneBGRtoYUV(const uchar * src_data, size_t src_step, case 4200: cvtPtr = cvtRGBtoYUV422<2,0,0,4>; break; case 4201: cvtPtr = cvtRGBtoYUV422<2,0,1,4>; break; case 4210: cvtPtr = cvtRGBtoYUV422<2,1,0,4>; break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + default: CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported color conversion code" ); break; }; cvtPtr(dst_data, dst_step, src_data, src_step, width, height); diff --git a/modules/imgproc/src/connectedcomponents.cpp b/modules/imgproc/src/connectedcomponents.cpp index a2f4b6e890..d402ea91c3 100644 --- a/modules/imgproc/src/connectedcomponents.cpp +++ b/modules/imgproc/src/connectedcomponents.cpp @@ -5716,7 +5716,7 @@ namespace cv{ } } - CV_Error(CV_StsUnsupportedFormat, "unsupported label/image type"); + CV_Error(cv::Error::StsUnsupportedFormat, "unsupported label/image type"); } } @@ -5738,7 +5738,7 @@ int cv::connectedComponents(InputArray img_, OutputArray _labels, int connectivi return connectedComponents_sub1(img, labels, connectivity, ccltype, sop); } else{ - CV_Error(CV_StsUnsupportedFormat, "the type of labels must be 16u or 32s"); + CV_Error(cv::Error::StsUnsupportedFormat, "the type of labels must be 16u or 32s"); } } @@ -5763,7 +5763,7 @@ int cv::connectedComponentsWithStats(InputArray img_, OutputArray _labels, Outpu return connectedComponents_sub1(img, labels, connectivity, ccltype, sop); } else{ - CV_Error(CV_StsUnsupportedFormat, "the type of labels must be 16u or 32s"); + CV_Error(cv::Error::StsUnsupportedFormat, "the type of labels must be 16u or 32s"); return 0; } } diff --git a/modules/imgproc/src/contours.cpp b/modules/imgproc/src/contours.cpp index 2e0d14e4c7..2e3121418a 100644 --- a/modules/imgproc/src/contours.cpp +++ b/modules/imgproc/src/contours.cpp @@ -59,10 +59,10 @@ cvStartReadChainPoints( CvChain * chain, CvChainPtReader * reader ) int i; if( !chain || !reader ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( chain->elem_size != 1 || chain->header_size < (int)sizeof(CvChain)) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); cvStartReadSeq( (CvSeq *) chain, (CvSeqReader *) reader, 0 ); @@ -80,7 +80,7 @@ CV_IMPL CvPoint cvReadChainPoint( CvChainPtReader * reader ) { if( !reader ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cv::Point2i pt = reader->pt; @@ -180,7 +180,7 @@ cvStartFindContours_Impl( void* _img, CvMemStorage* storage, int method, CvPoint offset, int needFillBorder ) { if( !storage ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CvMat stub, *mat = cvGetMat( _img, &stub ); @@ -189,7 +189,7 @@ cvStartFindContours_Impl( void* _img, CvMemStorage* storage, if( !((CV_IS_MASK_ARR( mat ) && mode < CV_RETR_FLOODFILL) || (CV_MAT_TYPE(mat->type) == CV_32SC1 && mode == CV_RETR_FLOODFILL)) ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "[Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL " "otherwise supports CV_32SC1 images only" ); @@ -198,10 +198,10 @@ cvStartFindContours_Impl( void* _img, CvMemStorage* storage, uchar* img = (uchar*)(mat->data.ptr); if( method < 0 || method > CV_CHAIN_APPROX_TC89_KCOS ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); if( header_size < (int) (method == CV_CHAIN_CODE ? sizeof( CvChain ) : sizeof( CvContour ))) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); CvContourScanner scanner = (CvContourScanner)cvAlloc( sizeof( *scanner )); memset( scanner, 0, sizeof(*scanner) ); @@ -487,7 +487,7 @@ cvSubstituteContour( CvContourScanner scanner, CvSeq * new_contour ) _CvContourInfo *l_cinfo; if( !scanner ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); l_cinfo = scanner->l_cinfo; if( l_cinfo && l_cinfo->contour && l_cinfo->contour != new_contour ) @@ -1029,7 +1029,7 @@ CvSeq * cvFindNextContour( CvContourScanner scanner ) { if( !scanner ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); CV_Assert(scanner->img_step >= 0); @@ -1313,7 +1313,7 @@ cvEndFindContours( CvContourScanner * _scanner ) CvSeq *first = 0; if( !_scanner ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); scanner = *_scanner; if( scanner ) @@ -1438,13 +1438,13 @@ icvFindContoursInInterval( const CvArr* src, CvSeq* prev = 0; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); if( !result ) - CV_Error( CV_StsNullPtr, "NULL double CvSeq pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL double CvSeq pointer" ); if( contourHeaderSize < (int)sizeof(CvContour)) - CV_Error( CV_StsBadSize, "Contour header size must be >= sizeof(CvContour)" ); + CV_Error( cv::Error::StsBadSize, "Contour header size must be >= sizeof(CvContour)" ); storage00.reset(cvCreateChildMemStorage(storage)); storage01.reset(cvCreateChildMemStorage(storage)); @@ -1453,7 +1453,7 @@ icvFindContoursInInterval( const CvArr* src, mat = cvGetMat( src, &stub ); if( !CV_IS_MASK_ARR(mat)) - CV_Error( CV_StsBadArg, "Input array must be 8uC1 or 8sC1" ); + CV_Error( cv::Error::StsBadArg, "Input array must be 8uC1 or 8sC1" ); src_data = mat->data.ptr; img_step = mat->step; img_size = cvGetMatSize(mat); @@ -1745,14 +1745,14 @@ cvFindContours_Impl( void* img, CvMemStorage* storage, int count = -1; if( !firstContour ) - CV_Error( CV_StsNullPtr, "NULL double CvSeq pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL double CvSeq pointer" ); *firstContour = 0; if( method == CV_LINK_RUNS ) { if( offset.x != 0 || offset.y != 0 ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "Nonzero offset is not supported in CV_LINK_RUNS yet" ); count = icvFindContoursInInterval( img, storage, firstContour, cntHeaderSize ); diff --git a/modules/imgproc/src/convhull.cpp b/modules/imgproc/src/convhull.cpp index d6e02cc0fb..f16618ccb6 100644 --- a/modules/imgproc/src/convhull.cpp +++ b/modules/imgproc/src/convhull.cpp @@ -471,7 +471,7 @@ cvConvexHull2( const CvArr* array, void* hull_storage, { ptseq = (CvSeq*)array; if( !CV_IS_SEQ_POINT_SET( ptseq )) - CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + CV_Error( cv::Error::StsBadArg, "Unsupported sequence type" ); if( hull_storage == 0 ) hull_storage = ptseq->storage; } @@ -503,15 +503,15 @@ cvConvexHull2( const CvArr* array, void* hull_storage, mat = (CvMat*)hull_storage; if( (mat->cols != 1 && mat->rows != 1) || !CV_IS_MAT_CONT(mat->type)) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The hull matrix should be continuous and have a single row or a single column" ); if( mat->cols + mat->rows - 1 < ptseq->total ) - CV_Error( CV_StsBadSize, "The hull matrix size might be not enough to fit the hull" ); + CV_Error( cv::Error::StsBadSize, "The hull matrix size might be not enough to fit the hull" ); if( CV_MAT_TYPE(mat->type) != CV_SEQ_ELTYPE(ptseq) && CV_MAT_TYPE(mat->type) != CV_32SC1 ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "The hull matrix must have the same type as input or 32sC1 (integers)" ); hullseq = cvMakeSeqHeaderForArray( @@ -526,7 +526,7 @@ cvConvexHull2( const CvArr* array, void* hull_storage, if( total == 0 ) { if( !isStorage ) - CV_Error( CV_StsBadSize, + CV_Error( cv::Error::StsBadSize, "Point sequence can not be empty if the output is matrix" ); return 0; } @@ -592,7 +592,7 @@ CV_IMPL CvSeq* cvConvexityDefects( const CvArr* array, if( CV_IS_SEQ( ptseq )) { if( !CV_IS_SEQ_POINT_SET( ptseq )) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "Input sequence is not a sequence of points" ); if( !storage ) storage = ptseq->storage; @@ -603,13 +603,13 @@ CV_IMPL CvSeq* cvConvexityDefects( const CvArr* array, } if( CV_SEQ_ELTYPE( ptseq ) != CV_32SC2 ) - CV_Error( CV_StsUnsupportedFormat, "Floating-point coordinates are not supported here" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Floating-point coordinates are not supported here" ); if( CV_IS_SEQ( hull )) { int hulltype = CV_SEQ_ELTYPE( hull ); if( hulltype != CV_SEQ_ELTYPE_PPOINT && hulltype != CV_SEQ_ELTYPE_INDEX ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "Convex hull must represented as a sequence " "of indices or sequence of pointers" ); if( !storage ) @@ -620,15 +620,15 @@ CV_IMPL CvSeq* cvConvexityDefects( const CvArr* array, CvMat* mat = (CvMat*)hull; if( !CV_IS_MAT( hull )) - CV_Error(CV_StsBadArg, "Convex hull is neither sequence nor matrix"); + CV_Error(cv::Error::StsBadArg, "Convex hull is neither sequence nor matrix"); if( (mat->cols != 1 && mat->rows != 1) || !CV_IS_MAT_CONT(mat->type) || CV_MAT_TYPE(mat->type) != CV_32SC1 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The matrix should be 1-dimensional and continuous array of int's" ); if( mat->cols + mat->rows - 1 > ptseq->total ) - CV_Error( CV_StsBadSize, "Convex hull is larger than the point sequence" ); + CV_Error( cv::Error::StsBadSize, "Convex hull is larger than the point sequence" ); hull = cvMakeSeqHeaderForArray( CV_SEQ_KIND_CURVE|CV_MAT_TYPE(mat->type)|CV_SEQ_FLAG_CLOSED, @@ -639,13 +639,13 @@ CV_IMPL CvSeq* cvConvexityDefects( const CvArr* array, is_index = CV_SEQ_ELTYPE(hull) == CV_SEQ_ELTYPE_INDEX; if( !storage ) - CV_Error( CV_StsNullPtr, "NULL storage pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL storage pointer" ); defects = cvCreateSeq( CV_SEQ_KIND_GENERIC, sizeof(CvSeq), sizeof(CvConvexityDefect), storage ); if( ptseq->total < 4 || hull->total < 3) { - //CV_ERROR( CV_StsBadSize, + //CV_ERROR( cv::Error::StsBadSize, // "point seq size must be >= 4, convex hull size must be >= 3" ); return defects; } @@ -779,7 +779,7 @@ cvCheckContourConvexity( const CvArr* array ) if( CV_IS_SEQ(contour) ) { if( !CV_IS_SEQ_POINT_SET(contour)) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "Input sequence must be polygon (closed 2d curve)" ); } else diff --git a/modules/imgproc/src/demosaicing.cpp b/modules/imgproc/src/demosaicing.cpp index 148df552e4..2bfa705b8a 100644 --- a/modules/imgproc/src/demosaicing.cpp +++ b/modules/imgproc/src/demosaicing.cpp @@ -1708,7 +1708,7 @@ void cv::demosaicing(InputArray _src, OutputArray _dst, int code, int dcn) else if( depth == CV_16U ) Bayer2Gray_ >(src, dst, code); else - CV_Error(CV_StsUnsupportedFormat, "Bayer->Gray demosaicing only supports 8u and 16u types"); + CV_Error(cv::Error::StsUnsupportedFormat, "Bayer->Gray demosaicing only supports 8u and 16u types"); break; case COLOR_BayerBG2BGRA: case COLOR_BayerGB2BGRA: case COLOR_BayerRG2BGRA: case COLOR_BayerGR2BGRA: @@ -1735,7 +1735,7 @@ void cv::demosaicing(InputArray _src, OutputArray _dst, int code, int dcn) else if( depth == CV_16U ) Bayer2RGB_ >(src, dst_, code); else - CV_Error(CV_StsUnsupportedFormat, "Bayer->RGB demosaicing only supports 8u and 16u types"); + CV_Error(cv::Error::StsUnsupportedFormat, "Bayer->RGB demosaicing only supports 8u and 16u types"); } else { @@ -1758,11 +1758,11 @@ void cv::demosaicing(InputArray _src, OutputArray _dst, int code, int dcn) else if (depth == CV_16U) Bayer2RGB_EdgeAware_T >(src, dst, code); else - CV_Error(CV_StsUnsupportedFormat, "Bayer->RGB Edge-Aware demosaicing only currently supports 8u and 16u types"); + CV_Error(cv::Error::StsUnsupportedFormat, "Bayer->RGB Edge-Aware demosaicing only currently supports 8u and 16u types"); break; default: - CV_Error( CV_StsBadFlag, "Unknown / unsupported color conversion code" ); + CV_Error( cv::Error::StsBadFlag, "Unknown / unsupported color conversion code" ); } } diff --git a/modules/imgproc/src/deriv.cpp b/modules/imgproc/src/deriv.cpp index 9cec64a9e9..cc9db282fd 100644 --- a/modules/imgproc/src/deriv.cpp +++ b/modules/imgproc/src/deriv.cpp @@ -101,7 +101,7 @@ static void getSobelKernels( OutputArray _kx, OutputArray _ky, Mat ky = _ky.getMat(); if( _ksize % 2 == 0 || _ksize > 31 ) - CV_Error( CV_StsOutOfRange, "The kernel size must be odd and not larger than 31" ); + CV_Error( cv::Error::StsOutOfRange, "The kernel size must be odd and not larger than 31" ); std::vector kerI(std::max(ksizeX, ksizeY) + 1); CV_Assert( dx >= 0 && dy >= 0 && dx+dy > 0 ); diff --git a/modules/imgproc/src/distransform.cpp b/modules/imgproc/src/distransform.cpp index c2bdb62948..6a7026c8c8 100644 --- a/modules/imgproc/src/distransform.cpp +++ b/modules/imgproc/src/distransform.cpp @@ -448,7 +448,7 @@ static void getDistanceTransformMask( int maskType, float *metrics ) metrics[2] = 2.1969f; break; default: - CV_Error(CV_StsBadArg, "Unknown metric type"); + CV_Error(cv::Error::StsBadArg, "Unknown metric type"); } } @@ -766,7 +766,7 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe float _mask[5] = {0}; if( maskSize != cv::DIST_MASK_3 && maskSize != cv::DIST_MASK_5 && maskSize != cv::DIST_MASK_PRECISE ) - CV_Error( CV_StsBadSize, "Mask size should be 3 or 5 or 0 (precise)" ); + CV_Error( cv::Error::StsBadSize, "Mask size should be 3 or 5 or 0 (precise)" ); if ((distType == cv::DIST_C || distType == cv::DIST_L1) && !need_labels) maskSize = cv::DIST_MASK_3; diff --git a/modules/imgproc/src/drawing.cpp b/modules/imgproc/src/drawing.cpp index 019c6e537e..355525eb6c 100644 --- a/modules/imgproc/src/drawing.cpp +++ b/modules/imgproc/src/drawing.cpp @@ -2239,7 +2239,7 @@ static const int* getFontData(int fontFace) ascii = HersheyScriptComplex; break; default: - CV_Error( CV_StsOutOfRange, "Unknown font type" ); + CV_Error( cv::Error::StsOutOfRange, "Unknown font type" ); } return ascii; } diff --git a/modules/imgproc/src/emd.cpp b/modules/imgproc/src/emd.cpp index eb86460535..8b7f325e74 100644 --- a/modules/imgproc/src/emd.cpp +++ b/modules/imgproc/src/emd.cpp @@ -174,28 +174,28 @@ CV_IMPL float cvCalcEMD2( const CvArr* signature_arr1, signature2 = cvGetMat( signature2, &sign_stub2 ); if( signature1->cols != signature2->cols ) - CV_Error( CV_StsUnmatchedSizes, "The arrays must have equal number of columns (which is number of dimensions but 1)" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The arrays must have equal number of columns (which is number of dimensions but 1)" ); dims = signature1->cols - 1; size1 = signature1->rows; size2 = signature2->rows; if( !CV_ARE_TYPES_EQ( signature1, signature2 )) - CV_Error( CV_StsUnmatchedFormats, "The array must have equal types" ); + CV_Error( cv::Error::StsUnmatchedFormats, "The array must have equal types" ); if( CV_MAT_TYPE( signature1->type ) != CV_32FC1 ) - CV_Error( CV_StsUnsupportedFormat, "The signatures must be 32fC1" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The signatures must be 32fC1" ); if( flow ) { flow = cvGetMat( flow, &flow_stub ); if( flow->rows != size1 || flow->cols != size2 ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The flow matrix size does not match to the signatures' sizes" ); if( CV_MAT_TYPE( flow->type ) != CV_32FC1 ) - CV_Error( CV_StsUnsupportedFormat, "The flow matrix must be 32fC1" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The flow matrix must be 32fC1" ); } cost->data.fl = 0; @@ -206,28 +206,28 @@ CV_IMPL float cvCalcEMD2( const CvArr* signature_arr1, if( cost_matrix ) { if( dist_func ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "Only one of cost matrix or distance function should be non-NULL in case of user-defined distance" ); if( lower_bound ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The lower boundary can not be calculated if the cost matrix is used" ); cost = cvGetMat( cost_matrix, &cost_stub ); if( cost->rows != size1 || cost->cols != size2 ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The cost matrix size does not match to the signatures' sizes" ); if( CV_MAT_TYPE( cost->type ) != CV_32FC1 ) - CV_Error( CV_StsUnsupportedFormat, "The cost matrix must be 32fC1" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The cost matrix must be 32fC1" ); } else if( !dist_func ) - CV_Error( CV_StsNullPtr, "In case of user-defined distance Distance function is undefined" ); + CV_Error( cv::Error::StsNullPtr, "In case of user-defined distance Distance function is undefined" ); } else { if( dims == 0 ) - CV_Error( CV_StsBadSize, + CV_Error( cv::Error::StsBadSize, "Number of dimensions can be 0 only if a user-defined metric is used" ); user_param = (void *) (size_t)dims; switch (dist_type) @@ -242,7 +242,7 @@ CV_IMPL float cvCalcEMD2( const CvArr* signature_arr1, dist_func = icvDistC; break; default: - CV_Error( CV_StsBadFlag, "Bad or unsupported metric type" ); + CV_Error( cv::Error::StsBadFlag, "Bad or unsupported metric type" ); } } @@ -279,7 +279,7 @@ CV_IMPL float cvCalcEMD2( const CvArr* signature_arr1, state.ssize, state.dsize, state.enter_x ); if( min_delta == CV_EMD_INF ) - CV_Error( CV_StsNoConv, "" ); + CV_Error( cv::Error::StsNoConv, "" ); /* if no negative deltamin, we found the optimal solution */ if( min_delta >= -eps ) @@ -287,7 +287,7 @@ CV_IMPL float cvCalcEMD2( const CvArr* signature_arr1, /* improve solution */ if(!icvNewSolution( &state )) - CV_Error( CV_StsNoConv, "" ); + CV_Error( cv::Error::StsNoConv, "" ); } } @@ -387,7 +387,7 @@ static int icvInitEMD( const float* signature1, int size1, } else if( weight < 0 ) - CV_Error(CV_StsBadArg, "signature1 must not contain negative weights"); + CV_Error(cv::Error::StsBadArg, "signature1 must not contain negative weights"); } for( i = 0; i < size2; i++ ) @@ -401,13 +401,13 @@ static int icvInitEMD( const float* signature1, int size1, state->idx2[dsize++] = i; } else if( weight < 0 ) - CV_Error(CV_StsBadArg, "signature2 must not contain negative weights"); + CV_Error(cv::Error::StsBadArg, "signature2 must not contain negative weights"); } if( ssize == 0 ) - CV_Error(CV_StsBadArg, "signature1 must contain at least one non-zero value"); + CV_Error(cv::Error::StsBadArg, "signature1 must contain at least one non-zero value"); if( dsize == 0 ) - CV_Error(CV_StsBadArg, "signature2 must contain at least one non-zero value"); + CV_Error(cv::Error::StsBadArg, "signature2 must contain at least one non-zero value"); /* if supply different than the demand, add a zero-cost dummy cluster */ diff = s_sum - d_sum; diff --git a/modules/imgproc/src/filter.simd.hpp b/modules/imgproc/src/filter.simd.hpp index 9306c78a30..21dab519af 100644 --- a/modules/imgproc/src/filter.simd.hpp +++ b/modules/imgproc/src/filter.simd.hpp @@ -3039,7 +3039,7 @@ Ptr getLinearRowFilter( if( sdepth == CV_64F && ddepth == CV_64F ) return makePtr >(kernel, anchor); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of source format (=%d), and buffer format (=%d)", srcType, bufType)); } @@ -3137,7 +3137,7 @@ Ptr getLinearColumnFilter( (kernel, anchor, delta, symmetryType); } - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of buffer format (=%d), and destination format (=%d)", bufType, dstType)); } @@ -3291,7 +3291,7 @@ Ptr getLinearFilter( return makePtr, FilterNoVec> >(kernel, anchor, delta); - CV_Error_( CV_StsNotImplemented, + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported combination of source format (=%d), and destination format (=%d)", srcType, dstType)); } diff --git a/modules/imgproc/src/floodfill.cpp b/modules/imgproc/src/floodfill.cpp index 91beca2a99..273f220bb0 100644 --- a/modules/imgproc/src/floodfill.cpp +++ b/modules/imgproc/src/floodfill.cpp @@ -487,12 +487,12 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, if ( (cn != 1) && (cn != 3) ) { - CV_Error( CV_StsBadArg, "Number of channels in input image must be 1 or 3" ); + CV_Error( cv::Error::StsBadArg, "Number of channels in input image must be 1 or 3" ); } const int connectivity = flags & 255; if( connectivity != 0 && connectivity != 4 && connectivity != 8 ) - CV_Error( CV_StsBadFlag, "Connectivity must be 4, 0(=4) or 8" ); + CV_Error( cv::Error::StsBadFlag, "Connectivity must be 4, 0(=4) or 8" ); if( _mask.empty() ) { @@ -513,13 +513,13 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, for( i = 0; i < cn; i++ ) { if( loDiff[i] < 0 || upDiff[i] < 0 ) - CV_Error( CV_StsBadArg, "lo_diff and up_diff must be non-negative" ); + CV_Error( cv::Error::StsBadArg, "lo_diff and up_diff must be non-negative" ); is_simple = is_simple && fabs(loDiff[i]) < DBL_EPSILON && fabs(upDiff[i]) < DBL_EPSILON; } if( (unsigned)seedPoint.x >= (unsigned)size.width || (unsigned)seedPoint.y >= (unsigned)size.height ) - CV_Error( CV_StsOutOfRange, "Seed point is outside of image" ); + CV_Error( cv::Error::StsOutOfRange, "Seed point is outside of image" ); scalarToRawData( newVal, &nv_buf, type, 0); size_t buffer_size = MAX( size.width, size.height ) * 2; @@ -550,7 +550,7 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, else if( type == CV_32FC3 ) floodFill_CnIR(img, seedPoint, Vec3f(nv_buf.f), &comp, flags, &buffer); else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); if( rect ) *rect = comp.rect; return comp.area; @@ -583,7 +583,7 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, ud_buf.f[i] = (float)upDiff[i]; } else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); uchar newMaskVal = (uchar)((flags & 0xff00) == 0 ? 1 : ((flags >> 8) & 255)); @@ -618,7 +618,7 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask, Diff32fC3(ld_buf.f, ud_buf.f), &comp, flags, &buffer); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); if( rect ) *rect = comp.rect; diff --git a/modules/imgproc/src/geometry.cpp b/modules/imgproc/src/geometry.cpp index 77d3d16e02..ae14590f22 100644 --- a/modules/imgproc/src/geometry.cpp +++ b/modules/imgproc/src/geometry.cpp @@ -87,7 +87,7 @@ CV_IMPL void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] ) { if( !pt ) - CV_Error( CV_StsNullPtr, "NULL vertex array pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL vertex array pointer" ); cv::RotatedRect(box).points((cv::Point2f*)pt); } diff --git a/modules/imgproc/src/grabcut.cpp b/modules/imgproc/src/grabcut.cpp index 5ec5af2be4..695c0dd6c5 100644 --- a/modules/imgproc/src/grabcut.cpp +++ b/modules/imgproc/src/grabcut.cpp @@ -96,7 +96,7 @@ GMM::GMM( Mat& _model ) _model.setTo(Scalar(0)); } else if( (_model.type() != CV_64FC1) || (_model.rows != 1) || (_model.cols != modelSize*componentsCount) ) - CV_Error( CV_StsBadArg, "_model must have CV_64FC1 type, rows == 1 and cols == 13*componentsCount" ); + CV_Error( cv::Error::StsBadArg, "_model must have CV_64FC1 type, rows == 1 and cols == 13*componentsCount" ); model = _model; @@ -329,18 +329,18 @@ static void calcNWeights( const Mat& img, Mat& leftW, Mat& upleftW, Mat& upW, Ma static void checkMask( const Mat& img, const Mat& mask ) { if( mask.empty() ) - CV_Error( CV_StsBadArg, "mask is empty" ); + CV_Error( cv::Error::StsBadArg, "mask is empty" ); if( mask.type() != CV_8UC1 ) - CV_Error( CV_StsBadArg, "mask must have CV_8UC1 type" ); + CV_Error( cv::Error::StsBadArg, "mask must have CV_8UC1 type" ); if( mask.cols != img.cols || mask.rows != img.rows ) - CV_Error( CV_StsBadArg, "mask must have as many rows and cols as img" ); + CV_Error( cv::Error::StsBadArg, "mask must have as many rows and cols as img" ); for( int y = 0; y < mask.rows; y++ ) { for( int x = 0; x < mask.cols; x++ ) { uchar val = mask.at(y,x); if( val!=GC_BGD && val!=GC_FGD && val!=GC_PR_BGD && val!=GC_PR_FGD ) - CV_Error( CV_StsBadArg, "mask element value must be equal " + CV_Error( cv::Error::StsBadArg, "mask element value must be equal " "GC_BGD or GC_FGD or GC_PR_BGD or GC_PR_FGD" ); } } @@ -552,9 +552,9 @@ void cv::grabCut( InputArray _img, InputOutputArray _mask, Rect rect, Mat& fgdModel = _fgdModel.getMatRef(); if( img.empty() ) - CV_Error( CV_StsBadArg, "image is empty" ); + CV_Error( cv::Error::StsBadArg, "image is empty" ); if( img.type() != CV_8UC3 ) - CV_Error( CV_StsBadArg, "image must have CV_8UC3 type" ); + CV_Error( cv::Error::StsBadArg, "image must have CV_8UC3 type" ); GMM bgdGMM( bgdModel ), fgdGMM( fgdModel ); Mat compIdxs( img.size(), CV_32SC1 ); diff --git a/modules/imgproc/src/histogram.cpp b/modules/imgproc/src/histogram.cpp index 499dd6e983..99d5e7b1d8 100644 --- a/modules/imgproc/src/histogram.cpp +++ b/modules/imgproc/src/histogram.cpp @@ -1005,7 +1005,7 @@ void cv::calcHist( const Mat* images, int nimages, const int* channels, else if( depth == CV_32F ) calcHist_(ptrs, deltas, imsize, ihist, dims, ranges, _uniranges, uniform ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); ihist.convertTo(hist, CV_32F); } @@ -1182,7 +1182,7 @@ static void calcHist( const Mat* images, int nimages, const int* channels, else if( depth == CV_32F ) calcSparseHist_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, uniform ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); if( !keepInt ) { @@ -1637,7 +1637,7 @@ void cv::calcBackProject( const Mat* images, int nimages, const int* channels, else if( depth == CV_32F ) calcBackProj_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, (float)scale, uniform ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } @@ -1810,7 +1810,7 @@ void cv::calcBackProject( const Mat* images, int nimages, const int* channels, calcSparseBackProj_(ptrs, deltas, imsize, hist, dims, ranges, _uniranges, (float)scale, uniform ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } #ifdef HAVE_OPENCL @@ -2211,7 +2211,7 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method ) } } else - CV_Error( CV_StsBadArg, "Unknown comparison method" ); + CV_Error( cv::Error::StsBadArg, "Unknown comparison method" ); } if( method == CV_COMP_CHISQR_ALT ) @@ -2350,7 +2350,7 @@ double cv::compareHist( const SparseMat& H1, const SparseMat& H2, int method ) } } else - CV_Error( CV_StsBadArg, "Unknown comparison method" ); + CV_Error( cv::Error::StsBadArg, "Unknown comparison method" ); if( method == CV_COMP_CHISQR_ALT ) result *= 2; @@ -2387,7 +2387,7 @@ cvCreateHist( int dims, int *sizes, CvHistType type, float** ranges, int uniform else if( type == CV_HIST_SPARSE ) hist->bins = cvCreateSparseMat( dims, sizes, CV_HIST_DEFAULT_TYPE ); else - CV_Error( CV_StsBadArg, "Invalid histogram type" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram type" ); if( ranges ) cvSetHistBinRanges( hist, ranges, uniform ); @@ -2402,10 +2402,10 @@ cvMakeHistHeaderForArray( int dims, int *sizes, CvHistogram *hist, float *data, float **ranges, int uniform ) { if( !hist ) - CV_Error( CV_StsNullPtr, "Null histogram header pointer" ); + CV_Error( cv::Error::StsNullPtr, "Null histogram header pointer" ); if( !data ) - CV_Error( CV_StsNullPtr, "Null data pointer" ); + CV_Error( cv::Error::StsNullPtr, "Null data pointer" ); hist->thresh2 = 0; hist->type = CV_HIST_MAGIC_VAL; @@ -2414,7 +2414,7 @@ cvMakeHistHeaderForArray( int dims, int *sizes, CvHistogram *hist, if( ranges ) { if( !uniform ) - CV_Error( CV_StsBadArg, "Only uniform bin ranges can be used here " + CV_Error( cv::Error::StsBadArg, "Only uniform bin ranges can be used here " "(to avoid memory allocation)" ); cvSetHistBinRanges( hist, ranges, uniform ); } @@ -2427,14 +2427,14 @@ CV_IMPL void cvReleaseHist( CvHistogram **hist ) { if( !hist ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( *hist ) { CvHistogram* temp = *hist; if( !CV_IS_HIST(temp)) - CV_Error( CV_StsBadArg, "Invalid histogram header" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header" ); *hist = 0; if( CV_IS_SPARSE_HIST( temp )) @@ -2455,7 +2455,7 @@ CV_IMPL void cvClearHist( CvHistogram *hist ) { if( !CV_IS_HIST(hist) ) - CV_Error( CV_StsBadArg, "Invalid histogram header" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header" ); cvZero( hist->bins ); } @@ -2465,7 +2465,7 @@ CV_IMPL void cvThreshHist( CvHistogram* hist, double thresh ) { if( !CV_IS_HIST(hist) ) - CV_Error( CV_StsBadArg, "Invalid histogram header" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header" ); if( !CV_IS_SPARSE_MAT(hist->bins) ) { @@ -2497,7 +2497,7 @@ cvNormalizeHist( CvHistogram* hist, double factor ) double sum = 0; if( !CV_IS_HIST(hist) ) - CV_Error( CV_StsBadArg, "Invalid histogram header" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header" ); if( !CV_IS_SPARSE_HIST(hist) ) { @@ -2544,7 +2544,7 @@ cvGetMinMaxHistValue( const CvHistogram* hist, int dims, size[CV_MAX_DIM]; if( !CV_IS_HIST(hist) ) - CV_Error( CV_StsBadArg, "Invalid histogram header" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header" ); dims = cvGetDims( hist->bins, size ); @@ -2662,10 +2662,10 @@ cvCompareHist( const CvHistogram* hist1, int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1; if( !CV_IS_HIST(hist1) || !CV_IS_HIST(hist2) ) - CV_Error( CV_StsBadArg, "Invalid histogram header[s]" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header[s]" ); if( CV_IS_SPARSE_MAT(hist1->bins) != CV_IS_SPARSE_MAT(hist2->bins)) - CV_Error(CV_StsUnmatchedFormats, "One of histograms is sparse and other is not"); + CV_Error(cv::Error::StsUnmatchedFormats, "One of histograms is sparse and other is not"); if( !CV_IS_SPARSE_MAT(hist1->bins) ) { @@ -2678,13 +2678,13 @@ cvCompareHist( const CvHistogram* hist1, int dims2 = cvGetDims( hist2->bins, size2 ); if( dims1 != dims2 ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The histograms have different numbers of dimensions" ); for( i = 0; i < dims1; i++ ) { if( size1[i] != size2[i] ) - CV_Error( CV_StsUnmatchedSizes, "The histograms have different sizes" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The histograms have different sizes" ); total *= size1[i]; } @@ -2804,7 +2804,7 @@ cvCompareHist( const CvHistogram* hist1, result = cv::compareHist( sH1, sH2, CV_COMP_KL_DIV ); } else - CV_Error( CV_StsBadArg, "Unknown comparison method" ); + CV_Error( cv::Error::StsBadArg, "Unknown comparison method" ); if( method == CV_COMP_CHISQR_ALT ) result *= 2; @@ -2817,12 +2817,12 @@ CV_IMPL void cvCopyHist( const CvHistogram* src, CvHistogram** _dst ) { if( !_dst ) - CV_Error( CV_StsNullPtr, "Destination double pointer is NULL" ); + CV_Error( cv::Error::StsNullPtr, "Destination double pointer is NULL" ); CvHistogram* dst = *_dst; if( !CV_IS_HIST(src) || (dst && !CV_IS_HIST(dst)) ) - CV_Error( CV_StsBadArg, "Invalid histogram header[s]" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header[s]" ); bool eq = false; int size1[CV_MAX_DIM]; @@ -2887,10 +2887,10 @@ cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform ) int i, j; if( !ranges ) - CV_Error( CV_StsNullPtr, "NULL ranges pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL ranges pointer" ); if( !CV_IS_HIST(hist) ) - CV_Error( CV_StsBadArg, "Invalid histogram header" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header" ); dims = cvGetDims( hist->bins, size ); for( i = 0; i < dims; i++ ) @@ -2901,7 +2901,7 @@ cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform ) for( i = 0; i < dims; i++ ) { if( !ranges[i] ) - CV_Error( CV_StsNullPtr, "One of elements is NULL" ); + CV_Error( cv::Error::StsNullPtr, "One of elements is NULL" ); hist->thresh[i][0] = ranges[i][0]; hist->thresh[i][1] = ranges[i][1]; } @@ -2925,13 +2925,13 @@ cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform ) float val0 = -FLT_MAX; if( !ranges[i] ) - CV_Error( CV_StsNullPtr, "One of elements is NULL" ); + CV_Error( cv::Error::StsNullPtr, "One of elements is NULL" ); for( j = 0; j <= size[i]; j++ ) { float val = ranges[i][j]; if( val <= val0 ) - CV_Error(CV_StsOutOfRange, "Bin ranges should go in ascenting order"); + CV_Error(cv::Error::StsOutOfRange, "Bin ranges should go in ascenting order"); val0 = dim_ranges[j] = val; } @@ -2949,10 +2949,10 @@ CV_IMPL void cvCalcArrHist( CvArr** img, CvHistogram* hist, int accumulate, const CvArr* mask ) { if( !CV_IS_HIST(hist)) - CV_Error( CV_StsBadArg, "Bad histogram pointer" ); + CV_Error( cv::Error::StsBadArg, "Bad histogram pointer" ); if( !img ) - CV_Error( CV_StsNullPtr, "Null double array pointer" ); + CV_Error( cv::Error::StsNullPtr, "Null double array pointer" ); int size[CV_MAX_DIM]; int i, dims = cvGetDims( hist->bins, size); @@ -3015,10 +3015,10 @@ CV_IMPL void cvCalcArrBackProject( CvArr** img, CvArr* dst, const CvHistogram* hist ) { if( !CV_IS_HIST(hist)) - CV_Error( CV_StsBadArg, "Bad histogram pointer" ); + CV_Error( cv::Error::StsBadArg, "Bad histogram pointer" ); if( !img ) - CV_Error( CV_StsNullPtr, "Null double array pointer" ); + CV_Error( cv::Error::StsNullPtr, "Null double array pointer" ); int size[CV_MAX_DIM]; int i, dims = cvGetDims( hist->bins, size ); @@ -3078,21 +3078,21 @@ cvCalcArrBackProjectPatch( CvArr** arr, CvArr* dst, CvSize patch_size, CvHistogr cv::Size size; if( !CV_IS_HIST(hist)) - CV_Error( CV_StsBadArg, "Bad histogram pointer" ); + CV_Error( cv::Error::StsBadArg, "Bad histogram pointer" ); if( !arr ) - CV_Error( CV_StsNullPtr, "Null double array pointer" ); + CV_Error( cv::Error::StsNullPtr, "Null double array pointer" ); if( norm_factor <= 0 ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "Bad normalization factor (set it to 1.0 if unsure)" ); if( patch_size.width <= 0 || patch_size.height <= 0 ) - CV_Error( CV_StsBadSize, "The patch width and height must be positive" ); + CV_Error( cv::Error::StsBadSize, "The patch width and height must be positive" ); dims = cvGetDims( hist->bins ); if (dims < 1) - CV_Error( CV_StsOutOfRange, "Invalid number of dimensions"); + CV_Error( cv::Error::StsOutOfRange, "Invalid number of dimensions"); cvNormalizeHist( hist, norm_factor ); for( i = 0; i < dims; i++ ) @@ -3105,11 +3105,11 @@ cvCalcArrBackProjectPatch( CvArr** arr, CvArr* dst, CvSize patch_size, CvHistogr dstmat = cvGetMat( dst, &dststub, 0, 0 ); if( CV_MAT_TYPE( dstmat->type ) != CV_32FC1 ) - CV_Error( CV_StsUnsupportedFormat, "Resultant image must have 32fC1 type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Resultant image must have 32fC1 type" ); if( dstmat->cols != img[0]->width - patch_size.width + 1 || dstmat->rows != img[0]->height - patch_size.height + 1 ) - CV_Error( CV_StsUnmatchedSizes, + CV_Error( cv::Error::StsUnmatchedSizes, "The output map must be (W-w+1 x H-h+1), " "where the input images are (W x H) each and the patch is (w x h)" ); @@ -3146,18 +3146,18 @@ cvCalcBayesianProb( CvHistogram** src, int count, CvHistogram** dst ) int i; if( !src || !dst ) - CV_Error( CV_StsNullPtr, "NULL histogram array pointer" ); + CV_Error( cv::Error::StsNullPtr, "NULL histogram array pointer" ); if( count < 2 ) - CV_Error( CV_StsOutOfRange, "Too small number of histograms" ); + CV_Error( cv::Error::StsOutOfRange, "Too small number of histograms" ); for( i = 0; i < count; i++ ) { if( !CV_IS_HIST(src[i]) || !CV_IS_HIST(dst[i]) ) - CV_Error( CV_StsBadArg, "Invalid histogram header" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram header" ); if( !CV_IS_MATND(src[i]->bins) || !CV_IS_MATND(dst[i]->bins) ) - CV_Error( CV_StsBadArg, "The function supports dense histograms only" ); + CV_Error( cv::Error::StsBadArg, "The function supports dense histograms only" ); } cvZero( dst[0]->bins ); @@ -3178,10 +3178,10 @@ cvCalcProbDensity( const CvHistogram* hist, const CvHistogram* hist_mask, CvHistogram* hist_dens, double scale ) { if( scale <= 0 ) - CV_Error( CV_StsOutOfRange, "scale must be positive" ); + CV_Error( cv::Error::StsOutOfRange, "scale must be positive" ); if( !CV_IS_HIST(hist) || !CV_IS_HIST(hist_mask) || !CV_IS_HIST(hist_dens) ) - CV_Error( CV_StsBadArg, "Invalid histogram pointer[s]" ); + CV_Error( cv::Error::StsBadArg, "Invalid histogram pointer[s]" ); { CvArr* arrs[] = { hist->bins, hist_mask->bins, hist_dens->bins }; @@ -3191,7 +3191,7 @@ cvCalcProbDensity( const CvHistogram* hist, const CvHistogram* hist_mask, cvInitNArrayIterator( 3, arrs, 0, stubs, &iterator ); if( CV_MAT_TYPE(iterator.hdr[0]->type) != CV_32FC1 ) - CV_Error( CV_StsUnsupportedFormat, "All histograms must have 32fC1 type" ); + CV_Error( cv::Error::StsUnsupportedFormat, "All histograms must have 32fC1 type" ); do { @@ -3533,7 +3533,7 @@ static void *icvReadHist( CvFileStorage * fs, CvFileNode * node ) int i, sizes[CV_MAX_DIM]; if(!CV_IS_MATND(mat)) - CV_Error( CV_StsError, "Expected CvMatND"); + CV_Error( cv::Error::StsError, "Expected CvMatND"); for(i=0; idims; i++) sizes[i] = mat->dim[i].size; @@ -3554,7 +3554,7 @@ static void *icvReadHist( CvFileStorage * fs, CvFileNode * node ) { h->bins = cvReadByName( fs, node, "bins" ); if(!CV_IS_SPARSE_MAT(h->bins)){ - CV_Error( CV_StsError, "Unknown Histogram type"); + CV_Error( cv::Error::StsError, "Unknown Histogram type"); } } @@ -3571,7 +3571,7 @@ static void *icvReadHist( CvFileStorage * fs, CvFileNode * node ) thresh_node = cvGetFileNodeByName( fs, node, "thresh" ); if(!thresh_node) - CV_Error( CV_StsError, "'thresh' node is missing"); + CV_Error( cv::Error::StsError, "'thresh' node is missing"); cvStartReadRawData( fs, thresh_node, &reader ); if(is_uniform) diff --git a/modules/imgproc/src/hough.cpp b/modules/imgproc/src/hough.cpp index 9961e9aace..523e4491c5 100644 --- a/modules/imgproc/src/hough.cpp +++ b/modules/imgproc/src/hough.cpp @@ -2396,11 +2396,11 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method, mat = (CvMat*)lineStorage; if( !CV_IS_MAT_CONT( mat->type ) || (mat->rows != 1 && mat->cols != 1) ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The destination matrix should be continuous and have a single row or a single column" ); if( CV_MAT_TYPE( mat->type ) != lineType ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The destination matrix data type is inappropriate, see the manual" ); lines = cvMakeSeqHeaderForArray( lineType, sizeof(CvSeq), elemSize, mat->data.ptr, @@ -2427,7 +2427,7 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method, threshold, iparam1, iparam2, l4, linesMax ); break; default: - CV_Error( CV_StsBadArg, "Unrecognized method id" ); + CV_Error( cv::Error::StsBadArg, "Unrecognized method id" ); } int nlines = (int)(l2.size() + l4.size()); @@ -2473,7 +2473,7 @@ cvHoughCircles( CvArr* src_image, void* circle_storage, cv::Mat src = cv::cvarrToMat(src_image), circles_mat; if( !circle_storage ) - CV_Error( CV_StsNullPtr, "NULL destination" ); + CV_Error( cv::Error::StsNullPtr, "NULL destination" ); bool isStorage = isStorageOrMat(circle_storage); @@ -2490,7 +2490,7 @@ cvHoughCircles( CvArr* src_image, void* circle_storage, if( !CV_IS_MAT_CONT( mat->type ) || (mat->rows != 1 && mat->cols != 1) || CV_MAT_TYPE(mat->type) != CV_32FC3 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The destination matrix should be continuous and have a single row or a single column" ); circles = cvMakeSeqHeaderForArray( CV_32FC3, sizeof(CvSeq), sizeof(float)*3, diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 7a9ed3033e..7c4567218b 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -206,7 +206,7 @@ static void initInterTab1D(int method, float* tab, int tabsz) interpolateLanczos4( i*scale, tab ); } else - CV_Error( CV_StsBadArg, "Unknown interpolation method" ); + CV_Error( cv::Error::StsBadArg, "Unknown interpolation method" ); } @@ -223,7 +223,7 @@ static const void* initInterTab2D( int method, bool fixpt ) else if( method == INTER_LANCZOS4 ) tab = Lanczos4Tab_f[0][0], itab = Lanczos4Tab_i[0][0], ksize=8; else - CV_Error( CV_StsBadArg, "Unknown/unsupported interpolation type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported interpolation type" ); if( !inittab[method] ) { @@ -1502,7 +1502,7 @@ static bool ocl_logPolar(InputArray _src, OutputArray _dst, Point2f center, double M, int flags) { if (M <= 0) - CV_Error(CV_StsOutOfRange, "M should be >0"); + CV_Error(cv::Error::StsOutOfRange, "M should be >0"); UMat src_with_border; // don't scope this variable (it holds image data) UMat mapx, mapy, r, cp_sp; @@ -1649,12 +1649,12 @@ static bool openvx_remap(Mat src, Mat dst, Mat map1, Mat map2, int interpolation } catch (const ivx::RuntimeError & e) { - CV_Error(CV_StsInternal, e.what()); + CV_Error(cv::Error::StsInternal, e.what()); return false; } catch (const ivx::WrapperError & e) { - CV_Error(CV_StsInternal, e.what()); + CV_Error(cv::Error::StsInternal, e.what()); return false; } return true; @@ -1888,7 +1888,7 @@ void cv::remap( InputArray _src, OutputArray _dst, CV_Assert( _src.channels() <= 4 ); } else - CV_Error( CV_StsBadArg, "Unknown interpolation method" ); + CV_Error( cv::Error::StsBadArg, "Unknown interpolation method" ); CV_Assert( ifunc != 0 ); ctab = initInterTab2D( interpolation, fixpt ); } @@ -2236,7 +2236,7 @@ void cv::convertMaps( InputArray _map1, InputArray _map2, } } else - CV_Error( CV_StsNotImplemented, "Unsupported combination of input/output matrices" ); + CV_Error( cv::Error::StsNotImplemented, "Unsupported combination of input/output matrices" ); } } @@ -3610,7 +3610,7 @@ void cv::invertAffineTransform(InputArray _matM, OutputArray __iM) iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2; } else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); } cv::Mat cv::getPerspectiveTransform(InputArray _src, InputArray _dst, int solveMethod) diff --git a/modules/imgproc/src/linefit.cpp b/modules/imgproc/src/linefit.cpp index cd205c60ab..67a3affccd 100644 --- a/modules/imgproc/src/linefit.cpp +++ b/modules/imgproc/src/linefit.cpp @@ -358,7 +358,7 @@ static void fitLine2D( const Point2f * points, int count, int dist, calc_weights = (void ( * )(float *, int, float *)) _PFP.fp; break;*/ default: - CV_Error(CV_StsBadArg, "Unknown distance type"); + CV_Error(cv::Error::StsBadArg, "Unknown distance type"); } AutoBuffer wr(count*2); @@ -499,7 +499,7 @@ static void fitLine3D( Point3f * points, int count, int dist, break; default: - CV_Error(CV_StsBadArg, "Unknown distance"); + CV_Error(cv::Error::StsBadArg, "Unknown distance"); } AutoBuffer buf(count*2); diff --git a/modules/imgproc/src/matchcontours.cpp b/modules/imgproc/src/matchcontours.cpp index e676bf9804..f278ddd366 100644 --- a/modules/imgproc/src/matchcontours.cpp +++ b/modules/imgproc/src/matchcontours.cpp @@ -158,7 +158,7 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou } break; default: - CV_Error( CV_StsBadArg, "Unknown comparison method" ); + CV_Error( cv::Error::StsBadArg, "Unknown comparison method" ); } //If anyA and anyB are both true, the result is correct. diff --git a/modules/imgproc/src/median_blur.simd.hpp b/modules/imgproc/src/median_blur.simd.hpp index 1fe2e4060c..1069d8abab 100644 --- a/modules/imgproc/src/median_blur.simd.hpp +++ b/modules/imgproc/src/median_blur.simd.hpp @@ -867,7 +867,7 @@ void medianBlur(const Mat& src0, /*const*/ Mat& dst, int ksize) else if( src.depth() == CV_32F ) medianBlur_SortNet( src, dst, ksize ); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); return; } diff --git a/modules/imgproc/src/moments.cpp b/modules/imgproc/src/moments.cpp index 523ea586d4..b2320258b1 100644 --- a/modules/imgproc/src/moments.cpp +++ b/modules/imgproc/src/moments.cpp @@ -584,7 +584,7 @@ cv::Moments cv::moments( InputArray _src, bool binary ) return contourMoments(mat); if( cn > 1 ) - CV_Error( CV_StsBadArg, "Invalid image type (must be single-channel)" ); + CV_Error( cv::Error::StsBadArg, "Invalid image type (must be single-channel)" ); CV_IPP_RUN(!binary, ipp_moments(mat, m), m); @@ -599,7 +599,7 @@ cv::Moments cv::moments( InputArray _src, bool binary ) else if( depth == CV_64F ) func = momentsInTile; else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); Mat src0(mat); @@ -730,9 +730,9 @@ CV_IMPL double cvGetSpatialMoment( CvMoments * moments, int x_order, int y_order int order = x_order + y_order; if( !moments ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( (x_order | y_order) < 0 || order > 3 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); return (&(moments->m00))[order + (order >> 1) + (order > 2) * 2 + y_order]; } @@ -743,9 +743,9 @@ CV_IMPL double cvGetCentralMoment( CvMoments * moments, int x_order, int y_order int order = x_order + y_order; if( !moments ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( (x_order | y_order) < 0 || order > 3 ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); return order >= 2 ? (&(moments->m00))[4 + order * 3 + y_order] : order == 0 ? moments->m00 : 0; @@ -768,7 +768,7 @@ CV_IMPL double cvGetNormalizedCentralMoment( CvMoments * moments, int x_order, i CV_IMPL void cvGetHuMoments( CvMoments * mState, CvHuMoments * HuState ) { if( !mState || !HuState ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); double m00s = mState->inv_sqrt_m00, m00 = m00s * m00s, s2 = m00 * m00, s3 = s2 * m00s; diff --git a/modules/imgproc/src/morph.dispatch.cpp b/modules/imgproc/src/morph.dispatch.cpp index a0857d1266..0cb50ec368 100644 --- a/modules/imgproc/src/morph.dispatch.cpp +++ b/modules/imgproc/src/morph.dispatch.cpp @@ -1076,7 +1076,7 @@ static bool ocl_morphologyEx(InputArray _src, OutputArray _dst, int op, return false; break; default: - CV_Error( CV_StsBadArg, "unknown morphological operation" ); + CV_Error( cv::Error::StsBadArg, "unknown morphological operation" ); } return true; @@ -1249,7 +1249,7 @@ void morphologyEx( InputArray _src, OutputArray _dst, int op, } break; default: - CV_Error( CV_StsBadArg, "unknown morphological operation" ); + CV_Error( cv::Error::StsBadArg, "unknown morphological operation" ); } } @@ -1296,7 +1296,7 @@ CV_IMPL void cvReleaseStructuringElement( IplConvKernel ** element ) { if( !element ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); cvFree( element ); } diff --git a/modules/imgproc/src/morph.simd.hpp b/modules/imgproc/src/morph.simd.hpp index ef813dccec..e93f829daa 100644 --- a/modules/imgproc/src/morph.simd.hpp +++ b/modules/imgproc/src/morph.simd.hpp @@ -753,7 +753,7 @@ Ptr getMorphologyRowFilter(int op, int type, int ksize, int ancho DilateRowVec64f> >(ksize, anchor); } - CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type)); + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported data type (=%d)", type)); } Ptr getMorphologyColumnFilter(int op, int type, int ksize, int anchor) @@ -801,7 +801,7 @@ Ptr getMorphologyColumnFilter(int op, int type, int ksize, int DilateColumnVec64f> >(ksize, anchor); } - CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type)); + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported data type (=%d)", type)); } Ptr getMorphologyFilter(int op, int type, const Mat& kernel, Point anchor) @@ -838,7 +838,7 @@ Ptr getMorphologyFilter(int op, int type, const Mat& kernel, Point a return makePtr, DilateVec64f> >(kernel, anchor); } - CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type)); + CV_Error_( cv::Error::StsNotImplemented, ("Unsupported data type (=%d)", type)); } #endif diff --git a/modules/imgproc/src/precomp.hpp b/modules/imgproc/src/precomp.hpp index a72d2a4d2a..29dbce6d5f 100644 --- a/modules/imgproc/src/precomp.hpp +++ b/modules/imgproc/src/precomp.hpp @@ -112,7 +112,7 @@ inline bool isStorageOrMat(void * arr) return true; else if (CV_IS_MAT( arr )) return false; - CV_Error( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" ); + CV_Error( cv::Error::StsBadArg, "Destination is not CvMemStorage* nor CvMat*" ); } diff --git a/modules/imgproc/src/pyramids.cpp b/modules/imgproc/src/pyramids.cpp index 52f957348d..64667a5f97 100644 --- a/modules/imgproc/src/pyramids.cpp +++ b/modules/imgproc/src/pyramids.cpp @@ -1448,7 +1448,7 @@ void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borde else if( depth == CV_64F ) func = pyrDown_< FltCast >; else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); func( src, dst, borderType ); } @@ -1551,7 +1551,7 @@ void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderT else if( depth == CV_64F ) func = pyrUp_< FltCast >; else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); func( src, dst, borderType ); } @@ -1722,7 +1722,7 @@ CV_IMPL void cvReleasePyramid( CvMat*** _pyramid, int extra_layers ) { if( !_pyramid ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); if( *_pyramid ) for( int i = 0; i <= extra_layers; i++ ) @@ -1743,7 +1743,7 @@ cvCreatePyramid( const CvArr* srcarr, int extra_layers, double rate, CvMat stub, *src = cvGetMat( srcarr, &stub ); if( extra_layers < 0 ) - CV_Error( CV_StsOutOfRange, "The number of extra layers must be non negative" ); + CV_Error( cv::Error::StsOutOfRange, "The number of extra layers must be non negative" ); int i, layer_step, elem_size = CV_ELEM_SIZE(src->type); cv::Size layer_size, size = cvGetMatSize(src); @@ -1770,7 +1770,7 @@ cvCreatePyramid( const CvArr* srcarr, int extra_layers, double rate, } if( bufsize < 0 ) - CV_Error( CV_StsOutOfRange, "The buffer is too small to fit the pyramid" ); + CV_Error( cv::Error::StsOutOfRange, "The buffer is too small to fit the pyramid" ); ptr = buf->data.ptr; } diff --git a/modules/imgproc/src/resize.cpp b/modules/imgproc/src/resize.cpp index 0943e97ead..7e45f1e0f4 100644 --- a/modules/imgproc/src/resize.cpp +++ b/modules/imgproc/src/resize.cpp @@ -4024,7 +4024,7 @@ void resize(int src_type, else if( interpolation == INTER_LINEAR || interpolation == INTER_AREA ) ksize = 2, func = linear_tab[depth]; else - CV_Error( CV_StsBadArg, "Unknown interpolation method" ); + CV_Error( cv::Error::StsBadArg, "Unknown interpolation method" ); ksize2 = ksize/2; CV_Assert( func != 0 ); diff --git a/modules/imgproc/src/rotcalipers.cpp b/modules/imgproc/src/rotcalipers.cpp index e3d81c7e0c..3bec592c9b 100644 --- a/modules/imgproc/src/rotcalipers.cpp +++ b/modules/imgproc/src/rotcalipers.cpp @@ -245,7 +245,7 @@ static void rotatingCalipers( const Point2f* points, int n, int mode, float* out base_b = lead_x; break; default: - CV_Error(CV_StsError, "main_element should be 0, 1, 2 or 3"); + CV_Error(cv::Error::StsError, "main_element should be 0, 1, 2 or 3"); } } /* change base point of main edge */ diff --git a/modules/imgproc/src/samplers.cpp b/modules/imgproc/src/samplers.cpp index 287e78c6df..5fb30c9434 100644 --- a/modules/imgproc/src/samplers.cpp +++ b/modules/imgproc/src/samplers.cpp @@ -417,7 +417,7 @@ void cv::getRectSubPix( InputArray _image, Size patchSize, Point2f center, getRectSubPix_Cn_, nop > (image.ptr(), image.step, image.size(), patch.ptr(), patch.step, patch.size(), center, cn); else - CV_Error( CV_StsUnsupportedFormat, "Unsupported combination of input and output formats"); + CV_Error( cv::Error::StsUnsupportedFormat, "Unsupported combination of input and output formats"); } @@ -473,7 +473,7 @@ cvSampleLine( const void* _img, CvPoint pt1, CvPoint pt2, size_t pixsize = img.elemSize(); if( !buffer ) - CV_Error( CV_StsNullPtr, "" ); + CV_Error( cv::Error::StsNullPtr, "" ); for( int i = 0; i < li.count; i++, ++li ) { diff --git a/modules/imgproc/src/segmentation.cpp b/modules/imgproc/src/segmentation.cpp index f4145c6cfa..0476c4a244 100644 --- a/modules/imgproc/src/segmentation.cpp +++ b/modules/imgproc/src/segmentation.cpp @@ -348,7 +348,7 @@ void cv::pyrMeanShiftFiltering( InputArray _src, OutputArray _dst, const int MAX_LEVELS = 8; if( (unsigned)max_level > (unsigned)MAX_LEVELS ) - CV_Error( CV_StsOutOfRange, "The number of pyramid levels is too large or negative" ); + CV_Error( cv::Error::StsOutOfRange, "The number of pyramid levels is too large or negative" ); std::vector src_pyramid(max_level+1); std::vector dst_pyramid(max_level+1); @@ -365,13 +365,13 @@ void cv::pyrMeanShiftFiltering( InputArray _src, OutputArray _dst, if( src0.type() != CV_8UC3 ) - CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 3-channel images are supported" ); + CV_Error( cv::Error::StsUnsupportedFormat, "Only 8-bit, 3-channel images are supported" ); if( src0.type() != dst0.type() ) - CV_Error( CV_StsUnmatchedFormats, "The input and output images must have the same type" ); + CV_Error( cv::Error::StsUnmatchedFormats, "The input and output images must have the same type" ); if( src0.size() != dst0.size() ) - CV_Error( CV_StsUnmatchedSizes, "The input and output images must have the same size" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The input and output images must have the same size" ); if( !(termcrit.type & CV_TERMCRIT_ITER) ) termcrit.maxCount = 5; diff --git a/modules/imgproc/src/shapedescr.cpp b/modules/imgproc/src/shapedescr.cpp index 194e5a0862..fe5664abf2 100644 --- a/modules/imgproc/src/shapedescr.cpp +++ b/modules/imgproc/src/shapedescr.cpp @@ -357,7 +357,7 @@ static RotatedRect fitEllipseNoDirect( InputArray _points ) RotatedRect box; if( n < 5 ) - CV_Error( CV_StsBadSize, "There should be at least 5 points to fit the ellipse" ); + CV_Error( cv::Error::StsBadSize, "There should be at least 5 points to fit the ellipse" ); // New fitellipse algorithm, contributed by Dr. Daniel Weiss Point2f c(0,0); @@ -520,7 +520,7 @@ cv::RotatedRect cv::fitEllipseAMS( InputArray _points ) RotatedRect box; if( n < 5 ) - CV_Error( CV_StsBadSize, "There should be at least 5 points to fit the ellipse" ); + CV_Error( cv::Error::StsBadSize, "There should be at least 5 points to fit the ellipse" ); Point2f c(0,0); @@ -705,7 +705,7 @@ cv::RotatedRect cv::fitEllipseDirect( InputArray _points ) RotatedRect box; if( n < 5 ) - CV_Error( CV_StsBadSize, "There should be at least 5 points to fit the ellipse" ); + CV_Error( cv::Error::StsBadSize, "There should be at least 5 points to fit the ellipse" ); Point2d c(0., 0.); @@ -1364,7 +1364,7 @@ cvContourArea( const void *array, CvSlice slice, int oriented ) { contour = (CvSeq*)array; if( !CV_IS_SEQ_POLYLINE( contour )) - CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + CV_Error( cv::Error::StsBadArg, "Unsupported sequence type" ); } else { @@ -1379,7 +1379,7 @@ cvContourArea( const void *array, CvSlice slice, int oriented ) } if( CV_SEQ_ELTYPE( contour ) != CV_32SC2 ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "Only curves with integer coordinates are supported in case of contour slice" ); area = icvContourSecArea( contour, slice ); return oriented ? area : fabs(area); @@ -1405,7 +1405,7 @@ cvArcLength( const void *array, CvSlice slice, int is_closed ) { contour = (CvSeq*)array; if( !CV_IS_SEQ_POLYLINE( contour )) - CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + CV_Error( cv::Error::StsBadArg, "Unsupported sequence type" ); if( is_closed < 0 ) is_closed = CV_IS_SEQ_CLOSED( contour ); } @@ -1498,7 +1498,7 @@ cvBoundingRect( CvArr* array, int update ) { ptseq = (CvSeq*)array; if( !CV_IS_SEQ_POINT_SET( ptseq )) - CV_Error( CV_StsBadArg, "Unsupported sequence type" ); + CV_Error( cv::Error::StsBadArg, "Unsupported sequence type" ); if( ptseq->header_size < (int)sizeof(CvContour)) { @@ -1517,7 +1517,7 @@ cvBoundingRect( CvArr* array, int update ) } else if( CV_MAT_TYPE(mat->type) != CV_8UC1 && CV_MAT_TYPE(mat->type) != CV_8SC1 ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "The image/matrix format is not supported by the function" ); update = 0; calculate = 1; diff --git a/modules/imgproc/src/smooth.dispatch.cpp b/modules/imgproc/src/smooth.dispatch.cpp index 8a521d6df3..26566c7e03 100644 --- a/modules/imgproc/src/smooth.dispatch.cpp +++ b/modules/imgproc/src/smooth.dispatch.cpp @@ -784,7 +784,7 @@ cvSmooth( const void* srcarr, void* dstarr, int smooth_type, cv::bilateralFilter( src, dst, param1, param3, param4, cv::BORDER_REPLICATE ); if( dst.data != dst0.data ) - CV_Error( CV_StsUnmatchedFormats, "The destination image does not have the proper type" ); + CV_Error( cv::Error::StsUnmatchedFormats, "The destination image does not have the proper type" ); } /* End of file. */ diff --git a/modules/imgproc/src/subdivision2d.cpp b/modules/imgproc/src/subdivision2d.cpp index 24075ac6eb..2a2ab1dfeb 100644 --- a/modules/imgproc/src/subdivision2d.cpp +++ b/modules/imgproc/src/subdivision2d.cpp @@ -282,10 +282,10 @@ int Subdiv2D::locate(Point2f pt, int& _edge, int& _vertex) int i, maxEdges = (int)(qedges.size() * 4); if( qedges.size() < (size_t)4 ) - CV_Error( CV_StsError, "Subdivision is empty" ); + CV_Error( cv::Error::StsError, "Subdivision is empty" ); if( pt.x < topLeft.x || pt.y < topLeft.y || pt.x >= bottomRight.x || pt.y >= bottomRight.y ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); int edge = recentEdge; CV_Assert(edge > 0); @@ -417,10 +417,10 @@ int Subdiv2D::insert(Point2f pt) int location = locate( pt, curr_edge, curr_point ); if( location == PTLOC_ERROR ) - CV_Error( CV_StsBadSize, "" ); + CV_Error( cv::Error::StsBadSize, "" ); if( location == PTLOC_OUTSIDE_RECT ) - CV_Error( CV_StsOutOfRange, "" ); + CV_Error( cv::Error::StsOutOfRange, "" ); if( location == PTLOC_VERTEX ) return curr_point; @@ -434,7 +434,7 @@ int Subdiv2D::insert(Point2f pt) else if( location == PTLOC_INSIDE ) ; else - CV_Error_(CV_StsError, ("Subdiv2D::locate returned invalid location = %d", location) ); + CV_Error_(cv::Error::StsError, ("Subdiv2D::locate returned invalid location = %d", location) ); CV_Assert( curr_edge != 0 ); validGeometry = false; diff --git a/modules/imgproc/src/templmatch.cpp b/modules/imgproc/src/templmatch.cpp index 67845e7429..5998bcbac7 100644 --- a/modules/imgproc/src/templmatch.cpp +++ b/modules/imgproc/src/templmatch.cpp @@ -145,7 +145,7 @@ void ConvolveBuf::create(Size image_size, Size templ_size) dft_size.width = std::max(getOptimalDFTSize(block_size.width + templ_size.width - 1), 2); dft_size.height = getOptimalDFTSize(block_size.height + templ_size.height - 1); if( dft_size.width <= 0 || dft_size.height <= 0 ) - CV_Error( CV_StsOutOfRange, "the input arrays are too big" ); + CV_Error( cv::Error::StsOutOfRange, "the input arrays are too big" ); // recompute block size block_size.width = dft_size.width - templ_size.width + 1; @@ -602,7 +602,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, dftsize.width = std::max(getOptimalDFTSize(blocksize.width + templ.cols - 1), 2); dftsize.height = getOptimalDFTSize(blocksize.height + templ.rows - 1); if( dftsize.width <= 0 || dftsize.height <= 0 ) - CV_Error( CV_StsOutOfRange, "the input arrays are too big" ); + CV_Error( cv::Error::StsOutOfRange, "the input arrays are too big" ); // recompute block size blocksize.width = dftsize.width - templ.cols + 1; diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index 8259902ed7..8d82c14a50 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -117,7 +117,7 @@ static void threshGeneric(Size roi, const T* src, size_t src_step, T* dst, return; default: - CV_Error( CV_StsBadArg, "" ); return; + CV_Error( cv::Error::StsBadArg, "" ); return; } } @@ -719,7 +719,7 @@ thresh_16s( const Mat& _src, Mat& _dst, short thresh, short maxval, int type ) } break; default: - CV_Error( CV_StsBadArg, "" ); return; + CV_Error( cv::Error::StsBadArg, "" ); return; } #else threshGeneric(roi, src, src_step, dst, dst_step, thresh, maxval, type); @@ -925,7 +925,7 @@ thresh_32f( const Mat& _src, Mat& _dst, float thresh, float maxval, int type ) } break; default: - CV_Error( CV_StsBadArg, "" ); return; + CV_Error( cv::Error::StsBadArg, "" ); return; } #else threshGeneric(roi, src, src_step, dst, dst_step, thresh, maxval, type); @@ -1096,7 +1096,7 @@ thresh_64f(const Mat& _src, Mat& _dst, double thresh, double maxval, int type) } break; default: - CV_Error(CV_StsBadArg, ""); return; + CV_Error(cv::Error::StsBadArg, ""); return; } #else threshGeneric(roi, src, src_step, dst, dst_step, thresh, maxval, type); @@ -1656,7 +1656,7 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m else if( src.depth() == CV_64F ) ; else - CV_Error( CV_StsUnsupportedFormat, "" ); + CV_Error( cv::Error::StsUnsupportedFormat, "" ); parallel_for_(Range(0, dst.rows), ThresholdRunner(src, dst, thresh, maxval, type), @@ -1704,7 +1704,7 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, meanfloat.convertTo(mean, src.type()); } else - CV_Error( CV_StsBadFlag, "Unknown/unsupported adaptive threshold method" ); + CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported adaptive threshold method" ); int i, j; uchar imaxval = saturate_cast(maxValue); @@ -1718,7 +1718,7 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, for( i = 0; i < 768; i++ ) tab[i] = (uchar)(i - 255 <= -idelta ? imaxval : 0); else - CV_Error( CV_StsBadFlag, "Unknown/unsupported threshold type" ); + CV_Error( cv::Error::StsBadFlag, "Unknown/unsupported threshold type" ); if( src.isContinuous() && mean.isContinuous() && dst.isContinuous() ) { diff --git a/modules/imgproc/src/utils.cpp b/modules/imgproc/src/utils.cpp index 4f45cde5e0..518de58eab 100644 --- a/modules/imgproc/src/utils.cpp +++ b/modules/imgproc/src/utils.cpp @@ -51,19 +51,19 @@ CV_IMPL CvSeq* cvPointSeqFromMat( int seq_kind, const CvArr* arr, CvMat* mat = (CvMat*)arr; if( !CV_IS_MAT( mat )) - CV_Error( CV_StsBadArg, "Input array is not a valid matrix" ); + CV_Error( cv::Error::StsBadArg, "Input array is not a valid matrix" ); if( CV_MAT_CN(mat->type) == 1 && mat->width == 2 ) mat = cvReshape(mat, &hdr, 2); eltype = CV_MAT_TYPE( mat->type ); if( eltype != CV_32SC2 && eltype != CV_32FC2 ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "The matrix can not be converted to point sequence because of " "inappropriate element type" ); if( (mat->width != 1 && mat->height != 1) || !CV_IS_MAT_CONT(mat->type)) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The matrix converted to point sequence must be " "1-dimensional and continuous" ); diff --git a/modules/imgproc/test/test_color.cpp b/modules/imgproc/test/test_color.cpp index 2c89932adc..5a5898415c 100644 --- a/modules/imgproc/test/test_color.cpp +++ b/modules/imgproc/test/test_color.cpp @@ -1824,7 +1824,7 @@ void CV_ColorBayerTest::prepare_to_validation( int /*test_case_idx*/ ) else if( depth == CV_16U ) bayer2BGR_(src, dst, fwd_code); else - CV_Error(CV_StsUnsupportedFormat, ""); + CV_Error(cv::Error::StsUnsupportedFormat, ""); } diff --git a/modules/imgproc/test/test_filter.cpp b/modules/imgproc/test/test_filter.cpp index 02d5e232a2..011cbaab0b 100644 --- a/modules/imgproc/test/test_filter.cpp +++ b/modules/imgproc/test/test_filter.cpp @@ -307,7 +307,7 @@ void CV_MorphologyBaseTest::prepare_to_validation( int /*test_case_idx*/ ) cvtest::add( dst, 1, src, -1, Scalar::all(0), dst, dst.type() ); } else - CV_Error( CV_StsBadArg, "Unknown operation" ); + CV_Error( cv::Error::StsBadArg, "Unknown operation" ); } cvReleaseStructuringElement( &element ); diff --git a/modules/ml/src/ann_mlp.cpp b/modules/ml/src/ann_mlp.cpp index 3843564e15..5f15c173a1 100644 --- a/modules/ml/src/ann_mlp.cpp +++ b/modules/ml/src/ann_mlp.cpp @@ -223,7 +223,7 @@ public: void setActivationFunction(int _activ_func, double _f_param1, double _f_param2) CV_OVERRIDE { if( _activ_func < 0 || _activ_func > LEAKYRELU) - CV_Error( CV_StsOutOfRange, "Unknown activation function" ); + CV_Error( cv::Error::StsOutOfRange, "Unknown activation function" ); activ_func = _activ_func; @@ -322,7 +322,7 @@ public: { int n = layer_sizes[i]; if( n < 1 + (0 < i && i < l_count-1)) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "there should be at least one input and one output " "and every hidden layer must have more than 1 neuron" ); max_lsize = std::max( max_lsize, n ); @@ -341,7 +341,7 @@ public: float predict( InputArray _inputs, OutputArray _outputs, int ) const CV_OVERRIDE { if( !trained ) - CV_Error( CV_StsError, "The network has not been trained or loaded" ); + CV_Error( cv::Error::StsError, "The network has not been trained or loaded" ); Mat inputs = _inputs.getMat(); int type = inputs.type(), l_count = layer_count(); @@ -790,7 +790,7 @@ public: { t = t*inv_scale[j*2] + inv_scale[2*j+1]; if( t < m1 || t > M1 ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "Some of new output training vector components run exceed the original range too much" ); } } @@ -817,25 +817,25 @@ public: Mat& sample_weights, int flags ) { if( layer_sizes.empty() ) - CV_Error( CV_StsError, + CV_Error( cv::Error::StsError, "The network has not been created. Use method create or the appropriate constructor" ); if( (inputs.type() != CV_32F && inputs.type() != CV_64F) || inputs.cols != layer_sizes[0] ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "input training data should be a floating-point matrix with " "the number of rows equal to the number of training samples and " "the number of columns equal to the size of 0-th (input) layer" ); if( (outputs.type() != CV_32F && outputs.type() != CV_64F) || outputs.cols != layer_sizes.back() ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "output training data should be a floating-point matrix with " "the number of rows equal to the number of training samples and " "the number of columns equal to the size of last (output) layer" ); if( inputs.rows != outputs.rows ) - CV_Error( CV_StsUnmatchedSizes, "The numbers of input and output samples do not match" ); + CV_Error( cv::Error::StsUnmatchedSizes, "The numbers of input and output samples do not match" ); Mat temp; double s = sum(sample_weights)[0]; @@ -1323,7 +1323,7 @@ public: fs << "itePerStep" << params.itePerStep; } else - CV_Error(CV_StsError, "Unknown training method"); + CV_Error(cv::Error::StsError, "Unknown training method"); fs << "term_criteria" << "{"; if( params.termCrit.type & TermCriteria::EPS ) @@ -1421,7 +1421,7 @@ public: params.itePerStep = tpn["itePerStep"]; } else - CV_Error(CV_StsParseError, "Unknown training method (should be BACKPROP or RPROP)"); + CV_Error(cv::Error::StsParseError, "Unknown training method (should be BACKPROP or RPROP)"); FileNode tcn = tpn["term_criteria"]; if( !tcn.empty() ) diff --git a/modules/ml/src/boost.cpp b/modules/ml/src/boost.cpp index be9c9a7b46..87e1fe4131 100644 --- a/modules/ml/src/boost.cpp +++ b/modules/ml/src/boost.cpp @@ -308,7 +308,7 @@ public: } } else - CV_Error(CV_StsNotImplemented, "Unknown boosting type"); + CV_Error(cv::Error::StsNotImplemented, "Unknown boosting type"); /*if( bparams.boostType != Boost::LOGIT ) { @@ -387,7 +387,7 @@ public: void write( FileStorage& fs ) const CV_OVERRIDE { if( roots.empty() ) - CV_Error( CV_StsBadArg, "RTrees have not been trained" ); + CV_Error( cv::Error::StsBadArg, "RTrees have not been trained" ); writeFormat(fs); writeParams(fs); diff --git a/modules/ml/src/data.cpp b/modules/ml/src/data.cpp index fd7c8d1016..6f8035947b 100644 --- a/modules/ml/src/data.cpp +++ b/modules/ml/src/data.cpp @@ -574,7 +574,7 @@ public: if( nvars == 0 ) { if( rowvals.empty() ) - CV_Error(CV_StsBadArg, "invalid CSV format; no data found"); + CV_Error(cv::Error::StsBadArg, "invalid CSV format; no data found"); nvars = (int)rowvals.size(); if( !varTypeSpec.empty() && varTypeSpec.size() > 0 ) { @@ -637,7 +637,7 @@ public: { for( i = ninputvars; i < nvars; i++ ) if( vtypes[i] == VAR_CATEGORICAL ) - CV_Error(CV_StsBadArg, + CV_Error(cv::Error::StsBadArg, "If responses are vector values, not scalars, they must be marked as ordered responses"); } } @@ -724,14 +724,14 @@ public: } if ( ptr[3] != '[') - CV_Error( CV_StsBadArg, errmsg ); + CV_Error( cv::Error::StsBadArg, errmsg ); ptr += 4; // pass "ord[" do { int b1 = (int)strtod( ptr, &stopstring ); if( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') ) - CV_Error( CV_StsBadArg, errmsg ); + CV_Error( cv::Error::StsBadArg, errmsg ); ptr = stopstring + 1; if( (stopstring[0] == ',') || (stopstring[0] == ']')) { @@ -745,7 +745,7 @@ public: { int b2 = (int)strtod( ptr, &stopstring); if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') ) - CV_Error( CV_StsBadArg, errmsg ); + CV_Error( cv::Error::StsBadArg, errmsg ); ptr = stopstring + 1; CV_Assert( 0 <= b1 && b1 <= b2 && b2 < nvars ); for (int i = b1; i <= b2; i++) @@ -753,7 +753,7 @@ public: specCounter += b2 - b1 + 1; } else - CV_Error( CV_StsBadArg, errmsg ); + CV_Error( cv::Error::StsBadArg, errmsg ); } } @@ -762,7 +762,7 @@ public: } if( specCounter != nvars ) - CV_Error( CV_StsBadArg, "type of some variables is not specified" ); + CV_Error( cv::Error::StsBadArg, "type of some variables is not specified" ); } void setTrainTestSplitRatio(double ratio, bool shuffle) CV_OVERRIDE diff --git a/modules/ml/src/gbt.cpp b/modules/ml/src/gbt.cpp index 57f2eb176b..d1d6f2c8ea 100644 --- a/modules/ml/src/gbt.cpp +++ b/modules/ml/src/gbt.cpp @@ -218,7 +218,7 @@ CvGBTrees::train( const CvMat* _train_data, int _tflag, orig_response->data.fl[i] = (float) _responses->data.i[i*step]; }; break; default: - CV_Error(CV_StsUnmatchedFormats, "Response should be a 32fC1 or 32sC1 vector."); + CV_Error(cv::Error::StsUnmatchedFormats, "Response should be a 32fC1 or 32sC1 vector."); } if (!is_regression) @@ -283,7 +283,7 @@ CvGBTrees::train( const CvMat* _train_data, int _tflag, sample_idx->data.i[active_samples_count++] = i; } break; - default: CV_Error(CV_StsUnmatchedFormats, "_sample_idx should be a 32sC1, 8sC1 or 8uC1 vector."); + default: CV_Error(cv::Error::StsUnmatchedFormats, "_sample_idx should be a 32sC1, 8sC1 or 8uC1 vector."); } } else @@ -1072,7 +1072,7 @@ void CvGBTrees::read_params( CvFileStorage* fs, CvFileNode* fnode ) if( params.loss_function_type < SQUARED_LOSS || params.loss_function_type > DEVIANCE_LOSS || params.loss_function_type == 2) - CV_ERROR( CV_StsBadArg, "Unknown loss function" ); + CV_ERROR( cv::Error::StsBadArg, "Unknown loss function" ); params.weak_count = cvReadIntByName( fs, fnode, "ensemble_length" ); params.shrinkage = (float)cvReadRealByName( fs, fnode, "shrinkage", 0.1 ); @@ -1082,7 +1082,7 @@ void CvGBTrees::read_params( CvFileStorage* fs, CvFileNode* fnode ) { class_labels = (CvMat*)cvReadByName( fs, fnode, "class_labels" ); if( class_labels && !CV_IS_MAT(class_labels)) - CV_ERROR( CV_StsParseError, "class_labels must stored as a matrix"); + CV_ERROR( cv::Error::StsParseError, "class_labels must stored as a matrix"); } data->is_classifier = 0; @@ -1105,7 +1105,7 @@ void CvGBTrees::write( CvFileStorage* fs, const char* name ) const cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_ML_GBT ); if( !weak ) - CV_ERROR( CV_StsBadArg, "The model has not been trained yet" ); + CV_ERROR( cv::Error::StsBadArg, "The model has not been trained yet" ); write_params( fs ); cvWriteReal( fs, "base_value", base_value); @@ -1170,13 +1170,13 @@ void CvGBTrees::read( CvFileStorage* fs, CvFileNode* node ) trees_fnode = cvGetFileNodeByName( fs, node, s.c_str() ); if( !trees_fnode || !CV_NODE_IS_SEQ(trees_fnode->tag) ) - CV_ERROR( CV_StsParseError, " tag is missing" ); + CV_ERROR( cv::Error::StsParseError, " tag is missing" ); cvStartReadSeq( trees_fnode->data.seq, &reader ); ntrees = trees_fnode->data.seq->total; if( ntrees != params.weak_count ) - CV_ERROR( CV_StsUnmatchedSizes, + CV_ERROR( cv::Error::StsUnmatchedSizes, "The number of trees stored does not match tag value" ); CV_CALL( storage = cvCreateMemStorage() ); diff --git a/modules/ml/src/inner_functions.cpp b/modules/ml/src/inner_functions.cpp index 6b3affcebc..c0e5f45dd1 100644 --- a/modules/ml/src/inner_functions.cpp +++ b/modules/ml/src/inner_functions.cpp @@ -63,7 +63,7 @@ bool StatModel::train(const Ptr& trainData, int ) { CV_TRACE_FUNCTION(); CV_Assert(!trainData.empty()); - CV_Error(CV_StsNotImplemented, ""); + CV_Error(cv::Error::StsNotImplemented, ""); return false; } diff --git a/modules/ml/src/lr.cpp b/modules/ml/src/lr.cpp index b43e104045..6f462e14c3 100644 --- a/modules/ml/src/lr.cpp +++ b/modules/ml/src/lr.cpp @@ -109,15 +109,15 @@ bool LogisticRegressionImpl::train(const Ptr& trainData, int) CV_Assert( !_labels_i.empty() && !_data_i.empty()); if(_labels_i.cols != 1) { - CV_Error( CV_StsBadArg, "labels should be a column matrix" ); + CV_Error( cv::Error::StsBadArg, "labels should be a column matrix" ); } if(_data_i.type() != CV_32FC1 || _labels_i.type() != CV_32FC1) { - CV_Error( CV_StsBadArg, "data and labels must be a floating point matrix" ); + CV_Error( cv::Error::StsBadArg, "data and labels must be a floating point matrix" ); } if(_labels_i.rows != _data_i.rows) { - CV_Error( CV_StsBadArg, "number of rows in data and labels should be equal" ); + CV_Error( cv::Error::StsBadArg, "number of rows in data and labels should be equal" ); } // class labels @@ -126,7 +126,7 @@ bool LogisticRegressionImpl::train(const Ptr& trainData, int) int num_classes = (int) this->forward_mapper.size(); if(num_classes < 2) { - CV_Error( CV_StsBadArg, "data should have at least 2 classes" ); + CV_Error( cv::Error::StsBadArg, "data should have at least 2 classes" ); } // add a column of ones to the data (bias/intercept term) @@ -174,7 +174,7 @@ bool LogisticRegressionImpl::train(const Ptr& trainData, int) this->learnt_thetas = thetas.clone(); if( cvIsNaN( (double)sum(this->learnt_thetas)[0] ) ) { - CV_Error( CV_StsBadArg, "check training parameters. Invalid training classifier" ); + CV_Error( cv::Error::StsBadArg, "check training parameters. Invalid training classifier" ); } // success @@ -187,7 +187,7 @@ float LogisticRegressionImpl::predict(InputArray samples, OutputArray results, i // check if learnt_mats array is populated if(!this->isTrained()) { - CV_Error( CV_StsBadArg, "classifier should be trained first" ); + CV_Error( cv::Error::StsBadArg, "classifier should be trained first" ); } // coefficient matrix @@ -206,7 +206,7 @@ float LogisticRegressionImpl::predict(InputArray samples, OutputArray results, i Mat data = samples.getMat(); if(data.type() != CV_32F) { - CV_Error( CV_StsBadArg, "data must be of floating type" ); + CV_Error( cv::Error::StsBadArg, "data must be of floating type" ); } // add a column of ones to the data (bias/intercept term) @@ -327,7 +327,7 @@ double LogisticRegressionImpl::compute_cost(const Mat& _data, const Mat& _labels if(cvIsNaN( cost ) == 1) { - CV_Error( CV_StsBadArg, "check training parameters. Invalid training classifier" ); + CV_Error( cv::Error::StsBadArg, "check training parameters. Invalid training classifier" ); } return cost; @@ -398,12 +398,12 @@ Mat LogisticRegressionImpl::batch_gradient_descent(const Mat& _data, const Mat& // implements batch gradient descent if(this->params.alpha<=0) { - CV_Error( CV_StsBadArg, "check training parameters (learning rate) for the classifier" ); + CV_Error( cv::Error::StsBadArg, "check training parameters (learning rate) for the classifier" ); } if(this->params.num_iters <= 0) { - CV_Error( CV_StsBadArg, "number of iterations cannot be zero or a negative number" ); + CV_Error( cv::Error::StsBadArg, "number of iterations cannot be zero or a negative number" ); } int llambda = 0; @@ -439,12 +439,12 @@ Mat LogisticRegressionImpl::mini_batch_gradient_descent(const Mat& _data, const if(this->params.mini_batch_size <= 0 || this->params.alpha == 0) { - CV_Error( CV_StsBadArg, "check training parameters for the classifier" ); + CV_Error( cv::Error::StsBadArg, "check training parameters for the classifier" ); } if(this->params.num_iters <= 0) { - CV_Error( CV_StsBadArg, "number of iterations cannot be zero or a negative number" ); + CV_Error( cv::Error::StsBadArg, "number of iterations cannot be zero or a negative number" ); } Mat theta_p = _init_theta.clone(); @@ -551,7 +551,7 @@ void LogisticRegressionImpl::write(FileStorage& fs) const // check if open if(fs.isOpened() == 0) { - CV_Error(CV_StsBadArg,"file can't open. Check file path"); + CV_Error(cv::Error::StsBadArg,"file can't open. Check file path"); } writeFormat(fs); string desc = "Logistic Regression Classifier"; @@ -574,7 +574,7 @@ void LogisticRegressionImpl::read(const FileNode& fn) // check if empty if(fn.empty()) { - CV_Error( CV_StsBadArg, "empty FileNode object" ); + CV_Error( cv::Error::StsBadArg, "empty FileNode object" ); } this->params.alpha = (double)fn["alpha"]; diff --git a/modules/ml/src/nbayes.cpp b/modules/ml/src/nbayes.cpp index 60dda0c7d4..910a1e1c37 100644 --- a/modules/ml/src/nbayes.cpp +++ b/modules/ml/src/nbayes.cpp @@ -101,7 +101,7 @@ public: norm(var_idx, __var_idx, NORM_INF) != 0 || cls_labels.size() != __cls_labels.size() || norm(cls_labels, __cls_labels, NORM_INF) != 0 ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The new training data is inconsistent with the original training data; varIdx and the class labels should be the same" ); } @@ -312,11 +312,11 @@ public: bool rawOutput = (flags & RAW_OUTPUT) != 0; if( samples.type() != CV_32F || samples.cols != nallvars ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "The input samples must be 32f matrix with the number of columns = nallvars" ); if( (samples.rows > 1) && (! _results.needed()) ) - CV_Error( CV_StsNullPtr, + CV_Error( cv::Error::StsNullPtr, "When the number of input samples is >1, the output vector of results must be passed" ); if( _results.needed() ) @@ -388,7 +388,7 @@ public: fn["var_all"] >> nallvars; if( nallvars <= 0 ) - CV_Error( CV_StsParseError, + CV_Error( cv::Error::StsParseError, "The field \"var_count\" of NBayes classifier is missing or non-positive" ); fn["var_idx"] >> var_idx; @@ -397,7 +397,7 @@ public: int nclasses = (int)cls_labels.total(), i; if( cls_labels.empty() || nclasses < 1 ) - CV_Error( CV_StsParseError, "No or invalid \"cls_labels\" in NBayes classifier" ); + CV_Error( cv::Error::StsParseError, "No or invalid \"cls_labels\" in NBayes classifier" ); FileNodeIterator count_it = fn["count"].begin(), diff --git a/modules/ml/src/precomp.hpp b/modules/ml/src/precomp.hpp index 328cc4732a..6a91ef98f0 100644 --- a/modules/ml/src/precomp.hpp +++ b/modules/ml/src/precomp.hpp @@ -131,13 +131,13 @@ namespace ml inline void setMaxCategories(int val) { if( val < 2 ) - CV_Error( CV_StsOutOfRange, "max_categories should be >= 2" ); + CV_Error( cv::Error::StsOutOfRange, "max_categories should be >= 2" ); maxCategories = std::min(val, 15 ); } inline void setMaxDepth(int val) { if( val < 0 ) - CV_Error( CV_StsOutOfRange, "max_depth should be >= 0" ); + CV_Error( cv::Error::StsOutOfRange, "max_depth should be >= 0" ); maxDepth = std::min( val, 25 ); } inline void setMinSampleCount(int val) @@ -147,11 +147,11 @@ namespace ml inline void setCVFolds(int val) { if( val < 0 ) - CV_Error( CV_StsOutOfRange, + CV_Error( cv::Error::StsOutOfRange, "params.CVFolds should be =0 (the tree is not pruned) " "or n>0 (tree is pruned using n-fold cross-validation)" ); if(val > 1) - CV_Error( CV_StsNotImplemented, + CV_Error( cv::Error::StsNotImplemented, "tree pruning using cross-validation is not implemented." "Set CVFolds to 1"); @@ -162,7 +162,7 @@ namespace ml inline void setRegressionAccuracy(float val) { if( val < 0 ) - CV_Error( CV_StsOutOfRange, "params.regression_accuracy should be >= 0" ); + CV_Error( cv::Error::StsOutOfRange, "params.regression_accuracy should be >= 0" ); regressionAccuracy = val; } diff --git a/modules/ml/src/rtrees.cpp b/modules/ml/src/rtrees.cpp index 2cad961f99..41ffa03a5e 100644 --- a/modules/ml/src/rtrees.cpp +++ b/modules/ml/src/rtrees.cpp @@ -309,7 +309,7 @@ public: { CV_TRACE_FUNCTION(); if( roots.empty() ) - CV_Error( CV_StsBadArg, "RTrees have not been trained" ); + CV_Error( cv::Error::StsBadArg, "RTrees have not been trained" ); writeFormat(fs); writeParams(fs); diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 40c18c03ea..0d62f7858a 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -95,11 +95,11 @@ const int QFLOAT_TYPE = DataDepth::value; static void checkParamGrid(const ParamGrid& pg) { if( pg.minVal > pg.maxVal ) - CV_Error( CV_StsBadArg, "Lower bound of the grid must be less then the upper one" ); + CV_Error( cv::Error::StsBadArg, "Lower bound of the grid must be less then the upper one" ); if( pg.minVal < DBL_EPSILON ) - CV_Error( CV_StsBadArg, "Lower bound of the grid must be positive" ); + CV_Error( cv::Error::StsBadArg, "Lower bound of the grid must be positive" ); if( pg.logStep < 1. + FLT_EPSILON ) - CV_Error( CV_StsBadArg, "Grid step must greater than 1" ); + CV_Error( cv::Error::StsBadArg, "Grid step must greater than 1" ); } // SVM training parameters @@ -325,7 +325,7 @@ public: calc_intersec(vcount, var_count, vecs, another, results); break; default: - CV_Error(CV_StsBadArg, "Unknown kernel type"); + CV_Error(cv::Error::StsBadArg, "Unknown kernel type"); } const Qfloat max_val = (Qfloat)(FLT_MAX*1e-3); for( int j = 0; j < vcount; j++ ) @@ -410,7 +410,7 @@ ParamGrid SVM::getDefaultGrid( int param_id ) grid.logStep = 7; // total iterations = 3 } else - cvError( CV_StsBadArg, "SVM::getDefaultGrid", "Invalid type of parameter " + cvError( cv::Error::StsBadArg, "SVM::getDefaultGrid", "Invalid type of parameter " "(use one of SVM::C, SVM::GAMMA et al.)", __FILE__, __LINE__ ); return grid; } @@ -1297,12 +1297,12 @@ public: if( kernelType != LINEAR && kernelType != POLY && kernelType != SIGMOID && kernelType != RBF && kernelType != INTER && kernelType != CHI2) - CV_Error( CV_StsBadArg, "Unknown/unsupported kernel type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported kernel type" ); if( kernelType == LINEAR ) params.gamma = 1; else if( params.gamma <= 0 ) - CV_Error( CV_StsOutOfRange, "gamma parameter of the kernel must be positive" ); + CV_Error( cv::Error::StsOutOfRange, "gamma parameter of the kernel must be positive" ); if( kernelType != SIGMOID && kernelType != POLY ) params.coef0 = 0; @@ -1310,14 +1310,14 @@ public: if( kernelType != POLY ) params.degree = 0; else if( params.degree <= 0 ) - CV_Error( CV_StsOutOfRange, "The kernel parameter must be positive" ); + CV_Error( cv::Error::StsOutOfRange, "The kernel parameter must be positive" ); kernel = makePtr(params); } else { if (!kernel) - CV_Error( CV_StsBadArg, "Custom kernel is not set" ); + CV_Error( cv::Error::StsBadArg, "Custom kernel is not set" ); } int svmType = params.svmType; @@ -1325,22 +1325,22 @@ public: if( svmType != C_SVC && svmType != NU_SVC && svmType != ONE_CLASS && svmType != EPS_SVR && svmType != NU_SVR ) - CV_Error( CV_StsBadArg, "Unknown/unsupported SVM type" ); + CV_Error( cv::Error::StsBadArg, "Unknown/unsupported SVM type" ); if( svmType == ONE_CLASS || svmType == NU_SVC ) params.C = 0; else if( params.C <= 0 ) - CV_Error( CV_StsOutOfRange, "The parameter C must be positive" ); + CV_Error( cv::Error::StsOutOfRange, "The parameter C must be positive" ); if( svmType == C_SVC || svmType == EPS_SVR ) params.nu = 0; else if( params.nu <= 0 || params.nu >= 1 ) - CV_Error( CV_StsOutOfRange, "The parameter nu must be between 0 and 1" ); + CV_Error( cv::Error::StsOutOfRange, "The parameter nu must be between 0 and 1" ); if( svmType != EPS_SVR ) params.p = 0; else if( params.p <= 0 ) - CV_Error( CV_StsOutOfRange, "The parameter p must be positive" ); + CV_Error( cv::Error::StsOutOfRange, "The parameter p must be positive" ); if( svmType != C_SVC ) params.classWeights.release(); @@ -1431,7 +1431,7 @@ public: if( (cw.cols != 1 && cw.rows != 1) || (int)cw.total() != class_count || (cw.type() != CV_32F && cw.type() != CV_64F) ) - CV_Error( CV_StsBadArg, "params.class_weights must be 1d floating-point vector " + CV_Error( cv::Error::StsBadArg, "params.class_weights must be 1d floating-point vector " "containing as many elements as the number of classes" ); cw.convertTo(class_weights, CV_64F, params.C); @@ -1446,7 +1446,7 @@ public: //check that while cross-validation there were the samples from all the classes if ((int)class_ranges.size() < class_count + 1) - CV_Error( CV_StsBadArg, "While cross-validation one or more of the classes have " + CV_Error( cv::Error::StsBadArg, "While cross-validation one or more of the classes have " "been fell out of the sample. Try to reduce " ); if( svmType == NU_SVC ) @@ -1620,7 +1620,7 @@ public: { responses = data->getTrainNormCatResponses(); if( responses.empty() ) - CV_Error(CV_StsBadArg, "in the case of classification problem the responses must be categorical; " + CV_Error(cv::Error::StsBadArg, "in the case of classification problem the responses must be categorical; " "either specify varType when creating TrainData, or pass integer responses"); class_labels = data->getClassLabels(); } @@ -1969,7 +1969,7 @@ public: } } else - CV_Error( CV_StsBadArg, "INTERNAL ERROR: Unknown SVM type, " + CV_Error( cv::Error::StsBadArg, "INTERNAL ERROR: Unknown SVM type, " "the SVM structure is probably corrupted" ); } @@ -2112,7 +2112,7 @@ public: int class_count = !class_labels.empty() ? (int)class_labels.total() : params.svmType == ONE_CLASS ? 1 : 0; if( !isTrained() ) - CV_Error( CV_StsParseError, "SVM model data is invalid, check sv_count, var_* and class_count tags" ); + CV_Error( cv::Error::StsParseError, "SVM model data is invalid, check sv_count, var_* and class_count tags" ); writeFormat(fs); write_params( fs ); @@ -2197,11 +2197,11 @@ public: svm_type_str == "NU_SVR" ? NU_SVR : -1; if( svmType < 0 ) - CV_Error( CV_StsParseError, "Missing or invalid SVM type" ); + CV_Error( cv::Error::StsParseError, "Missing or invalid SVM type" ); FileNode kernel_node = fn["kernel"]; if( kernel_node.empty() ) - CV_Error( CV_StsParseError, "SVM kernel tag is not found" ); + CV_Error( cv::Error::StsParseError, "SVM kernel tag is not found" ); String kernel_type_str = (String)kernel_node["type"]; int kernelType = @@ -2213,7 +2213,7 @@ public: kernel_type_str == "INTER" ? INTER : CUSTOM; if( kernelType == CUSTOM ) - CV_Error( CV_StsParseError, "Invalid SVM kernel type (or custom kernel)" ); + CV_Error( cv::Error::StsParseError, "Invalid SVM kernel type (or custom kernel)" ); _params.svmType = svmType; _params.kernelType = kernelType; @@ -2253,7 +2253,7 @@ public: int class_count = (int)fn["class_count"]; if( sv_total <= 0 || var_count <= 0 ) - CV_Error( CV_StsParseError, "SVM model data is invalid, check sv_count, var_* and class_count tags" ); + CV_Error( cv::Error::StsParseError, "SVM model data is invalid, check sv_count, var_* and class_count tags" ); FileNode m = fn["class_labels"]; if( !m.empty() ) @@ -2263,7 +2263,7 @@ public: m >> params.classWeights; if( class_count > 1 && (class_labels.empty() || (int)class_labels.total() != class_count)) - CV_Error( CV_StsParseError, "Array of class labels is missing or invalid" ); + CV_Error( cv::Error::StsParseError, "Array of class labels is missing or invalid" ); // read support vectors FileNode sv_node = fn["support_vectors"]; diff --git a/modules/ml/src/svmsgd.cpp b/modules/ml/src/svmsgd.cpp index 266c7cf300..ccb5ca3a85 100644 --- a/modules/ml/src/svmsgd.cpp +++ b/modules/ml/src/svmsgd.cpp @@ -375,7 +375,7 @@ bool SVMSGDImpl::isTrained() const void SVMSGDImpl::write(FileStorage& fs) const { if( !isTrained() ) - CV_Error( CV_StsParseError, "SVMSGD model data is invalid, it hasn't been trained" ); + CV_Error( cv::Error::StsParseError, "SVMSGD model data is invalid, it hasn't been trained" ); writeFormat(fs); writeParams( fs ); @@ -437,7 +437,7 @@ void SVMSGDImpl::readParams( const FileNode& fn ) svmsgdTypeStr == "ASGD" ? ASGD : -1; if( svmsgdType < 0 ) - CV_Error( CV_StsParseError, "Missing or invalid SVMSGD type" ); + CV_Error( cv::Error::StsParseError, "Missing or invalid SVMSGD type" ); params.svmsgdType = svmsgdType; @@ -447,7 +447,7 @@ void SVMSGDImpl::readParams( const FileNode& fn ) marginTypeStr == "HARD_MARGIN" ? HARD_MARGIN : -1; if( marginType < 0 ) - CV_Error( CV_StsParseError, "Missing or invalid margin type" ); + CV_Error( cv::Error::StsParseError, "Missing or invalid margin type" ); params.marginType = marginType; @@ -517,7 +517,7 @@ void SVMSGDImpl::setOptimalParameters(int svmsgdType, int marginType) break; default: - CV_Error( CV_StsParseError, "SVMSGD model data is invalid" ); + CV_Error( cv::Error::StsParseError, "SVMSGD model data is invalid" ); } } } //ml diff --git a/modules/ml/src/testset.cpp b/modules/ml/src/testset.cpp index 48cd134154..b20115d199 100644 --- a/modules/ml/src/testset.cpp +++ b/modules/ml/src/testset.cpp @@ -60,13 +60,13 @@ void createConcentricSpheresTestSet( int num_samples, int num_features, int num_ OutputArray _samples, OutputArray _responses) { if( num_samples < 1 ) - CV_Error( CV_StsBadArg, "num_samples parameter must be positive" ); + CV_Error( cv::Error::StsBadArg, "num_samples parameter must be positive" ); if( num_features < 1 ) - CV_Error( CV_StsBadArg, "num_features parameter must be positive" ); + CV_Error( cv::Error::StsBadArg, "num_features parameter must be positive" ); if( num_classes < 1 ) - CV_Error( CV_StsBadArg, "num_classes parameter must be positive" ); + CV_Error( cv::Error::StsBadArg, "num_classes parameter must be positive" ); int i, cur_class; diff --git a/modules/ml/src/tree.cpp b/modules/ml/src/tree.cpp index b69ddaece2..3d8941344d 100644 --- a/modules/ml/src/tree.cpp +++ b/modules/ml/src/tree.cpp @@ -404,7 +404,7 @@ int DTreesImpl::addNodeAndTrySplit( int parent, const vector& sidx ) { node.defaultDir = calcDir( node.split, sidx, sleft, sright ); if( params.useSurrogates ) - CV_Error( CV_StsNotImplemented, "surrogate splits are not implemented yet"); + CV_Error( cv::Error::StsNotImplemented, "surrogate splits are not implemented yet"); int left = addNodeAndTrySplit( nidx, sleft ); int right = addNodeAndTrySplit( nidx, sright ); @@ -1445,7 +1445,7 @@ float DTreesImpl::predictTrees( const Range& range, const Mat& sample, int flags int ival = cvRound(val); if( ival != val ) - CV_Error( CV_StsBadArg, + CV_Error( cv::Error::StsBadArg, "one of input categorical variable is not an integer" ); CV_Assert(cmap != NULL); diff --git a/modules/photo/src/inpaint.cpp b/modules/photo/src/inpaint.cpp index 05d2d49dca..a763b63f33 100644 --- a/modules/photo/src/inpaint.cpp +++ b/modules/photo/src/inpaint.cpp @@ -693,18 +693,18 @@ icvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_ output_img = cvGetMat( _output_img, &output_hdr ); if( !CV_ARE_SIZES_EQ(input_img,output_img) || !CV_ARE_SIZES_EQ(input_img,inpaint_mask)) - CV_Error( CV_StsUnmatchedSizes, "All the input and output images must have the same size" ); + CV_Error( cv::Error::StsUnmatchedSizes, "All the input and output images must have the same size" ); if( (CV_MAT_TYPE(input_img->type) != CV_8U && CV_MAT_TYPE(input_img->type) != CV_16U && CV_MAT_TYPE(input_img->type) != CV_32F && CV_MAT_TYPE(input_img->type) != CV_8UC3) || !CV_ARE_TYPES_EQ(input_img,output_img) ) - CV_Error( CV_StsUnsupportedFormat, + CV_Error( cv::Error::StsUnsupportedFormat, "8-bit, 16-bit unsigned or 32-bit float 1-channel and 8-bit 3-channel input/output images are supported" ); if( CV_MAT_TYPE(inpaint_mask->type) != CV_8UC1 ) - CV_Error( CV_StsUnsupportedFormat, "The mask must be 8-bit 1-channel image" ); + CV_Error( cv::Error::StsUnsupportedFormat, "The mask must be 8-bit 1-channel image" ); range = MAX(range,1); range = MIN(range,100); diff --git a/modules/stitching/src/motion_estimators.cpp b/modules/stitching/src/motion_estimators.cpp index dfe929f9ba..8d227409ca 100644 --- a/modules/stitching/src/motion_estimators.cpp +++ b/modules/stitching/src/motion_estimators.cpp @@ -962,7 +962,7 @@ void waveCorrect(std::vector &rmats, WaveCorrectKind kind) else if (kind == WAVE_CORRECT_VERT) rg1 = eigen_vecs.row(0).t(); else - CV_Error(CV_StsBadArg, "unsupported kind of wave correction"); + CV_Error(cv::Error::StsBadArg, "unsupported kind of wave correction"); Mat img_k = Mat::zeros(3, 1, CV_32F); for (size_t i = 0; i < rmats.size(); ++i) diff --git a/modules/ts/src/ts.cpp b/modules/ts/src/ts.cpp index e5d36b435b..2d795cd3a2 100644 --- a/modules/ts/src/ts.cpp +++ b/modules/ts/src/ts.cpp @@ -643,7 +643,7 @@ void TS::update_context( BaseTest* test, int test_case_idx, bool update_ts_conte current_test_info.test = test; current_test_info.test_case_idx = test_case_idx; current_test_info.code = 0; - cvSetErrStatus( CV_StsOk ); + cvSetErrStatus( cv::Error::StsOk ); } diff --git a/modules/videoio/src/cap_mjpeg_encoder.cpp b/modules/videoio/src/cap_mjpeg_encoder.cpp index 2e7452cf17..2bb01f4a81 100644 --- a/modules/videoio/src/cap_mjpeg_encoder.cpp +++ b/modules/videoio/src/cap_mjpeg_encoder.cpp @@ -95,7 +95,7 @@ static bool createEncodeHuffmanTable( const int* src, unsigned* table, int max_s if( size > max_size ) { - CV_Error(CV_StsOutOfRange, "too big maximum Huffman code size"); + CV_Error(cv::Error::StsOutOfRange, "too big maximum Huffman code size"); } memset( table, 0, size*sizeof(table[0])); @@ -487,7 +487,7 @@ public: colorspace = COLORSPACE_YUV444P; } else - CV_Error(CV_StsBadArg, "Invalid combination of specified video colorspace and the input image colorspace"); + CV_Error(cv::Error::StsBadArg, "Invalid combination of specified video colorspace and the input image colorspace"); if( !rawstream ) { int avi_index = container.getAVIIndex(0, dc); diff --git a/modules/videoio/src/cap_msmf.cpp b/modules/videoio/src/cap_msmf.cpp index 93545c615e..d4afa23440 100644 --- a/modules/videoio/src/cap_msmf.cpp +++ b/modules/videoio/src/cap_msmf.cpp @@ -707,7 +707,7 @@ public: if (FAILED(MFCreateAttributes(&attr, 1)) || FAILED(attr->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, sourceType))) { - CV_Error(CV_StsError, "Failed to create attributes"); + CV_Error(cv::Error::StsError, "Failed to create attributes"); } if (FAILED(MFEnumDeviceSources(attr.Get(), &devices, &count))) { @@ -961,14 +961,14 @@ _ComPtr CvCapture_MSMF::getDefaultSourceConfig(UINT32 num) FAILED(res->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, true)) ) { - CV_Error(CV_StsError, "Failed to create attributes"); + CV_Error(cv::Error::StsError, "Failed to create attributes"); } #ifdef HAVE_MSMF_DXVA if (D3DMgr) { if (FAILED(res->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, D3DMgr.Get()))) { - CV_Error(CV_StsError, "Failed to create attributes"); + CV_Error(cv::Error::StsError, "Failed to create attributes"); } } #endif diff --git a/modules/videoio/src/cap_openni2.cpp b/modules/videoio/src/cap_openni2.cpp index 034509cdf7..214cc1a559 100644 --- a/modules/videoio/src/cap_openni2.cpp +++ b/modules/videoio/src/cap_openni2.cpp @@ -90,7 +90,7 @@ private: openni::Status status = openni::OpenNI::initialize(); if (status != openni::STATUS_OK) { - CV_Error(CV_StsError, std::string("Failed to initialize:") + openni::OpenNI::getExtendedError()); + CV_Error(cv::Error::StsError, std::string("Failed to initialize:") + openni::OpenNI::getExtendedError()); } } @@ -274,7 +274,7 @@ CvCapture_OpenNI2::CvCapture_OpenNI2(int index, const char * filename) : deviceURI = ldevs[index].getUri(); else { - CV_Error(CV_StsError, "OpenCVKinect2: Device index exceeds the number of available OpenNI devices"); + CV_Error(cv::Error::StsError, "OpenCVKinect2: Device index exceeds the number of available OpenNI devices"); } } } @@ -287,7 +287,7 @@ CvCapture_OpenNI2::CvCapture_OpenNI2(int index, const char * filename) : status = device.open(deviceURI); if (status != openni::STATUS_OK) { - CV_Error(CV_StsError, std::string("OpenCVKinect2: Failed to open device: ") + openni::OpenNI::getExtendedError()); + CV_Error(cv::Error::StsError, std::string("OpenCVKinect2: Failed to open device: ") + openni::OpenNI::getExtendedError()); } toggleStream(CV_DEPTH_STREAM, true); @@ -361,7 +361,7 @@ void CvCapture_OpenNI2::toggleStream(int stream, bool toggle) if (status != openni::STATUS_OK) { streams[stream].destroy(); - CV_Error(CV_StsError, std::string("OpenCVKinect2 : Couldn't set ") + + CV_Error(cv::Error::StsError, std::string("OpenCVKinect2 : Couldn't set ") + stream_names[stream] + std::string(" stream output mode: ") + std::string(openni::OpenNI::getExtendedError())); } @@ -373,14 +373,14 @@ void CvCapture_OpenNI2::toggleStream(int stream, bool toggle) if (status != openni::STATUS_OK) { streams[stream].destroy(); - CV_Error(CV_StsError, std::string("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't start ") + + CV_Error(cv::Error::StsError, std::string("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't start ") + stream_names[stream] + std::string(" stream: ") + std::string(openni::OpenNI::getExtendedError())); } } else { - CV_Error(CV_StsError, std::string("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't find ") + + CV_Error(cv::Error::StsError, std::string("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't find ") + stream_names[stream] + " stream: " + std::string(openni::OpenNI::getExtendedError())); } @@ -1026,7 +1026,7 @@ inline void getBGRImageFromMetaData( const openni::VideoFrameRef& imageMetaData, { cv::Mat bufferImage; if( imageMetaData.getVideoMode().getPixelFormat() != openni::PIXEL_FORMAT_RGB888 ) - CV_Error( CV_StsUnsupportedFormat, "Unsupported format of grabbed image." ); + CV_Error( cv::Error::StsUnsupportedFormat, "Unsupported format of grabbed image." ); bgrImage.create(imageMetaData.getHeight(), imageMetaData.getWidth(), CV_8UC3); bufferImage.create(imageMetaData.getHeight(), imageMetaData.getWidth(), CV_8UC3); @@ -1049,7 +1049,7 @@ inline void getGrayImageFromMetaData(const openni::VideoFrameRef& imageMetaData, } else { - CV_Error(CV_StsUnsupportedFormat, "Unsupported format of grabbed image."); + CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported format of grabbed image."); } } From bc8295918438040ff87ecef2c0a500b63159f082 Mon Sep 17 00:00:00 2001 From: Michael Klatis Date: Tue, 5 Mar 2024 01:40:21 -0800 Subject: [PATCH 09/56] Merge pull request #25123 from klatism:zlib-upgrade Zlib upgrade to version 1.3.1 #25123 Upgrade zlib dependency from 1.3.0 to 1.3.1 - [X] I agree to contribute to the project under Apache 2 License. - [X] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [X] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake Co-authored-by: Misha Klatis --- 3rdparty/zlib/CMakeLists.txt | 10 ++--- 3rdparty/zlib/ChangeLog | 10 +++++ 3rdparty/zlib/README | 6 +-- 3rdparty/zlib/deflate.c | 47 +++++++++++++++++----- 3rdparty/zlib/deflate.h | 35 +++++++++++++++- 3rdparty/zlib/gzguts.h | 8 +--- 3rdparty/zlib/gzlib.c | 12 +++--- 3rdparty/zlib/inflate.c | 2 +- 3rdparty/zlib/inftrees.c | 6 +-- 3rdparty/zlib/inftrees.h | 4 +- 3rdparty/zlib/trees.c | 20 +++++++-- 3rdparty/zlib/{zconf.h => zconf.h.cmakein} | 30 +++++--------- 3rdparty/zlib/zlib.h | 22 +++++----- 3rdparty/zlib/zutil.h | 27 ++----------- 14 files changed, 142 insertions(+), 97 deletions(-) rename 3rdparty/zlib/{zconf.h => zconf.h.cmakein} (96%) diff --git a/3rdparty/zlib/CMakeLists.txt b/3rdparty/zlib/CMakeLists.txt index addd3e5a14..d88ad8f39f 100644 --- a/3rdparty/zlib/CMakeLists.txt +++ b/3rdparty/zlib/CMakeLists.txt @@ -23,9 +23,6 @@ endif() # if(NOT MSVC) check_include_file(unistd.h Z_HAVE_UNISTD_H) - if(Z_HAVE_UNISTD_H) - add_definitions(-DZ_HAVE_UNISTD_H) - endif() endif() if(MSVC) @@ -41,10 +38,13 @@ if(HAVE_OFF64_T) add_definitions(-D_LARGEFILE64_SOURCE=1) endif() -ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}") +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) + +ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") set(ZLIB_PUBLIC_HDRS - zconf.h + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h zlib.h ) set(ZLIB_PRIVATE_HDRS diff --git a/3rdparty/zlib/ChangeLog b/3rdparty/zlib/ChangeLog index 8707988ac1..b801a1031e 100644 --- a/3rdparty/zlib/ChangeLog +++ b/3rdparty/zlib/ChangeLog @@ -1,6 +1,16 @@ ChangeLog file for zlib +Changes in 1.3.1 (22 Jan 2024) +- Reject overflows of zip header fields in minizip +- Fix bug in inflateSync() for data held in bit buffer +- Add LIT_MEM define to use more memory for a small deflate speedup +- Fix decision on the emission of Zip64 end records in minizip +- Add bounds checking to ERR_MSG() macro, used by zError() +- Neutralize zip file traversal attacks in miniunz +- Fix a bug in ZLIB_DEBUG compiles in check_match() +- Various portability and appearance improvements + Changes in 1.3 (18 Aug 2023) - Remove K&R function definitions and zlib2ansi - Fix bug in deflateBound() for level 0 and memLevel 9 diff --git a/3rdparty/zlib/README b/3rdparty/zlib/README index e02fc5aa20..c5f917540b 100644 --- a/3rdparty/zlib/README +++ b/3rdparty/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.3 is a general purpose data compression library. All the code is +zlib 1.3.1 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -31,7 +31,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at https://marknelson.us/posts/1997/01/01/zlib-engine.html . -The changes made in version 1.3 are documented in the file ChangeLog. +The changes made in version 1.3.1 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . @@ -83,7 +83,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2023 Jean-loup Gailly and Mark Adler + (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/3rdparty/zlib/deflate.c b/3rdparty/zlib/deflate.c index bd01175192..012ea8148e 100644 --- a/3rdparty/zlib/deflate.c +++ b/3rdparty/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.3 Copyright 1995-2023 Jean-loup Gailly and Mark Adler "; + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -493,7 +493,7 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, * symbols from which it is being constructed. */ - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); s->pending_buf_size = (ulg)s->lit_bufsize * 4; if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || @@ -503,8 +503,14 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, deflateEnd (strm); return Z_MEM_ERROR; } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else s->sym_buf = s->pending_buf + s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3; +#endif /* We avoid equality with lit_bufsize*3 because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. @@ -720,9 +726,15 @@ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else if (bits < 0 || bits > 16 || s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; +#endif do { put = Buf_size - s->bi_valid; if (put > bits) @@ -1294,7 +1306,7 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { @@ -1305,10 +1317,15 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; @@ -1539,13 +1556,21 @@ local uInt longest_match(deflate_state *s, IPos cur_match) { */ local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); z_error("invalid match"); } if (z_verbose > 1) { diff --git a/3rdparty/zlib/deflate.h b/3rdparty/zlib/deflate.h index 8696791429..300c6ada62 100644 --- a/3rdparty/zlib/deflate.h +++ b/3rdparty/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2018 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -23,6 +23,10 @@ # define GZIP #endif +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + /* =========================================================================== * Internal compression state. */ @@ -217,7 +221,14 @@ typedef struct internal_state { /* Depth of each subtree used as tie breaker for trees of equal frequency */ +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for @@ -239,7 +250,7 @@ typedef struct internal_state { * - I can't count above 4 */ - uInt sym_next; /* running index in sym_buf */ + uInt sym_next; /* running index in symbol buffer */ uInt sym_end; /* symbol table full when sym_next reaches this */ ulg opt_len; /* bit length of current block with optimal trees */ @@ -318,6 +329,25 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, extern const uch ZLIB_INTERNAL _dist_code[]; #endif +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->sym_buf[s->sym_next++] = 0; \ @@ -337,6 +367,7 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } +#endif #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ diff --git a/3rdparty/zlib/gzguts.h b/3rdparty/zlib/gzguts.h index f9375047e8..eba72085bb 100644 --- a/3rdparty/zlib/gzguts.h +++ b/3rdparty/zlib/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -210,9 +210,5 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error); /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else unsigned ZLIB_INTERNAL gz_intmax(void); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/3rdparty/zlib/gzlib.c b/3rdparty/zlib/gzlib.c index 29fc4486fb..983153cc8e 100644 --- a/3rdparty/zlib/gzlib.c +++ b/3rdparty/zlib/gzlib.c @@ -1,5 +1,5 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -563,20 +563,20 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { #endif } -#ifndef INT_MAX /* portably return maximum value for an int (when limits.h presumed not available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ unsigned ZLIB_INTERNAL gz_intmax(void) { - unsigned p, q; - - p = 1; +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; do { q = p; p <<= 1; p++; } while (p > q); return q >> 1; -} #endif +} diff --git a/3rdparty/zlib/inflate.c b/3rdparty/zlib/inflate.c index bce123b363..81545bbbdf 100644 --- a/3rdparty/zlib/inflate.c +++ b/3rdparty/zlib/inflate.c @@ -1388,7 +1388,7 @@ int ZEXPORT inflateSync(z_streamp strm) { /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; - state->hold <<= state->bits & 7; + state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { diff --git a/3rdparty/zlib/inftrees.c b/3rdparty/zlib/inftrees.c index 8a208c2daa..98cfe16445 100644 --- a/3rdparty/zlib/inftrees.c +++ b/3rdparty/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2023 Mark Adler + * Copyright (C) 1995-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.3 Copyright 1995-2023 Mark Adler "; + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -57,7 +57,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/3rdparty/zlib/inftrees.h b/3rdparty/zlib/inftrees.h index a10712d8cb..396f74b5da 100644 --- a/3rdparty/zlib/inftrees.h +++ b/3rdparty/zlib/inftrees.h @@ -41,8 +41,8 @@ typedef struct { examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ diff --git a/3rdparty/zlib/trees.c b/3rdparty/zlib/trees.c index 8dbdc40bac..6a523ef34e 100644 --- a/3rdparty/zlib/trees.c +++ b/3rdparty/zlib/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2021 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -899,14 +899,19 @@ local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ + unsigned sx = 0; /* running index in symbol buffers */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else dist = s->sym_buf[sx++] & 0xff; dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; lc = s->sym_buf[sx++]; +#endif if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); @@ -931,8 +936,12 @@ local void compress_block(deflate_state *s, const ct_data *ltree, } } /* literal or match pair ? */ - /* Check that the overlay between pending_buf and sym_buf is ok: */ + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif } while (sx < s->sym_next); @@ -1082,9 +1091,14 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; +#endif if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; diff --git a/3rdparty/zlib/zconf.h b/3rdparty/zlib/zconf.h.cmakein similarity index 96% rename from 3rdparty/zlib/zconf.h rename to 3rdparty/zlib/zconf.h.cmakein index fb76ffe312..96e9296a9a 100644 --- a/3rdparty/zlib/zconf.h +++ b/3rdparty/zlib/zconf.h.cmakein @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -7,6 +7,8 @@ #ifndef ZCONF_H #define ZCONF_H +#cmakedefine Z_PREFIX +#cmakedefine Z_HAVE_UNISTD_H /* * If you *really* need a unique prefix for all types and library functions, @@ -300,14 +302,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have @@ -478,12 +472,8 @@ typedef uLong FAR uLongf; #endif #ifndef Z_HAVE_UNISTD_H -# ifdef __WATCOMC__ -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_HAVE_UNISTD_H -# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# if defined(__WATCOMC__) || defined(__GO32__) || \ + (defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)) # define Z_HAVE_UNISTD_H # endif #endif @@ -523,12 +513,12 @@ typedef uLong FAR uLongf; #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t +#elif defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +#elif defined(__GO32__) +# define z_off64_t offset_t #else -# if defined(_WIN32) && !defined(__GNUC__) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif +# define z_off64_t z_off_t #endif /* MVS linker does not support external names larger than 8 bytes */ diff --git a/3rdparty/zlib/zlib.h b/3rdparty/zlib/zlib.h index 6b7244f994..8d4b932eaf 100644 --- a/3rdparty/zlib/zlib.h +++ b/3rdparty/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3, August 18th, 2023 + version 1.3.1, January 22nd, 2024 - Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.3" -#define ZLIB_VERNUM 0x1300 +#define ZLIB_VERSION "1.3.1" +#define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 0 +#define ZLIB_VER_REVISION 1 #define ZLIB_VER_SUBREVISION 0 /* @@ -936,10 +936,10 @@ ZEXTERN int ZEXPORT inflateSync(z_streamp strm); inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, @@ -1758,14 +1758,14 @@ ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. + len2. len2 must be non-negative. */ /* ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with - crc32_combine_op(). + crc32_combine_op(). len2 must be non-negative. */ ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); diff --git a/3rdparty/zlib/zutil.h b/3rdparty/zlib/zutil.h index 902a304cc2..48dd7febae 100644 --- a/3rdparty/zlib/zutil.h +++ b/3rdparty/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -56,7 +56,7 @@ typedef unsigned long ulg; extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) @@ -137,17 +137,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#if defined(MACOS) || defined(TARGET_OS_MAC) +#if defined(MACOS) # define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif #endif #ifdef __acorn @@ -170,18 +161,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 19 #endif -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 From bf06e3d09f3cf752def28fd3c86f3d06994fcae8 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Tue, 5 Mar 2024 16:19:45 +0300 Subject: [PATCH 10/56] Merge pull request #25042 from mshabunin:doc-upgrade Documentation transition to fresh Doxygen #25042 * current Doxygen version is 1.10, but we will use 1.9.8 for now due to issue with snippets (https://github.com/doxygen/doxygen/pull/10584) * Doxyfile adapted to new version * MathJax updated to 3.x * `@relates` instructions removed temporarily due to issue in Doxygen (to avoid warnings) * refactored matx.hpp - extracted matx.inl.hpp * opencv_contrib - https://github.com/opencv/opencv_contrib/pull/3638 --- CMakeLists.txt | 2 - doc/CMakeLists.txt | 6 + doc/Doxyfile.in | 73 +- .../js_setup/js_nodejs/js_nodejs.markdown | 2 +- doc/mymath.js | 38 +- .../py_setup_in_windows.markdown | 24 - .../discrete_fourier_transform.markdown | 14 +- .../mat_mask_operations.markdown | 2 +- doc/tutorials/dnn/dnn_OCR/dnn_OCR.markdown | 7 +- .../dnn/dnn_googlenet/dnn_googlenet.markdown | 2 +- .../dnn_text_spotting.markdown | 12 +- .../erosion_dilatation.markdown | 14 +- ...sian_median_blur_bilateral_filter.markdown | 8 +- .../copyMakeBorder/copyMakeBorder.markdown | 16 +- .../imgtrans/filter_2d/filter_2d.markdown | 6 +- .../hough_circle/hough_circle.markdown | 12 +- .../imgtrans/hough_lines/hough_lines.markdown | 12 +- .../laplace_operator.markdown | 14 +- .../sobel_derivatives.markdown | 18 +- .../morph_lines_detection.md | 12 +- .../imgproc/pyramids/pyramids.markdown | 8 +- .../android_dev_intro.markdown | 6 +- .../building_tegra_cuda.markdown | 66 +- .../clojure_dev_intro.markdown | 16 +- .../env_reference/env_reference.markdown | 56 +- .../windows_install/windows_install.markdown | 12 +- modules/core/include/opencv2/core.hpp | 4 - modules/core/include/opencv2/core/cvstd.hpp | 1 - modules/core/include/opencv2/core/matx.hpp | 1262 ++--------------- .../core/include/opencv2/core/matx.inl.hpp | 1115 +++++++++++++++ .../core/include/opencv2/core/persistence.hpp | 40 - .../features2d/include/opencv2/features2d.hpp | 32 +- modules/gapi/doc/00-root.markdown | 14 +- modules/gapi/doc/30-implementation.markdown | 2 +- modules/gapi/include/opencv2/gapi.hpp | 2 +- modules/gapi/include/opencv2/gapi/gcommon.hpp | 4 +- .../gapi/include/opencv2/gapi/gstreaming.hpp | 4 +- .../gapi/include/opencv2/gapi/infer/ov.hpp | 1 - modules/highgui/doc/highgui_qt.cpp | 39 + modules/highgui/include/opencv2/highgui.hpp | 98 +- .../imgcodecs/include/opencv2/imgcodecs.hpp | 3 +- modules/imgproc/doc/colors.markdown | 18 +- modules/imgproc/include/opencv2/imgproc.hpp | 199 ++- modules/java/jar/build.xml.in | 2 +- .../objdetect/include/opencv2/objdetect.hpp | 82 +- modules/photo/include/opencv2/photo.hpp | 19 +- modules/video/include/opencv2/video.hpp | 1 - modules/videoio/doc/videoio_overview.markdown | 18 +- .../ImgTrans/copyMakeBorder_demo.cpp | 4 +- 49 files changed, 1764 insertions(+), 1658 deletions(-) create mode 100644 modules/core/include/opencv2/core/matx.inl.hpp create mode 100644 modules/highgui/doc/highgui_qt.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fe4f7f0bf6..bd01eb3a2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -572,8 +572,6 @@ if(OPENCV_DISABLE_FILESYSTEM_SUPPORT) add_definitions(-DOPENCV_HAVE_FILESYSTEM_SUPPORT=0) endif() -set(OPENCV_MATHJAX_RELPATH "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0" CACHE STRING "URI to a MathJax installation") - # ---------------------------------------------------------------------------- # Get actual OpenCV version number from sources # ---------------------------------------------------------------------------- diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 64a065217c..8a27ac89bc 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -16,6 +16,10 @@ endif() find_package(Doxygen) if(DOXYGEN_FOUND) + if (DOXYGEN_VERSION VERSION_LESS 1.9.8) + message(WARNING "Found doxygen ${DOXYGEN_VERSION}, version 1.9.8 is used for testing, there is + a chance your documentation will look different or have some limitations.") + endif() add_custom_target(doxygen) # not documented modules list @@ -191,6 +195,8 @@ if(DOXYGEN_FOUND) list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tutorial-utils.js") string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_HTML_FILES "${CMAKE_DOXYGEN_HTML_FILES}") + set(OPENCV_MATHJAX_RELPATH "https://cdn.jsdelivr.net/npm/mathjax@3.0.1" CACHE STRING "URI to a MathJax installation") + set(OPENCV_DOCS_DOT_PATH "" CACHE PATH "Doxygen/DOT_PATH value") set(CMAKECONFIG_DOT_PATH "${OPENCV_DOCS_DOT_PATH}") diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index ce207d3e31..5cc7a31ea0 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -3,8 +3,11 @@ PROJECT_NAME = OpenCV PROJECT_NUMBER = @OPENCV_VERSION@ PROJECT_BRIEF = "Open Source Computer Vision" PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/opencv-logo-small.png +#PROJECT_ICON = OUTPUT_DIRECTORY = @CMAKE_DOXYGEN_OUTPUT_PATH@ CREATE_SUBDIRS = YES +CREATE_SUBDIRS_LEVEL = 8 +ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES @@ -26,8 +29,10 @@ STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@/modules @CMAKE_DOXYGEN_INCLUDE_ROOTS STRIP_FROM_INC_PATH = @CMAKE_DOXYGEN_INCLUDE_ROOTS@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO +JAVADOC_BANNER = NO QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO +PYTHON_DOCSTRING = YES INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 4 @@ -43,26 +48,34 @@ OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +OPTIMIZE_OUTPUT_SLICE = NO EXTENSION_MAPPING = MARKDOWN_SUPPORT = YES +TOC_INCLUDE_HEADINGS = 5 +MARKDOWN_ID_STYLE = DOXYGEN AUTOLINK_SUPPORT = YES BUILTIN_STL_SUPPORT = YES CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO SUBGROUPING = YES INLINE_GROUPED_CLASSES = NO INLINE_SIMPLE_STRUCTS = NO TYPEDEF_HIDES_STRUCT = YES LOOKUP_CACHE_SIZE = 0 +NUM_PROC_THREADS = 1 +TIMESTAMP = YES EXTRACT_ALL = YES EXTRACT_PRIVATE = NO +EXTRACT_PRIV_VIRTUAL = NO EXTRACT_PACKAGE = NO EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = NO EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO +RESOLVE_UNNAMED_PARAMS = YES HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO @@ -70,6 +83,8 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_HEADERFILE = YES SHOW_INCLUDE_FILES = YES SHOW_GROUPED_MEMB_INC = YES FORCE_LOCAL_INCLUDES = NO @@ -96,11 +111,16 @@ QUIET = YES WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES +WARN_IF_INCOMPLETE_DOC = YES WARN_NO_PARAMDOC = NO +WARN_IF_UNDOC_ENUM_VAL = NO +WARN_AS_ERROR = NO WARN_FORMAT = "$file:$line: $text" +WARN_LINE_FORMAT = "at line $line of file $file" WARN_LOGFILE = INPUT = @CMAKE_DOXYGEN_INPUT_LIST@ INPUT_ENCODING = UTF-8 +INPUT_FILE_ENCODING = FILE_PATTERNS = RECURSIVE = YES EXCLUDE = @CMAKE_DOXYGEN_EXCLUDE_LIST@ @@ -125,8 +145,11 @@ REFERENCES_LINK_SOURCE = YES SOURCE_TOOLTIPS = YES USE_HTAGS = NO VERBATIM_HEADERS = NO +CLANG_ASSISTED_PARSING = NO +CLANG_ADD_INC_PATHS = YES +CLANG_OPTIONS = +CLANG_DATABASE_PATH = ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = GENERATE_HTML = YES HTML_OUTPUT = html @@ -136,14 +159,19 @@ HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/footer.html HTML_STYLESHEET = HTML_EXTRA_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/stylesheet.css HTML_EXTRA_FILES = @CMAKE_DOXYGEN_HTML_FILES@ +HTML_COLORSTYLE = LIGHT HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 -HTML_TIMESTAMP = YES +HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = NO +HTML_CODE_FOLDING = YES +#HTML_COPY_CLIPBOARD = YES +#HTML_PROJECT_COOKIE = HTML_INDEX_NUM_ENTRIES = 100 GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_FEEDURL = DOCSET_BUNDLE_ID = org.doxygen.Project DOCSET_PUBLISHER_ID = org.doxygen.Publisher DOCSET_PUBLISHER_NAME = Publisher @@ -154,6 +182,7 @@ GENERATE_CHI = NO CHM_INDEX_ENCODING = BINARY_TOC = NO TOC_EXPAND = NO +SITEMAP_URL = GENERATE_QHP = @CMAKE_DOXYGEN_GENERATE_QHP@ QCH_FILE = ../opencv-@OPENCV_VERSION@.qch QHP_NAMESPACE = org.opencv.@OPENCV_VERSION@ @@ -166,15 +195,19 @@ GENERATE_ECLIPSEHELP = NO ECLIPSE_DOC_ID = org.doxygen.Project DISABLE_INDEX = NO GENERATE_TREEVIEW = NO +FULL_SIDEBAR = NO ENUM_VALUES_PER_LINE = 1 TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = YES +OBFUSCATE_EMAILS = YES +HTML_FORMULA_FORMAT = svg FORMULA_FONTSIZE = 14 -FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = USE_MATHJAX = YES -MATHJAX_FORMAT = HTML-CSS +MATHJAX_VERSION = MathJax_3 +MATHJAX_FORMAT = chtml MATHJAX_RELPATH = @OPENCV_MATHJAX_RELPATH@ -MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +MATHJAX_EXTENSIONS = ams MATHJAX_CODEFILE = @CMAKE_CURRENT_SOURCE_DIR@/mymath.js SEARCHENGINE = YES SERVER_BASED_SEARCH = NO @@ -187,18 +220,20 @@ GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex +LATEX_MAKEINDEX_CMD = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4 EXTRA_PACKAGES = mymath LATEX_HEADER = LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain +LATEX_EMOJI_DIRECTORY = GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO @@ -208,13 +243,18 @@ RTF_EXTENSIONS_FILE = GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 +MAN_SUBDIR = MAN_LINKS = NO GENERATE_XML = NO XML_OUTPUT = xml XML_PROGRAMLISTING = YES +XML_NS_MEMB_FILE_SCOPE = NO GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook GENERATE_AUTOGEN_DEF = NO +GENERATE_SQLITE3 = NO +SQLITE3_OUTPUT = sqlite3 +SQLITE3_RECREATE_DB = YES GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES @@ -272,19 +312,20 @@ GENERATE_TAGFILE = @CMAKE_DOXYGEN_OUTPUT_PATH@/html/opencv.tag ALLEXTERNALS = NO EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -CLASS_DIAGRAMS = YES -DIA_PATH = HIDE_UNDOC_RELATIONS = NO HAVE_DOT = @CMAKECONFIG_HAVE_DOT@ DOT_NUM_THREADS = 0 -DOT_FONTNAME = Helvetica -DOT_FONTSIZE = 10 DOT_FONTPATH = +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" CLASS_GRAPH = YES COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES +GROUP_GRAPHS = NO UML_LOOK = YES UML_LIMIT_NUM_FIELDS = 10 +DOT_UML_DETAILS = NO +DOT_WRAP_THRESHOLD = 17 TEMPLATE_RELATIONS = YES INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES @@ -292,15 +333,19 @@ CALL_GRAPH = YES CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES +DIR_GRAPH_MAX_DEPTH = 1 DOT_IMAGE_FORMAT = @CMAKECONFIG_DOT_IMAGE_FORMAT@ INTERACTIVE_SVG = @CMAKECONFIG_INTERACTIVE_SVG@ DOT_PATH = @CMAKECONFIG_DOT_PATH@ DOTFILE_DIRS = -MSCFILE_DIRS = DIAFILE_DIRS = -DOT_GRAPH_MAX_NODES = 50 +PLANTUML_JAR_PATH = +PLANTUML_CFG_FILE = +PLANTUML_INCLUDE_PATH = +DOT_GRAPH_MAX_NODES = 250 MAX_DOT_GRAPH_DEPTH = 0 -DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES +MSCGEN_TOOL = +MSCFILE_DIRS = diff --git a/doc/js_tutorials/js_setup/js_nodejs/js_nodejs.markdown b/doc/js_tutorials/js_setup/js_nodejs/js_nodejs.markdown index a9d8ff5cad..b0d1a1d169 100644 --- a/doc/js_tutorials/js_setup/js_nodejs/js_nodejs.markdown +++ b/doc/js_tutorials/js_setup/js_nodejs/js_nodejs.markdown @@ -336,7 +336,7 @@ function installDOM(){ - Make sure the files `aarcascade_frontalface_default.xml` and `haarcascade_eye.xml` are present in project's directory. They can be obtained from [OpenCV sources](https://github.com/opencv/opencv/tree/4.x/data/haarcascades). - Make sure a sample image file `lena.jpg` exists in project's directory. It should display people's faces for this example to make sense. The following image is known to work: -![image](lena.jpg) +![image](js_assets/lena.jpg) The following command should generate the file `output3.jpg`: diff --git a/doc/mymath.js b/doc/mymath.js index ffa2b11d3d..1ab480b5a4 100644 --- a/doc/mymath.js +++ b/doc/mymath.js @@ -1,22 +1,20 @@ // diff --git a/doc/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.markdown b/doc/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.markdown index 1cefb01d5c..c30f80dd18 100644 --- a/doc/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.markdown +++ b/doc/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.markdown @@ -79,62 +79,38 @@ Building OpenCV from source -# Extract it to a folder, opencv and create a new folder build in it. -# Open CMake-gui (*Start \> All Programs \> CMake-gui*) -# Fill the fields as follows (see the image below): - -# Click on **Browse Source...** and locate the opencv folder. - -# Click on **Browse Build...** and locate the build folder we created. - -# Click on **Configure**. - ![image](images/Capture1.jpg) - -# It will open a new window to select the compiler. Choose appropriate compiler (here, Visual Studio 11) and click **Finish**. - ![image](images/Capture2.png) - -# Wait until analysis is finished. - -# You will see all the fields are marked in red. Click on the **WITH** field to expand it. It decides what extra features you need. So mark appropriate fields. See the below image: - ![image](images/Capture3.png) - -# Now click on **BUILD** field to expand it. First few fields configure the build method. See the below image: - ![image](images/Capture5.png) - -# Remaining fields specify what modules are to be built. Since GPU modules are not yet supported by OpenCV-Python, you can completely avoid it to save time (But if you work with them, keep it there). See the image below: - ![image](images/Capture6.png) - -# Now click on **ENABLE** field to expand it. Make sure **ENABLE_SOLUTION_FOLDERS** is unchecked (Solution folders are not supported by Visual Studio Express edition). See the image below: - ![image](images/Capture7.png) - -# Also make sure that in the **PYTHON** field, everything is filled. (Ignore PYTHON_DEBUG_LIBRARY). See image below: - ![image](images/Capture80.png) - -# Finally click the **Generate** button. - -# Now go to our **opencv/build** folder. There you will find **OpenCV.sln** file. Open it with Visual Studio. - -# Check build mode as **Release** instead of **Debug**. - -# In the solution explorer, right-click on the **Solution** (or **ALL_BUILD**) and build it. It will take some time to finish. - -# Again, right-click on **INSTALL** and build it. Now OpenCV-Python will be installed. - ![image](images/Capture8.png) - -# Open Python IDLE and enter 'import cv2 as cv'. If no error, it is installed correctly. @note We have installed with no other support like TBB, Eigen, Qt, Documentation etc. It would be diff --git a/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.markdown b/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.markdown index 9c11ec3b2e..adb1c6fb0e 100644 --- a/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.markdown +++ b/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.markdown @@ -87,7 +87,7 @@ Fourier Transform too needs to be of a discrete type resulting in a Discrete Fou (*DFT*). You'll want to use this whenever you need to determine the structure of an image from a geometrical point of view. Here are the steps to follow (in case of a gray scale input image *I*): -#### Expand the image to an optimal size +### Expand the image to an optimal size The performance of a DFT is dependent of the image size. It tends to be the fastest for image sizes that are multiple of the numbers two, three and @@ -108,7 +108,7 @@ image (the appended pixels are initialized with zero): @snippet python/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.py expand @end_toggle -#### Make place for both the complex and the real values +### Make place for both the complex and the real values The result of a Fourier Transform is complex. This implies that for each image value the result is two image values (one per @@ -128,7 +128,7 @@ input image to this type and expand it with another channel to hold the complex @snippet python/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.py complex_and_real @end_toggle -#### Make the Discrete Fourier Transform +### Make the Discrete Fourier Transform It's possible an in-place calculation (same input as output): @@ -144,7 +144,7 @@ output): @snippet python/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.py dft @end_toggle -#### Transform the real and complex values to magnitude +### Transform the real and complex values to magnitude A complex number has a real (*Re*) and a complex (imaginary - *Im*) part. The results of a DFT are complex numbers. The magnitude of a DFT is: @@ -165,7 +165,7 @@ Translated to OpenCV code: @snippet python/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.py magnitude @end_toggle -#### Switch to a logarithmic scale +### Switch to a logarithmic scale It turns out that the dynamic range of the Fourier coefficients is too large to be displayed on the screen. We have some small and some high changing values that we can't observe like this. Therefore the high values will all turn out as @@ -188,7 +188,7 @@ Translated to OpenCV code: @snippet python/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.py log @end_toggle -#### Crop and rearrange +### Crop and rearrange Remember, that at the first step, we expanded the image? Well, it's time to throw away the newly introduced values. For visualization purposes we may also rearrange the quadrants of the result, so that the origin (zero, zero) corresponds with the image center. @@ -205,7 +205,7 @@ quadrants of the result, so that the origin (zero, zero) corresponds with the im @snippet python/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.py crop_rearrange @end_toggle -#### Normalize +### Normalize This is done again for visualization purposes. We now have the magnitudes, however this are still out of our image display range of zero to one. We normalize our values to this range using the @ref cv::normalize() function. diff --git a/doc/tutorials/core/mat-mask-operations/mat_mask_operations.markdown b/doc/tutorials/core/mat-mask-operations/mat_mask_operations.markdown index 8958155961..e401e61012 100644 --- a/doc/tutorials/core/mat-mask-operations/mat_mask_operations.markdown +++ b/doc/tutorials/core/mat-mask-operations/mat_mask_operations.markdown @@ -73,7 +73,7 @@ Here's a function that will do this: @snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp basic_method At first we make sure that the input images data is in unsigned char format. For this we use the -@ref cv::CV_Assert function that throws an error when the expression inside it is false. +@ref CV_Assert function (macro) that throws an error when the expression inside it is false. @snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp 8_bit @end_toggle diff --git a/doc/tutorials/dnn/dnn_OCR/dnn_OCR.markdown b/doc/tutorials/dnn/dnn_OCR/dnn_OCR.markdown index f7bdd9512d..ae4deb01de 100644 --- a/doc/tutorials/dnn/dnn_OCR/dnn_OCR.markdown +++ b/doc/tutorials/dnn/dnn_OCR/dnn_OCR.markdown @@ -22,7 +22,7 @@ In this tutorial, we first introduce how to obtain the custom OCR model, then ho After completing the model training, please use [transform_to_onnx.py](https://github.com/zihaomu/deep-text-recognition-benchmark/blob/master/transform_to_onnx.py) to convert the model into onnx format. -#### Execute in webcam +### Execute in webcam The Python version example code can be found at [here](https://github.com/opencv/opencv/blob/4.x/samples/dnn/text_detection.py). Example: @@ -44,9 +44,10 @@ Their performance at different text recognition datasets is shown in the table b | CRNN_VGG-BiLSTM-CTC | 82.63 | 82.07 | 92.96 | 88.867 | 66.28 | 71.01 | 62.37 | 78.03 | 8.45 | | ResNet-CTC | 84.00 | 84.08 | 92.39 | 88.96 | 67.74 | 74.73 | 67.60 | 79.93 | 44.28 | -The performance of the text recognition model were tesred on OpenCV DNN, and does not include the text detection model. +The performance of the text recognition model were tested on OpenCV DNN, and does not include the text detection model. + +### Model selection suggestion -#### Model selection suggestion: The input of text recognition model is the output of the text detection model, which causes the performance of text detection to greatly affect the performance of text recognition. DenseNet_CTC has the smallest parameters and best FPS, and it is suitable for edge devices, which are very sensitive to the cost of calculation. If you have limited computing resources and want to achieve better accuracy, VGG_CTC is a good choice. diff --git a/doc/tutorials/dnn/dnn_googlenet/dnn_googlenet.markdown b/doc/tutorials/dnn/dnn_googlenet/dnn_googlenet.markdown index 972842b4f5..635961b7e4 100644 --- a/doc/tutorials/dnn/dnn_googlenet/dnn_googlenet.markdown +++ b/doc/tutorials/dnn/dnn_googlenet/dnn_googlenet.markdown @@ -17,7 +17,7 @@ In this tutorial you will learn how to use opencv_dnn module for image classific GoogLeNet trained network from [Caffe model zoo](http://caffe.berkeleyvision.org/model_zoo.html). We will demonstrate results of this example on the following picture. -![Buran space shuttle](images/space_shuttle.jpg) +![Buran space shuttle](dnn/images/space_shuttle.jpg) Source Code ----------- diff --git a/doc/tutorials/dnn/dnn_text_spotting/dnn_text_spotting.markdown b/doc/tutorials/dnn/dnn_text_spotting/dnn_text_spotting.markdown index b6f4e120fb..b675c1fd29 100644 --- a/doc/tutorials/dnn/dnn_text_spotting/dnn_text_spotting.markdown +++ b/doc/tutorials/dnn/dnn_text_spotting/dnn_text_spotting.markdown @@ -14,7 +14,7 @@ In this tutorial, we will introduce the APIs for TextRecognitionModel and TextDetectionModel in detail. --- -#### TextRecognitionModel: +### TextRecognitionModel In the current version, @ref cv::dnn::TextRecognitionModel only supports CNN+RNN+CTC based algorithms, and the greedy decoding method for CTC is provided. @@ -38,7 +38,7 @@ Before recognition, you should `setVocabulary` and `setDecodeType`. --- -#### TextDetectionModel: +### TextDetectionModel @ref cv::dnn::TextDetectionModel API provides these methods for text detection: - cv::dnn::TextDetectionModel::detect() returns the results in std::vector> (4-points quadrangles) @@ -60,7 +60,7 @@ We encourage you to add new algorithms to these APIs. ## Pretrained Models -#### TextRecognitionModel: +### TextRecognitionModel ``` crnn.onnx: @@ -92,7 +92,7 @@ More models can be found in [here](https://drive.google.com/drive/folders/1cTbQ3 which are taken from [clovaai](https://github.com/clovaai/deep-text-recognition-benchmark). You can train more models by [CRNN](https://github.com/meijieru/crnn.pytorch), and convert models by `torch.onnx.export`. -#### TextDetectionModel: +### TextDetectionModel ``` - DB_IC15_resnet50.onnx: @@ -297,7 +297,7 @@ For more information, please refer to: - [samples/dnn/text_detection.cpp](https://github.com/opencv/opencv/blob/4.x/samples/dnn/text_detection.cpp) - [samples/dnn/scene_text_spotting.cpp](https://github.com/opencv/opencv/blob/4.x/samples/dnn/scene_text_spotting.cpp) -#### Test with an image +### Test with an image Examples: ```bash example_dnn_scene_text_recognition -mp=path/to/crnn_cs.onnx -i=path/to/an/image -rgb=1 -vp=/path/to/alphabet_94.txt @@ -306,7 +306,7 @@ example_dnn_scene_text_spotting -dmp=path/to/DB_IC15_resnet50.onnx -rmp=path/to/ example_dnn_text_detection -dmp=path/to/EAST.pb -rmp=path/to/crnn_cs.onnx -i=path/to/an/image -rgb=1 -vp=path/to/alphabet_94.txt ``` -#### Test on public datasets +### Test on public datasets Text Recognition: The download link for testing images can be found in the **Images for Testing** diff --git a/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown b/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown index a9826c54d8..36829683d5 100644 --- a/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown +++ b/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown @@ -111,7 +111,7 @@ called and it will update the output image based on the current trackbar values. Let's analyze these two functions: -#### The erosion function +### The erosion function (CPP) @snippet cpp/tutorial_code/ImgProc/Morphology_1.cpp erosion @@ -135,7 +135,7 @@ receives three arguments: That is all. We are ready to perform the erosion of our image. -#### The dilation function +### The dilation function (CPP) The code is below. As you can see, it is completely similar to the snippet of code for **erosion**. Here we also have the option of defining our kernel, its anchor point and the size of the operator @@ -175,7 +175,7 @@ In short we The action and state changed listeners added call at the end the `update` method which updates the image based on the current slider values. So every time we move any slider, the `update` method is triggered. -#### Updating the image +### Updating the image (Java) To update the image we used the following implementation: @@ -190,7 +190,7 @@ In other words we Let's analyze the `erode` and `dilate` methods: -#### The erosion method +### The erosion method (Java) @snippet java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java erosion @@ -213,7 +213,7 @@ receives three arguments: That is all. We are ready to perform the erosion of our image. -#### The dilation function +### The dilation function (Java) The code is below. As you can see, it is completely similar to the snippet of code for **erosion**. Here we also have the option of defining our kernel, its anchor point and the size of the operator @@ -240,7 +240,7 @@ called and it will update the output image based on the current trackbar values. Let's analyze these two functions: -#### The erosion function +### The erosion function (Python) @snippet python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py erosion @@ -262,7 +262,7 @@ specified, it is assumed to be in the center. That is all. We are ready to perform the erosion of our image. -#### The dilation function +### The dilation function (Python) The code is below. As you can see, it is completely similar to the snippet of code for **erosion**. Here we also have the option of defining our kernel, its anchor point and the size of the operator diff --git a/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.markdown b/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.markdown index 7cdbcaf823..2023de809b 100644 --- a/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.markdown +++ b/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.markdown @@ -133,7 +133,7 @@ Explanation Let's check the OpenCV functions that involve only the smoothing procedure, since the rest is already known by now. -#### Normalized Block Filter: +### Normalized Block Filter: - OpenCV offers the function **blur()** to perform smoothing with this filter. We specify 4 arguments (more details, check the Reference): @@ -157,7 +157,7 @@ already known by now. @snippet samples/python/tutorial_code/imgProc/Smoothing/smoothing.py blur @end_toggle -#### Gaussian Filter: +### Gaussian Filter: - It is performed by the function **GaussianBlur()** : Here we use 4 arguments (more details, check the OpenCV reference): @@ -183,7 +183,7 @@ already known by now. @snippet samples/python/tutorial_code/imgProc/Smoothing/smoothing.py gaussianblur @end_toggle -#### Median Filter: +### Median Filter: - This filter is provided by the **medianBlur()** function: We use three arguments: @@ -203,7 +203,7 @@ already known by now. @snippet samples/python/tutorial_code/imgProc/Smoothing/smoothing.py medianblur @end_toggle -#### Bilateral Filter +### Bilateral Filter - Provided by OpenCV function **bilateralFilter()** We use 5 arguments: diff --git a/doc/tutorials/imgproc/imgtrans/copyMakeBorder/copyMakeBorder.markdown b/doc/tutorials/imgproc/imgtrans/copyMakeBorder/copyMakeBorder.markdown index 7a1efcdac2..1741b1e19a 100644 --- a/doc/tutorials/imgproc/imgtrans/copyMakeBorder/copyMakeBorder.markdown +++ b/doc/tutorials/imgproc/imgtrans/copyMakeBorder/copyMakeBorder.markdown @@ -78,7 +78,7 @@ You can also download it from Explanation ----------- -#### Declare the variables +### Declare the variables First we declare the variables we are going to use: @@ -97,7 +97,7 @@ First we declare the variables we are going to use: Especial attention deserves the variable *rng* which is a random number generator. We use it to generate the random border color, as we will see soon. -#### Load an image +### Load an image As usual we load our source image *src*: @@ -113,7 +113,7 @@ As usual we load our source image *src*: @snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py load @end_toggle -#### Create a window +### Create a window After giving a short intro of how to use the program, we create a window: @@ -129,7 +129,7 @@ After giving a short intro of how to use the program, we create a window: @snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py create_window @end_toggle -#### Initialize arguments +### Initialize arguments Now we initialize the argument that defines the size of the borders (*top*, *bottom*, *left* and *right*). We give them a value of 5% the size of *src*. @@ -146,7 +146,7 @@ Now we initialize the argument that defines the size of the borders (*top*, *bot @snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py init_arguments @end_toggle -#### Loop +### Loop The program runs in an infinite loop while the key **ESC** isn't pressed. If the user presses '**c**' or '**r**', the *borderType* variable @@ -164,7 +164,7 @@ takes the value of *BORDER_CONSTANT* or *BORDER_REPLICATE* respectively: @snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py check_keypress @end_toggle -#### Random color +### Random color In each iteration (after 0.5 seconds), the random border color (*value*) is updated... @@ -182,7 +182,7 @@ In each iteration (after 0.5 seconds), the random border color (*value*) is upda This value is a set of three numbers picked randomly in the range \f$[0,255]\f$. -#### Form a border around the image +### Form a border around the image Finally, we call the function **copyMakeBorder()** to apply the respective padding: @@ -209,7 +209,7 @@ Finally, we call the function **copyMakeBorder()** to apply the respective paddi -# *value*: If *borderType* is *BORDER_CONSTANT*, this is the value used to fill the border pixels. -#### Display the results +### Display the results We display our output image in the image created previously diff --git a/doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.markdown b/doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.markdown index e93a26d8d0..f4dc885b41 100644 --- a/doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.markdown +++ b/doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.markdown @@ -94,7 +94,7 @@ You can also download it from Explanation ----------- -#### Load an image +### Load an image @add_toggle_cpp @snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp load @@ -108,7 +108,7 @@ Explanation @snippet python/tutorial_code/ImgTrans/Filter2D/filter2D.py load @end_toggle -#### Initialize the arguments +### Initialize the arguments @add_toggle_cpp @snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp init_arguments @@ -122,7 +122,7 @@ Explanation @snippet python/tutorial_code/ImgTrans/Filter2D/filter2D.py init_arguments @end_toggle -##### Loop +### Loop Perform an infinite loop updating the kernel size and applying our linear filter to the input image. Let's analyze that more in detail: diff --git a/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.markdown b/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.markdown index 15b01a4d77..cbdf30d285 100644 --- a/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.markdown +++ b/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.markdown @@ -74,7 +74,7 @@ Explanation The image we used can be found [here](https://raw.githubusercontent.com/opencv/opencv/4.x/samples/data/smarties.png) -#### Load an image: +### Load an image: @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp load @@ -88,7 +88,7 @@ The image we used can be found [here](https://raw.githubusercontent.com/opencv/o @snippet samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py load @end_toggle -#### Convert it to grayscale: +### Convert it to grayscale: @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp convert_to_gray @@ -102,7 +102,7 @@ The image we used can be found [here](https://raw.githubusercontent.com/opencv/o @snippet samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py convert_to_gray @end_toggle -#### Apply a Median blur to reduce noise and avoid false circle detection: +### Apply a Median blur to reduce noise and avoid false circle detection: @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp reduce_noise @@ -116,7 +116,7 @@ The image we used can be found [here](https://raw.githubusercontent.com/opencv/o @snippet samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py reduce_noise @end_toggle -#### Proceed to apply Hough Circle Transform: +### Proceed to apply Hough Circle Transform: @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp houghcircles @@ -144,7 +144,7 @@ The image we used can be found [here](https://raw.githubusercontent.com/opencv/o - *min_radius = 0*: Minimum radius to be detected. If unknown, put zero as default. - *max_radius = 0*: Maximum radius to be detected. If unknown, put zero as default. -#### Draw the detected circles: +### Draw the detected circles: @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp draw @@ -160,7 +160,7 @@ The image we used can be found [here](https://raw.githubusercontent.com/opencv/o You can see that we will draw the circle(s) on red and the center(s) with a small green dot -#### Display the detected circle(s) and wait for the user to exit the program: +### Display the detected circle(s) and wait for the user to exit the program: @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp display diff --git a/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.markdown b/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.markdown index 22295c1829..ca4d9b9a17 100644 --- a/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.markdown +++ b/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.markdown @@ -129,7 +129,7 @@ The sample code that we will explain can be downloaded from Explanation ----------- -#### Load an image: +### Load an image: @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp load @@ -143,7 +143,7 @@ Explanation @snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py load @end_toggle -#### Detect the edges of the image by using a Canny detector: +### Detect the edges of the image by using a Canny detector: @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp edge_detection @@ -160,7 +160,7 @@ Explanation Now we will apply the Hough Line Transform. We will explain how to use both OpenCV functions available for this purpose. -#### Standard Hough Line Transform: +### Standard Hough Line Transform: First, you apply the Transform: @add_toggle_cpp @@ -199,7 +199,7 @@ And then you display the result by drawing the lines. @snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py draw_lines @end_toggle -#### Probabilistic Hough Line Transform +### Probabilistic Hough Line Transform First you apply the transform: @add_toggle_cpp @@ -242,7 +242,7 @@ And then you display the result by drawing the lines. @snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py draw_lines_p @end_toggle -#### Display the original image and the detected lines: +### Display the original image and the detected lines: @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp imshow @@ -256,7 +256,7 @@ And then you display the result by drawing the lines. @snippet samples/python/tutorial_code/ImgTrans/HoughLine/hough_lines.py imshow @end_toggle -#### Wait until the user exits the program +### Wait until the user exits the program @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgTrans/houghlines.cpp exit diff --git a/doc/tutorials/imgproc/imgtrans/laplace_operator/laplace_operator.markdown b/doc/tutorials/imgproc/imgtrans/laplace_operator/laplace_operator.markdown index 272456c776..33e375a821 100644 --- a/doc/tutorials/imgproc/imgtrans/laplace_operator/laplace_operator.markdown +++ b/doc/tutorials/imgproc/imgtrans/laplace_operator/laplace_operator.markdown @@ -81,7 +81,7 @@ Code Explanation ----------- -#### Declare variables +### Declare variables @add_toggle_cpp @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp variables @@ -95,7 +95,7 @@ Explanation @snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py variables @end_toggle -#### Load source image +### Load source image @add_toggle_cpp @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp load @@ -109,7 +109,7 @@ Explanation @snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py load @end_toggle -#### Reduce noise +### Reduce noise @add_toggle_cpp @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp reduce_noise @@ -123,7 +123,7 @@ Explanation @snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py reduce_noise @end_toggle -#### Grayscale +### Grayscale @add_toggle_cpp @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp convert_to_gray @@ -137,7 +137,7 @@ Explanation @snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py convert_to_gray @end_toggle -#### Laplacian operator +### Laplacian operator @add_toggle_cpp @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp laplacian @@ -160,7 +160,7 @@ Explanation this example. - *scale*, *delta* and *BORDER_DEFAULT*: We leave them as default values. -#### Convert output to a *CV_8U* image +### Convert output to a *CV_8U* image @add_toggle_cpp @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp convert @@ -174,7 +174,7 @@ Explanation @snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py convert @end_toggle -#### Display the result +### Display the result @add_toggle_cpp @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp display diff --git a/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.markdown b/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.markdown index 1e5a12356f..70b7ef89c9 100644 --- a/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.markdown +++ b/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.markdown @@ -58,7 +58,7 @@ Theory gradient of an image intensity function. -# The Sobel Operator combines Gaussian smoothing and differentiation. -#### Formulation +### Formulation Assuming that the image to be operated is \f$I\f$: @@ -140,23 +140,23 @@ You can also download it from Explanation ----------- -#### Declare variables +### Declare variables @snippet cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp variables -#### Load source image +### Load source image @snippet cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp load -#### Reduce noise +### Reduce noise @snippet cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp reduce_noise -#### Grayscale +### Grayscale @snippet cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp convert_to_gray -#### Sobel Operator +### Sobel Operator @snippet cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp sobel @@ -174,18 +174,18 @@ Explanation Notice that to calculate the gradient in *x* direction we use: \f$x_{order}= 1\f$ and \f$y_{order} = 0\f$. We do analogously for the *y* direction. -#### Convert output to a CV_8U image +### Convert output to a CV_8U image @snippet cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp convert -#### Gradient +### Gradient @snippet cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp blend We try to approximate the *gradient* by adding both directional gradients (note that this is not an exact calculation at all! but it is good for our purposes). -#### Show results +### Show results @snippet cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp display diff --git a/doc/tutorials/imgproc/morph_lines_detection/morph_lines_detection.md b/doc/tutorials/imgproc/morph_lines_detection/morph_lines_detection.md index 2d0f5de98d..2636d85fea 100644 --- a/doc/tutorials/imgproc/morph_lines_detection/morph_lines_detection.md +++ b/doc/tutorials/imgproc/morph_lines_detection/morph_lines_detection.md @@ -80,7 +80,7 @@ Explanation / Result Get image from [here](https://raw.githubusercontent.com/opencv/opencv/4.x/doc/tutorials/imgproc/morph_lines_detection/images/src.png) . -#### Load Image +### Load Image @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgProc/morph_lines_detection/Morphology_3.cpp load_image @@ -96,7 +96,7 @@ Get image from [here](https://raw.githubusercontent.com/opencv/opencv/4.x/doc/tu ![](images/src.png) -#### Grayscale +### Grayscale @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgProc/morph_lines_detection/Morphology_3.cpp gray @@ -112,7 +112,7 @@ Get image from [here](https://raw.githubusercontent.com/opencv/opencv/4.x/doc/tu ![](images/gray.png) -#### Grayscale to Binary image +### Grayscale to Binary image @add_toggle_cpp @snippet samples/cpp/tutorial_code/ImgProc/morph_lines_detection/Morphology_3.cpp bin @@ -128,7 +128,7 @@ Get image from [here](https://raw.githubusercontent.com/opencv/opencv/4.x/doc/tu ![](images/binary.png) -#### Output images +### Output images Now we are ready to apply morphological operations in order to extract the horizontal and vertical lines and as a consequence to separate the music notes from the music sheet, but first let's initialize the output images that we will use for that reason: @@ -144,7 +144,7 @@ Now we are ready to apply morphological operations in order to extract the horiz @snippet samples/python/tutorial_code/imgProc/morph_lines_detection/morph_lines_detection.py init @end_toggle -#### Structure elements +### Structure elements As we specified in the theory in order to extract the object that we desire, we need to create the corresponding structure element. Since we want to extract the horizontal lines, a corresponding structure element for that purpose will have the following shape: ![](images/linear_horiz.png) @@ -182,7 +182,7 @@ and again this is represented as follows: ![](images/vert.png) -#### Refine edges / Result +### Refine edges / Result As you can see we are almost there. However, at that point you will notice that the edges of the notes are a bit rough. For that reason we need to refine the edges in order to obtain a smoother result: diff --git a/doc/tutorials/imgproc/pyramids/pyramids.markdown b/doc/tutorials/imgproc/pyramids/pyramids.markdown index 8a6b9ce267..84887fd13b 100644 --- a/doc/tutorials/imgproc/pyramids/pyramids.markdown +++ b/doc/tutorials/imgproc/pyramids/pyramids.markdown @@ -43,7 +43,7 @@ Theory pyramid (with less resolution) - In this tutorial we'll use the *Gaussian pyramid*. -#### Gaussian Pyramid +### Gaussian Pyramid - Imagine the pyramid as a set of layers in which the higher the layer, the smaller the size. @@ -100,7 +100,7 @@ Explanation Let's check the general structure of the program: -#### Load an image +### Load an image @add_toggle_cpp @snippet cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp load @@ -114,7 +114,7 @@ Let's check the general structure of the program: @snippet python/tutorial_code/imgProc/Pyramids/pyramids.py load @end_toggle -#### Create window +### Create window @add_toggle_cpp @snippet cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp show_image @@ -128,7 +128,7 @@ Let's check the general structure of the program: @snippet python/tutorial_code/imgProc/Pyramids/pyramids.py show_image @end_toggle -#### Loop +### Loop @add_toggle_cpp @snippet cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp loop diff --git a/doc/tutorials/introduction/android_binary_package/android_dev_intro.markdown b/doc/tutorials/introduction/android_binary_package/android_dev_intro.markdown index ce247279fd..106278bb95 100644 --- a/doc/tutorials/introduction/android_binary_package/android_dev_intro.markdown +++ b/doc/tutorials/introduction/android_binary_package/android_dev_intro.markdown @@ -85,7 +85,7 @@ Setup Device for Testing and Debugging Usually the recipe above works as expected, but in some cases there are additional actions that must be performed. In this section we'll cover some cases. -#### Windows host computer +### Windows host computer If you have Windows 10 or higher then you don't have to do additional actions to connect a phone and run samples on it. However, earlier Windows versions require a longer procedure: @@ -163,7 +163,7 @@ a phone and run samples on it. However, earlier Windows versions require a longe -# Now, in Eclipse go Run -\> Run/Debug to run your application in regular or debugging mode. Device Chooser will let you choose among the devices. -#### Linux host computer +### Linux host computer While the latest Ubuntu versions work well with connected Android devices, there can be issues on older versions. However, most of them can be fixed easily. You have to create a new **/etc/udev/rules.d/51-android.rules** configuration file that contains @@ -184,7 +184,7 @@ R58MB40Q3VP device savuor@rostislav-laptop:~/Android/Sdk/platform-tools$ ``` -#### Mac OS host computer +### Mac OS host computer No actions are required, just connect your device via USB and run adb devices to check connection. diff --git a/doc/tutorials/introduction/building_tegra_cuda/building_tegra_cuda.markdown b/doc/tutorials/introduction/building_tegra_cuda/building_tegra_cuda.markdown index 753b3efe58..e1c129f0e1 100644 --- a/doc/tutorials/introduction/building_tegra_cuda/building_tegra_cuda.markdown +++ b/doc/tutorials/introduction/building_tegra_cuda/building_tegra_cuda.markdown @@ -15,7 +15,7 @@ This tutorial is deprecated. @tableofcontents OpenCV with CUDA for Tegra -========================== +-------------------------- This document is a basic guide to building the OpenCV libraries with CUDA support for use in the Tegra environment. It covers the basic elements of building the version 3.1.0 libraries from source code for three (3) different types of platforms: @@ -36,7 +36,7 @@ The OpenCV build system supports native compilation for all the supported platfo At the present time, this document focuses only on native compilation. Getting the Source Code {#tutorial_building_tegra_cuda_getting_the_code} -======================= +----------------------- There are two (2) ways to get the OpenCV source code: @@ -45,8 +45,7 @@ There are two (2) ways to get the OpenCV source code: For this guide, the focus is on using the git repositories. This is because the 3.1.0 version of OpenCV will not build with CUDA 8.0 without applying a few small upstream changes from the git repository. -OpenCV ------- +### OpenCV Start with the `opencv` repository: @@ -93,8 +92,7 @@ You should see output similar to: At this point, the `opencv` repository is ready for building. -OpenCV Extra ------------- +### OpenCV Extra The `opencv_extra` repository contains extra data for the OpenCV library, including the data files used by the tests and demos. It must be cloned separately: @@ -111,12 +109,11 @@ You may opt to not fetch this repository if you do not plan on running the tests __Note:__ If you plan to run the tests, some tests expect the data to be present and will fail without it. Preparation and Prerequisites {#tutorial_building_tegra_cuda_preparation} -============================= +----------------------------- To build OpenCV, you need a directory to create the configuration and build the libraries. You also need a number of 3rd-party libraries upon which OpenCV depends. -Prerequisites for Ubuntu Linux ------------------------------- +### Prerequisites for Ubuntu Linux These are the basic requirements for building OpenCV for Tegra on Linux: @@ -186,8 +183,7 @@ The commands that will do this: Once all the necessary packages are installed, you can configure the build. -Preparing the Build Area ------------------------- +### Preparing the Build Area Software projects that use the CMake system for configuring their builds expect the actual builds to be done outside of the source tree itself. For configuring and building OpenCV, create a directory called "build" in the same base directory into which you cloned the git repositories: @@ -197,7 +193,7 @@ Software projects that use the CMake system for configuring their builds expect You are now ready to configure and build OpenCV. Configuring OpenCV for Building {#tutorial_building_tegra_cuda_configuring} -=============================== +------------------------------- The CMake configuration options given below for the different platforms are targeted towards the functionality needed for Tegra. They are based on the original configuration options used for building OpenCV 2.4.13. @@ -209,8 +205,7 @@ For the Linux-based platforms, the shown value for the `CMAKE_INSTALL_PREFIX` pa In each of the `cmake` invocations below, the last parameter, `OPENCV_TEST_DATA_PATH`, tells the build system where to find the test-data that is provided by the `opencv_extra` repository. When this is included, a `make install` installs this test-data alongside the libraries and example code, and a `make test` automatically provides this path to the tests that have to load data from it. If you did not clone the `opencv_extra` repository, do not include this parameter. -Vibrante V4L Configuration --------------------------- +### Vibrante V4L Configuration Supported platform: Drive PX 2 @@ -251,8 +246,7 @@ The configuration provided above builds the Python bindings for Python 2 (but no -DBUILD_opencv_python2=OFF -Jetson L4T Configuration ------------------------- +### Jetson L4T Configuration Supported platforms: @@ -261,7 +255,7 @@ Supported platforms: Configuration is slightly different for the Jetson TK1 and the Jetson TX1 systems. -### Jetson TK1 +#### Jetson TK1 $ cmake \ -DCMAKE_BUILD_TYPE=Release \ @@ -299,7 +293,7 @@ Configuration is slightly different for the Jetson TK1 and the Jetson TX1 system __Note:__ This uses CUDA 6.5, not 8.0. -### Jetson TX1 +#### Jetson TX1 $ cmake \ -DCMAKE_BUILD_TYPE=Release \ @@ -336,8 +330,7 @@ __Note:__ This uses CUDA 6.5, not 8.0. __Note:__ This configuration does not set the `ENABLE_NEON` parameter. -Ubuntu Desktop Linux Configuration ----------------------------------- +### Ubuntu Desktop Linux Configuration Supported platforms: @@ -383,12 +376,11 @@ This configuration is nearly identical to that for V4L and L4T, except that the As with previous examples, the configuration given above builds the Python bindings for Python 2 (but not Python 3) as part of the build process. Building OpenCV {#tutorial_building_tegra_cuda_building} -=============== +--------------- Once `cmake` finishes configuring OpenCV, building is done using the standard `make` utility. -Building with `make` --------------------- +### Building with `make` The only parameter that is needed for the invocation of `make` is the `-j` parameter for specifying how many parallel threads to use. This varies depending on the system and how much memory is available, other running processes, etc. The following table offers suggested values for this parameter: @@ -408,12 +400,11 @@ By default, CMake hides the details of the build steps. If you need to see more $ make -j6 VERBOSE=1 Testing OpenCV {#tutorial_building_tegra_cuda_testing} -============== +-------------- Once the build completes successfully, you have the option of running the extensive set of tests that OpenCV provides. If you did not clone the `opencv_extra` repository and specify the path to `testdata` in the `cmake` invocation, then testing is not recommended. -Testing under Linux -------------------- +### Testing under Linux To run the basic tests under Linux, execute: @@ -425,7 +416,7 @@ This executes `ctest` to carry out the tests, as specified in CTest syntax withi In this example, there are two (2) arguments passed to `ctest`: `--verbose` and `--parallel 3`. The first argument causes the output from `ctest` to be more detailed, and the second causes `ctest` to run as many as three (3) tests in parallel. As with choosing a thread count for building, base any choice for testing on the available number of processor cores, physical memory, etc. Some of the tests do attempt to allocate significant amounts of memory. -### Known Issues with Tests +#### Known Issues with Tests At present, not all of the tests in the OpenCV test suite pass. There are tests that fail whether or not CUDA is compiled, and there are tests that are only specific to CUDA that also do not currently pass. @@ -434,7 +425,7 @@ __Note:__ There are no tests that pass without CUDA but fail only when CUDA is i As the full lists of failing tests vary based on platform, it is impractical to list them here. Installing OpenCV {#tutorial_building_tegra_cuda_installing} -================= +----------------- Installing OpenCV is very straightforward. For the Linux-based platforms, the command is: @@ -443,14 +434,13 @@ Installing OpenCV is very straightforward. For the Linux-based platforms, the co Depending on the chosen installation location, you may need root privilege to install. Building OpenCV 2.4.X {#tutorial_building_tegra_cuda_opencv_24X} -===================== +--------------------- If you wish to build your own version of the 2.4 version of OpenCV, there are only a few adjustments that must be made. At the time of this writing, the latest version on the 2.4 tree is 2.4.13. These instructions may work for later versions of 2.4, though they have not been tested for any earlier versions. __Note:__ The 2.4.X OpenCV source does not have the extra modules and code for Tegra that was upstreamed into the 3.X versions of OpenCV. This part of the guide is only for cases where you want to build a vanilla version of OpenCV 2.4. -Selecting the 2.4 Source ------------------------- +### Selecting the 2.4 Source First you must select the correct source branch or tag. If you want a specific version such as 2.4.13, you want to make a local branch based on the tag, as was done with the 3.1.0 tag above: @@ -466,14 +456,13 @@ If you simply want the newest code from the 2.4 line of OpenCV, there is a `2.4` There is no need for the `git cherry-pick` commands used with 3.1.0 when building the 2.4.13 source. -Configuring ------------ +### Configuring Configuring is done with CMake as before. The primary difference is that OpenCV 2.4 only provides Python bindings for Python 2, and thus does not distinguish between Python 2 and Python 3 in the CMake parameters. There is only one parameter, `BUILD_opencv_python`. In addition, there is a build-related parameter that controls features in 2.4 that are not in 3.1.0. This parameter is `BUILD_opencv_nonfree`. Configuration still takes place in a separate directory that must be a sibling to the `opencv` and `opencv_extra` directories. -### Configuring Vibrante V4L +#### Configuring Vibrante V4L For DRIVE PX 2: @@ -510,7 +499,7 @@ For DRIVE PX 2: -DOPENCV_TEST_DATA_PATH=../opencv_extra/testdata \ ../opencv -### Configuring Jetson L4T +#### Configuring Jetson L4T For Jetson TK1: @@ -582,7 +571,7 @@ For Jetson TX1: -DOPENCV_TEST_DATA_PATH=../opencv_extra/testdata \ ../opencv -### Configuring Desktop Ubuntu Linux +#### Configuring Desktop Ubuntu Linux For both 14.04 LTS and 16.04 LTS: @@ -618,13 +607,12 @@ For both 14.04 LTS and 16.04 LTS: -DOPENCV_TEST_DATA_PATH=../opencv_extra/testdata \ ../opencv -Building, Testing and Installing --------------------------------- +### Building, Testing and Installing Once configured, the steps of building, testing, and installing are the same as above for the 3.1.0 source. CMake Parameter Reference {#tutorial_building_tegra_cuda_parameter_reference} -========================= +------------------------- The following is a table of all the parameters passed to CMake in the recommended invocations above. Some of these are parameters from CMake itself, while most are specific to OpenCV. diff --git a/doc/tutorials/introduction/clojure_dev_intro/clojure_dev_intro.markdown b/doc/tutorials/introduction/clojure_dev_intro/clojure_dev_intro.markdown index 98ba16b7fe..cbf52bbdc3 100644 --- a/doc/tutorials/introduction/clojure_dev_intro/clojure_dev_intro.markdown +++ b/doc/tutorials/introduction/clojure_dev_intro/clojure_dev_intro.markdown @@ -35,11 +35,11 @@ issue the following command to run the sample from the command line. cd path/to/samples/java/clojure/simple-sample lein run @endcode + Preamble -------- -For detailed instruction on installing OpenCV with desktop Java support refer to the @ref tutorial_java_dev_intro "corresponding -tutorial". +For detailed instruction on installing OpenCV with desktop Java support refer to the @ref tutorial_java_dev_intro "corresponding tutorial". If you are in hurry, here is a minimum quick start guide to install OpenCV on Mac OS X: @@ -63,6 +63,7 @@ make -j8 # optional # make install @endcode + Install Leiningen ----------------- @@ -170,6 +171,7 @@ i386 -> x86 arm -> arm sparc -> sparc @endcode + ### Package the native lib as a jar Next you need to package the native lib in a jar file by using the jar command to create a new jar @@ -193,6 +195,7 @@ tree 3 directories, 3 files @endcode + ### Locally install the jars We are now ready to add the two jars as artifacts to the local maven repository with the help of the @@ -402,6 +405,7 @@ Let's now try to port to Clojure the @ref tutorial_java_dev_intro "OpenCV Java t Instead of writing it in a source file we're going to evaluate it at the REPL. Following is the original Java source code of the cited sample. + @code{.java} import org.opencv.core.Mat; import org.opencv.core.CvType; @@ -430,20 +434,25 @@ Before start coding, we'd like to eliminate the boring need of interactively loa opencv lib any time we start a new REPL to interact with it. First, stop the REPL by evaluating the (exit) expression at the REPL prompt. + @code{.clojure} user=> (exit) Bye for now! @endcode + Then open your project.clj file and edit it as follows: + @code{.clojure} (defproject simple-sample "0.1.0-SNAPSHOT" ... injections [(clojure.lang.RT/loadLibrary org.opencv.core.Core/NATIVE_LIBRARY_NAME)]) @endcode + Here we're saying to load the opencv native lib anytime we run the REPL in such a way that we have not anymore to remember to manually do it. Rerun the lein repl task + @code{.bash} lein repl nREPL server started on port 51645 on host 127.0.0.1 @@ -458,11 +467,14 @@ Clojure 1.5.1 user=> @endcode + Import the interested OpenCV java interfaces. + @code{.clojure} user=> (import '[org.opencv.core Mat CvType Scalar]) org.opencv.core.Scalar @endcode + We're going to mimic almost verbatim the original OpenCV java tutorial to: - create a 5x10 matrix with all its elements initialized to 0 diff --git a/doc/tutorials/introduction/env_reference/env_reference.markdown b/doc/tutorials/introduction/env_reference/env_reference.markdown index 2a850dc299..91b8e64841 100644 --- a/doc/tutorials/introduction/env_reference/env_reference.markdown +++ b/doc/tutorials/introduction/env_reference/env_reference.markdown @@ -6,7 +6,7 @@ OpenCV environment variables reference {#tutorial_env_reference} @tableofcontents -### Introduction +## Introduction OpenCV can change its behavior depending on the runtime environment: - enable extra debugging output or performance tracing @@ -18,7 +18,7 @@ OpenCV can change its behavior depending on the runtime environment: - ⭐ marks most popular variables - variables with names like this `VAR_${NAME}` describes family of variables, where `${NAME}` should be changed to one of predefined values, e.g. `VAR_TBB`, `VAR_OPENMP`, ... -##### Setting environment variable in Windows +### Setting environment variable in Windows In terminal or cmd-file (bat-file): ```.bat set MY_ENV_VARIABLE=true @@ -30,7 +30,7 @@ In GUI: - In new window click on the "Environment variables" button - Add an entry to the "User variables" list -##### Setting environment variable in Linux +### Setting environment variable in Linux In terminal or shell script: ```.sh @@ -42,7 +42,7 @@ or as a single command: MY_ENV_VARIABLE=true ./my_app ``` -##### Setting environment variable in Python +### Setting environment variable in Python ```.py import os @@ -51,7 +51,7 @@ import cv2 # variables set after this may not have effect ``` -### Types +## Types - _non-null_ - set to anything to enable feature, in some cases can be interpreted as other types (e.g. path) - _bool_ - `1`, `True`, `true`, `TRUE` / `0`, `False`, `false`, `FALSE` @@ -61,7 +61,7 @@ import cv2 # variables set after this may not have effect - _paths_ - `;`-separated on Windows, `:`-separated on others -### General, core +## General, core | name | type | default | description | |------|------|---------|-------------| | OPENCV_SKIP_CPU_BASELINE_CHECK | non-null | | do not check that current CPU supports all features used by the build (baseline) | @@ -84,14 +84,14 @@ Links: - https://github.com/opencv/opencv/wiki/CPU-optimizations-build-options -### Logging +## Logging | name | type | default | description | |------|------|---------|-------------| | ⭐ OPENCV_LOG_LEVEL | string | | logging level (see accepted values below) | | OPENCV_LOG_TIMESTAMP | bool | true | logging with timestamps | | OPENCV_LOG_TIMESTAMP_NS | bool | false | add nsec to logging timestamps | -##### Levels: +### Levels - `0`, `O`, `OFF`, `S`, `SILENT`, `DISABLE`, `DISABLED` - `F`, `FATAL` - `E`, `ERROR` @@ -101,7 +101,7 @@ Links: - `V`, `VERBOSE` -### core/parallel_for +## core/parallel_for | name | type | default | description | |------|------|---------|-------------| | ⭐ OPENCV_FOR_THREADS_NUM | num | 0 | set number of threads | @@ -112,7 +112,7 @@ Links: | OPENCV_FOR_OPENMP_DYNAMIC_DISABLE | bool | false | use single OpenMP thread | -### backends +## backends OPENCV_LEGACY_WAITKEY Some modules have multiple available backends, following variables allow choosing specific backend or changing default priorities in which backends will be probed (e.g. when opening a video file). @@ -128,7 +128,7 @@ Some modules have multiple available backends, following variables allow choosin | OPENCV_VIDEOIO_PRIORITY_LIST | string, `,`-separated | | list of videoio backends in priority order | -### plugins +## plugins Some external dependencies can be detached into a dynamic library, which will be loaded at runtime (plugin). Following variables allow changing default search locations and naming pattern for these plugins. | name | type | default | description | |------|------|---------|-------------| @@ -141,7 +141,7 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_VIDEOIO_PLUGIN_PATH | paths | | directories to search for _videoio_ plugins | | OPENCV_VIDEOIO_PLUGIN_${NAME} | string, glob | | _videoio_ plugin library name (glob) | -### OpenCL +## OpenCL **Note:** OpenCL device specification format is `::`, e.g. `AMD:GPU:` @@ -170,7 +170,7 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_OPENCL_FORCE | bool | false | force running OpenCL kernel even if usual conditions are not met (e.g. dst.isUMat) | | OPENCV_OPENCL_PERF_CHECK_BYPASS | bool | false | force running OpenCL kernel even if usual performance-related conditions are not met (e.g. image is very small) | -##### SVM (Shared Virtual Memory) - disabled by default +### SVM (Shared Virtual Memory) - disabled by default | name | type | default | description | |------|------|---------|-------------| | OPENCV_OPENCL_SVM_DISABLE | bool | false | disable SVM | @@ -179,11 +179,11 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_OPENCL_SVM_CAPABILITIES_MASK | num | | | | OPENCV_OPENCL_SVM_BUFFERPOOL_LIMIT | num | | same as OPENCV_OPENCL_BUFFERPOOL_LIMIT, but for SVM buffers | -##### Links: +### Links: - https://github.com/opencv/opencv/wiki/OpenCL-optimizations -### Tracing/Profiling +## Tracing/Profiling | name | type | default | description | |------|------|---------|-------------| | ⭐ OPENCV_TRACE | bool | false | enable trace | @@ -196,11 +196,11 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_TRACE_ITT_PARENT | bool | false | set parentID for ITT task | | OPENCV_TRACE_ITT_SET_THREAD_NAME | bool | false | set name for OpenCV's threads "OpenCVThread-%03d" | -##### Links: +### Links: - https://github.com/opencv/opencv/wiki/Profiling-OpenCV-Applications -##### Cache +## Cache **Note:** Default tmp location is `%TMPDIR%` (Windows); `$XDG_CACHE_HOME`, `$HOME/.cache`, `/var/tmp`, `/tmp` (others) | name | type | default | description | |------|------|---------|-------------| @@ -210,7 +210,7 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_OPENCL_CACHE_DIR | path | default tmp location | cache directory for OpenCL kernels cache (subdirectory `opencl_cache`) | -### dnn +## dnn **Note:** In the table below `dump_base_name` equals to `ocv_dnn_net_%05d_%02d` where first argument is internal network ID and the second - dump level. | name | type | default | description | |------|------|---------|-------------| @@ -240,7 +240,7 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_OCL4DNN_TUNING_RAISE_CHECK_ERROR | bool | false | raise exception on errors (auto-tuning) | -### Tests +## Tests | name | type | default | description | |------|------|---------|-------------| | ⭐ OPENCV_TEST_DATA_PATH | dir path | | set test data search location (e.g. `/home/user/opencv_extra/testdata`) | @@ -254,11 +254,11 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_PERF_VALIDATION_DIR | dir path | | location of files read/written by `--perf_read_validation_results`/`--perf_write_validation_results` | | ⭐ OPENCV_PYTEST_FILTER | string (glob) | | test filter for Python tests | -##### Links: +### Links: * https://github.com/opencv/opencv/wiki/QA_in_OpenCV -### videoio +## videoio **Note:** extra FFmpeg options should be pased in form `key;value|key;value|key;value`, for example `hwaccel;cuvid|video_codec;h264_cuvid|vsync;0` or `vcodec;x264|vprofile;high|vlevel;4.0` | name | type | default | description | @@ -288,7 +288,7 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_VIDEOWRITER_DEBUG | bool | false | enable debug messages for VideoWriter | | ⭐ OPENCV_VIDEOIO_DEBUG | bool | false | debug messages for both VideoCapture and VideoWriter | -##### videoio tests +### videoio tests | name | type | default | description | |------|------|---------|-------------| | OPENCV_TEST_VIDEOIO_BACKEND_REQUIRE_FFMPEG | | | test app will exit if no FFmpeg backend is available | @@ -297,14 +297,14 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_TEST_CAMERA_%d_FPS | num | | fps to set for N-th camera (0-based index) (waitAny_V4L test) | -### gapi +## gapi | name | type | default | description | |------|------|---------|-------------| | ⭐ GRAPH_DUMP_PATH | file path | | dump graph (dot format) | | PIPELINE_MODELS_PATH | dir path | | pipeline_modeling_tool sample application uses this var | | OPENCV_GAPI_INFERENCE_ENGINE_CORE_LIFETIME_WORKAROUND | bool | true (Windows, Apple), false (others) | similar to OPENCV_DNN_INFERENCE_ENGINE_CORE_LIFETIME_WORKAROUND | -##### gapi tests/samples +### gapi tests/samples | name | type | default | description | |------|------|---------|-------------| | PLAIDML_DEVICE | string | | specific to PlaidML backend test | @@ -312,12 +312,12 @@ Some external dependencies can be detached into a dynamic library, which will be | OPENCV_GAPI_ONNX_MODEL_PATH | dir path | | search location for ONNX models test | | OPENCV_TEST_FREETYPE_FONT_PATH | file path | | location of TrueType font for one of tests | -##### Links: +### Links: * https://github.com/opencv/opencv/wiki/Using-G-API-with-OpenVINO-Toolkit * https://github.com/opencv/opencv/wiki/Using-G-API-with-MS-ONNX-Runtime -### highgui +## highgui | name | type | default | description | |------|------|---------|-------------| @@ -325,14 +325,14 @@ Some external dependencies can be detached into a dynamic library, which will be | $XDG_RUNTIME_DIR | | | Wayland backend specific - create shared memory-mapped file for interprocess communication (named `opencv-shared-??????`) | -### imgproc +## imgproc | name | type | default | description | |------|------|---------|-------------| | OPENCV_OPENCL_IMGPROC_MORPH_SPECIAL_KERNEL | bool | true (Apple), false (others) | use special OpenCL kernel for small morph kernel (Intel devices) | | OPENCV_GAUSSIANBLUR_CHECK_BITEXACT_KERNELS | bool | false | validate Gaussian kernels before running (src is CV_16U, bit-exact version) | -### imgcodecs +## imgcodecs | name | type | default | description | |------|------|---------|-------------| | OPENCV_IMGCODECS_AVIF_MAX_FILE_SIZE | num | 64MB | limit input AVIF size | diff --git a/doc/tutorials/introduction/windows_install/windows_install.markdown b/doc/tutorials/introduction/windows_install/windows_install.markdown index 2568592d0c..36d4e0ccba 100644 --- a/doc/tutorials/introduction/windows_install/windows_install.markdown +++ b/doc/tutorials/introduction/windows_install/windows_install.markdown @@ -22,8 +22,7 @@ best to help you out. with the latest Microsoft Visual Studio IDE and do not take advantage of the most advanced technologies we integrate into our library. .. _Windows_Install_Prebuild: -Installation by Using the Pre-built Libraries {#tutorial_windows_install_prebuilt} -============================================= +## Installation by Using the Pre-built Libraries {#tutorial_windows_install_prebuilt} -# Launch a web browser of choice and go to our [page on Sourceforge](http://sourceforge.net/projects/opencvlibrary/files/). @@ -35,8 +34,7 @@ Installation by Using the Pre-built Libraries {#tutorial_windows_install_prebuil -# To finalize the installation go to the @ref tutorial_windows_install_path section. -Installation by Using git-bash (version>=2.14.1) and cmake (version >=3.9.1){#tutorial_windows_gitbash_build} -=============================================================== +## Installation by Using git-bash (version>=2.14.1) and cmake (version >=3.9.1){#tutorial_windows_gitbash_build} -# You must download [cmake (version >=3.9.1)](https://cmake.org) and install it. You must add cmake to PATH variable during installation @@ -108,8 +106,7 @@ CMAKE_OPTIONS=(-DBUILD_PERF_TESTS:BOOL=OFF -DBUILD_TESTS:BOOL=OFF -DBUILD_DOCS:B -# Next time you run this script, opencv and opencv_contrib will be updated and rebuild -Installation by Making Your Own Libraries from the Source Files {#tutorial_windows_install_build} -=============================================================== +## Installation by Making Your Own Libraries from the Source Files {#tutorial_windows_install_build} You may find the content of this tutorial also inside the following videos: [Part 1](https://www.youtube.com/watch?v=NnovZ1cTlMs) and [Part 2](https://www.youtube.com/watch?v=qGNWMcfWwPU), hosted on YouTube. @@ -364,8 +361,7 @@ libraries). If you do not need the support for some of these, you can just freel caused mostly by old video card drivers. For testing the GPU (if built) run the *performance_gpu.exe* sample application. -Set the OpenCV environment variable and add it to the systems path {#tutorial_windows_install_path} -================================================================= +## Set the OpenCV environment variable and add it to the systems path {#tutorial_windows_install_path} First, we set an environment variable to make our work easier. This will hold the build directory of our OpenCV library that we use in our projects. Start up a command window and enter: diff --git a/modules/core/include/opencv2/core.hpp b/modules/core/include/opencv2/core.hpp index cfb995b1da..0958fe019d 100644 --- a/modules/core/include/opencv2/core.hpp +++ b/modules/core/include/opencv2/core.hpp @@ -62,10 +62,6 @@ @defgroup core Core functionality @{ @defgroup core_basic Basic structures - @defgroup core_c C structures and operations - @{ - @defgroup core_c_glue Connections with C++ - @} @defgroup core_array Operations on arrays @defgroup core_async Asynchronous API @defgroup core_xml XML/YAML Persistence diff --git a/modules/core/include/opencv2/core/cvstd.hpp b/modules/core/include/opencv2/core/cvstd.hpp index 6ce9e4b060..d216d267ef 100644 --- a/modules/core/include/opencv2/core/cvstd.hpp +++ b/modules/core/include/opencv2/core/cvstd.hpp @@ -140,7 +140,6 @@ public: //! @} core_utils -//! @endcond //! @addtogroup core_basic //! @{ diff --git a/modules/core/include/opencv2/core/matx.hpp b/modules/core/include/opencv2/core/matx.hpp index b4b2e7ef17..ad13797da3 100644 --- a/modules/core/include/opencv2/core/matx.hpp +++ b/modules/core/include/opencv2/core/matx.hpp @@ -61,8 +61,6 @@ namespace cv //! @addtogroup core_basic //! @{ -////////////////////////////// Small Matrix /////////////////////////// - //! @cond IGNORED // FIXIT Remove this (especially CV_EXPORTS modifier) struct CV_EXPORTS Matx_AddOp { Matx_AddOp() {} Matx_AddOp(const Matx_AddOp&) {} }; @@ -74,6 +72,8 @@ struct CV_EXPORTS Matx_MatMulOp { Matx_MatMulOp() {} Matx_MatMulOp(const Matx_Ma struct CV_EXPORTS Matx_TOp { Matx_TOp() {} Matx_TOp(const Matx_TOp&) {} }; //! @endcond +////////////////////////////// Small Matrix /////////////////////////// + /** @brief Template class for small matrices whose type and size are known at compilation time If you need a more flexible type, use Mat . The elements of the matrix M are accessible using the @@ -256,56 +256,83 @@ typedef Matx Matx44d; typedef Matx Matx66f; typedef Matx Matx66d; -/*! - traits -*/ -template class DataType< Matx<_Tp, m, n> > -{ -public: - typedef Matx<_Tp, m, n> value_type; - typedef Matx::work_type, m, n> work_type; - typedef _Tp channel_type; - typedef value_type vec_type; +template static inline +double determinant(const Matx<_Tp, m, m>& a); - enum { generic_type = 0, - channels = m * n, - fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) -#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED - ,depth = DataType::depth - ,type = CV_MAKETYPE(depth, channels) -#endif - }; -}; +template static inline +double trace(const Matx<_Tp, m, n>& a); -namespace traits { -template -struct Depth< Matx<_Tp, m, n> > { enum { value = Depth<_Tp>::value }; }; -template -struct Type< Matx<_Tp, m, n> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, n*m) }; }; -} // namespace +template static inline +double norm(const Matx<_Tp, m, n>& M); +template static inline +double norm(const Matx<_Tp, m, n>& M, int normType); -/** @brief Comma-separated Matrix Initializer -*/ -template class MatxCommaInitializer -{ -public: - MatxCommaInitializer(Matx<_Tp, m, n>* _mtx); - template MatxCommaInitializer<_Tp, m, n>& operator , (T2 val); - Matx<_Tp, m, n> operator *() const; +template static inline +Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b); - Matx<_Tp, m, n>* dst; - int idx; -}; +template static inline +Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b); -/* - Utility methods -*/ -template static double determinant(const Matx<_Tp, m, m>& a); -template static double trace(const Matx<_Tp, m, n>& a); -template static double norm(const Matx<_Tp, m, n>& M); -template static double norm(const Matx<_Tp, m, n>& M, int normType); +template static inline +Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b); +template static inline +Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b); + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha); + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha); + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha); + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha); + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha); + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha); + +template static inline +Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a); + +template static inline +Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a); + +template static inline +Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a); + +template static inline +Matx<_Tp, m, n>& operator /= (Matx<_Tp, m, n>& a, float alpha); + +template static inline +Matx<_Tp, m, n>& operator /= (Matx<_Tp, m, n>& a, double alpha); + +template static inline +Matx<_Tp, m, n> operator / (const Matx<_Tp, m, n>& a, float alpha); + +template static inline +Matx<_Tp, m, n> operator / (const Matx<_Tp, m, n>& a, double alpha); + +template static inline +Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a); + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b); + +template static inline +Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b); + +template static inline +bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b); + +template static inline +bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b); /////////////////////// Vec (used as element of multi-channel images ///////////////////// @@ -439,1094 +466,79 @@ typedef Vec Vec4d; typedef Vec Vec6d; /** @} */ -/*! - traits -*/ -template class DataType< Vec<_Tp, cn> > -{ -public: - typedef Vec<_Tp, cn> value_type; - typedef Vec::work_type, cn> work_type; - typedef _Tp channel_type; - typedef value_type vec_type; +template inline +Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v); - enum { generic_type = 0, - channels = cn, - fmt = DataType::fmt + ((channels - 1) << 8), -#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED - depth = DataType::depth, - type = CV_MAKETYPE(depth, channels), -#endif - _dummy_enum_finalizer = 0 - }; -}; +template static inline +Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b); -namespace traits { -template -struct Depth< Vec<_Tp, cn> > { enum { value = Depth<_Tp>::value }; }; -template -struct Type< Vec<_Tp, cn> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, cn) }; }; -} // namespace +template static inline +Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b); +template static inline +Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b); -/** @brief Comma-separated Vec Initializer -*/ -template class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1> -{ -public: - VecCommaInitializer(Vec<_Tp, m>* _vec); - template VecCommaInitializer<_Tp, m>& operator , (T2 val); - Vec<_Tp, m> operator *() const; -}; +template static inline +Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b); -template static Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v); +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha); + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha); + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha); + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha); + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha); + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha); + +template static inline +Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha); + +template static inline +Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a); + +template static inline +Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha); + +template static inline +Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a); + +template static inline +Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha); + +template static inline +Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a); + +template static inline +Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha); + +template static inline +Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha); + +template static inline +Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha); + +template static inline +Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a); + +template inline +Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2); + +template inline +Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2); //! @} core_basic -//! @cond IGNORED - -///////////////////////////////////// helper classes ///////////////////////////////////// -namespace internal -{ - -template struct Matx_DetOp -{ - double operator ()(const Matx<_Tp, m, m>& a) const - { - Matx<_Tp, m, m> temp = a; - double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0); - if( p == 0 ) - return p; - for( int i = 0; i < m; i++ ) - p *= temp(i, i); - return p; - } -}; - -template struct Matx_DetOp<_Tp, 1> -{ - double operator ()(const Matx<_Tp, 1, 1>& a) const - { - return a(0,0); - } -}; - -template struct Matx_DetOp<_Tp, 2> -{ - double operator ()(const Matx<_Tp, 2, 2>& a) const - { - return a(0,0)*a(1,1) - a(0,1)*a(1,0); - } -}; - -template struct Matx_DetOp<_Tp, 3> -{ - double operator ()(const Matx<_Tp, 3, 3>& a) const - { - return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) - - a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) + - a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1)); - } -}; - -template Vec<_Tp, 2> inline conjugate(const Vec<_Tp, 2>& v) -{ - return Vec<_Tp, 2>(v[0], -v[1]); -} - -template Vec<_Tp, 4> inline conjugate(const Vec<_Tp, 4>& v) -{ - return Vec<_Tp, 4>(v[0], -v[1], -v[2], -v[3]); -} - -} // internal - - - -////////////////////////////////// Matx Implementation /////////////////////////////////// - -template inline -Matx<_Tp, m, n>::Matx() -{ - for(int i = 0; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0) -{ - val[0] = v0; - for(int i = 1; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1) -{ - CV_StaticAssert(channels >= 2, "Matx should have at least 2 elements."); - val[0] = v0; val[1] = v1; - for(int i = 2; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2) -{ - CV_StaticAssert(channels >= 3, "Matx should have at least 3 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; - for(int i = 3; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3) -{ - CV_StaticAssert(channels >= 4, "Matx should have at least 4 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; - for(int i = 4; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) -{ - CV_StaticAssert(channels >= 5, "Matx should have at least 5 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4; - for(int i = 5; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) -{ - CV_StaticAssert(channels >= 6, "Matx should have at least 6 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; - val[4] = v4; val[5] = v5; - for(int i = 6; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) -{ - CV_StaticAssert(channels >= 7, "Matx should have at least 7 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; - val[4] = v4; val[5] = v5; val[6] = v6; - for(int i = 7; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) -{ - CV_StaticAssert(channels >= 8, "Matx should have at least 8 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; - val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; - for(int i = 8; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) -{ - CV_StaticAssert(channels >= 9, "Matx should have at least 9 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; - val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; - val[8] = v8; - for(int i = 9; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) -{ - CV_StaticAssert(channels >= 10, "Matx should have at least 10 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; - val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; - val[8] = v8; val[9] = v9; - for(int i = 10; i < channels; i++) val[i] = _Tp(0); -} - - -template inline -Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11) -{ - CV_StaticAssert(channels >= 12, "Matx should have at least 12 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; - val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; - val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; - for(int i = 12; i < channels; i++) val[i] = _Tp(0); -} - -template inline -Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13) -{ - CV_StaticAssert(channels >= 14, "Matx should have at least 14 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; - val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; - val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; - val[12] = v12; val[13] = v13; - for (int i = 14; i < channels; i++) val[i] = _Tp(0); -} - - -template inline -Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13, _Tp v14, _Tp v15) -{ - CV_StaticAssert(channels >= 16, "Matx should have at least 16 elements."); - val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; - val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; - val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; - val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15; - for(int i = 16; i < channels; i++) val[i] = _Tp(0); -} - -// WARNING: unreachable code using Ninja -#if defined _MSC_VER && _MSC_VER >= 1920 -#pragma warning(push) -#pragma warning(disable: 4702) -#endif -template inline -Matx<_Tp, m, n>::Matx(const _Tp* values) -{ - for( int i = 0; i < channels; i++ ) val[i] = values[i]; -} -#if defined _MSC_VER && _MSC_VER >= 1920 -#pragma warning(pop) -#endif - -template inline -Matx<_Tp, m, n>::Matx(std::initializer_list<_Tp> list) -{ - CV_DbgAssert(list.size() == channels); - int i = 0; - for(const auto& elem : list) - { - val[i++] = elem; - } -} - -template inline -Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha) -{ - Matx<_Tp, m, n> M; - for( int i = 0; i < m*n; i++ ) M.val[i] = alpha; - return M; -} - -template inline -Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros() -{ - return all(0); -} - -template inline -Matx<_Tp,m,n> Matx<_Tp,m,n>::ones() -{ - return all(1); -} - -template inline -Matx<_Tp,m,n> Matx<_Tp,m,n>::eye() -{ - Matx<_Tp,m,n> M; - for(int i = 0; i < shortdim; i++) - M(i,i) = 1; - return M; -} - -template inline -_Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const -{ - _Tp s = 0; - for( int i = 0; i < channels; i++ ) s += val[i]*M.val[i]; - return s; -} - -template inline -double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const -{ - double s = 0; - for( int i = 0; i < channels; i++ ) s += (double)val[i]*M.val[i]; - return s; -} - -template inline -Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d) -{ - Matx<_Tp,m,n> M; - for(int i = 0; i < shortdim; i++) - M(i,i) = d(i, 0); - return M; -} - -template template -inline Matx<_Tp, m, n>::operator Matx() const -{ - Matx M; - for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast(val[i]); - return M; -} - -template template inline -Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const -{ - CV_StaticAssert(m1*n1 == m*n, "Input and destination matrices must have the same number of elements"); - return (const Matx<_Tp, m1, n1>&)*this; -} - -template -template inline -Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int base_row, int base_col) const -{ - CV_DbgAssert(0 <= base_row && base_row+m1 <= m && 0 <= base_col && base_col+n1 <= n); - Matx<_Tp, m1, n1> s; - for( int di = 0; di < m1; di++ ) - for( int dj = 0; dj < n1; dj++ ) - s(di, dj) = (*this)(base_row+di, base_col+dj); - return s; -} - -template inline -Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const -{ - CV_DbgAssert((unsigned)i < (unsigned)m); - return Matx<_Tp, 1, n>(&val[i*n]); -} - -template inline -Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const -{ - CV_DbgAssert((unsigned)j < (unsigned)n); - Matx<_Tp, m, 1> v; - for( int i = 0; i < m; i++ ) - v.val[i] = val[i*n + j]; - return v; -} - -template inline -typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const -{ - diag_type d; - for( int i = 0; i < shortdim; i++ ) - d.val[i] = val[i*n + i]; - return d; -} - -template inline -const _Tp& Matx<_Tp, m, n>::operator()(int row_idx, int col_idx) const -{ - CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n ); - return this->val[row_idx*n + col_idx]; -} - -template inline -_Tp& Matx<_Tp, m, n>::operator ()(int row_idx, int col_idx) -{ - CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n ); - return val[row_idx*n + col_idx]; -} - -template inline -const _Tp& Matx<_Tp, m, n>::operator ()(int i) const -{ - CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); - CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); - return val[i]; -} - -template inline -_Tp& Matx<_Tp, m, n>::operator ()(int i) -{ - CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); - CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); - return val[i]; -} - -template inline -Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp) -{ - for( int i = 0; i < channels; i++ ) - val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]); -} - -template inline -Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp) -{ - for( int i = 0; i < channels; i++ ) - val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]); -} - -template template inline -Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp) -{ - for( int i = 0; i < channels; i++ ) - val[i] = saturate_cast<_Tp>(a.val[i] * alpha); -} - -template inline -Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp) -{ - for( int i = 0; i < channels; i++ ) - val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]); -} - -template inline -Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp) -{ - for( int i = 0; i < channels; i++ ) - val[i] = saturate_cast<_Tp>(a.val[i] / b.val[i]); -} - -template template inline -Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp) -{ - for( int i = 0; i < m; i++ ) - for( int j = 0; j < n; j++ ) - { - _Tp s = 0; - for( int k = 0; k < l; k++ ) - s += a(i, k) * b(k, j); - val[i*n + j] = s; - } -} - -template inline -Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp) -{ - for( int i = 0; i < m; i++ ) - for( int j = 0; j < n; j++ ) - val[i*n + j] = a(j, i); -} - -template inline -Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const -{ - return Matx<_Tp, m, n>(*this, a, Matx_MulOp()); -} - -template inline -Matx<_Tp, m, n> Matx<_Tp, m, n>::div(const Matx<_Tp, m, n>& a) const -{ - return Matx<_Tp, m, n>(*this, a, Matx_DivOp()); -} - -template inline -Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const -{ - return Matx<_Tp, n, m>(*this, Matx_TOp()); -} - -template inline -Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const -{ - Matx<_Tp, n, 1> x = solve((const Matx<_Tp, m, 1>&)(rhs), method); - return (Vec<_Tp, n>&)(x); -} - -template static inline -double determinant(const Matx<_Tp, m, m>& a) -{ - return cv::internal::Matx_DetOp<_Tp, m>()(a); -} - -template static inline -double trace(const Matx<_Tp, m, n>& a) -{ - _Tp s = 0; - for( int i = 0; i < std::min(m, n); i++ ) - s += a(i,i); - return s; -} - -template static inline -double norm(const Matx<_Tp, m, n>& M) -{ - return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n)); -} - -template static inline -double norm(const Matx<_Tp, m, n>& M, int normType) -{ - switch(normType) { - case NORM_INF: - return (double)normInf<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); - case NORM_L1: - return (double)normL1<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); - case NORM_L2SQR: - return (double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); - default: - case NORM_L2: - return std::sqrt((double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n)); - } -} - - - -//////////////////////////////// matx comma initializer ////////////////////////////////// - -template static inline -MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val) -{ - MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx); - return (commaInitializer, val); -} - -template inline -MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx) - : dst(_mtx), idx(0) -{} - -template template inline -MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value) -{ - CV_DbgAssert( idx < m*n ); - dst->val[idx++] = saturate_cast<_Tp>(value); - return *this; -} - -template inline -Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const -{ - CV_DbgAssert( idx == n*m ); - return *dst; -} - - - -/////////////////////////////////// Vec Implementation /////////////////////////////////// - -template inline -Vec<_Tp, cn>::Vec() {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0) - : Matx<_Tp, cn, 1>(v0) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1) - : Matx<_Tp, cn, 1>(v0, v1) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2) - : Matx<_Tp, cn, 1>(v0, v1, v2) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3) - : Matx<_Tp, cn, 1>(v0, v1, v2, v3) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) - : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) - : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) - : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) - : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) - : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) - : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {} - -template inline -Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13) - : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) {} - -template inline -Vec<_Tp, cn>::Vec(const _Tp* values) - : Matx<_Tp, cn, 1>(values) {} - -template inline -Vec<_Tp, cn>::Vec(std::initializer_list<_Tp> list) - : Matx<_Tp, cn, 1>(list) {} - -template inline -Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m) - : Matx<_Tp, cn, 1>(m.val) {} - -template inline -Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op) - : Matx<_Tp, cn, 1>(a, b, op) {} - -template inline -Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op) - : Matx<_Tp, cn, 1>(a, b, op) {} - -template template inline -Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op) - : Matx<_Tp, cn, 1>(a, alpha, op) {} - -template inline -Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha) -{ - Vec v; - for( int i = 0; i < cn; i++ ) v.val[i] = alpha; - return v; -} - -template inline -Vec<_Tp, cn> Vec<_Tp, cn>::ones() -{ - return Vec::all(1); -} - -template inline -Vec<_Tp, cn> Vec<_Tp, cn>::zeros() -{ - return Vec::all(0); -} - -template inline -Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const -{ - Vec<_Tp, cn> w; - for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]); - return w; -} - -template<> inline -Vec Vec::conj() const -{ - return cv::internal::conjugate(*this); -} - -template<> inline -Vec Vec::conj() const -{ - return cv::internal::conjugate(*this); -} - -template<> inline -Vec Vec::conj() const -{ - return cv::internal::conjugate(*this); -} - -template<> inline -Vec Vec::conj() const -{ - return cv::internal::conjugate(*this); -} - -template inline -Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>&) const -{ - CV_StaticAssert(cn == 3, "for arbitrary-size vector there is no cross-product defined"); - return Vec<_Tp, cn>(); -} - -template<> inline -Vec Vec::cross(const Vec& v) const -{ - return Vec(this->val[1]*v.val[2] - this->val[2]*v.val[1], - this->val[2]*v.val[0] - this->val[0]*v.val[2], - this->val[0]*v.val[1] - this->val[1]*v.val[0]); -} - -template<> inline -Vec Vec::cross(const Vec& v) const -{ - return Vec(this->val[1]*v.val[2] - this->val[2]*v.val[1], - this->val[2]*v.val[0] - this->val[0]*v.val[2], - this->val[0]*v.val[1] - this->val[1]*v.val[0]); -} - -template template inline -Vec<_Tp, cn>::operator Vec() const -{ - Vec v; - for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast(this->val[i]); - return v; -} - -template inline -const _Tp& Vec<_Tp, cn>::operator [](int i) const -{ - CV_DbgAssert( (unsigned)i < (unsigned)cn ); - return this->val[i]; -} - -template inline -_Tp& Vec<_Tp, cn>::operator [](int i) -{ - CV_DbgAssert( (unsigned)i < (unsigned)cn ); - return this->val[i]; -} - -template inline -const _Tp& Vec<_Tp, cn>::operator ()(int i) const -{ - CV_DbgAssert( (unsigned)i < (unsigned)cn ); - return this->val[i]; -} - -template inline -_Tp& Vec<_Tp, cn>::operator ()(int i) -{ - CV_DbgAssert( (unsigned)i < (unsigned)cn ); - return this->val[i]; -} - -template inline -Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v) -{ - double nv = norm(v); - return v * (nv ? 1./nv : 0.); -} - - - -//////////////////////////////// vec comma initializer ////////////////////////////////// - - -template static inline -VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val) -{ - VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec); - return (commaInitializer, val); -} - -template inline -VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec) - : MatxCommaInitializer<_Tp, cn, 1>(_vec) -{} - -template template inline -VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value) -{ - CV_DbgAssert( this->idx < cn ); - this->dst->val[this->idx++] = saturate_cast<_Tp>(value); - return *this; -} - -template inline -Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const -{ - CV_DbgAssert( this->idx == cn ); - return *this->dst; -} - -//! @endcond - -///////////////////////////// Matx out-of-class operators //////////////////////////////// - -//! @relates cv::Matx -//! @{ - -template static inline -Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) -{ - for( int i = 0; i < m*n; i++ ) - a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); - return a; -} - -template static inline -Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) -{ - for( int i = 0; i < m*n; i++ ) - a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); - return a; -} - -template static inline -Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) -{ - return Matx<_Tp, m, n>(a, b, Matx_AddOp()); -} - -template static inline -Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) -{ - return Matx<_Tp, m, n>(a, b, Matx_SubOp()); -} - -template static inline -Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha) -{ - for( int i = 0; i < m*n; i++ ) - a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); - return a; -} - -template static inline -Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha) -{ - for( int i = 0; i < m*n; i++ ) - a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); - return a; -} - -template static inline -Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha) -{ - for( int i = 0; i < m*n; i++ ) - a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); - return a; -} - -template static inline -Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha) -{ - return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha) -{ - return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha) -{ - return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a) -{ - return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a) -{ - return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a) -{ - return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Matx<_Tp, m, n>& operator /= (Matx<_Tp, m, n>& a, float alpha) -{ - for( int i = 0; i < m*n; i++ ) - a.val[i] = a.val[i] / alpha; - return a; -} - -template static inline -Matx<_Tp, m, n>& operator /= (Matx<_Tp, m, n>& a, double alpha) -{ - for( int i = 0; i < m*n; i++ ) - a.val[i] = a.val[i] / alpha; - return a; -} - -template static inline -Matx<_Tp, m, n> operator / (const Matx<_Tp, m, n>& a, float alpha) -{ - return Matx<_Tp, m, n>(a, 1.f/alpha, Matx_ScaleOp()); -} - -template static inline -Matx<_Tp, m, n> operator / (const Matx<_Tp, m, n>& a, double alpha) -{ - return Matx<_Tp, m, n>(a, 1./alpha, Matx_ScaleOp()); -} - -template static inline -Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a) -{ - return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp()); -} - -template static inline -Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b) -{ - return Matx<_Tp, m, n>(a, b, Matx_MatMulOp()); -} - -template static inline -Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b) -{ - Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp()); - return (const Vec<_Tp, m>&)(c); -} - -template static inline -bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) -{ - for( int i = 0; i < m*n; i++ ) - if( a.val[i] != b.val[i] ) return false; - return true; -} - -template static inline -bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) -{ - return !(a == b); -} - -//! @} - -////////////////////////////// Vec out-of-class operators //////////////////////////////// - -//! @relates cv::Vec -//! @{ - -template static inline -Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) -{ - for( int i = 0; i < cn; i++ ) - a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); - return a; -} - -template static inline -Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) -{ - for( int i = 0; i < cn; i++ ) - a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); - return a; -} - -template static inline -Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) -{ - return Vec<_Tp, cn>(a, b, Matx_AddOp()); -} - -template static inline -Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) -{ - return Vec<_Tp, cn>(a, b, Matx_SubOp()); -} - -template static inline -Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha) -{ - for( int i = 0; i < cn; i++ ) - a[i] = saturate_cast<_Tp>(a[i]*alpha); - return a; -} - -template static inline -Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha) -{ - for( int i = 0; i < cn; i++ ) - a[i] = saturate_cast<_Tp>(a[i]*alpha); - return a; -} - -template static inline -Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha) -{ - for( int i = 0; i < cn; i++ ) - a[i] = saturate_cast<_Tp>(a[i]*alpha); - return a; -} - -template static inline -Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha) -{ - double ialpha = 1./alpha; - for( int i = 0; i < cn; i++ ) - a[i] = saturate_cast<_Tp>(a[i]*ialpha); - return a; -} - -template static inline -Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha) -{ - float ialpha = 1.f/alpha; - for( int i = 0; i < cn; i++ ) - a[i] = saturate_cast<_Tp>(a[i]*ialpha); - return a; -} - -template static inline -Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha) -{ - double ialpha = 1./alpha; - for( int i = 0; i < cn; i++ ) - a[i] = saturate_cast<_Tp>(a[i]*ialpha); - return a; -} - -template static inline -Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha) -{ - return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a) -{ - return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha) -{ - return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a) -{ - return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha) -{ - return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a) -{ - return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); -} - -template static inline -Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha) -{ - return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); -} - -template static inline -Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha) -{ - return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp()); -} - -template static inline -Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha) -{ - return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); -} - -template static inline -Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a) -{ - Vec<_Tp,cn> t; - for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]); - return t; -} - -template inline Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) -{ - return Vec<_Tp, 4>(saturate_cast<_Tp>(v1[0]*v2[0] - v1[1]*v2[1] - v1[2]*v2[2] - v1[3]*v2[3]), - saturate_cast<_Tp>(v1[0]*v2[1] + v1[1]*v2[0] + v1[2]*v2[3] - v1[3]*v2[2]), - saturate_cast<_Tp>(v1[0]*v2[2] - v1[1]*v2[3] + v1[2]*v2[0] + v1[3]*v2[1]), - saturate_cast<_Tp>(v1[0]*v2[3] + v1[1]*v2[2] - v1[2]*v2[1] + v1[3]*v2[0])); -} - -template inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) -{ - v1 = v1 * v2; - return v1; -} - -//! @} - } // cv +#include "opencv2/core/matx.inl.hpp" + #endif // OPENCV_CORE_MATX_HPP diff --git a/modules/core/include/opencv2/core/matx.inl.hpp b/modules/core/include/opencv2/core/matx.inl.hpp new file mode 100644 index 0000000000..faa3e749d6 --- /dev/null +++ b/modules/core/include/opencv2/core/matx.inl.hpp @@ -0,0 +1,1115 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_MATX_INL_HPP +#define OPENCV_CORE_MATX_INL_HPP + +#ifndef __cplusplus +# error matx.inl.hpp header must be compiled as C++ +#endif + +#include "opencv2/core/matx.hpp" + +namespace cv +{ + +//============================================================================== +// Helpers + +namespace internal +{ + +template struct Matx_DetOp +{ + double operator ()(const Matx<_Tp, m, m>& a) const + { + Matx<_Tp, m, m> temp = a; + double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0); + if( p == 0 ) + return p; + for( int i = 0; i < m; i++ ) + p *= temp(i, i); + return p; + } +}; + +template struct Matx_DetOp<_Tp, 1> +{ + double operator ()(const Matx<_Tp, 1, 1>& a) const + { + return a(0,0); + } +}; + +template struct Matx_DetOp<_Tp, 2> +{ + double operator ()(const Matx<_Tp, 2, 2>& a) const + { + return a(0,0)*a(1,1) - a(0,1)*a(1,0); + } +}; + +template struct Matx_DetOp<_Tp, 3> +{ + double operator ()(const Matx<_Tp, 3, 3>& a) const + { + return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) - + a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) + + a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1)); + } +}; + +template Vec<_Tp, 2> inline conjugate(const Vec<_Tp, 2>& v) +{ + return Vec<_Tp, 2>(v[0], -v[1]); +} + +template Vec<_Tp, 4> inline conjugate(const Vec<_Tp, 4>& v) +{ + return Vec<_Tp, 4>(v[0], -v[1], -v[2], -v[3]); +} + +} // internal:: + + +//============================================================================== +// Matx + +template class DataType< Matx<_Tp, m, n> > +{ +public: + typedef Matx<_Tp, m, n> value_type; + typedef Matx::work_type, m, n> work_type; + typedef _Tp channel_type; + typedef value_type vec_type; + + enum { generic_type = 0, + channels = m * n, + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; +}; + + +namespace traits { +template +struct Depth< Matx<_Tp, m, n> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Matx<_Tp, m, n> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, n*m) }; }; +} // namespace + + +//! @brief Comma-separated Matrix Initializer +template class MatxCommaInitializer +{ +public: + MatxCommaInitializer(Matx<_Tp, m, n>* _mtx); + template MatxCommaInitializer<_Tp, m, n>& operator , (T2 val); + Matx<_Tp, m, n> operator *() const; + + Matx<_Tp, m, n>* dst; + int idx; +}; + +template static inline +MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val) +{ + MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx); + return (commaInitializer, val); +} + +template inline +MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx) + : dst(_mtx), idx(0) +{} + +template template inline +MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value) +{ + CV_DbgAssert( idx < m*n ); + dst->val[idx++] = saturate_cast<_Tp>(value); + return *this; +} + +template inline +Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const +{ + CV_DbgAssert( idx == n*m ); + return *dst; +} + +////////////////////////////////// Matx Implementation /////////////////////////////////// + +template inline +Matx<_Tp, m, n>::Matx() +{ + for(int i = 0; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0) +{ + val[0] = v0; + for(int i = 1; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1) +{ + CV_StaticAssert(channels >= 2, "Matx should have at least 2 elements."); + val[0] = v0; val[1] = v1; + for(int i = 2; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2) +{ + CV_StaticAssert(channels >= 3, "Matx should have at least 3 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; + for(int i = 3; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3) +{ + CV_StaticAssert(channels >= 4, "Matx should have at least 4 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + for(int i = 4; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) +{ + CV_StaticAssert(channels >= 5, "Matx should have at least 5 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4; + for(int i = 5; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) +{ + CV_StaticAssert(channels >= 6, "Matx should have at least 6 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; + for(int i = 6; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) +{ + CV_StaticAssert(channels >= 7, "Matx should have at least 7 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; + for(int i = 7; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) +{ + CV_StaticAssert(channels >= 8, "Matx should have at least 8 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + for(int i = 8; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) +{ + CV_StaticAssert(channels >= 9, "Matx should have at least 9 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; + for(int i = 9; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) +{ + CV_StaticAssert(channels >= 10, "Matx should have at least 10 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; + for(int i = 10; i < channels; i++) val[i] = _Tp(0); +} + + +template inline +Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11) +{ + CV_StaticAssert(channels >= 12, "Matx should have at least 12 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; + for(int i = 12; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13) +{ + CV_StaticAssert(channels >= 14, "Matx should have at least 14 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; + val[12] = v12; val[13] = v13; + for (int i = 14; i < channels; i++) val[i] = _Tp(0); +} + + +template inline +Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13, _Tp v14, _Tp v15) +{ + CV_StaticAssert(channels >= 16, "Matx should have at least 16 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; + val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15; + for(int i = 16; i < channels; i++) val[i] = _Tp(0); +} + +// WARNING: unreachable code using Ninja +#if defined _MSC_VER && _MSC_VER >= 1920 +#pragma warning(push) +#pragma warning(disable: 4702) +#endif +template inline +Matx<_Tp, m, n>::Matx(const _Tp* values) +{ + for( int i = 0; i < channels; i++ ) val[i] = values[i]; +} +#if defined _MSC_VER && _MSC_VER >= 1920 +#pragma warning(pop) +#endif + +template inline +Matx<_Tp, m, n>::Matx(std::initializer_list<_Tp> list) +{ + CV_DbgAssert(list.size() == channels); + int i = 0; + for(const auto& elem : list) + { + val[i++] = elem; + } +} + +template inline +Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha) +{ + Matx<_Tp, m, n> M; + for( int i = 0; i < m*n; i++ ) M.val[i] = alpha; + return M; +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros() +{ + return all(0); +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::ones() +{ + return all(1); +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::eye() +{ + Matx<_Tp,m,n> M; + for(int i = 0; i < shortdim; i++) + M(i,i) = 1; + return M; +} + +template inline +_Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const +{ + _Tp s = 0; + for( int i = 0; i < channels; i++ ) s += val[i]*M.val[i]; + return s; +} + +template inline +double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const +{ + double s = 0; + for( int i = 0; i < channels; i++ ) s += (double)val[i]*M.val[i]; + return s; +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d) +{ + Matx<_Tp,m,n> M; + for(int i = 0; i < shortdim; i++) + M(i,i) = d(i, 0); + return M; +} + +template template +inline Matx<_Tp, m, n>::operator Matx() const +{ + Matx M; + for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast(val[i]); + return M; +} + +template template inline +Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const +{ + CV_StaticAssert(m1*n1 == m*n, "Input and destination matrices must have the same number of elements"); + return (const Matx<_Tp, m1, n1>&)*this; +} + +template +template inline +Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int base_row, int base_col) const +{ + CV_DbgAssert(0 <= base_row && base_row+m1 <= m && 0 <= base_col && base_col+n1 <= n); + Matx<_Tp, m1, n1> s; + for( int di = 0; di < m1; di++ ) + for( int dj = 0; dj < n1; dj++ ) + s(di, dj) = (*this)(base_row+di, base_col+dj); + return s; +} + +template inline +Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const +{ + CV_DbgAssert((unsigned)i < (unsigned)m); + return Matx<_Tp, 1, n>(&val[i*n]); +} + +template inline +Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const +{ + CV_DbgAssert((unsigned)j < (unsigned)n); + Matx<_Tp, m, 1> v; + for( int i = 0; i < m; i++ ) + v.val[i] = val[i*n + j]; + return v; +} + +template inline +typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const +{ + diag_type d; + for( int i = 0; i < shortdim; i++ ) + d.val[i] = val[i*n + i]; + return d; +} + +template inline +const _Tp& Matx<_Tp, m, n>::operator()(int row_idx, int col_idx) const +{ + CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n ); + return this->val[row_idx*n + col_idx]; +} + +template inline +_Tp& Matx<_Tp, m, n>::operator ()(int row_idx, int col_idx) +{ + CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n ); + return val[row_idx*n + col_idx]; +} + +template inline +const _Tp& Matx<_Tp, m, n>::operator ()(int i) const +{ + CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); + CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); + return val[i]; +} + +template inline +_Tp& Matx<_Tp, m, n>::operator ()(int i) +{ + CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); + CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); + return val[i]; +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]); +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]); +} + +template template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] * alpha); +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]); +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] / b.val[i]); +} + +template template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp) +{ + for( int i = 0; i < m; i++ ) + for( int j = 0; j < n; j++ ) + { + _Tp s = 0; + for( int k = 0; k < l; k++ ) + s += a(i, k) * b(k, j); + val[i*n + j] = s; + } +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp) +{ + for( int i = 0; i < m; i++ ) + for( int j = 0; j < n; j++ ) + val[i*n + j] = a(j, i); +} + +template inline +Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const +{ + return Matx<_Tp, m, n>(*this, a, Matx_MulOp()); +} + +template inline +Matx<_Tp, m, n> Matx<_Tp, m, n>::div(const Matx<_Tp, m, n>& a) const +{ + return Matx<_Tp, m, n>(*this, a, Matx_DivOp()); +} + +template inline +Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const +{ + return Matx<_Tp, n, m>(*this, Matx_TOp()); +} + +template inline +Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const +{ + Matx<_Tp, n, 1> x = solve((const Matx<_Tp, m, 1>&)(rhs), method); + return (Vec<_Tp, n>&)(x); +} + +template static inline +double determinant(const Matx<_Tp, m, m>& a) +{ + return cv::internal::Matx_DetOp<_Tp, m>()(a); +} + +template static inline +double trace(const Matx<_Tp, m, n>& a) +{ + _Tp s = 0; + for( int i = 0; i < std::min(m, n); i++ ) + s += a(i,i); + return s; +} + +template static inline +double norm(const Matx<_Tp, m, n>& M) +{ + return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n)); +} + +template static inline +double norm(const Matx<_Tp, m, n>& M, int normType) +{ + switch(normType) { + case NORM_INF: + return (double)normInf<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); + case NORM_L1: + return (double)normL1<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); + case NORM_L2SQR: + return (double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); + default: + case NORM_L2: + return std::sqrt((double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n)); + } +} + +template static inline +Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); + return a; +} + +template static inline +Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); + return a; +} + +template static inline +Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + return Matx<_Tp, m, n>(a, b, Matx_AddOp()); +} + +template static inline +Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + return Matx<_Tp, m, n>(a, b, Matx_SubOp()); +} + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); + return a; +} + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); + return a; +} + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); + return a; +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n>& operator /= (Matx<_Tp, m, n>& a, float alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = a.val[i] / alpha; + return a; +} + +template static inline +Matx<_Tp, m, n>& operator /= (Matx<_Tp, m, n>& a, double alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = a.val[i] / alpha; + return a; +} + +template static inline +Matx<_Tp, m, n> operator / (const Matx<_Tp, m, n>& a, float alpha) +{ + return Matx<_Tp, m, n>(a, 1.f/alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator / (const Matx<_Tp, m, n>& a, double alpha) +{ + return Matx<_Tp, m, n>(a, 1./alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b) +{ + return Matx<_Tp, m, n>(a, b, Matx_MatMulOp()); +} + +template static inline +Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b) +{ + Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp()); + return (const Vec<_Tp, m>&)(c); +} + +template static inline +bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + for( int i = 0; i < m*n; i++ ) + if( a.val[i] != b.val[i] ) return false; + return true; +} + +template static inline +bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + return !(a == b); +} + +//============================================================================== +// Vec + +template class DataType< Vec<_Tp, cn> > +{ +public: + typedef Vec<_Tp, cn> value_type; + typedef Vec::work_type, cn> work_type; + typedef _Tp channel_type; + typedef value_type vec_type; + + enum { generic_type = 0, + channels = cn, + fmt = DataType::fmt + ((channels - 1) << 8), +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + depth = DataType::depth, + type = CV_MAKETYPE(depth, channels), +#endif + _dummy_enum_finalizer = 0 + }; +}; + +namespace traits { +template +struct Depth< Vec<_Tp, cn> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Vec<_Tp, cn> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, cn) }; }; +} // namespace + +/** @brief Comma-separated Vec Initializer +*/ +template class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1> +{ +public: + VecCommaInitializer(Vec<_Tp, m>* _vec); + template VecCommaInitializer<_Tp, m>& operator , (T2 val); + Vec<_Tp, m> operator *() const; +}; + +template static inline +VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val) +{ + VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec); + return (commaInitializer, val); +} + +template inline +VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec) + : MatxCommaInitializer<_Tp, cn, 1>(_vec) +{} + +template template inline +VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value) +{ + CV_DbgAssert( this->idx < cn ); + this->dst->val[this->idx++] = saturate_cast<_Tp>(value); + return *this; +} + +template inline +Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const +{ + CV_DbgAssert( this->idx == cn ); + return *this->dst; +} + + +template inline +Vec<_Tp, cn>::Vec() {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0) + : Matx<_Tp, cn, 1>(v0) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1) + : Matx<_Tp, cn, 1>(v0, v1) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2) + : Matx<_Tp, cn, 1>(v0, v1, v2) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) {} + +template inline +Vec<_Tp, cn>::Vec(const _Tp* values) + : Matx<_Tp, cn, 1>(values) {} + +template inline +Vec<_Tp, cn>::Vec(std::initializer_list<_Tp> list) + : Matx<_Tp, cn, 1>(list) {} + +template inline +Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m) + : Matx<_Tp, cn, 1>(m.val) {} + +template inline +Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op) + : Matx<_Tp, cn, 1>(a, b, op) {} + +template inline +Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op) + : Matx<_Tp, cn, 1>(a, b, op) {} + +template template inline +Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op) + : Matx<_Tp, cn, 1>(a, alpha, op) {} + +template inline +Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha) +{ + Vec v; + for( int i = 0; i < cn; i++ ) v.val[i] = alpha; + return v; +} + +template inline +Vec<_Tp, cn> Vec<_Tp, cn>::ones() +{ + return Vec::all(1); +} + +template inline +Vec<_Tp, cn> Vec<_Tp, cn>::zeros() +{ + return Vec::all(0); +} + +template inline +Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const +{ + Vec<_Tp, cn> w; + for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]); + return w; +} + +template<> inline +Vec Vec::conj() const +{ + return cv::internal::conjugate(*this); +} + +template<> inline +Vec Vec::conj() const +{ + return cv::internal::conjugate(*this); +} + +template<> inline +Vec Vec::conj() const +{ + return cv::internal::conjugate(*this); +} + +template<> inline +Vec Vec::conj() const +{ + return cv::internal::conjugate(*this); +} + +template inline +Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>&) const +{ + CV_StaticAssert(cn == 3, "for arbitrary-size vector there is no cross-product defined"); + return Vec<_Tp, cn>(); +} + +template<> inline +Vec Vec::cross(const Vec& v) const +{ + return Vec(this->val[1]*v.val[2] - this->val[2]*v.val[1], + this->val[2]*v.val[0] - this->val[0]*v.val[2], + this->val[0]*v.val[1] - this->val[1]*v.val[0]); +} + +template<> inline +Vec Vec::cross(const Vec& v) const +{ + return Vec(this->val[1]*v.val[2] - this->val[2]*v.val[1], + this->val[2]*v.val[0] - this->val[0]*v.val[2], + this->val[0]*v.val[1] - this->val[1]*v.val[0]); +} + +template template inline +Vec<_Tp, cn>::operator Vec() const +{ + Vec v; + for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast(this->val[i]); + return v; +} + +template inline +const _Tp& Vec<_Tp, cn>::operator [](int i) const +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline +_Tp& Vec<_Tp, cn>::operator [](int i) +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline +const _Tp& Vec<_Tp, cn>::operator ()(int i) const +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline +_Tp& Vec<_Tp, cn>::operator ()(int i) +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline +Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v) +{ + double nv = norm(v); + return v * (nv ? 1./nv : 0.); +} + +template static inline +Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) +{ + for( int i = 0; i < cn; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); + return a; +} + +template static inline +Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) +{ + for( int i = 0; i < cn; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); + return a; +} + +template static inline +Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) +{ + return Vec<_Tp, cn>(a, b, Matx_AddOp()); +} + +template static inline +Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) +{ + return Vec<_Tp, cn>(a, b, Matx_SubOp()); +} + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha) +{ + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*alpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha) +{ + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*alpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha) +{ + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*alpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha) +{ + double ialpha = 1./alpha; + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*ialpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha) +{ + float ialpha = 1.f/alpha; + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*ialpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha) +{ + double ialpha = 1./alpha; + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*ialpha); + return a; +} + +template static inline +Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha) +{ + return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha) +{ + return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha) +{ + return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a) +{ + Vec<_Tp,cn> t; + for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]); + return t; +} + +template inline Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) +{ + return Vec<_Tp, 4>(saturate_cast<_Tp>(v1[0]*v2[0] - v1[1]*v2[1] - v1[2]*v2[2] - v1[3]*v2[3]), + saturate_cast<_Tp>(v1[0]*v2[1] + v1[1]*v2[0] + v1[2]*v2[3] - v1[3]*v2[2]), + saturate_cast<_Tp>(v1[0]*v2[2] - v1[1]*v2[3] + v1[2]*v2[0] + v1[3]*v2[1]), + saturate_cast<_Tp>(v1[0]*v2[3] + v1[1]*v2[2] - v1[2]*v2[1] + v1[3]*v2[0])); +} + +template inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) +{ + v1 = v1 * v2; + return v1; +} + +} // cv:: + +#endif // OPENCV_CORE_MATX_INL_HPP diff --git a/modules/core/include/opencv2/core/persistence.hpp b/modules/core/include/opencv2/core/persistence.hpp index 8e135d1a11..9c4f33fb14 100644 --- a/modules/core/include/opencv2/core/persistence.hpp +++ b/modules/core/include/opencv2/core/persistence.hpp @@ -696,9 +696,6 @@ protected: /////////////////// XML & YAML I/O implementation ////////////////// -//! @relates cv::FileStorage -//! @{ - CV_EXPORTS void write( FileStorage& fs, const String& name, int value ); CV_EXPORTS void write( FileStorage& fs, const String& name, float value ); CV_EXPORTS void write( FileStorage& fs, const String& name, double value ); @@ -715,11 +712,6 @@ CV_EXPORTS void writeScalar( FileStorage& fs, float value ); CV_EXPORTS void writeScalar( FileStorage& fs, double value ); CV_EXPORTS void writeScalar( FileStorage& fs, const String& value ); -//! @} - -//! @relates cv::FileNode -//! @{ - CV_EXPORTS void read(const FileNode& node, int& value, int default_value); CV_EXPORTS void read(const FileNode& node, float& value, float default_value); CV_EXPORTS void read(const FileNode& node, double& value, double default_value); @@ -796,10 +788,7 @@ static inline void read(const FileNode& node, Range& value, const Range& default value.start = temp.x; value.end = temp.y; } -//! @} - /** @brief Writes string to a file storage. -@relates cv::FileStorage */ CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str); @@ -884,9 +873,6 @@ namespace internal //! @endcond -//! @relates cv::FileStorage -//! @{ - template static inline void write(FileStorage& fs, const _Tp& value) { @@ -1118,10 +1104,6 @@ static inline void write(FileStorage& fs, const std::vector& vec) } #endif -//! @} FileStorage - -//! @relates cv::FileNode -//! @{ static inline void read(const FileNode& node, bool& value, bool default_value) @@ -1208,11 +1190,6 @@ void read( const FileNode& node, std::vector& vec, const std::vector static inline @@ -1244,11 +1221,6 @@ FileStorage& operator << (FileStorage& fs, char* value) return (fs << String(value)); } -//! @} FileStorage - -//! @relates cv::FileNodeIterator -//! @{ - /** @brief Reads data from a file storage. */ template static inline @@ -1268,11 +1240,6 @@ FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec) return it; } -//! @} FileNodeIterator - -//! @relates cv::FileNode -//! @{ - /** @brief Reads data from a file storage. */ template static inline @@ -1323,11 +1290,6 @@ void operator >> (const FileNode& n, DMatch& m) it >> m.queryIdx >> m.trainIdx >> m.imgIdx >> m.distance; } -//! @} FileNode - -//! @relates cv::FileNodeIterator -//! @{ - CV_EXPORTS bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2); CV_EXPORTS bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2); @@ -1343,8 +1305,6 @@ bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2) return it1.remaining() > it2.remaining(); } -//! @} FileNodeIterator - } // cv #endif // OPENCV_CORE_PERSISTENCE_HPP diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index e0d0187bdc..b4c4dde712 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -56,15 +56,15 @@ @defgroup features2d_main Feature Detection and Description @defgroup features2d_match Descriptor Matchers -Matchers of keypoint descriptors in OpenCV have wrappers with a common interface that enables you to -easily switch between different algorithms solving the same problem. This section is devoted to -matching descriptors that are represented as vectors in a multidimensional space. All objects that -implement vector descriptor matchers inherit the DescriptorMatcher interface. + Matchers of keypoint descriptors in OpenCV have wrappers with a common interface that enables + you to easily switch between different algorithms solving the same problem. This section is + devoted to matching descriptors that are represented as vectors in a multidimensional space. + All objects that implement vector descriptor matchers inherit the DescriptorMatcher interface. @defgroup features2d_draw Drawing Function of Keypoints and Matches @defgroup features2d_category Object Categorization -This section describes approaches based on local 2D features and used to categorize objects. + This section describes approaches based on local 2D features and used to categorize objects. @defgroup feature2d_hal Hardware Acceleration Layer @{ @@ -567,10 +567,6 @@ public: CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; }; -//! @} features2d_main - -//! @addtogroup features2d_main -//! @{ /** @brief Wrapping class for feature detection using the FAST method. : */ @@ -627,10 +623,6 @@ detection, use cv.FAST.detect() method. CV_EXPORTS void FAST( InputArray image, CV_OUT std::vector& keypoints, int threshold, bool nonmaxSuppression, FastFeatureDetector::DetectorType type ); -//! @} features2d_main - -//! @addtogroup features2d_main -//! @{ /** @brief Wrapping class for feature detection using the AGAST method. : */ @@ -793,10 +785,6 @@ public: CV_WRAP virtual const std::vector >& getBlobContours() const; }; -//! @} features2d_main - -//! @addtogroup features2d_main -//! @{ /** @brief Class implementing the KAZE keypoint detector and descriptor extractor, described in @cite ABD12 . @@ -925,7 +913,6 @@ public: CV_WRAP virtual int getMaxPoints() const = 0; }; -//! @} features2d_main /****************************************************************************************\ * Distance * @@ -990,6 +977,8 @@ struct L1 } }; +//! @} features2d_main + /****************************************************************************************\ * DescriptorMatcher * \****************************************************************************************/ @@ -1431,6 +1420,9 @@ CV_EXPORTS_AS(drawMatchesKnn) void drawMatches( InputArray img1, const std::vect * Functions to evaluate the feature detectors and [generic] descriptor extractors * \****************************************************************************************/ +//! @addtogroup features2d_main +//! @{ + CV_EXPORTS void evaluateFeatureDetector( const Mat& img1, const Mat& img2, const Mat& H1to2, std::vector* keypoints1, std::vector* keypoints2, float& repeatability, int& correspCount, @@ -1443,6 +1435,8 @@ CV_EXPORTS void computeRecallPrecisionCurve( const std::vector& recallPrecisionCurve, float l_precision ); CV_EXPORTS int getNearestPoint( const std::vector& recallPrecisionCurve, float l_precision ); +//! @} + /****************************************************************************************\ * Bag of visual words * \****************************************************************************************/ @@ -1603,8 +1597,6 @@ protected: //! @} features2d_category -//! @} features2d - } /* namespace cv */ #endif diff --git a/modules/gapi/doc/00-root.markdown b/modules/gapi/doc/00-root.markdown index b28fbc6619..cfbbe8cf3f 100644 --- a/modules/gapi/doc/00-root.markdown +++ b/modules/gapi/doc/00-root.markdown @@ -17,7 +17,7 @@ is volatile at the moment and there may be minor but compatibility-breaking changes in the future. # Contents - +gapi G-API documentation is organized into the following chapters: - @subpage gapi_purposes @@ -41,6 +41,10 @@ G-API documentation is organized into the following chapters: - API Reference: functions and classes + - @subpage gapi_ref + + Core G-API classes, data types, backends, etc. + - @subpage gapi_core Core G-API operations - arithmetic, boolean, and other matrix @@ -51,6 +55,14 @@ G-API documentation is organized into the following chapters: Image processing functions: color space conversions, various filters, etc. + - @subpage gapi_video + + Video processing functionality. + + - @subpage gapi_draw + + Drawing and composition functionality + # API Example {#gapi_example} A very basic example of G-API pipeline is shown below: diff --git a/modules/gapi/doc/30-implementation.markdown b/modules/gapi/doc/30-implementation.markdown index 7ce4b8012e..cdb5df413b 100644 --- a/modules/gapi/doc/30-implementation.markdown +++ b/modules/gapi/doc/30-implementation.markdown @@ -4,7 +4,7 @@ # G-API Implementation details -Note -- this section is still in progress. +@note this section is still in progress. # API layer {#gapi_detail_api} diff --git a/modules/gapi/include/opencv2/gapi.hpp b/modules/gapi/include/opencv2/gapi.hpp index f10dfd471d..2087641023 100644 --- a/modules/gapi/include/opencv2/gapi.hpp +++ b/modules/gapi/include/opencv2/gapi.hpp @@ -10,7 +10,7 @@ #include -/** \defgroup gapi G-API framework +/** \defgroup gapi_ref G-API framework @{ @defgroup gapi_main_classes G-API Main Classes @defgroup gapi_data_objects G-API Data Types diff --git a/modules/gapi/include/opencv2/gapi/gcommon.hpp b/modules/gapi/include/opencv2/gapi/gcommon.hpp index 2aa676da3a..c61110e4d5 100644 --- a/modules/gapi/include/opencv2/gapi/gcommon.hpp +++ b/modules/gapi/include/opencv2/gapi/gcommon.hpp @@ -249,6 +249,8 @@ template struct wrap_serialize } // namespace s11n } // namespace gapi +/** @} gapi_compile_args */ + /** * @brief Ask G-API to dump compiled graph in Graphviz format under * the given file name. @@ -261,7 +263,6 @@ struct graph_dump_path { std::string m_dump_path; }; -/** @} */ /** * @brief Ask G-API to use threaded executor when cv::GComputation @@ -276,7 +277,6 @@ struct GAPI_EXPORTS use_threaded_executor uint32_t num_threads; }; -/** @} */ namespace detail { diff --git a/modules/gapi/include/opencv2/gapi/gstreaming.hpp b/modules/gapi/include/opencv2/gapi/gstreaming.hpp index e8f534ee5f..d413195b81 100644 --- a/modules/gapi/include/opencv2/gapi/gstreaming.hpp +++ b/modules/gapi/include/opencv2/gapi/gstreaming.hpp @@ -388,7 +388,6 @@ protected: /// @private std::shared_ptr m_priv; }; -/** @} */ namespace gapi { @@ -413,7 +412,6 @@ struct GAPI_EXPORTS_W_SIMPLE queue_capacity GAPI_PROP_RW size_t capacity; }; -/** @} */ } // namespace streaming } // namespace gapi @@ -425,6 +423,8 @@ template<> struct CompileArgTag }; } +/** @} gapi_main_classes */ + } #endif // OPENCV_GAPI_GSTREAMING_COMPILED_HPP diff --git a/modules/gapi/include/opencv2/gapi/infer/ov.hpp b/modules/gapi/include/opencv2/gapi/infer/ov.hpp index 02d6225c7a..782792489b 100644 --- a/modules/gapi/include/opencv2/gapi/infer/ov.hpp +++ b/modules/gapi/include/opencv2/gapi/infer/ov.hpp @@ -690,7 +690,6 @@ namespace wip { namespace ov { * taking into account the i/o data transfer. */ struct benchmark_mode { }; -/** @} */ } // namespace ov } // namespace wip diff --git a/modules/highgui/doc/highgui_qt.cpp b/modules/highgui/doc/highgui_qt.cpp new file mode 100644 index 0000000000..a3a1f938b4 --- /dev/null +++ b/modules/highgui/doc/highgui_qt.cpp @@ -0,0 +1,39 @@ +#include "opencv2/highgui.hpp" + +int main(int argc, char *argv[]) +{ + int value = 50; + int value2 = 0; + + namedWindow("main1",WINDOW_NORMAL); + namedWindow("main2",WINDOW_AUTOSIZE | WINDOW_GUI_NORMAL); + createTrackbar( "track1", "main1", &value, 255, NULL); + + String nameb1 = "button1"; + String nameb2 = "button2"; + + createButton(nameb1,callbackButton,&nameb1,QT_CHECKBOX,1); + createButton(nameb2,callbackButton,NULL,QT_CHECKBOX,0); + createTrackbar( "track2", NULL, &value2, 255, NULL); + createButton("button5",callbackButton1,NULL,QT_RADIOBOX,0); + createButton("button6",callbackButton2,NULL,QT_RADIOBOX,1); + + setMouseCallback( "main2",on_mouse,NULL ); + + Mat img1 = imread("files/flower.jpg"); + VideoCapture video; + video.open("files/hockey.avi"); + + Mat img2,img3; + while( waitKey(33) != 27 ) + { + img1.convertTo(img2,-1,1,value); + video >> img3; + + imshow("main1",img2); + imshow("main2",img3); + } + + destroyAllWindows(); + return 0; +} diff --git a/modules/highgui/include/opencv2/highgui.hpp b/modules/highgui/include/opencv2/highgui.hpp index e6a40caf3d..41ce7b6186 100644 --- a/modules/highgui/include/opencv2/highgui.hpp +++ b/modules/highgui/include/opencv2/highgui.hpp @@ -85,50 +85,8 @@ It provides easy interface to: created. Then, a new button is attached to it. See below the example used to generate the figure: - @code - int main(int argc, char *argv[]) - { - - int value = 50; - int value2 = 0; - - - namedWindow("main1",WINDOW_NORMAL); - namedWindow("main2",WINDOW_AUTOSIZE | WINDOW_GUI_NORMAL); - createTrackbar( "track1", "main1", &value, 255, NULL); - - String nameb1 = "button1"; - String nameb2 = "button2"; - - createButton(nameb1,callbackButton,&nameb1,QT_CHECKBOX,1); - createButton(nameb2,callbackButton,NULL,QT_CHECKBOX,0); - createTrackbar( "track2", NULL, &value2, 255, NULL); - createButton("button5",callbackButton1,NULL,QT_RADIOBOX,0); - createButton("button6",callbackButton2,NULL,QT_RADIOBOX,1); - - setMouseCallback( "main2",on_mouse,NULL ); - - Mat img1 = imread("files/flower.jpg"); - VideoCapture video; - video.open("files/hockey.avi"); - - Mat img2,img3; - - while( waitKey(33) != 27 ) - { - img1.convertTo(img2,-1,1,value); - video >> img3; - - imshow("main1",img2); - imshow("main2",img3); - } - - destroyAllWindows(); - - return 0; - } - @endcode + @include highgui_qt.cpp @defgroup highgui_winrt WinRT support @@ -139,36 +97,34 @@ It provides easy interface to: See below the example used to generate the figure: @code - void sample_app::MainPage::ShowWindow() + void sample_app::MainPage::ShowWindow() + { + static cv::String windowName("sample"); + cv::winrt_initContainer(this->cvContainer); + cv::namedWindow(windowName); // not required + + cv::Mat image = cv::imread("Assets/sample.jpg"); + cv::Mat converted = cv::Mat(image.rows, image.cols, CV_8UC4); + cv::cvtColor(image, converted, COLOR_BGR2BGRA); + cv::imshow(windowName, converted); // this will create window if it hasn't been created before + + int state = 42; + cv::TrackbarCallback callback = [](int pos, void* userdata) { - static cv::String windowName("sample"); - cv::winrt_initContainer(this->cvContainer); - cv::namedWindow(windowName); // not required - - cv::Mat image = cv::imread("Assets/sample.jpg"); - cv::Mat converted = cv::Mat(image.rows, image.cols, CV_8UC4); - cv::cvtColor(image, converted, COLOR_BGR2BGRA); - cv::imshow(windowName, converted); // this will create window if it hasn't been created before - - int state = 42; - cv::TrackbarCallback callback = [](int pos, void* userdata) - { - if (pos == 0) { - cv::destroyWindow(windowName); - } - }; - cv::TrackbarCallback callbackTwin = [](int pos, void* userdata) - { - if (pos >= 70) { - cv::destroyAllWindows(); - } - }; - cv::createTrackbar("Sample trackbar", windowName, &state, 100, callback); - cv::createTrackbar("Twin brother", windowName, &state, 100, callbackTwin); - } + if (pos == 0) { + cv::destroyWindow(windowName); + } + }; + cv::TrackbarCallback callbackTwin = [](int pos, void* userdata) + { + if (pos >= 70) { + cv::destroyAllWindows(); + } + }; + cv::createTrackbar("Sample trackbar", windowName, &state, 100, callback); + cv::createTrackbar("Twin brother", windowName, &state, 100, callbackTwin); + } @endcode - - @defgroup highgui_c C API @} */ diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index c01d8568e4..e815dc4e9b 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -48,7 +48,6 @@ /** @defgroup imgcodecs Image file reading and writing @{ - @defgroup imgcodecs_c C API @defgroup imgcodecs_flags Flags used for image file reading and writing @defgroup imgcodecs_ios iOS glue @defgroup imgcodecs_macosx MacOS(OSX) glue @@ -297,7 +296,7 @@ It also demonstrates how to save multiple images in a TIFF file: CV_EXPORTS_W bool imwrite( const String& filename, InputArray img, const std::vector& params = std::vector()); -/// @overload multi-image overload for bindings +//! @brief multi-image overload for bindings CV_WRAP static inline bool imwritemulti(const String& filename, InputArrayOfArrays img, const std::vector& params = std::vector()) diff --git a/modules/imgproc/doc/colors.markdown b/modules/imgproc/doc/colors.markdown index c1c2abfce7..9881ca793f 100644 --- a/modules/imgproc/doc/colors.markdown +++ b/modules/imgproc/doc/colors.markdown @@ -1,10 +1,12 @@ Color conversions {#imgproc_color_conversions} ================= + See cv::cvtColor and cv::ColorConversionCodes + @todo document other conversion modes @anchor color_convert_rgb_gray -RGB \f$\leftrightarrow\f$ GRAY +RGB \emoji arrow_right GRAY ------------------------------ Transformations within RGB space like adding/removing the alpha channel, reversing the channel order, conversion to/from 16-bit RGB color (R5:G6:B5 or R5:G5:B5), as well as conversion @@ -20,7 +22,7 @@ More advanced channel reordering can also be done with cv::mixChannels. @see cv::COLOR_BGR2GRAY, cv::COLOR_RGB2GRAY, cv::COLOR_GRAY2BGR, cv::COLOR_GRAY2RGB @anchor color_convert_rgb_xyz -RGB \f$\leftrightarrow\f$ CIE XYZ.Rec 709 with D65 white point +RGB \emoji arrow_right CIE XYZ.Rec 709 with D65 white point -------------------------------------------------------------- \f[\begin{bmatrix} X \\ Y \\ Z \end{bmatrix} \leftarrow \begin{bmatrix} 0.412453 & 0.357580 & 0.180423 \\ 0.212671 & 0.715160 & 0.072169 \\ 0.019334 & 0.119193 & 0.950227 @@ -35,7 +37,7 @@ RGB \f$\leftrightarrow\f$ CIE XYZ.Rec 709 with D65 white point @see cv::COLOR_BGR2XYZ, cv::COLOR_RGB2XYZ, cv::COLOR_XYZ2BGR, cv::COLOR_XYZ2RGB @anchor color_convert_rgb_ycrcb -RGB \f$\leftrightarrow\f$ YCrCb JPEG (or YCC) +RGB \emoji arrow_right YCrCb JPEG (or YCC) --------------------------------------------- \f[Y \leftarrow 0.299 \cdot R + 0.587 \cdot G + 0.114 \cdot B\f] \f[Cr \leftarrow (R-Y) \cdot 0.713 + delta\f] @@ -49,7 +51,7 @@ Y, Cr, and Cb cover the whole value range. @see cv::COLOR_BGR2YCrCb, cv::COLOR_RGB2YCrCb, cv::COLOR_YCrCb2BGR, cv::COLOR_YCrCb2RGB @anchor color_convert_rgb_hsv -RGB \f$\leftrightarrow\f$ HSV +RGB \emoji arrow_right HSV ----------------------------- In case of 8-bit and 16-bit images, R, G, and B are converted to the floating-point format and scaled to fit the 0 to 1 range. @@ -71,7 +73,7 @@ The values are then converted to the destination data type: @see cv::COLOR_BGR2HSV, cv::COLOR_RGB2HSV, cv::COLOR_HSV2BGR, cv::COLOR_HSV2RGB @anchor color_convert_rgb_hls -RGB \f$\leftrightarrow\f$ HLS +RGB \emoji arrow_right HLS ----------------------------- In case of 8-bit and 16-bit images, R, G, and B are converted to the floating-point format and scaled to fit the 0 to 1 range. @@ -96,7 +98,7 @@ The values are then converted to the destination data type: @see cv::COLOR_BGR2HLS, cv::COLOR_RGB2HLS, cv::COLOR_HLS2BGR, cv::COLOR_HLS2RGB @anchor color_convert_rgb_lab -RGB \f$\leftrightarrow\f$ CIE L\*a\*b\* +RGB \emoji arrow_right CIE L\*a\*b\* --------------------------------------- In case of 8-bit and 16-bit images, R, G, and B are converted to the floating-point format and scaled to fit the 0 to 1 range. @@ -121,7 +123,7 @@ are then converted to the destination data type: @see cv::COLOR_BGR2Lab, cv::COLOR_RGB2Lab, cv::COLOR_Lab2BGR, cv::COLOR_Lab2RGB @anchor color_convert_rgb_luv -RGB \f$\leftrightarrow\f$ CIE L\*u\*v\* +RGB \emoji arrow_right CIE L\*u\*v\* --------------------------------------- In case of 8-bit and 16-bit images, R, G, and B are converted to the floating-point format and scaled to fit 0 to 1 range. @@ -148,7 +150,7 @@ sources on the web, primarily from the Charles Poynton site : \texttt{src} \rightarrow -\texttt{dst}\f$, the OpenCV functions first compute the corresponding inverse mapping -\f$\left: \texttt{dst} \rightarrow \texttt{src}\f$ and then use the above formula. + In case when you specify the forward mapping \f$\left: \texttt{src} \rightarrow + \texttt{dst}\f$, the OpenCV functions first compute the corresponding inverse mapping + \f$\left: \texttt{dst} \rightarrow \texttt{src}\f$ and then use the above formula. -The actual implementations of the geometrical transformations, from the most generic remap and to -the simplest and the fastest resize, need to solve two main problems with the above formula: + The actual implementations of the geometrical transformations, from the most generic remap and to + the simplest and the fastest resize, need to solve two main problems with the above formula: -- Extrapolation of non-existing pixels. Similarly to the filtering functions described in the -previous section, for some \f$(x,y)\f$, either one of \f$f_x(x,y)\f$, or \f$f_y(x,y)\f$, or both -of them may fall outside of the image. In this case, an extrapolation method needs to be used. -OpenCV provides the same selection of extrapolation methods as in the filtering functions. In -addition, it provides the method #BORDER_TRANSPARENT. This means that the corresponding pixels in -the destination image will not be modified at all. + - Extrapolation of non-existing pixels. Similarly to the filtering functions described in the + previous section, for some \f$(x,y)\f$, either one of \f$f_x(x,y)\f$, or \f$f_y(x,y)\f$, or both + of them may fall outside of the image. In this case, an extrapolation method needs to be used. + OpenCV provides the same selection of extrapolation methods as in the filtering functions. In + addition, it provides the method #BORDER_TRANSPARENT. This means that the corresponding pixels in + the destination image will not be modified at all. -- Interpolation of pixel values. Usually \f$f_x(x,y)\f$ and \f$f_y(x,y)\f$ are floating-point -numbers. This means that \f$\left\f$ can be either an affine or perspective -transformation, or radial lens distortion correction, and so on. So, a pixel value at fractional -coordinates needs to be retrieved. In the simplest case, the coordinates can be just rounded to the -nearest integer coordinates and the corresponding pixel can be used. This is called a -nearest-neighbor interpolation. However, a better result can be achieved by using more -sophisticated [interpolation methods](http://en.wikipedia.org/wiki/Multivariate_interpolation) , -where a polynomial function is fit into some neighborhood of the computed pixel \f$(f_x(x,y), -f_y(x,y))\f$, and then the value of the polynomial at \f$(f_x(x,y), f_y(x,y))\f$ is taken as the -interpolated pixel value. In OpenCV, you can choose between several interpolation methods. See -#resize for details. + - Interpolation of pixel values. Usually \f$f_x(x,y)\f$ and \f$f_y(x,y)\f$ are floating-point + numbers. This means that \f$\left\f$ can be either an affine or perspective + transformation, or radial lens distortion correction, and so on. So, a pixel value at fractional + coordinates needs to be retrieved. In the simplest case, the coordinates can be just rounded to the + nearest integer coordinates and the corresponding pixel can be used. This is called a + nearest-neighbor interpolation. However, a better result can be achieved by using more + sophisticated [interpolation methods](http://en.wikipedia.org/wiki/Multivariate_interpolation) , + where a polynomial function is fit into some neighborhood of the computed pixel \f$(f_x(x,y), + f_y(x,y))\f$, and then the value of the polynomial at \f$(f_x(x,y), f_y(x,y))\f$ is taken as the + interpolated pixel value. In OpenCV, you can choose between several interpolation methods. See + #resize for details. -@note The geometrical transformations do not work with `CV_8S` or `CV_32S` images. + @note The geometrical transformations do not work with `CV_8S` or `CV_32S` images. @defgroup imgproc_misc Miscellaneous Image Transformations @defgroup imgproc_draw Drawing Functions -Drawing functions work with matrices/images of arbitrary depth. The boundaries of the shapes can be -rendered with antialiasing (implemented only for 8-bit images for now). All the functions include -the parameter color that uses an RGB value (that may be constructed with the Scalar constructor ) -for color images and brightness for grayscale images. For color images, the channel ordering is -normally *Blue, Green, Red*. This is what imshow, imread, and imwrite expect. So, if you form a -color using the Scalar constructor, it should look like: + Drawing functions work with matrices/images of arbitrary depth. The boundaries of the shapes can be + rendered with antialiasing (implemented only for 8-bit images for now). All the functions include + the parameter color that uses an RGB value (that may be constructed with the Scalar constructor ) + for color images and brightness for grayscale images. For color images, the channel ordering is + normally *Blue, Green, Red*. This is what imshow, imread, and imwrite expect. So, if you form a + color using the Scalar constructor, it should look like: -\f[\texttt{Scalar} (blue \_ component, green \_ component, red \_ component[, alpha \_ component])\f] + \f[\texttt{Scalar} (blue \_ component, green \_ component, red \_ component[, alpha \_ component])\f] -If you are using your own image rendering and I/O functions, you can use any channel ordering. The -drawing functions process each channel independently and do not depend on the channel order or even -on the used color space. The whole image can be converted from BGR to RGB or to a different color -space using cvtColor . + If you are using your own image rendering and I/O functions, you can use any channel ordering. The + drawing functions process each channel independently and do not depend on the channel order or even + on the used color space. The whole image can be converted from BGR to RGB or to a different color + space using cvtColor . -If a drawn figure is partially or completely outside the image, the drawing functions clip it. Also, -many drawing functions can handle pixel coordinates specified with sub-pixel accuracy. This means -that the coordinates can be passed as fixed-point numbers encoded as integers. The number of -fractional bits is specified by the shift parameter and the real point coordinates are calculated as -\f$\texttt{Point}(x,y)\rightarrow\texttt{Point2f}(x*2^{-shift},y*2^{-shift})\f$ . This feature is -especially effective when rendering antialiased shapes. + If a drawn figure is partially or completely outside the image, the drawing functions clip it. Also, + many drawing functions can handle pixel coordinates specified with sub-pixel accuracy. This means + that the coordinates can be passed as fixed-point numbers encoded as integers. The number of + fractional bits is specified by the shift parameter and the real point coordinates are calculated as + \f$\texttt{Point}(x,y)\rightarrow\texttt{Point2f}(x*2^{-shift},y*2^{-shift})\f$ . This feature is + especially effective when rendering antialiased shapes. -@note The functions do not support alpha-transparency when the target image is 4-channel. In this -case, the color[3] is simply copied to the repainted pixels. Thus, if you want to paint -semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main -image. + @note The functions do not support alpha-transparency when the target image is 4-channel. In this + case, the color[3] is simply copied to the repainted pixels. Thus, if you want to paint + semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main + image. @defgroup imgproc_color_conversions Color Space Conversions @defgroup imgproc_colormap ColorMaps in OpenCV -The human perception isn't built for observing fine changes in grayscale images. Human eyes are more -sensitive to observing changes between colors, so you often need to recolor your grayscale images to -get a clue about them. OpenCV now comes with various colormaps to enhance the visualization in your -computer vision application. + The human perception isn't built for observing fine changes in grayscale images. Human eyes are more + sensitive to observing changes between colors, so you often need to recolor your grayscale images to + get a clue about them. OpenCV now comes with various colormaps to enhance the visualization in your + computer vision application. -In OpenCV you only need applyColorMap to apply a colormap on a given image. The following sample -code reads the path to an image from command line, applies a Jet colormap on it and shows the -result: + In OpenCV you only need applyColorMap to apply a colormap on a given image. The following sample + code reads the path to an image from command line, applies a Jet colormap on it and shows the + result: -@include snippets/imgproc_applyColorMap.cpp + @include snippets/imgproc_applyColorMap.cpp -@see #ColormapTypes + @see #ColormapTypes @defgroup imgproc_subdiv2d Planar Subdivision -The Subdiv2D class described in this section is used to perform various planar subdivision on -a set of 2D points (represented as vector of Point2f). OpenCV subdivides a plane into triangles -using the Delaunay's algorithm, which corresponds to the dual graph of the Voronoi diagram. -In the figure below, the Delaunay's triangulation is marked with black lines and the Voronoi -diagram with red lines. + The Subdiv2D class described in this section is used to perform various planar subdivision on + a set of 2D points (represented as vector of Point2f). OpenCV subdivides a plane into triangles + using the Delaunay's algorithm, which corresponds to the dual graph of the Voronoi diagram. + In the figure below, the Delaunay's triangulation is marked with black lines and the Voronoi + diagram with red lines. -![Delaunay triangulation (black) and Voronoi (red)](pics/delaunay_voronoi.png) + ![Delaunay triangulation (black) and Voronoi (red)](pics/delaunay_voronoi.png) -The subdivisions can be used for the 3D piece-wise transformation of a plane, morphing, fast -location of points on the plane, building special graphs (such as NNG,RNG), and so forth. + The subdivisions can be used for the 3D piece-wise transformation of a plane, morphing, fast + location of points on the plane, building special graphs (such as NNG,RNG), and so forth. @defgroup imgproc_hist Histograms @defgroup imgproc_shape Structural Analysis and Shape Descriptors @@ -190,7 +190,6 @@ location of points on the plane, building special graphs (such as NNG,RNG), and @defgroup imgproc_feature Feature Detection @defgroup imgproc_object Object Detection @defgroup imgproc_segmentation Image Segmentation - @defgroup imgproc_c C API @defgroup imgproc_hal Hardware Acceleration Layer @{ @defgroup imgproc_hal_functions Functions diff --git a/modules/java/jar/build.xml.in b/modules/java/jar/build.xml.in index 732b398576..eefaa343b6 100644 --- a/modules/java/jar/build.xml.in +++ b/modules/java/jar/build.xml.in @@ -52,7 +52,7 @@ var pos = url.lastIndexOf('/javadoc/'); url = pos >= 0 ? (url.substring(0, pos) + '/javadoc/mymath.js') : (window.location.origin + '/mymath.js'); var script = document.createElement('script'); - script.src = '@OPENCV_MATHJAX_RELPATH@/MathJax.js?config=TeX-AMS-MML_HTMLorMML,' + url; + script.src = '@OPENCV_MATHJAX_RELPATH@/es5/tex-chtml.js,' + url; document.getElementsByTagName('head')[0].appendChild(script); ]]> diff --git a/modules/objdetect/include/opencv2/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect.hpp index fa75532c1a..7f11890608 100644 --- a/modules/objdetect/include/opencv2/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect.hpp @@ -54,59 +54,61 @@ @{ @defgroup objdetect_cascade_classifier Cascade Classifier for Object Detection -The object detector described below has been initially proposed by Paul Viola @cite Viola01 and -improved by Rainer Lienhart @cite Lienhart02 . + The object detector described below has been initially proposed by Paul Viola @cite Viola01 and + improved by Rainer Lienhart @cite Lienhart02 . -First, a classifier (namely a *cascade of boosted classifiers working with haar-like features*) is -trained with a few hundred sample views of a particular object (i.e., a face or a car), called -positive examples, that are scaled to the same size (say, 20x20), and negative examples - arbitrary -images of the same size. + First, a classifier (namely a *cascade of boosted classifiers working with haar-like features*) is + trained with a few hundred sample views of a particular object (i.e., a face or a car), called + positive examples, that are scaled to the same size (say, 20x20), and negative examples - arbitrary + images of the same size. -After a classifier is trained, it can be applied to a region of interest (of the same size as used -during the training) in an input image. The classifier outputs a "1" if the region is likely to show -the object (i.e., face/car), and "0" otherwise. To search for the object in the whole image one can -move the search window across the image and check every location using the classifier. The -classifier is designed so that it can be easily "resized" in order to be able to find the objects of -interest at different sizes, which is more efficient than resizing the image itself. So, to find an -object of an unknown size in the image the scan procedure should be done several times at different -scales. + After a classifier is trained, it can be applied to a region of interest (of the same size as used + during the training) in an input image. The classifier outputs a "1" if the region is likely to show + the object (i.e., face/car), and "0" otherwise. To search for the object in the whole image one can + move the search window across the image and check every location using the classifier. The + classifier is designed so that it can be easily "resized" in order to be able to find the objects of + interest at different sizes, which is more efficient than resizing the image itself. So, to find an + object of an unknown size in the image the scan procedure should be done several times at different + scales. -The word "cascade" in the classifier name means that the resultant classifier consists of several -simpler classifiers (*stages*) that are applied subsequently to a region of interest until at some -stage the candidate is rejected or all the stages are passed. The word "boosted" means that the -classifiers at every stage of the cascade are complex themselves and they are built out of basic -classifiers using one of four different boosting techniques (weighted voting). Currently Discrete -Adaboost, Real Adaboost, Gentle Adaboost and Logitboost are supported. The basic classifiers are -decision-tree classifiers with at least 2 leaves. Haar-like features are the input to the basic -classifiers, and are calculated as described below. The current algorithm uses the following -Haar-like features: + The word "cascade" in the classifier name means that the resultant classifier consists of several + simpler classifiers (*stages*) that are applied subsequently to a region of interest until at some + stage the candidate is rejected or all the stages are passed. The word "boosted" means that the + classifiers at every stage of the cascade are complex themselves and they are built out of basic + classifiers using one of four different boosting techniques (weighted voting). Currently Discrete + Adaboost, Real Adaboost, Gentle Adaboost and Logitboost are supported. The basic classifiers are + decision-tree classifiers with at least 2 leaves. Haar-like features are the input to the basic + classifiers, and are calculated as described below. The current algorithm uses the following + Haar-like features: -![image](pics/haarfeatures.png) + ![image](pics/haarfeatures.png) -The feature used in a particular classifier is specified by its shape (1a, 2b etc.), position within -the region of interest and the scale (this scale is not the same as the scale used at the detection -stage, though these two scales are multiplied). For example, in the case of the third line feature -(2c) the response is calculated as the difference between the sum of image pixels under the -rectangle covering the whole feature (including the two white stripes and the black stripe in the -middle) and the sum of the image pixels under the black stripe multiplied by 3 in order to -compensate for the differences in the size of areas. The sums of pixel values over a rectangular -regions are calculated rapidly using integral images (see below and the integral description). + The feature used in a particular classifier is specified by its shape (1a, 2b etc.), position within + the region of interest and the scale (this scale is not the same as the scale used at the detection + stage, though these two scales are multiplied). For example, in the case of the third line feature + (2c) the response is calculated as the difference between the sum of image pixels under the + rectangle covering the whole feature (including the two white stripes and the black stripe in the + middle) and the sum of the image pixels under the black stripe multiplied by 3 in order to + compensate for the differences in the size of areas. The sums of pixel values over a rectangular + regions are calculated rapidly using integral images (see below and the integral description). -Check @ref tutorial_cascade_classifier "the corresponding tutorial" for more details. + Check @ref tutorial_cascade_classifier "the corresponding tutorial" for more details. -The following reference is for the detection part only. There is a separate application called -opencv_traincascade that can train a cascade of boosted classifiers from a set of samples. + The following reference is for the detection part only. There is a separate application called + opencv_traincascade that can train a cascade of boosted classifiers from a set of samples. -@note In the new C++ interface it is also possible to use LBP (local binary pattern) features in -addition to Haar-like features. .. [Viola01] Paul Viola and Michael J. Jones. Rapid Object Detection -using a Boosted Cascade of Simple Features. IEEE CVPR, 2001. The paper is available online at - + @note In the new C++ interface it is also possible to use LBP (local binary pattern) features in + addition to Haar-like features. .. [Viola01] Paul Viola and Michael J. Jones. Rapid Object Detection + using a Boosted Cascade of Simple Features. IEEE CVPR, 2001. The paper is available online at + @defgroup objdetect_hog HOG (Histogram of Oriented Gradients) descriptor and object detector @defgroup objdetect_barcode Barcode detection and decoding @defgroup objdetect_qrcode QRCode detection and encoding @defgroup objdetect_dnn_face DNN-based face detection and recognition -Check @ref tutorial_dnn_face "the corresponding tutorial" for more details. + + Check @ref tutorial_dnn_face "the corresponding tutorial" for more details. + @defgroup objdetect_common Common functions and classes @defgroup objdetect_aruco ArUco markers and boards detection for robust camera pose estimation @{ diff --git a/modules/photo/include/opencv2/photo.hpp b/modules/photo/include/opencv2/photo.hpp index cef4e4da59..392232851a 100644 --- a/modules/photo/include/opencv2/photo.hpp +++ b/modules/photo/include/opencv2/photo.hpp @@ -55,30 +55,29 @@ This module includes photo processing algorithms @defgroup photo_denoise Denoising @defgroup photo_hdr HDR imaging -This section describes high dynamic range imaging algorithms namely tonemapping, exposure alignment, -camera calibration with multiple exposures and exposure fusion. + This section describes high dynamic range imaging algorithms namely tonemapping, exposure alignment, + camera calibration with multiple exposures and exposure fusion. @defgroup photo_decolor Contrast Preserving Decolorization -Useful links: + Useful links: -http://www.cse.cuhk.edu.hk/leojia/projects/color2gray/index.html + http://www.cse.cuhk.edu.hk/leojia/projects/color2gray/index.html @defgroup photo_clone Seamless Cloning -Useful links: + Useful links: -https://www.learnopencv.com/seamless-cloning-using-opencv-python-cpp + https://www.learnopencv.com/seamless-cloning-using-opencv-python-cpp @defgroup photo_render Non-Photorealistic Rendering -Useful links: + Useful links: -http://www.inf.ufrgs.br/~eslgastal/DomainTransform + http://www.inf.ufrgs.br/~eslgastal/DomainTransform -https://www.learnopencv.com/non-photorealistic-rendering-using-opencv-python-c/ + https://www.learnopencv.com/non-photorealistic-rendering-using-opencv-python-c/ - @defgroup photo_c C API @} */ diff --git a/modules/video/include/opencv2/video.hpp b/modules/video/include/opencv2/video.hpp index a3dde60399..b1c19196d4 100644 --- a/modules/video/include/opencv2/video.hpp +++ b/modules/video/include/opencv2/video.hpp @@ -49,7 +49,6 @@ @{ @defgroup video_motion Motion Analysis @defgroup video_track Object Tracking - @defgroup video_c C API @} */ diff --git a/modules/videoio/doc/videoio_overview.markdown b/modules/videoio/doc/videoio_overview.markdown index c61c36c5d8..041f2949a5 100644 --- a/modules/videoio/doc/videoio_overview.markdown +++ b/modules/videoio/doc/videoio_overview.markdown @@ -1,12 +1,14 @@ Video I/O with OpenCV Overview {#videoio_overview} -=================================== +============================== -### See also: +@tableofcontents + +@sa - @ref videoio "Video I/O Code Reference" - Tutorials: @ref tutorial_table_of_content_app General Information -=================== +------------------- The OpenCV @ref videoio module is a set of classes and functions to read and write video or images sequence. @@ -53,10 +55,11 @@ cv::VideoCapture cap(filename, cv::CAP_MSMF); //or specify the apiPreference with open cap.open(filename, cv::CAP_MSMF); ``` - @sa cv::VideoCapture::open() , cv::VideoCapture::VideoCapture() -#### How to enable backends + +How to enable backends +---------------------- There are two kinds of videoio backends: built-in backends and plugins which will be loaded at runtime (since OpenCV 4.1.0). Use functions cv::videoio_registry::getBackends, cv::videoio_registry::hasBackend and cv::videoio_registry::getBackendName to check actual presence of backend during runtime. @@ -71,7 +74,9 @@ To enable dynamically-loaded videoio backend (currently supported: GStreamer and @note Don't forget to clean CMake cache when switching between these two modes -#### Use 3rd party drivers or cameras + +Use 3rd party drivers or cameras +-------------------------------- Many industrial cameras or some video I/O devices don't provide standard driver interfaces for the operating system. Thus you can't use VideoCapture or VideoWriter with these devices. @@ -83,6 +88,7 @@ It is a common case that these libraries read/write images from/to a memory buff possible to make a `Mat` header for memory buffer (user-allocated data) and process it in-place using OpenCV functions. See cv::Mat::Mat() for more details. + The FFmpeg library ------------------ diff --git a/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp b/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp index 2eeff1cf0d..b9736da065 100644 --- a/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp @@ -45,9 +45,9 @@ int main( int argc, char** argv ) printf( " ** Press 'r' to set the border to be replicated \n"); printf( " ** Press 'ESC' to exit the program \n"); - //![create_window] +//![create_window] namedWindow( window_name, WINDOW_AUTOSIZE ); - //![create_window] +//![create_window] //![init_arguments] // Initialize arguments for the filter From b34ec576825ce8750806b8144fec8e1922bc7d51 Mon Sep 17 00:00:00 2001 From: Kumataro Date: Tue, 5 Mar 2024 22:24:42 +0900 Subject: [PATCH 11/56] Merge pull request #25141 from Kumataro:fix25140_4.x calib3d: doc: remove C API link (For 4.x) #25141 Related to #25140 (for 4.x) ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/calib3d/include/opencv2/calib3d.hpp | 2 -- modules/calib3d/src/calib3d_c_api.h | 6 ------ 2 files changed, 8 deletions(-) diff --git a/modules/calib3d/include/opencv2/calib3d.hpp b/modules/calib3d/include/opencv2/calib3d.hpp index f22c1114b2..61e3aca810 100644 --- a/modules/calib3d/include/opencv2/calib3d.hpp +++ b/modules/calib3d/include/opencv2/calib3d.hpp @@ -433,8 +433,6 @@ R & t \\ Summary: Generic camera model @cite Kannala2006 with perspective projection and without distortion correction - @defgroup calib3d_c C API - @} */ diff --git a/modules/calib3d/src/calib3d_c_api.h b/modules/calib3d/src/calib3d_c_api.h index c9ac9b49f5..cdbf021667 100644 --- a/modules/calib3d/src/calib3d_c_api.h +++ b/modules/calib3d/src/calib3d_c_api.h @@ -51,10 +51,6 @@ extern "C" { #endif -/** @addtogroup calib3d_c - @{ - */ - /****************************************************************************************\ * Camera Calibration, Pose Estimation and Stereo * \****************************************************************************************/ @@ -416,8 +412,6 @@ void cvUndistortPoints( const CvMat* src, CvMat* dst, const CvMat* R CV_DEFAULT(0), const CvMat* P CV_DEFAULT(0)); -/** @} calib3d_c */ - #ifdef __cplusplus } // extern "C" #endif From f2c38eb62f0eb56099ba0a63b9491bd69c3b5b11 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 5 Mar 2024 17:12:31 +0300 Subject: [PATCH 12/56] Backport some highgui changes from #22754 --- modules/highgui/src/window.cpp | 18 +++++----- modules/highgui/src/window_QT.cpp | 22 ++++++------ modules/highgui/src/window_gtk.cpp | 50 +++++++++++++------------- modules/highgui/src/window_w32.cpp | 34 +++++++++--------- modules/highgui/src/window_wayland.cpp | 6 ++-- 5 files changed, 65 insertions(+), 65 deletions(-) diff --git a/modules/highgui/src/window.cpp b/modules/highgui/src/window.cpp index fef71f2b31..4bb6e9d880 100644 --- a/modules/highgui/src/window.cpp +++ b/modules/highgui/src/window.cpp @@ -217,9 +217,9 @@ CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_valu switch(prop_id) { //change between fullscreen or not. - case CV_WND_PROP_FULLSCREEN: + case cv::WND_PROP_FULLSCREEN: - if (prop_value != CV_WINDOW_NORMAL && prop_value != CV_WINDOW_FULLSCREEN) // bad argument + if (prop_value != cv::WINDOW_NORMAL && prop_value != cv::WINDOW_FULLSCREEN) // bad argument break; #if defined (HAVE_QT) @@ -236,13 +236,13 @@ CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_valu break; - case CV_WND_PROP_AUTOSIZE: + case cv::WND_PROP_AUTOSIZE: #if defined (HAVE_QT) cvSetPropWindow_QT(name,prop_value); #endif break; - case CV_WND_PROP_ASPECTRATIO: + case cv::WND_PROP_ASPECT_RATIO: #if defined (HAVE_QT) cvSetRatioWindow_QT(name,prop_value); #endif @@ -305,7 +305,7 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) #else switch(prop_id) { - case CV_WND_PROP_FULLSCREEN: + case cv::WND_PROP_FULLSCREEN: #if defined (HAVE_QT) return cvGetModeWindow_QT(name); @@ -322,7 +322,7 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) #endif break; - case CV_WND_PROP_AUTOSIZE: + case cv::WND_PROP_AUTOSIZE: #if defined (HAVE_QT) return cvGetPropWindow_QT(name); @@ -335,7 +335,7 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) #endif break; - case CV_WND_PROP_ASPECTRATIO: + case cv::WND_PROP_ASPECT_RATIO: #if defined (HAVE_QT) return cvGetRatioWindow_QT(name); @@ -348,7 +348,7 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) #endif break; - case CV_WND_PROP_OPENGL: + case cv::WND_PROP_OPENGL: #if defined (HAVE_QT) return cvGetOpenGlProp_QT(name); @@ -361,7 +361,7 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) #endif break; - case CV_WND_PROP_VISIBLE: + case cv::WND_PROP_VISIBLE: #if defined (HAVE_QT) return cvGetPropVisible_QT(name); #elif defined(HAVE_WIN32UI) diff --git a/modules/highgui/src/window_QT.cpp b/modules/highgui/src/window_QT.cpp index 65bcdb5239..726cb69695 100644 --- a/modules/highgui/src/window_QT.cpp +++ b/modules/highgui/src/window_QT.cpp @@ -1016,7 +1016,7 @@ double GuiReceiver::isFullScreen(QString name) if (!w) return -1; - return w->isFullScreen() ? CV_WINDOW_FULLSCREEN : CV_WINDOW_NORMAL; + return w->isFullScreen() ? cv::WINDOW_FULLSCREEN : cv::WINDOW_NORMAL; } @@ -1702,11 +1702,11 @@ CvWindow::CvWindow(QString name, int arg2) //3: my view #ifndef HAVE_QT_OPENGL - if (arg2 & CV_WINDOW_OPENGL) + if (arg2 & cv::WINDOW_OPENGL) CV_Error( cv::Error::OpenGlNotSupported, "Library was built without OpenGL support" ); mode_display = CV_MODE_NORMAL; #else - mode_display = arg2 & CV_WINDOW_OPENGL ? CV_MODE_OPENGL : CV_MODE_NORMAL; + mode_display = arg2 & cv::WINDOW_OPENGL ? CV_MODE_OPENGL : CV_MODE_NORMAL; if (mode_display == CV_MODE_OPENGL) param_gui_mode = CV_GUI_NORMAL; #endif @@ -1837,13 +1837,13 @@ void CvWindow::setPropWindow(int flags) switch(flags) { - case CV_WINDOW_NORMAL: + case cv::WINDOW_NORMAL: myGlobalLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); param_flags = flags; break; - case CV_WINDOW_AUTOSIZE: + case cv::WINDOW_AUTOSIZE: myGlobalLayout->setSizeConstraint(QLayout::SetFixedSize); param_flags = flags; @@ -1856,14 +1856,14 @@ void CvWindow::setPropWindow(int flags) void CvWindow::toggleFullScreen(int flags) { - if (isFullScreen() && flags == CV_WINDOW_NORMAL) + if (isFullScreen() && flags == cv::WINDOW_NORMAL) { showTools(); showNormal(); return; } - if (!isFullScreen() && flags == CV_WINDOW_FULLSCREEN) + if (!isFullScreen() && flags == cv::WINDOW_FULLSCREEN) { hideTools(); showFullScreen(); @@ -2013,9 +2013,9 @@ void CvWindow::createGlobalLayout() #endif setMinimumSize(1, 1); - if (param_flags == CV_WINDOW_AUTOSIZE) + if (param_flags == cv::WINDOW_AUTOSIZE) myGlobalLayout->setSizeConstraint(QLayout::SetFixedSize); - else if (param_flags == CV_WINDOW_NORMAL) + else if (param_flags == cv::WINDOW_NORMAL) myGlobalLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); } @@ -2605,7 +2605,7 @@ void DefaultViewPort::setRatio(int flags) return; //if valid flags - if (flags == CV_WINDOW_FREERATIO || flags == CV_WINDOW_KEEPRATIO) + if (flags == cv::WINDOW_FREERATIO || flags == cv::WINDOW_KEEPRATIO) { centralWidget->param_ratio_mode = flags; param_keepRatio = flags; @@ -2816,7 +2816,7 @@ void DefaultViewPort::resizeEvent(QResizeEvent* evnt) ratioX = width() / float(image2Draw_mat->cols); ratioY = height() / float(image2Draw_mat->rows); - if (param_keepRatio == CV_WINDOW_KEEPRATIO)//to keep the same aspect ratio + if (param_keepRatio == cv::WINDOW_KEEPRATIO)//to keep the same aspect ratio { QSize newSize = QSize(image2Draw_mat->cols, image2Draw_mat->rows); newSize.scale(evnt->size(), Qt::KeepAspectRatio); diff --git a/modules/highgui/src/window_gtk.cpp b/modules/highgui/src/window_gtk.cpp index fa169f0bee..c3fb853305 100644 --- a/modules/highgui/src/window_gtk.cpp +++ b/modules/highgui/src/window_gtk.cpp @@ -271,7 +271,7 @@ cvImageWidget_get_preferred_width (GtkWidget *widget, gint *minimal_width, gint CvImageWidget * image_widget = CV_IMAGE_WIDGET( widget ); if(image_widget->original_image != NULL) { - *minimal_width = (image_widget->flags & CV_WINDOW_AUTOSIZE) != CV_WINDOW_AUTOSIZE ? + *minimal_width = (image_widget->flags & cv::WINDOW_AUTOSIZE) != cv::WINDOW_AUTOSIZE ? gdk_window_get_width(gtk_widget_get_window(widget)) : image_widget->original_image->cols; } else { @@ -295,7 +295,7 @@ cvImageWidget_get_preferred_height (GtkWidget *widget, gint *minimal_height, gin CvImageWidget * image_widget = CV_IMAGE_WIDGET( widget ); if(image_widget->original_image != NULL) { - *minimal_height = (image_widget->flags & CV_WINDOW_AUTOSIZE) != CV_WINDOW_AUTOSIZE ? + *minimal_height = (image_widget->flags & cv::WINDOW_AUTOSIZE) != cv::WINDOW_AUTOSIZE ? gdk_window_get_height(gtk_widget_get_window(widget)) : image_widget->original_image->rows; } else { @@ -322,7 +322,7 @@ cvImageWidget_size_request (GtkWidget *widget, //printf("cvImageWidget_size_request "); // the case the first time cvShowImage called or when AUTOSIZE if( image_widget->original_image && - ((image_widget->flags & CV_WINDOW_AUTOSIZE) || + ((image_widget->flags & cv::WINDOW_AUTOSIZE) || (image_widget->flags & CV_WINDOW_NO_IMAGE))) { //printf("original "); @@ -351,7 +351,7 @@ static void cvImageWidget_set_size(GtkWidget * widget, int max_width, int max_he //printf("cvImageWidget_set_size %d %d\n", max_width, max_height); // don't allow to set the size - if(image_widget->flags & CV_WINDOW_AUTOSIZE) return; + if(image_widget->flags & cv::WINDOW_AUTOSIZE) return; if(!image_widget->original_image) return; CvSize scaled_image_size = cvImageWidget_calc_size( image_widget->original_image->cols, @@ -390,7 +390,7 @@ cvImageWidget_size_allocate (GtkWidget *widget, image_widget = CV_IMAGE_WIDGET (widget); - if( (image_widget->flags & CV_WINDOW_AUTOSIZE)==0 && image_widget->original_image ){ + if( (image_widget->flags & cv::WINDOW_AUTOSIZE)==0 && image_widget->original_image ){ // (re) allocated scaled image if( image_widget->flags & CV_WINDOW_NO_IMAGE ){ cvImageWidget_set_size( widget, image_widget->original_image->cols, @@ -407,7 +407,7 @@ cvImageWidget_size_allocate (GtkWidget *widget, image_widget = CV_IMAGE_WIDGET (widget); if( image_widget->original_image && - ((image_widget->flags & CV_WINDOW_AUTOSIZE) || + ((image_widget->flags & cv::WINDOW_AUTOSIZE) || (image_widget->flags & CV_WINDOW_NO_IMAGE)) ) { #if defined (GTK_VERSION3) @@ -808,7 +808,7 @@ void cvSetModeWindow_GTK( const char* name, double prop_value)//Yannick Verdie static bool setModeWindow_(const std::shared_ptr& window, int mode) { - if (window->flags & CV_WINDOW_AUTOSIZE) //if the flag CV_WINDOW_AUTOSIZE is set + if (window->flags & cv::WINDOW_AUTOSIZE) //if the flag cv::WINDOW_AUTOSIZE is set return false; //so easy to do fullscreen here, Linux rocks ! @@ -816,17 +816,17 @@ static bool setModeWindow_(const std::shared_ptr& window, int mode) if (window->status == mode) return true; - if (window->status==CV_WINDOW_FULLSCREEN && mode==CV_WINDOW_NORMAL) + if (window->status==cv::WINDOW_FULLSCREEN && mode==cv::WINDOW_NORMAL) { gtk_window_unfullscreen(GTK_WINDOW(window->frame)); - window->status=CV_WINDOW_NORMAL; + window->status=cv::WINDOW_NORMAL; return true; } - if (window->status==CV_WINDOW_NORMAL && mode==CV_WINDOW_FULLSCREEN) + if (window->status==cv::WINDOW_NORMAL && mode==cv::WINDOW_FULLSCREEN) { gtk_window_fullscreen(GTK_WINDOW(window->frame)); - window->status=CV_WINDOW_FULLSCREEN; + window->status=cv::WINDOW_FULLSCREEN; return true; } @@ -859,7 +859,7 @@ double cvGetPropWindowAutoSize_GTK(const char* name) if (!window) return -1; // keep silence here - double result = window->flags & CV_WINDOW_AUTOSIZE; + double result = window->flags & cv::WINDOW_AUTOSIZE; return result; } @@ -1037,7 +1037,7 @@ static std::shared_ptr namedWindow_(const std::string& name, int flags auto window_ptr = std::make_shared(name); CvWindow* window = window_ptr.get(); window->flags = flags; - window->status = CV_WINDOW_NORMAL;//YV + window->status = cv::WINDOW_NORMAL;//YV window->frame = gtk_window_new( GTK_WINDOW_TOPLEVEL ); @@ -1049,10 +1049,10 @@ static std::shared_ptr namedWindow_(const std::string& name, int flags gtk_widget_show( window->paned ); #ifndef HAVE_OPENGL - if (flags & CV_WINDOW_OPENGL) + if (flags & cv::WINDOW_OPENGL) CV_Error( cv::Error::OpenGlNotSupported, "Library was built without OpenGL support" ); #else - if (flags & CV_WINDOW_OPENGL) + if (flags & cv::WINDOW_OPENGL) createGlContext(window); window->glDrawCallback = 0; @@ -1097,7 +1097,7 @@ static std::shared_ptr namedWindow_(const std::string& name, int flags getGTKWindows().push_back(window_ptr); } - bool b_nautosize = ((flags & CV_WINDOW_AUTOSIZE) == 0); + bool b_nautosize = ((flags & cv::WINDOW_AUTOSIZE) == 0); gtk_window_set_resizable( GTK_WINDOW(window->frame), b_nautosize ); // allow window to be resized @@ -1333,7 +1333,7 @@ void resizeWindow_(const std::shared_ptr& window, int width, int heigh { CV_Assert(window); CvImageWidget* image_widget = CV_IMAGE_WIDGET( window->widget ); - //if(image_widget->flags & CV_WINDOW_AUTOSIZE) + //if(image_widget->flags & cv::WINDOW_AUTOSIZE) //EXIT; gtk_window_set_resizable( GTK_WINDOW(window->frame), 1 ); @@ -1916,7 +1916,7 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da if( cv_event >= 0 ) { // scale point if image is scaled - if( (image_widget->flags & CV_WINDOW_AUTOSIZE)==0 && + if( (image_widget->flags & cv::WINDOW_AUTOSIZE)==0 && image_widget->original_image && image_widget->scaled_image ) { @@ -2080,17 +2080,17 @@ public: // see cvGetWindowProperty switch (prop) { - case CV_WND_PROP_FULLSCREEN: + case cv::WND_PROP_FULLSCREEN: return (double)window->status; - case CV_WND_PROP_AUTOSIZE: - return (window->flags & CV_WINDOW_AUTOSIZE) ? 1.0 : 0.0; + case cv::WND_PROP_AUTOSIZE: + return (window->flags & cv::WINDOW_AUTOSIZE) ? 1.0 : 0.0; - case CV_WND_PROP_ASPECTRATIO: + case cv::WND_PROP_ASPECT_RATIO: return getRatioWindow_(window); #ifdef HAVE_OPENGL - case CV_WND_PROP_OPENGL: + case cv::WND_PROP_OPENGL: return window->useGl ? 1.0 : 0.0; #endif @@ -2107,8 +2107,8 @@ public: // see cvSetWindowProperty switch (prop) { - case CV_WND_PROP_FULLSCREEN: - if (value != CV_WINDOW_NORMAL && value != CV_WINDOW_FULLSCREEN) // bad arg + case cv::WND_PROP_FULLSCREEN: + if (value != cv::WINDOW_NORMAL && value != cv::WINDOW_FULLSCREEN) // bad arg break; setModeWindow_(window, value); return true; diff --git a/modules/highgui/src/window_w32.cpp b/modules/highgui/src/window_w32.cpp index a3a71a6cc4..a693b1de90 100644 --- a/modules/highgui/src/window_w32.cpp +++ b/modules/highgui/src/window_w32.cpp @@ -587,7 +587,7 @@ void cvSetModeWindow_W32(const char* name, double prop_value)//Yannick Verdie static bool setModeWindow_(CvWindow& window, int mode) { - if (window.flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set + if (window.flags & cv::WINDOW_AUTOSIZE)//if the flag cv::WINDOW_AUTOSIZE is set return false; if (window.status == mode) @@ -597,18 +597,18 @@ static bool setModeWindow_(CvWindow& window, int mode) DWORD dwStyle = (DWORD)GetWindowLongPtr(window.frame, GWL_STYLE); CvRect position; - if (window.status == CV_WINDOW_FULLSCREEN && mode == CV_WINDOW_NORMAL) + if (window.status == cv::WINDOW_FULLSCREEN && mode == cv::WINDOW_NORMAL) { icvLoadWindowPos(window.name.c_str(), position); SetWindowLongPtr(window.frame, GWL_STYLE, dwStyle | WS_CAPTION | WS_THICKFRAME); SetWindowPos(window.frame, HWND_TOP, position.x, position.y , position.width,position.height, SWP_NOZORDER | SWP_FRAMECHANGED); - window.status=CV_WINDOW_NORMAL; + window.status=cv::WINDOW_NORMAL; return true; } - if (window.status == CV_WINDOW_NORMAL && mode == CV_WINDOW_FULLSCREEN) + if (window.status == cv::WINDOW_NORMAL && mode == cv::WINDOW_FULLSCREEN) { //save dimension RECT rect = { 0 }; @@ -630,7 +630,7 @@ static bool setModeWindow_(CvWindow& window, int mode) SetWindowLongPtr(window.frame, GWL_STYLE, dwStyle & ~WS_CAPTION & ~WS_THICKFRAME); SetWindowPos(window.frame, HWND_TOP, position.x, position.y , position.width,position.height, SWP_NOZORDER | SWP_FRAMECHANGED); - window.status=CV_WINDOW_FULLSCREEN; + window.status=cv::WINDOW_FULLSCREEN; return true; } @@ -836,7 +836,7 @@ double cvGetPropWindowAutoSize_W32(const char* name) if (!window) CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); - result = window->flags & CV_WINDOW_AUTOSIZE; + result = window->flags & cv::WINDOW_AUTOSIZE; return result; } @@ -1055,11 +1055,11 @@ static std::shared_ptr namedWindow_(const std::string& name, int flags CvRect rect; icvLoadWindowPos(name.c_str(), rect); - if (!(flags & CV_WINDOW_AUTOSIZE))//YV add border in order to resize the window + if (!(flags & cv::WINDOW_AUTOSIZE))//YV add border in order to resize the window defStyle |= WS_SIZEBOX; #ifdef HAVE_OPENGL - if (flags & CV_WINDOW_OPENGL) + if (flags & cv::WINDOW_OPENGL) defStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS; #endif @@ -1076,14 +1076,14 @@ static std::shared_ptr namedWindow_(const std::string& name, int flags CV_Error(Error::StsError, "Frame window can not be created"); #ifndef HAVE_OPENGL - if (flags & CV_WINDOW_OPENGL) + if (flags & cv::WINDOW_OPENGL) CV_Error(Error::OpenGlNotSupported, "Library was built without OpenGL support"); #else useGl = false; hGLDC = 0; hGLRC = 0; - if (flags & CV_WINDOW_OPENGL) + if (flags & cv::WINDOW_OPENGL) createGlContext(hWnd, hGLDC, hGLRC, useGl); #endif @@ -1117,7 +1117,7 @@ static std::shared_ptr namedWindow_(const std::string& name, int flags #endif window->last_key = 0; - window->status = CV_WINDOW_NORMAL;//YV + window->status = cv::WINDOW_NORMAL;//YV window->on_mouse = 0; window->on_mouse_param = 0; @@ -1338,7 +1338,7 @@ static void icvUpdateWindowPos(CvWindow& window) { RECT rect = { 0 }; - if ((window.flags & CV_WINDOW_AUTOSIZE) && window.image) + if ((window.flags & cv::WINDOW_AUTOSIZE) && window.image) { int i; SIZE size = {0,0}; @@ -1383,7 +1383,7 @@ cvShowImage(const char* name, const CvArr* arr) window = icvFindWindowByName(name); if (!window) { - cvNamedWindow(name, CV_WINDOW_AUTOSIZE); + cvNamedWindow(name, cv::WINDOW_AUTOSIZE); window = icvFindWindowByName(name); } } @@ -1548,7 +1548,7 @@ MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; case WM_GETMINMAXINFO: - if (!(window.flags & CV_WINDOW_AUTOSIZE)) + if (!(window.flags & cv::WINDOW_AUTOSIZE)) { MINMAXINFO* minmax = (MINMAXINFO*)lParam; RECT rect = { 0 }; @@ -1579,7 +1579,7 @@ MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) MoveWindow(window.toolbar.toolbar, 0, 0, pos->cx, rect.bottom - rect.top, TRUE); } - if (!(window.flags & CV_WINDOW_AUTOSIZE)) + if (!(window.flags & cv::WINDOW_AUTOSIZE)) icvUpdateWindowPos(window); break; @@ -1846,7 +1846,7 @@ static LRESULT CALLBACK HighGUIProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); - if (window.flags & CV_WINDOW_AUTOSIZE) + if (window.flags & cv::WINDOW_AUTOSIZE) { // As user can't change window size, do not scale window coordinates. Underlying windowing system // may prevent full window from being displayed and in this case coordinates should not be scaled. @@ -1908,7 +1908,7 @@ static LRESULT CALLBACK HighGUIProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM SetDIBColorTable(window.dc, 0, 255, table); } - if (window.flags & CV_WINDOW_AUTOSIZE) + if (window.flags & cv::WINDOW_AUTOSIZE) { BitBlt(hdc, 0, 0, size.cx, size.cy, window.dc, 0, 0, SRCCOPY); } diff --git a/modules/highgui/src/window_wayland.cpp b/modules/highgui/src/window_wayland.cpp index be5eb243b7..61a2f0e17a 100644 --- a/modules/highgui/src/window_wayland.cpp +++ b/modules/highgui/src/window_wayland.cpp @@ -1509,7 +1509,7 @@ void cv_wl_viewer::get_preferred_height_for_width(int width, int &minimum, int & minimum = natural = image_.size().height; } else { natural = static_cast(width * aspect_ratio(image_.size())); - minimum = (flags_ & CV_WINDOW_FREERATIO ? 0 : natural); + minimum = (flags_ & cv::WINDOW_FREERATIO ? 0 : natural); } } @@ -1548,11 +1548,11 @@ cv::Rect cv_wl_viewer::draw(void *data, cv::Size const &size, bool force) { CV_Assert(image_.size() == size); write_mat_to_xrgb8888(image_, data); } else { - if (flags_ & CV_WINDOW_FREERATIO) { + if (flags_ & cv::WINDOW_FREERATIO) { cv::Mat resized; cv::resize(image_, resized, size); write_mat_to_xrgb8888(resized, data); - } else /* CV_WINDOW_KEEPRATIO */ { + } else /* cv::WINDOW_KEEPRATIO */ { auto rect = cv::Rect(cv::Point(0, 0), size); if (aspect_ratio(size) >= aspect_ratio(image_.size())) { rect.height = static_cast(image_.size().height * ((double) rect.width / image_.size().width)); From 98aed21dd4f54004470b0b620ca92b0a8bff32e8 Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Tue, 5 Mar 2024 18:18:24 +0300 Subject: [PATCH 13/56] Avoid copy of ONNX graph during import --- modules/dnn/src/onnx/onnx_importer.cpp | 44 +++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp index 7e3d1017e6..5583fd0453 100644 --- a/modules/dnn/src/onnx/onnx_importer.cpp +++ b/modules/dnn/src/onnx/onnx_importer.cpp @@ -112,7 +112,7 @@ protected: std::unique_ptr layerHandler; Net& dstNet; - opencv_onnx::GraphProto graph_proto; + opencv_onnx::GraphProto* graph_proto; std::string framework_name; std::map constBlobs; @@ -787,7 +787,7 @@ void ONNXImporter::setParamsDtype(LayerParams& layerParams, const opencv_onnx::N void ONNXImporter::populateNet() { CV_Assert(model_proto.has_graph()); - graph_proto = model_proto.graph(); + graph_proto = model_proto.mutable_graph(); std::string framework_version; if (model_proto.has_producer_name()) @@ -799,25 +799,25 @@ void ONNXImporter::populateNet() << (model_proto.has_ir_version() ? cv::format(" v%d", (int)model_proto.ir_version()) : cv::String()) << " model produced by '" << framework_name << "'" << (framework_version.empty() ? cv::String() : cv::format(":%s", framework_version.c_str())) - << ". Number of nodes = " << graph_proto.node_size() - << ", initializers = " << graph_proto.initializer_size() - << ", inputs = " << graph_proto.input_size() - << ", outputs = " << graph_proto.output_size() + << ". Number of nodes = " << graph_proto->node_size() + << ", initializers = " << graph_proto->initializer_size() + << ", inputs = " << graph_proto->input_size() + << ", outputs = " << graph_proto->output_size() ); parseOperatorSet(); - simplifySubgraphs(graph_proto); + simplifySubgraphs(*graph_proto); - const int layersSize = graph_proto.node_size(); + const int layersSize = graph_proto->node_size(); CV_LOG_DEBUG(NULL, "DNN/ONNX: graph simplified to " << layersSize << " nodes"); - constBlobs = getGraphTensors(graph_proto); // scan GraphProto.initializer + constBlobs = getGraphTensors(*graph_proto); // scan GraphProto.initializer std::vector netInputs; // map with network inputs (without const blobs) // Add all the inputs shapes. It includes as constant blobs as network's inputs shapes. - for (int i = 0; i < graph_proto.input_size(); ++i) + for (int i = 0; i < graph_proto->input_size(); ++i) { - const opencv_onnx::ValueInfoProto& valueInfoProto = graph_proto.input(i); + const opencv_onnx::ValueInfoProto& valueInfoProto = graph_proto->input(i); CV_Assert(valueInfoProto.has_name()); const std::string& name = valueInfoProto.name(); CV_Assert(valueInfoProto.has_type()); @@ -873,26 +873,26 @@ void ONNXImporter::populateNet() } // dump outputs - for (int i = 0; i < graph_proto.output_size(); ++i) + for (int i = 0; i < graph_proto->output_size(); ++i) { - dumpValueInfoProto(i, graph_proto.output(i), "output"); + dumpValueInfoProto(i, graph_proto->output(i), "output"); } if (DNN_DIAGNOSTICS_RUN) { CV_LOG_INFO(NULL, "DNN/ONNX: start diagnostic run!"); - layerHandler->fillRegistry(graph_proto); + layerHandler->fillRegistry(*graph_proto); } for(int li = 0; li < layersSize; li++) { - const opencv_onnx::NodeProto& node_proto = graph_proto.node(li); + const opencv_onnx::NodeProto& node_proto = graph_proto->node(li); handleNode(node_proto); } // register outputs - for (int i = 0; i < graph_proto.output_size(); ++i) + for (int i = 0; i < graph_proto->output_size(); ++i) { - const std::string& output_name = graph_proto.output(i).name(); + const std::string& output_name = graph_proto->output(i).name(); if (output_name.empty()) { CV_LOG_ERROR(NULL, "DNN/ONNX: can't register output without name: " << i); @@ -3180,9 +3180,9 @@ void ONNXImporter::parseLayerNorm(LayerParams& layerParams, const opencv_onnx::N { // remove from graph proto for (size_t i = 1; i < node_proto.output_size(); i++) { - for (int j = graph_proto.output_size() - 1; j >= 0; j--) { - if (graph_proto.output(j).name() == node_proto.output(i)) { - graph_proto.mutable_output()->DeleteSubrange(j, 1); + for (int j = graph_proto->output_size() - 1; j >= 0; j--) { + if (graph_proto->output(j).name() == node_proto.output(i)) { + graph_proto->mutable_output()->DeleteSubrange(j, 1); break; } } @@ -3683,9 +3683,9 @@ void ONNXImporter::parseQEltwise(LayerParams& layerParams, const opencv_onnx::No layerParams.type = "ScaleInt8"; layerParams.set("bias_term", op == "sum"); int axis = 1; - for (int i = 0; i < graph_proto.initializer_size(); i++) + for (int i = 0; i < graph_proto->initializer_size(); i++) { - opencv_onnx::TensorProto tensor_proto = graph_proto.initializer(i); + opencv_onnx::TensorProto tensor_proto = graph_proto->initializer(i); if (tensor_proto.name() == node_proto.input(constId)) { axis = inpShape.size() - tensor_proto.dims_size(); From 7b77ebc8c3fb1f49973cb5361aed2af8a072837a Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Tue, 5 Mar 2024 17:27:17 +0300 Subject: [PATCH 14/56] doc: removed duplicated markdown file, fixed gapi tutorial --- doc/tutorials/others/_old/table_of_content_objdetect.markdown | 4 ---- modules/gapi/doc/00-root.markdown | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 doc/tutorials/others/_old/table_of_content_objdetect.markdown diff --git a/doc/tutorials/others/_old/table_of_content_objdetect.markdown b/doc/tutorials/others/_old/table_of_content_objdetect.markdown deleted file mode 100644 index 0aa69fcd8d..0000000000 --- a/doc/tutorials/others/_old/table_of_content_objdetect.markdown +++ /dev/null @@ -1,4 +0,0 @@ -Object Detection (objdetect module) {#tutorial_table_of_content_objdetect} -=================================== - -Content has been moved to this page: @ref tutorial_table_of_content_other diff --git a/modules/gapi/doc/00-root.markdown b/modules/gapi/doc/00-root.markdown index cfbbe8cf3f..cb99495c1b 100644 --- a/modules/gapi/doc/00-root.markdown +++ b/modules/gapi/doc/00-root.markdown @@ -17,7 +17,7 @@ is volatile at the moment and there may be minor but compatibility-breaking changes in the future. # Contents -gapi + G-API documentation is organized into the following chapters: - @subpage gapi_purposes From f174363f600aa578874b3f0cb7b190c5dad8a07d Mon Sep 17 00:00:00 2001 From: Dmitry Matveev Date: Wed, 6 Mar 2024 14:15:49 +0000 Subject: [PATCH 15/56] Merge pull request #25055 from dmatveev:dm/value_initialized_gmat G-API: A quick value-initialization support GMat #25055 This PR enables `GMat` objects to be value-initialized in the same way as it was done for `GScalar`s (and, possibly, other types). - Added some helper methods in backends to distinguish if a certain G-type value initialization is supported or not; - Added tests, including negative. Where it is needed: - Further extension of the OVCV backend (#24379 - will be refreshed soon); - Further experiments with DNN module; - Further experiments with "G-API behind UMat" sort of aggregation. In the current form, PR can be reviewed & merged (@TolyaTalamanov please have a look) ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- modules/gapi/include/opencv2/gapi/gmat.hpp | 12 ++ modules/gapi/include/opencv2/gapi/gscalar.hpp | 11 +- modules/gapi/src/api/gbackend.cpp | 3 + modules/gapi/src/api/gbackend_priv.hpp | 8 ++ modules/gapi/src/api/gcomputation.cpp | 9 +- modules/gapi/src/api/gmat.cpp | 4 + modules/gapi/src/api/gproto.cpp | 1 + modules/gapi/src/backends/cpu/gcpubackend.cpp | 11 ++ modules/gapi/src/backends/ocl/goclbackend.cpp | 11 ++ modules/gapi/src/compiler/gobjref.hpp | 1 + modules/gapi/src/compiler/passes/exec.cpp | 24 +++- modules/gapi/src/executor/gexecutor.cpp | 6 + .../gapi/src/executor/gthreadedexecutor.cpp | 6 +- modules/gapi/test/gapi_mat_tests.cpp | 114 ++++++++++++++++++ 14 files changed, 208 insertions(+), 13 deletions(-) create mode 100644 modules/gapi/test/gapi_mat_tests.cpp diff --git a/modules/gapi/include/opencv2/gapi/gmat.hpp b/modules/gapi/include/opencv2/gapi/gmat.hpp index 198cb728d0..6d6f74ff7f 100644 --- a/modules/gapi/include/opencv2/gapi/gmat.hpp +++ b/modules/gapi/include/opencv2/gapi/gmat.hpp @@ -77,6 +77,18 @@ public: */ GAPI_WRAP GMat(); // Empty constructor + /** + * @brief Constructs a value-initialized GMat + * + * GMat may be associated with a buffer at graph construction time. + * It is useful when some operation has a Mat input which doesn't + * change during the program execution, and is set only once. + * In this case, there's no need to declare such GMat as graph input. + * + * @param m a cv::Mat buffer to associate with this GMat object. + */ + GAPI_WRAP explicit GMat(cv::Mat m); // Value-initialization constructor + /// @private GMat(const GNode &n, std::size_t out); // Operation result constructor /// @private diff --git a/modules/gapi/include/opencv2/gapi/gscalar.hpp b/modules/gapi/include/opencv2/gapi/gscalar.hpp index 43d12c782a..de0dfe1383 100644 --- a/modules/gapi/include/opencv2/gapi/gscalar.hpp +++ b/modules/gapi/include/opencv2/gapi/gscalar.hpp @@ -54,12 +54,11 @@ public: /** * @brief Constructs a value-initialized GScalar * - * In contrast with GMat (which can be either an explicit graph input - * or a result of some operation), GScalars may have their values - * be associated at graph construction time. It is useful when - * some operation has a GScalar input which doesn't change during - * the program execution, and is set only once. In this case, - * there is no need to declare such GScalar as a graph input. + * GScalars may have their values be associated at graph + * construction time. It is useful when some operation has a + * GScalar input which doesn't change during the program + * execution, and is set only once. In this case, there is no need + * to declare such GScalar as a graph input. * * @note The value of GScalar may be overwritten by assigning some * other GScalar to the object using `operator=` -- on the diff --git a/modules/gapi/src/api/gbackend.cpp b/modules/gapi/src/api/gbackend.cpp index 46c8dc1640..dc51eef76d 100644 --- a/modules/gapi/src/api/gbackend.cpp +++ b/modules/gapi/src/api/gbackend.cpp @@ -80,6 +80,9 @@ bool cv::gapi::GBackend::Priv::allowsMerge(const cv::gimpl::GIslandModel::Graph return true; } +bool cv::gapi::GBackend::Priv::supportsConst(cv::GShape) const { + return false; +} // GBackend public implementation ////////////////////////////////////////////// cv::gapi::GBackend::GBackend() diff --git a/modules/gapi/src/api/gbackend_priv.hpp b/modules/gapi/src/api/gbackend_priv.hpp index 5609b304aa..80436abde8 100644 --- a/modules/gapi/src/api/gbackend_priv.hpp +++ b/modules/gapi/src/api/gbackend_priv.hpp @@ -84,6 +84,14 @@ public: const ade::NodeHandle &slot_nh, const ade::NodeHandle &b_nh) const; + // Ask backend if it supports CONST_VAL data of the given shape or not. + // If the backend does support this data type, a Data node with such + // value can be fused into the backend's Island body. + // If the backend doesn't support this data type, a Data node won't + // be fused into the Islands's body -- will be marked as an in-graph + // input connection for this Island. + virtual bool supportsConst(cv::GShape shape) const; + virtual ~Priv() = default; }; diff --git a/modules/gapi/src/api/gcomputation.cpp b/modules/gapi/src/api/gcomputation.cpp index c57c66b879..076c1acee3 100644 --- a/modules/gapi/src/api/gcomputation.cpp +++ b/modules/gapi/src/api/gcomputation.cpp @@ -191,8 +191,8 @@ void cv::GComputation::recompile(GMetaArgs&& in_metas, GCompileArgs &&args) if (m_priv->m_lastMetas != in_metas) { if (m_priv->m_lastCompiled && - m_priv->m_lastCompiled.canReshape() && - formats_are_same(m_priv->m_lastMetas, in_metas)) + m_priv->m_lastCompiled.canReshape() && + formats_are_same(m_priv->m_lastMetas, in_metas)) { m_priv->m_lastCompiled.reshape(in_metas, args); } @@ -203,6 +203,11 @@ void cv::GComputation::recompile(GMetaArgs&& in_metas, GCompileArgs &&args) } m_priv->m_lastMetas = in_metas; } + else if (in_metas.size() == 0) { + // Happens when the graph is head-less (e.g. starts with const-vals only) + // always compile ad-hoc + m_priv->m_lastCompiled = compile(GMetaArgs(in_metas), std::move(args)); + } } void cv::GComputation::apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args) diff --git a/modules/gapi/src/api/gmat.cpp b/modules/gapi/src/api/gmat.cpp index 03f2e736be..c6bcb288ba 100644 --- a/modules/gapi/src/api/gmat.cpp +++ b/modules/gapi/src/api/gmat.cpp @@ -26,6 +26,10 @@ cv::GMat::GMat(const GNode &n, std::size_t out) { } +cv::GMat::GMat(cv::Mat m) + : m_priv(new GOrigin(GShape::GMAT, cv::gimpl::ConstVal(m))) { +} + cv::GOrigin& cv::GMat::priv() { return *m_priv; diff --git a/modules/gapi/src/api/gproto.cpp b/modules/gapi/src/api/gproto.cpp index 43bcfb9c14..bb60f4e51f 100644 --- a/modules/gapi/src/api/gproto.cpp +++ b/modules/gapi/src/api/gproto.cpp @@ -80,6 +80,7 @@ cv::GRunArg cv::value_of(const cv::GOrigin &origin) { case GShape::GSCALAR: return GRunArg(util::get(origin.value)); case GShape::GARRAY: return GRunArg(util::get(origin.value)); + case GShape::GMAT: return GRunArg(util::get(origin.value)); default: util::throw_error(std::logic_error("Unsupported shape for constant")); } } diff --git a/modules/gapi/src/backends/cpu/gcpubackend.cpp b/modules/gapi/src/backends/cpu/gcpubackend.cpp index f50f8ecd28..c6a35ead27 100644 --- a/modules/gapi/src/backends/cpu/gcpubackend.cpp +++ b/modules/gapi/src/backends/cpu/gcpubackend.cpp @@ -65,6 +65,17 @@ namespace { return EPtr{new cv::gimpl::GCPUExecutable(graph, compileArgs, nodes)}; } + + virtual bool supportsConst(cv::GShape shape) const override + { + // Supports all types of const values + return shape == cv::GShape::GOPAQUE + || shape == cv::GShape::GSCALAR + || shape == cv::GShape::GARRAY; + // yes, value-initialized GMats are not supported currently + // as in-island data -- compiler will lift these values to the + // GIslandModel's SLOT level (will be handled uniformly) + } }; } diff --git a/modules/gapi/src/backends/ocl/goclbackend.cpp b/modules/gapi/src/backends/ocl/goclbackend.cpp index 9c6d7154e4..eb63cec35b 100644 --- a/modules/gapi/src/backends/ocl/goclbackend.cpp +++ b/modules/gapi/src/backends/ocl/goclbackend.cpp @@ -62,6 +62,17 @@ namespace { return EPtr{new cv::gimpl::GOCLExecutable(graph, nodes)}; } + + virtual bool supportsConst(cv::GShape shape) const override + { + // Supports all types of const values + return shape == cv::GShape::GOPAQUE + || shape == cv::GShape::GSCALAR + || shape == cv::GShape::GARRAY; + // yes, value-initialized GMats are not supported currently + // as in-island data -- compiler will lift these values to the + // GIslandModel's SLOT level (will be handled uniformly) + } }; } diff --git a/modules/gapi/src/compiler/gobjref.hpp b/modules/gapi/src/compiler/gobjref.hpp index bca6fa525e..8f68142cc5 100644 --- a/modules/gapi/src/compiler/gobjref.hpp +++ b/modules/gapi/src/compiler/gobjref.hpp @@ -24,6 +24,7 @@ namespace gimpl < util::monostate , cv::Scalar , cv::detail::VectorRef + , cv::Mat >; struct RcDesc diff --git a/modules/gapi/src/compiler/passes/exec.cpp b/modules/gapi/src/compiler/passes/exec.cpp index 24dcef7bc1..a978e47b42 100644 --- a/modules/gapi/src/compiler/passes/exec.cpp +++ b/modules/gapi/src/compiler/passes/exec.cpp @@ -9,7 +9,7 @@ #include #include // list -#include // setw, etc +#include // setw, etc #include // ofstream #include #include @@ -85,7 +85,7 @@ namespace const auto& backend = *src_g.metadata().get().backends.cbegin(); const auto& proto = src_g.metadata().get(); - GIsland::node_set all, in_ops, out_ops; + GIsland::node_set all, in_ops, out_ops, in_cvals; all.insert(src_g.nodes().begin(), src_g.nodes().end()); @@ -99,7 +99,22 @@ namespace all.erase(nh); out_ops.insert(nh->inNodes().begin(), nh->inNodes().end()); } - + for (const auto& nh : src_g.nodes()) + { + if (src_g.metadata(nh).get().t == NodeType::DATA) + { + const auto &d = src_g.metadata(nh).get(); + if (d.storage == Data::Storage::CONST_VAL + && !backend.priv().supportsConst(d.shape)) { + // don't put this node into the island's graph - so the island + // executable don't need to handle value-initialized G-type manually. + // Still mark its readers as inputs + all.erase(nh); + in_cvals.insert(nh); + in_ops.insert(nh->outNodes().begin(), nh->outNodes().end()); + } + } + } auto isl = std::make_shared(backend, std::move(all), std::move(in_ops), @@ -108,7 +123,8 @@ namespace auto ih = GIslandModel::mkIslandNode(g, std::move(isl)); - for (const auto& nh : proto.in_nhs) + for (const auto& nh : ade::util::chain(ade::util::toRange(proto.in_nhs), + ade::util::toRange(in_cvals))) { auto slot = GIslandModel::mkSlotNode(g, nh); g.link(slot, ih); diff --git a/modules/gapi/src/executor/gexecutor.cpp b/modules/gapi/src/executor/gexecutor.cpp index bf25302b75..f68aa18fbb 100644 --- a/modules/gapi/src/executor/gexecutor.cpp +++ b/modules/gapi/src/executor/gexecutor.cpp @@ -208,6 +208,12 @@ void cv::gimpl::GExecutor::initResource(const ade::NodeHandle & nh, const ade::N switch (d.shape) { case GShape::GMAT: + if (d.storage == Data::Storage::CONST_VAL) + { + auto rc = RcDesc{d.rc, d.shape, d.ctor}; + magazine::bindInArgExec(m_res, rc, m_gm.metadata(orig_nh).get().arg); + } + else { // Let island allocate it's outputs if it can, // allocate cv::Mat and wrap it with RMat otherwise diff --git a/modules/gapi/src/executor/gthreadedexecutor.cpp b/modules/gapi/src/executor/gthreadedexecutor.cpp index 6999b7bb8d..ecd53eb952 100644 --- a/modules/gapi/src/executor/gthreadedexecutor.cpp +++ b/modules/gapi/src/executor/gthreadedexecutor.cpp @@ -175,7 +175,11 @@ void cv::gimpl::GThreadedExecutor::initResource(const ade::NodeHandle &nh, const // to as it is bound externally (e.g. already in the m_state.mag) switch (d.shape) { - case GShape::GMAT: { + case GShape::GMAT: + if (d.storage == Data::Storage::CONST_VAL) { + auto rc = RcDesc{d.rc, d.shape, d.ctor}; + magazine::bindInArgExec(m_state.mag, rc, m_gm.metadata(orig_nh).get().arg); + } else { // Let island allocate it's outputs if it can, // allocate cv::Mat and wrap it with RMat otherwise GAPI_Assert(!nh->inNodes().empty()); diff --git a/modules/gapi/test/gapi_mat_tests.cpp b/modules/gapi/test/gapi_mat_tests.cpp new file mode 100644 index 0000000000..0f2d1cc7a2 --- /dev/null +++ b/modules/gapi/test/gapi_mat_tests.cpp @@ -0,0 +1,114 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2024 Intel Corporation + + +#include "test_precomp.hpp" + +#include +#include +#include + +namespace opencv_test +{ +namespace +{ +enum class KernelPackage: int +{ + OCV, + OCL, + FLUID, +}; +std::ostream& operator<< (std::ostream &os, const KernelPackage &e) +{ + switch (e) + { +#define _C(X) case KernelPackage::X: os << #X; break + _C(OCV); + _C(OCL); + _C(FLUID); +#undef _C + default: GAPI_Error("Unknown package"); + } + return os; +} +} // namespace + +struct GMatWithValue : public TestWithParam { + cv::GKernelPackage getKernelPackage() { + switch (GetParam()) { + case KernelPackage::OCV: return cv::gapi::core::cpu::kernels(); + case KernelPackage::OCL: return cv::gapi::core::ocl::kernels(); + case KernelPackage::FLUID: return cv::gapi::core::fluid::kernels(); + default: GAPI_Error("Unknown package"); + } + } +}; + +TEST_P(GMatWithValue, SingleIsland) +{ + cv::Size sz(2, 2); + cv::Mat in_mat = cv::Mat::eye(sz, CV_8U); + + cv::GComputationT addEye([&](cv::GMat in) { + return in + cv::GMat(cv::Mat::eye(sz, CV_8U)); + }); + + cv::Mat out_mat; + addEye.apply(in_mat, out_mat, cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + + cv::Mat out_mat_ref = in_mat*2; + EXPECT_EQ(0, cvtest::norm(out_mat, out_mat_ref, NORM_INF)); +} + +TEST_P(GMatWithValue, GraphWithNoInput) +{ + cv::Mat cval = cv::Mat::eye(cv::Size(2, 2), CV_8U); + cv::GMat gval = cv::GMat(cval); + cv::GMat out = cv::gapi::bitwise_not(gval); + + cv::Mat out_mat; + cv::GComputation f(cv::GIn(), cv::GOut(out)); + + // Compiling this isn't supported for now + EXPECT_ANY_THROW(f.compile(cv::descr_of(cval), + cv::compile_args(cv::gapi::use_only{getKernelPackage()}))); +} + +INSTANTIATE_TEST_CASE_P(GAPI_GMat, GMatWithValue, + Values(KernelPackage::OCV, + KernelPackage::OCL, + KernelPackage::FLUID)); + +TEST(GAPI_MatWithValue, MultipleIslands) +{ + // This test employs a non-trivial island fusion process + // as there's multiple backends in the graph + + cv::Size sz(2, 2); + cv::Mat cval2 = cv::Mat::eye(sz, CV_8U) * 2; + cv::Mat cval1 = cv::Mat::eye(sz, CV_8U); + + cv::GMat in; + cv::GMat tmp = in + cv::GMat(cval2); // Will be a Fluid operation + cv::GMat out = tmp - cv::GMat(cval1); // Will be an OCV operation + + cv::GKernelPackage fluid_kernels = cv::gapi::core::fluid::kernels(); + cv::GKernelPackage opencv_kernels = cv::gapi::core::cpu::kernels(); + fluid_kernels.remove(); + opencv_kernels.remove(); + auto kernels = cv::gapi::combine(fluid_kernels, opencv_kernels); + + cv::Mat in_mat = cv::Mat::zeros(sz, CV_8U); + cv::Mat out_mat; + auto cc = cv::GComputation(in, out) + .compile(cv::descr_of(in_mat), + cv::compile_args(cv::gapi::use_only{kernels})); + cc(cv::gin(in_mat), cv::gout(out_mat)); + + EXPECT_EQ(0, cvtest::norm(out_mat, cv::Mat::eye(sz, CV_8U), NORM_INF)); +} + +} // namespace opencv_test From ad61e7e21d80951ef578c5d3d9ef4bae24ca5661 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Wed, 6 Mar 2024 17:34:06 +0300 Subject: [PATCH 16/56] doc: auto-enabling DOT support in documentation if dot executable has been found --- doc/CMakeLists.txt | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 8a27ac89bc..ad7b39da99 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -17,8 +17,8 @@ endif() find_package(Doxygen) if(DOXYGEN_FOUND) if (DOXYGEN_VERSION VERSION_LESS 1.9.8) - message(WARNING "Found doxygen ${DOXYGEN_VERSION}, version 1.9.8 is used for testing, there is - a chance your documentation will look different or have some limitations.") + message(WARNING "Found doxygen ${DOXYGEN_VERSION}, version 1.9.8 is used for testing, there is " + "a chance your documentation will look different or have some limitations.") endif() add_custom_target(doxygen) @@ -197,10 +197,18 @@ if(DOXYGEN_FOUND) set(OPENCV_MATHJAX_RELPATH "https://cdn.jsdelivr.net/npm/mathjax@3.0.1" CACHE STRING "URI to a MathJax installation") - set(OPENCV_DOCS_DOT_PATH "" CACHE PATH "Doxygen/DOT_PATH value") - set(CMAKECONFIG_DOT_PATH "${OPENCV_DOCS_DOT_PATH}") - set(OPENCV_DOCS_HAVE_DOT "NO" CACHE BOOL "Doxygen: build extra diagrams") + if (DOXYGEN_DOT_EXECUTABLE) + message(STATUS "Found DOT executable: ${DOXYGEN_DOT_EXECUTABLE}") + set(init_dot_path "${DOXYGEN_DOT_EXECUTABLE}") + set(init_dot_mode "YES") + else() + set(init_dot_path "") + set(init_dot_mode "NO") + endif() + set(OPENCV_DOCS_DOT_PATH "${init_dot_path}" CACHE PATH "Doxygen/DOT_PATH value") + set(OPENCV_DOCS_HAVE_DOT "${init_dot_mode}" CACHE BOOL "Doxygen: build extra diagrams") + set(CMAKECONFIG_DOT_PATH "${OPENCV_DOCS_DOT_PATH}") set(CMAKECONFIG_HAVE_DOT "${OPENCV_DOCS_HAVE_DOT}") # 'png' is good enough for compatibility (but requires +50% storage space) From ed93384817e1085560939183befed79e96fb649c Mon Sep 17 00:00:00 2001 From: MaximSmolskiy Date: Fri, 8 Mar 2024 03:25:40 +0300 Subject: [PATCH 17/56] Fix bug in maskBoundingRect --- modules/imgproc/src/shapedescr.cpp | 12 ++++-------- modules/imgproc/test/test_boundingrect.cpp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/modules/imgproc/src/shapedescr.cpp b/modules/imgproc/src/shapedescr.cpp index fe5664abf2..9be6038d9d 100644 --- a/modules/imgproc/src/shapedescr.cpp +++ b/modules/imgproc/src/shapedescr.cpp @@ -1056,16 +1056,12 @@ static Rect maskBoundingRect( const Mat& img ) for( ; j < offset; j++ ) if( _ptr[j] ) { + if( j < xmin ) + xmin = j; + if( j > xmax ) + xmax = j; have_nz = 1; - break; } - if( j < offset ) - { - if( j < xmin ) - xmin = j; - if( j > xmax ) - xmax = j; - } if( offset < size.width ) { xmin -= offset; diff --git a/modules/imgproc/test/test_boundingrect.cpp b/modules/imgproc/test/test_boundingrect.cpp index 52a84e5cfe..d3e5495b4f 100644 --- a/modules/imgproc/test/test_boundingrect.cpp +++ b/modules/imgproc/test/test_boundingrect.cpp @@ -140,4 +140,20 @@ void CV_BoundingRectTest::run(int) TEST (Imgproc_BoundingRect, accuracy) { CV_BoundingRectTest test; test.safe_run(); } +TEST (Imgproc_BoundingRect, bug_24217) +{ + for (int image_width = 3; image_width < 20; image_width++) + { + for (int image_height = 1; image_height < 15; image_height++) + { + cv::Rect rect(0, image_height - 1, 3, 1); + + cv::Mat image(cv::Size(image_width, image_height), CV_8UC1, cv::Scalar(0)); + image(rect) = 255; + + ASSERT_EQ(boundingRect(image), rect); + } + } +} + }} // namespace From 6a370ba9e733d82e0f1ade32b1d48157109d6deb Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Fri, 8 Mar 2024 10:46:07 +0300 Subject: [PATCH 18/56] Avoid extra memset in convolution initialization --- modules/dnn/src/layers/cpu_kernels/convolution.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/dnn/src/layers/cpu_kernels/convolution.cpp b/modules/dnn/src/layers/cpu_kernels/convolution.cpp index 6ae304f29d..7bbcf1e8e8 100644 --- a/modules/dnn/src/layers/cpu_kernels/convolution.cpp +++ b/modules/dnn/src/layers/cpu_kernels/convolution.cpp @@ -210,7 +210,6 @@ Ptr initFastConv( { conv->weightsBuf_FP16.resize(nweights + VEC_ALIGN); auto weightsPtr_FP16 = conv->getWeightsFP16(); - memset(reinterpret_cast(weightsPtr_FP16), 0, nweights * sizeof(weightsPtr_FP16[0])); parallel_for_(Range(0, C), [&](const Range& r0){ for(int c = r0.start; c < r0.end; c++) @@ -222,7 +221,6 @@ Ptr initFastConv( { conv->weightsBuf.resize(nweights + VEC_ALIGN); auto weightsPtr = conv->getWeights(); - memset(weightsPtr, 0, nweights*sizeof(weightsPtr[0])); parallel_for_(Range(0, C), [&](const Range& r0) { for(int c = r0.start; c < r0.end; c++) @@ -276,14 +274,12 @@ Ptr initFastConv( { conv->weightsWinoBuf_FP16.resize(nweights + VEC_ALIGN); wptrWino_FP16 = conv->getWeightsWinoFP16(); - memset(reinterpret_cast(wptrWino_FP16), 0, nweights * sizeof(wptrWino_FP16[0])); } else #endif { conv->weightsWinoBuf.resize(nweights + VEC_ALIGN); wptrWino = conv->getWeightsWino(); - memset(wptrWino, 0, nweights * sizeof(wptrWino[0])); } parallel_for_(Range(0, K), [&](const Range& r0){ @@ -377,14 +373,12 @@ Ptr initFastConv( { conv->weightsBuf_FP16.resize(nweights_FP16 + VEC_ALIGN); weightsPtr_FP16 = conv->getWeightsFP16(); - memset(reinterpret_cast(weightsPtr_FP16), 0, nweights_FP16*sizeof(weightsPtr_FP16[0])); } else #endif { conv->weightsBuf.resize(nweights + VEC_ALIGN); weightsPtr = conv->getWeights(); - memset(weightsPtr, 0, nweights*sizeof(weightsPtr[0])); } // Pack the weight. @@ -651,7 +645,6 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta for (int c = 0; c < Cg; c++, inptr += inp_planesize, inpbuf += CONV_NR_esz) { _cvt32f16f(inptr, (float16_t *)inpbuf, slice_len); - memset(inpbuf + slice_len * esz, 0, (CONV_NR - slice_len) * esz); } } else @@ -659,7 +652,6 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta for (int c = 0; c < Cg; c++, inptr += inp_planesize, inpbuf += CONV_NR_esz) { memcpy(inpbuf, inptr, slice_len * esz); - memset(inpbuf + slice_len * esz, 0, (CONV_NR - slice_len) * esz); } } } From 50b36ef8236cefee5f7869811cad02ef3a670323 Mon Sep 17 00:00:00 2001 From: Misha Klatis Date: Fri, 8 Mar 2024 10:22:54 -0800 Subject: [PATCH 19/56] ios build fixes --- modules/videoio/src/cap_avfoundation.mm | 4 ++-- platforms/ios/Info.Dynamic.plist.in | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/videoio/src/cap_avfoundation.mm b/modules/videoio/src/cap_avfoundation.mm index d0f2b41c37..0853e57255 100644 --- a/modules/videoio/src/cap_avfoundation.mm +++ b/modules/videoio/src/cap_avfoundation.mm @@ -824,7 +824,7 @@ CvCaptureFile::CvCaptureFile(const char* filename) { // Available since iOS 15 #if TARGET_OS_VISION || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 150000) - if (@available(iOS 15, visionOS 1, *)) { + if (@available(iOS 15, *)) { [mAsset loadTracksWithMediaType:AVMediaTypeVideo completionHandler:^(NSArray* tracks, NSError* err) { if (err != nil) { handleTracks(tracks, filename); @@ -1311,7 +1311,7 @@ CvVideoWriter_AVFoundation::CvVideoWriter_AVFoundation(const char* filename, int #if TARGET_OS_VISION || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) }else if(fourcc == CV_FOURCC('H','2','6','5') || fourcc == CV_FOURCC('h','v','c','1') || fourcc == CV_FOURCC('H','E','V','C') || fourcc == CV_FOURCC('h','e','v','c')){ - if (@available(iOS 11, visionOS 1, *)) { + if (@available(iOS 11, *)) { codec = [AVVideoCodecTypeHEVC copy]; } else { codec = [AVVideoCodecTypeH264 copy]; diff --git a/platforms/ios/Info.Dynamic.plist.in b/platforms/ios/Info.Dynamic.plist.in index e48fffdb9d..ce41a52d5b 100644 --- a/platforms/ios/Info.Dynamic.plist.in +++ b/platforms/ios/Info.Dynamic.plist.in @@ -23,7 +23,7 @@ iPhoneOS MinimumOSVersion - 8.0 + ${IPHONEOS_DEPLOYMENT_TARGET} UIDeviceFamily 1 From 8550c415ef8e98b74851a6c9d433d0c3c13c9570 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Thu, 7 Mar 2024 17:36:07 +0300 Subject: [PATCH 20/56] doc: fix formulas in JavaDoc broken after Doxygen upgrade --- CMakeLists.txt | 4 ++++ doc/CMakeLists.txt | 3 --- doc/mymath.js | 5 ++++- modules/java/jar/build.xml.in | 13 +++++++++---- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd01eb3a2c..933aed91d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -572,6 +572,10 @@ if(OPENCV_DISABLE_FILESYSTEM_SUPPORT) add_definitions(-DOPENCV_HAVE_FILESYSTEM_SUPPORT=0) endif() +# MathJax is used for math rendering by both Doxygen HTML and JavaDoc, so +# this var have to be defined before "modules" AND "doc" are processed +set(OPENCV_MATHJAX_RELPATH "https://cdn.jsdelivr.net/npm/mathjax@3.0.1" CACHE STRING "URI to a MathJax installation") + # ---------------------------------------------------------------------------- # Get actual OpenCV version number from sources # ---------------------------------------------------------------------------- diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index ad7b39da99..411b77808a 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -195,9 +195,6 @@ if(DOXYGEN_FOUND) list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tutorial-utils.js") string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_HTML_FILES "${CMAKE_DOXYGEN_HTML_FILES}") - set(OPENCV_MATHJAX_RELPATH "https://cdn.jsdelivr.net/npm/mathjax@3.0.1" CACHE STRING "URI to a MathJax installation") - - if (DOXYGEN_DOT_EXECUTABLE) message(STATUS "Found DOT executable: ${DOXYGEN_DOT_EXECUTABLE}") set(init_dot_path "${DOXYGEN_DOT_EXECUTABLE}") diff --git a/doc/mymath.js b/doc/mymath.js index 1ab480b5a4..028fa41cd2 100644 --- a/doc/mymath.js +++ b/doc/mymath.js @@ -1,6 +1,8 @@ // diff --git a/modules/java/jar/build.xml.in b/modules/java/jar/build.xml.in index eefaa343b6..41ef1d55ba 100644 --- a/modules/java/jar/build.xml.in +++ b/modules/java/jar/build.xml.in @@ -45,18 +45,23 @@ @CMAKE_CONFIG_OPENCV_JAVADOC_LINK@ additionalparam="--allow-script-in-comments" > -
+ var url = window.location.href; var pos = url.lastIndexOf('/javadoc/'); url = pos >= 0 ? (url.substring(0, pos) + '/javadoc/mymath.js') : (window.location.origin + '/mymath.js'); var script = document.createElement('script'); - script.src = '@OPENCV_MATHJAX_RELPATH@/es5/tex-chtml.js,' + url; - document.getElementsByTagName('head')[0].appendChild(script); + script.setAttribute("src", url); + script.setAttribute("defer", "") + document.head.appendChild(script); + script = document.createElement('script'); + script.setAttribute("src", '@OPENCV_MATHJAX_RELPATH@/es5/tex-chtml.js'); + script.setAttribute("defer", "") + document.head.appendChild(script); ]]> -
+ From 01a4abb2c2f945621a28a8940f085689aac212f0 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Tue, 12 Mar 2024 19:47:18 +0300 Subject: [PATCH 21/56] RISC-V: fixed comparison of float32 vectors --- .../opencv2/core/hal/intrin_rvv_scalable.hpp | 78 ++++++++++--------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp b/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp index e2475e0e7d..49d5cae5ee 100644 --- a/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp @@ -775,56 +775,62 @@ OPENCV_HAL_IMPL_RVV_SIGNED_SHIFT_OP(v_int32, VTraits::vlanes()) OPENCV_HAL_IMPL_RVV_SIGNED_SHIFT_OP(v_int64, VTraits::vlanes()) ////////////// Comparison ////////////// -#define OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, op, intrin, suffix, vl) \ +#define OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, op, intrin, suffix) \ inline _Tpvec v_##op(const _Tpvec& a, const _Tpvec& b) \ { \ + size_t VLEN = VTraits<_Tpvec>::vlanes(); \ uint64_t ones = -1; \ - return vmerge(intrin(a, b, vl), vmv_v_x_##suffix##m1(0, vl), ones, vl); \ + return vmerge(intrin(a, b, VLEN), vmv_v_x_##suffix##m1(0, VLEN), ones, VLEN); \ } -#define OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, op, intrin, suffix, vl) \ +#define OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, op, intrin, suffix) \ inline _Tpvec v_##op (const _Tpvec& a, const _Tpvec& b) \ { \ - union { uint64 u; double d; } ones; ones.u = -1; \ - return _Tpvec(vfmerge(intrin(a, b, vl), vfmv_v_f_##suffix##m1(0, vl), ones.d, vl)); \ + size_t VLEN = VTraits<_Tpvec>::vlanes(); \ + union { uint64_t u; VTraits<_Tpvec>::lane_type d; } ones; \ + ones.u = -1; \ + auto diff = intrin(a, b, VLEN); \ + auto z = vfmv_v_f_##suffix##m1(0, VLEN); \ + auto res = vfmerge(diff, z, ones.d, VLEN); \ + return _Tpvec(res); \ } //TODO -#define OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(_Tpvec, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, eq, vmseq, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ne, vmsne, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, lt, vmsltu, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, gt, vmsgtu, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, le, vmsleu, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ge, vmsgeu, suffix, vl) +#define OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(_Tpvec, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, eq, vmseq, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ne, vmsne, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, lt, vmsltu, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, gt, vmsgtu, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, le, vmsleu, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ge, vmsgeu, suffix) -#define OPENCV_HAL_IMPL_RVV_SIGNED_CMP(_Tpvec, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, eq, vmseq, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ne, vmsne, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, lt, vmslt, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, gt, vmsgt, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, le, vmsle, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ge, vmsge, suffix, vl) +#define OPENCV_HAL_IMPL_RVV_SIGNED_CMP(_Tpvec, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, eq, vmseq, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ne, vmsne, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, lt, vmslt, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, gt, vmsgt, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, le, vmsle, suffix) \ +OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ge, vmsge, suffix) -#define OPENCV_HAL_IMPL_RVV_FLOAT_CMP(_Tpvec, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, eq, vmfeq, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, ne, vmfne, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, lt, vmflt, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, gt, vmfgt, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, le, vmfle, suffix, vl) \ -OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, ge, vmfge, suffix, vl) +#define OPENCV_HAL_IMPL_RVV_FLOAT_CMP(_Tpvec, suffix) \ +OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, eq, vmfeq, suffix) \ +OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, ne, vmfne, suffix) \ +OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, lt, vmflt, suffix) \ +OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, gt, vmfgt, suffix) \ +OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, le, vmfle, suffix) \ +OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, ge, vmfge, suffix) -OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint8, u8, VTraits::vlanes()) -OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint16, u16, VTraits::vlanes()) -OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint32, u32, VTraits::vlanes()) -OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint64, u64, VTraits::vlanes()) -OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int8, i8, VTraits::vlanes()) -OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int16, i16, VTraits::vlanes()) -OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int32, i32, VTraits::vlanes()) -OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int64, i64, VTraits::vlanes()) -OPENCV_HAL_IMPL_RVV_FLOAT_CMP(v_float32, f32, VTraits::vlanes()) +OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint8, u8) +OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint16, u16) +OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint32, u32) +OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint64, u64) +OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int8, i8) +OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int16, i16) +OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int32, i32) +OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int64, i64) +OPENCV_HAL_IMPL_RVV_FLOAT_CMP(v_float32, f32) #if CV_SIMD_SCALABLE_64F -OPENCV_HAL_IMPL_RVV_FLOAT_CMP(v_float64, f64, VTraits::vlanes()) +OPENCV_HAL_IMPL_RVV_FLOAT_CMP(v_float64, f64) #endif inline v_float32 v_not_nan(const v_float32& a) From 6fc926ea4d11efd8025dbed98157e70372293480 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Tue, 12 Mar 2024 17:38:15 +0300 Subject: [PATCH 22/56] Updated RVV intrinsics and test to remove initializer_list --- .../opencv2/core/hal/intrin_rvv_scalable.hpp | 8 -- modules/core/test/test_intrin_utils.hpp | 127 +----------------- 2 files changed, 2 insertions(+), 133 deletions(-) diff --git a/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp b/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp index e2475e0e7d..ceb0fa6429 100644 --- a/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp @@ -8,9 +8,6 @@ #ifndef OPENCV_HAL_INTRIN_RVV_SCALABLE_HPP #define OPENCV_HAL_INTRIN_RVV_SCALABLE_HPP -#include -#include -#include #include // RVV intrinsics have been renamed in version 0.11, so we need to include @@ -418,11 +415,6 @@ inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ { \ vse##width(ptr, vslidedown_vx_##suffix##m1(vmv(0, vl), a, hvl, vl), hvl); \ } \ -inline _Tpvec v_load(std::initializer_list<_Tp> nScalars) \ -{ \ - assert(nScalars.size() == vl); \ - return vle##width##_v_##suffix##m1(nScalars.begin(), nScalars.size()); \ -} \ template \ _Tpvec v_load_##suffix(Targs... nScalars) \ { \ diff --git a/modules/core/test/test_intrin_utils.hpp b/modules/core/test/test_intrin_utils.hpp index 38b8d10f7b..be4f7beac7 100644 --- a/modules/core/test/test_intrin_utils.hpp +++ b/modules/core/test/test_intrin_utils.hpp @@ -22,130 +22,6 @@ void test_hal_intrin_float16(); #ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY -template struct Data; -template struct initializer; - -#if CV_SIMD_SCALABLE -template <> struct initializer<128> -{ - template static R init(const Data & d) - { - return v_load({d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15], - d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31], - d[32], d[33], d[34], d[35], d[36], d[37], d[38], d[39], d[40], d[41], d[42], d[43], d[44], d[45], d[46], d[47], - d[48], d[49], d[50], d[51], d[52], d[53], d[54], d[55], d[56], d[57], d[58], d[59], d[60], d[61], d[62], d[63], - d[64], d[65], d[66], d[67], d[68], d[69], d[70], d[71], d[72], d[73], d[74], d[75], d[76], d[77], d[78], d[79], - d[80], d[81], d[82], d[83], d[84], d[85], d[86], d[87], d[88], d[89], d[90], d[91], d[92], d[93], d[94], d[95], - d[96], d[97], d[98], d[99], d[100], d[101], d[102], d[103], d[104], d[105], d[106], d[107], d[108], d[109], d[110], d[111], - d[112], d[113], d[114], d[115], d[116], d[117], d[118], d[119], d[120], d[121], d[122], d[123], d[124], d[125], d[126], d[127]}); - } -}; - -template <> struct initializer<64> -{ - template static R init(const Data & d) - { - return v_load({d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15], - d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31], - d[32], d[33], d[34], d[35], d[36], d[37], d[38], d[39], d[40], d[41], d[42], d[43], d[44], d[45], d[46], d[47], - d[48], d[49], d[50], d[51], d[52], d[53], d[54], d[55], d[56], d[57], d[58], d[59], d[60], d[61], d[62], d[63]}); - } -}; - -template <> struct initializer<32> -{ - template static R init(const Data & d) - { - return v_load({d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15], - d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31]}); - } -}; - -template <> struct initializer<16> -{ - template static R init(const Data & d) - { - return v_load({d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]}); - } -}; - -template <> struct initializer<8> -{ - template static R init(const Data & d) - { - return v_load({d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]}); - } -}; - -template <> struct initializer<4> -{ - template static R init(const Data & d) - { - return v_load({d[0], d[1], d[2], d[3]}); - } -}; - -template <> struct initializer<2> -{ - template static R init(const Data & d) - { - return v_load({d[0], d[1]}); - } -}; - -#else -template <> struct initializer<64> -{ - template static R init(const Data & d) - { - return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15], - d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31], - d[32], d[33], d[34], d[35], d[36], d[37], d[38], d[39], d[40], d[41], d[42], d[43], d[44], d[45], d[46], d[47], - d[48], d[49], d[50], d[51], d[52], d[53], d[54], d[55], d[56], d[57], d[58], d[59], d[60], d[61], d[62], d[63]); - } -}; - -template <> struct initializer<32> -{ - template static R init(const Data & d) - { - return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15], - d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31]); - } -}; - -template <> struct initializer<16> -{ - template static R init(const Data & d) - { - return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); - } -}; - -template <> struct initializer<8> -{ - template static R init(const Data & d) - { - return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]); - } -}; - -template <> struct initializer<4> -{ - template static R init(const Data & d) - { - return R(d[0], d[1], d[2], d[3]); - } -}; - -template <> struct initializer<2> -{ - template static R init(const Data & d) - { - return R(d[0], d[1]); - } -}; -#endif //================================================================================================== template struct Data @@ -168,7 +44,8 @@ template struct Data } operator R () const { - return initializer::max_nlanes>().init(*this); + CV_Assert(VTraits::vlanes() <= VTraits::max_nlanes); + return vx_load(d); } Data & operator=(const R & r) { From 0d413068df308cffb3f36eed3d1e980d950e72f3 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Wed, 13 Mar 2024 22:12:22 +0300 Subject: [PATCH 23/56] doc: fix toggle buttons in some tutorials --- doc/tutorial-utils.js | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/doc/tutorial-utils.js b/doc/tutorial-utils.js index 6462872580..3f08f1d2c1 100644 --- a/doc/tutorial-utils.js +++ b/doc/tutorial-utils.js @@ -50,7 +50,7 @@ function addButton(label, buttonName) { function buttonsToAdd($elements, $heading, $type) { if ($elements.length === 0) { - $elements = $("" + $type + ":contains(" + $heading.html() + ")").parent().prev("div.newInnerHTML"); + return; } var arr = jQuery.makeArray($elements); var seen = {}; @@ -72,18 +72,12 @@ function buttonsToAdd($elements, $heading, $type) { } function addTutorialsButtons() { - $("h2").each(function() { - $heading = $(this); - $smallerHeadings = $(this).nextUntil("h2").filter("h3").add($(this).nextUntil("h2").find("h3")); - if ($smallerHeadings.length) { - $smallerHeadings.each(function() { - var $elements = $(this).nextUntil("h2,h3").filter("div.newInnerHTML"); - buttonsToAdd($elements, $(this), "h3"); - }); - } else { - var $elements = $(this).nextUntil("h2").filter("div.newInnerHTML"); - buttonsToAdd($elements, $heading, "h2"); - } + $("h1").each(function() { + var $elements = $(this).nextUntil("h1") + var $lower = $elements.find("div.newInnerHTML") + $elements = $elements.add($lower) + $elements = $elements.filter("div.newInnerHTML") + buttonsToAdd($elements, $(this), "h1") }); $(".toggleable_button").first().click(); var $clickDefault = $('.toggleable_button.label_python').first(); From 6da2ddcf0e614ecace25c1ad07c8a51054a7e9a2 Mon Sep 17 00:00:00 2001 From: Oleg Pipikin Date: Mon, 11 Mar 2024 20:23:48 +0400 Subject: [PATCH 24/56] Fix for OpenVINO 2024.0 Remove support OpenVINO lower than 2022.1 release Remove legacy InferenceEngine wrappers --- cmake/OpenCVDetectInferenceEngine.cmake | 64 -- modules/dnn/src/ie_ngraph.cpp | 697 ++---------------- modules/dnn/src/ie_ngraph.hpp | 42 +- .../dnn/src/int8layers/batch_norm_layer.cpp | 12 +- .../dnn/src/int8layers/convolution_layer.cpp | 62 +- .../dnn/src/int8layers/elementwise_layers.cpp | 20 +- modules/dnn/src/int8layers/eltwise_layer.cpp | 8 +- .../src/int8layers/fully_connected_layer.cpp | 32 +- modules/dnn/src/int8layers/pooling_layer.cpp | 23 +- modules/dnn/src/int8layers/scale_layer.cpp | 14 +- modules/dnn/src/int8layers/softmax_layer.cpp | 6 +- modules/dnn/src/layers/batch_norm_layer.cpp | 14 +- modules/dnn/src/layers/blank_layer.cpp | 4 +- modules/dnn/src/layers/concat_layer.cpp | 13 +- modules/dnn/src/layers/const_layer.cpp | 16 +- modules/dnn/src/layers/convolution_layer.cpp | 74 +- .../dnn/src/layers/crop_and_resize_layer.cpp | 22 +- .../dnn/src/layers/detection_output_layer.cpp | 30 +- modules/dnn/src/layers/elementwise_layers.cpp | 92 +-- modules/dnn/src/layers/eltwise_layer.cpp | 20 +- modules/dnn/src/layers/flatten_layer.cpp | 7 +- .../dnn/src/layers/fully_connected_layer.cpp | 18 +- modules/dnn/src/layers/gemm_layer.cpp | 26 +- .../dnn/src/layers/instance_norm_layer.cpp | 23 +- modules/dnn/src/layers/layer_norm.cpp | 25 +- modules/dnn/src/layers/lrn_layer.cpp | 4 +- modules/dnn/src/layers/matmul_layer.cpp | 8 +- .../dnn/src/layers/max_unpooling_layer.cpp | 22 +- modules/dnn/src/layers/mvn_layer.cpp | 8 +- .../dnn/src/layers/nary_eltwise_layers.cpp | 26 +- .../dnn/src/layers/normalize_bbox_layer.cpp | 14 +- modules/dnn/src/layers/padding_layer.cpp | 12 +- modules/dnn/src/layers/permute_layer.cpp | 6 +- modules/dnn/src/layers/pooling_layer.cpp | 45 +- modules/dnn/src/layers/prior_box_layer.cpp | 39 +- modules/dnn/src/layers/proposal_layer.cpp | 16 +- modules/dnn/src/layers/region_layer.cpp | 155 ++-- modules/dnn/src/layers/reorg_layer.cpp | 8 +- modules/dnn/src/layers/reshape_layer.cpp | 6 +- modules/dnn/src/layers/resize_layer.cpp | 74 +- modules/dnn/src/layers/scale_layer.cpp | 27 +- modules/dnn/src/layers/slice_layer.cpp | 14 +- modules/dnn/src/layers/softmax_layer.cpp | 4 +- modules/dnn/src/net_openvino.cpp | 112 +-- modules/dnn/src/op_inf_engine.cpp | 139 +--- modules/dnn/src/op_inf_engine.hpp | 73 +- modules/dnn/src/op_webnn.hpp | 2 +- modules/dnn/test/test_ie_models.cpp | 145 ++-- 48 files changed, 646 insertions(+), 1677 deletions(-) diff --git a/cmake/OpenCVDetectInferenceEngine.cmake b/cmake/OpenCVDetectInferenceEngine.cmake index 319fd5bf0a..9a2eb38b03 100644 --- a/cmake/OpenCVDetectInferenceEngine.cmake +++ b/cmake/OpenCVDetectInferenceEngine.cmake @@ -13,67 +13,3 @@ if(WITH_OPENVINO) return() endif() endif() - -# ====================== - -if(WITH_OPENVINO) - find_package(OpenVINO QUIET) - if(OpenVINO_FOUND) - message(STATUS "OpenVINO FOUND: ${OpenVINO_VERSION}") - math(EXPR ver "${OpenVINO_VERSION_MAJOR} * 1000000 + ${OpenVINO_VERSION_MINOR} * 10000 + ${OpenVINO_VERSION_PATCH} * 100") - ocv_add_external_target(openvino "" "openvino::runtime" "INF_ENGINE_RELEASE=${ver};HAVE_NGRAPH;HAVE_DNN_NGRAPH;HAVE_INF_ENGINE") - set(HAVE_OPENVINO 1) - return() - endif() -endif() - -# ====================== - -find_package(InferenceEngine QUIET) -if(InferenceEngine_FOUND) - set(INF_ENGINE_TARGET ${InferenceEngine_LIBRARIES}) - set(INF_ENGINE_VERSION "${InferenceEngine_VERSION}") - message(STATUS "Detected InferenceEngine: cmake package (${InferenceEngine_VERSION})") -endif() - -if(DEFINED InferenceEngine_VERSION) - message(STATUS "InferenceEngine: ${InferenceEngine_VERSION}") - if(NOT INF_ENGINE_RELEASE AND NOT (InferenceEngine_VERSION VERSION_LESS "2021.4")) - math(EXPR INF_ENGINE_RELEASE_INIT "${InferenceEngine_VERSION_MAJOR} * 1000000 + ${InferenceEngine_VERSION_MINOR} * 10000 + ${InferenceEngine_VERSION_PATCH} * 100") - endif() -endif() -if(NOT INF_ENGINE_RELEASE AND NOT INF_ENGINE_RELEASE_INIT) - message(STATUS "WARNING: InferenceEngine version has not been set, 2021.4.2 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.") - set(INF_ENGINE_RELEASE_INIT "2021040200") -elseif(DEFINED INF_ENGINE_RELEASE) - set(INF_ENGINE_RELEASE_INIT "${INF_ENGINE_RELEASE}") -endif() -set(INF_ENGINE_RELEASE "${INF_ENGINE_RELEASE_INIT}" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)") - -set(tgts) -set(defs) - -# Add more features to the target -if(INF_ENGINE_TARGET) - set_target_properties(${INF_ENGINE_TARGET} PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}" - ) - list(APPEND tgts ${INF_ENGINE_TARGET}) - list(APPEND defs "INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}" "HAVE_INF_ENGINE") -endif() - -if(WITH_NGRAPH OR NOT DEFINED WITH_NGRAPH) - find_package(ngraph QUIET) - if(ngraph_FOUND) - ocv_assert(TARGET ngraph::ngraph) - if(INF_ENGINE_RELEASE VERSION_LESS "2019039999") - message(WARNING "nGraph is not tested with current InferenceEngine version: INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}") - endif() - message(STATUS "Detected ngraph: cmake package (${ngraph_VERSION})") - set(HAVE_NGRAPH ON) - list(APPEND tgts ngraph::ngraph) - list(APPEND defs "HAVE_NGRAPH" "HAVE_DNN_NGRAPH") - endif() -endif() - -ocv_add_external_target(openvino "" "${tgts}" "${defs}") diff --git a/modules/dnn/src/ie_ngraph.cpp b/modules/dnn/src/ie_ngraph.cpp index 18aa8cc3b6..6e7b9f9be5 100644 --- a/modules/dnn/src/ie_ngraph.cpp +++ b/modules/dnn/src/ie_ngraph.cpp @@ -14,7 +14,7 @@ #include #ifdef HAVE_DNN_NGRAPH -#include +#include #endif // HAVE_DNN_NGRAPH #include @@ -35,36 +35,6 @@ static bool DNN_IE_SERIALIZE = utils::getConfigurationParameterBool("OPENCV_DNN_ static std::string kDefaultInpLayerName = "opencv_ngraph_empty_inp_layer_name"; static constexpr const char* kOpenCVLayersType = "opencv_ngraph_layer"; -#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2022_1) -static std::string shapesToStr(const std::vector& mats) -{ - std::ostringstream shapes; - shapes << mats.size() << " "; - for (const Mat& m : mats) - { - shapes << m.dims << " "; - for (int i = 0; i < m.dims; ++i) - shapes << m.size[i] << " "; - } - return shapes.str(); -} - -static void strToShapes(const std::string& str, std::vector >& shapes) -{ - std::istringstream ss(str); - int num, dims; - ss >> num; - shapes.resize(num); - for (int i = 0; i < num; ++i) - { - ss >> dims; - shapes[i].resize(dims); - for (int j = 0; j < dims; ++j) - ss >> shapes[i][j]; - } -} -#endif // OpenVINO < 2022.1 - static std::vector > ngraphWrappers(const std::vector >& ptrs) { @@ -78,13 +48,11 @@ ngraphWrappers(const std::vector >& ptrs) return wrappers; } -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) - class NgraphCustomOp: public ov::op::Op { public: OPENVINO_OP(kOpenCVLayersType); - NgraphCustomOp(const ngraph::OutputVector& inputs, Ptr& cvLayer, const std::vector& outputs, const std::vector& internals): + NgraphCustomOp(const ov::OutputVector& inputs, Ptr& cvLayer, const std::vector& outputs, const std::vector& internals): Op(inputs), cvLayer(cvLayer), outputs(outputs), internals(internals) { constructor_validate_and_infer_types(); @@ -103,7 +71,7 @@ public: } } - std::shared_ptr clone_with_new_inputs(const ngraph::OutputVector& new_args) const override + std::shared_ptr clone_with_new_inputs(const ov::OutputVector& new_args) const override { return std::make_shared(new_args, cvLayer, outputs, internals); } @@ -131,265 +99,13 @@ public: std::vector outputs, internals; }; -#else - -class NgraphCustomOp: public ngraph::op::Op { -public: - const ngraph::NodeTypeInfo& get_type_info() const override - { - static constexpr ngraph::NodeTypeInfo type_info{kOpenCVLayersType, static_cast(0)}; - return type_info; - } - -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3) - NgraphCustomOp(const ngraph::OutputVector& inputs, -#else - NgraphCustomOp(const ngraph::NodeVector& inputs, -#endif - const std::map& params = {}): - Op(inputs), params(params) - { - constructor_validate_and_infer_types(); - } - - ~NgraphCustomOp() - { - // nothing - } - - void validate_and_infer_types() override - { - std::vector > shapes; - strToShapes(params["outputs"], shapes); - set_output_size(shapes.size()); - for (size_t i = 0; i < shapes.size(); ++i) - { - ngraph::Shape output_shape(shapes[i]); - set_output_type(i, get_input_element_type(0), output_shape); - } - } - -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_4) - std::shared_ptr clone_with_new_inputs(const ngraph::OutputVector& new_args) const override - { - return std::make_shared(new_args, params); - } -#else - std::shared_ptr copy_with_new_args(const ngraph::NodeVector& new_args) const override - { -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3) - return std::make_shared(ngraph::as_output_vector(new_args), params); -#else - return std::make_shared(new_args, params); -#endif - } -#endif - - bool visit_attributes(ngraph::AttributeVisitor& visitor) override - { - for (auto& attr : params) - { - if (attr.second.is()) - visitor.on_attribute(attr.first, attr.second.as()); - } - return true; - } - - std::map params; -}; - - -class InfEngineNgraphCustomLayer : public InferenceEngine::ILayerExecImpl -{ -public: -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2) - explicit InfEngineNgraphCustomLayer(const std::shared_ptr& _node) - { - node = std::dynamic_pointer_cast(_node); - CV_Assert(node); - std::string implStr = node->params["impl"]; - std::istringstream iss(implStr); -#else - explicit InfEngineNgraphCustomLayer(const InferenceEngine::CNNLayer& layer) : cnnLayer(layer) - { - std::istringstream iss(layer.GetParamAsString("impl")); -#endif - size_t ptr; - iss >> ptr; - cvLayer = (Layer*)ptr; - - std::vector > shapes; -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2) - strToShapes(node->params["internals"], shapes); -#else - strToShapes(layer.GetParamAsString("internals"), shapes); -#endif - internals.resize(shapes.size()); - for (int i = 0; i < shapes.size(); ++i) - internals[i].create(std::vector(shapes[i].begin(), shapes[i].end()), CV_32F); - } - - ~InfEngineNgraphCustomLayer() - { - // nothing - } - - virtual InferenceEngine::StatusCode execute(std::vector& inputs, - std::vector& outputs, - InferenceEngine::ResponseDesc *resp) noexcept - { - std::vector inpMats, outMats; - infEngineBlobsToMats(inputs, inpMats); - infEngineBlobsToMats(outputs, outMats); - - try - { - cvLayer->forward(inpMats, outMats, internals); - return InferenceEngine::StatusCode::OK; - } - catch (...) - { - return InferenceEngine::StatusCode::GENERAL_ERROR; - } - } - - virtual InferenceEngine::StatusCode - getSupportedConfigurations(std::vector& conf, - InferenceEngine::ResponseDesc* resp) noexcept - { - std::vector inDataConfig; - std::vector outDataConfig; -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2) - InferenceEngine::SizeVector order; - for (int i = 0; i < node->get_input_size(); ++i) - { - InferenceEngine::DataConfig conf; - auto shape = node->input_value(i).get_shape(); - order.resize(shape.size()); - std::iota(order.begin(), order.end(), 0); - conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order}); - inDataConfig.push_back(conf); - } - - for (int i = 0; i < node->get_output_size(); ++i) - { - InferenceEngine::DataConfig conf; - auto shape = node->output(i).get_shape(); - order.resize(shape.size()); - std::iota(order.begin(), order.end(), 0); - conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order}); - outDataConfig.push_back(conf); - } -#else - for (auto& it : cnnLayer.insData) - { - InferenceEngine::DataConfig conf; - conf.desc = it.lock()->getTensorDesc(); - inDataConfig.push_back(conf); - } - - for (auto& it : cnnLayer.outData) - { - InferenceEngine::DataConfig conf; - conf.desc = it->getTensorDesc(); - outDataConfig.push_back(conf); - } -#endif - - InferenceEngine::LayerConfig layerConfig; - layerConfig.inConfs = inDataConfig; - layerConfig.outConfs = outDataConfig; - - conf.push_back(layerConfig); - return InferenceEngine::StatusCode::OK; - } - - InferenceEngine::StatusCode init(InferenceEngine::LayerConfig& config, - InferenceEngine::ResponseDesc *resp) noexcept - { - return InferenceEngine::StatusCode::OK; - } - -private: -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2) - std::shared_ptr node; -#else - InferenceEngine::CNNLayer cnnLayer; -#endif - dnn::Layer* cvLayer; - std::vector internals; -}; - -#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2020_2) -class InfEngineNgraphCustomLayerFactory : public InferenceEngine::ILayerImplFactory { -public: - explicit InfEngineNgraphCustomLayerFactory(const InferenceEngine::CNNLayer* layer) : cnnLayer(*layer) - { - // nothing - } - - InferenceEngine::StatusCode - getImplementations(std::vector& impls, - InferenceEngine::ResponseDesc* resp) noexcept override - { - impls.push_back(std::make_shared(cnnLayer)); - return InferenceEngine::StatusCode::OK; - } - -private: - InferenceEngine::CNNLayer cnnLayer; -}; -#endif - - -class InfEngineNgraphExtension : public InferenceEngine::IExtension -{ -public: - void Unload() noexcept override {} - void Release() noexcept override { delete this; } - void GetVersion(const InferenceEngine::Version*&) const noexcept override {} - -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2) - std::vector getImplTypes(const std::shared_ptr& node) override { - return {"CPU"}; - } - - InferenceEngine::ILayerImpl::Ptr getImplementation(const std::shared_ptr& node, const std::string& implType) override { - if (std::dynamic_pointer_cast(node) && implType == "CPU") { - return std::make_shared(node); - } - return nullptr; - } -#else - virtual void SetLogCallback(InferenceEngine::IErrorListener&) noexcept {} - - virtual InferenceEngine::StatusCode getPrimitiveTypes(char**&, unsigned int&, - InferenceEngine::ResponseDesc*) noexcept - { - return InferenceEngine::StatusCode::OK; - } - - InferenceEngine::StatusCode getFactoryFor(InferenceEngine::ILayerImplFactory*& factory, - const InferenceEngine::CNNLayer* cnnLayer, - InferenceEngine::ResponseDesc* resp) noexcept - { - if (cnnLayer->type != kOpenCVLayersType) - return InferenceEngine::StatusCode::NOT_IMPLEMENTED; - factory = new InfEngineNgraphCustomLayerFactory(cnnLayer); - return InferenceEngine::StatusCode::OK; - } -#endif -}; - -#endif // OpenVINO >= 2022.1 - -InfEngineNgraphNode::InfEngineNgraphNode(ngraph::Output&& _node) +InfEngineNgraphNode::InfEngineNgraphNode(ov::Output&& _node) : BackendNode(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH), node(std::move(_node)) { CV_Assert(node.get_node()); CV_Assert(node.get_node_shared_ptr()); } -InfEngineNgraphNode::InfEngineNgraphNode(const ngraph::Output& _node) +InfEngineNgraphNode::InfEngineNgraphNode(const ov::Output& _node) : BackendNode(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH), node(_node) { CV_Assert(node.get_node()); CV_Assert(node.get_node_shared_ptr()); @@ -400,27 +116,11 @@ InfEngineNgraphNode::InfEngineNgraphNode(const std::vector >& n std::vector& outputs, std::vector& internals) : BackendNode(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH), cvLayer(cvLayer_) { -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3) - ngraph::OutputVector inp_nodes; -#else - ngraph::NodeVector inp_nodes; -#endif + ov::OutputVector inp_nodes; for (const auto& node : nodes) inp_nodes.emplace_back(node.dynamicCast()->node); -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) node = std::make_shared(inp_nodes, cvLayer, outputs, internals); -#else - std::ostringstream oss; - oss << (size_t)cvLayer.get(); - std::map params = { - {"impl", oss.str()}, - {"outputs", shapesToStr(outputs)}, - {"internals", shapesToStr(internals)} - }; - node = std::make_shared(inp_nodes, params); -#endif - CV_Assert(!cvLayer->name.empty()); setName(cvLayer->name); } @@ -436,7 +136,7 @@ InfEngineNgraphNet::InfEngineNgraphNet(detail::NetImplBase& netImpl) device_name = "CPU"; } -InfEngineNgraphNet::InfEngineNgraphNet(detail::NetImplBase& netImpl, InferenceEngine::CNNNetwork& net) +InfEngineNgraphNet::InfEngineNgraphNet(detail::NetImplBase& netImpl, std::shared_ptr& net) : netImpl_(netImpl) , cnn(net) { @@ -455,64 +155,31 @@ void InfEngineNgraphNet::createNet(Target targetId) { if (!hasNetOwner) { CV_Assert(!requestedOutputs.empty()); - ngraph::ResultVector outs; + ov::ResultVector outs; for (auto output_node_it = requestedOutputs.begin(); output_node_it != requestedOutputs.end(); ++output_node_it) { CV_LOG_DEBUG(NULL, "DNN/NGRAPH: Add 'Result' output: " << output_node_it->first); CV_Assert(output_node_it->second); - auto out = std::make_shared(output_node_it->second->node); -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) + auto out = std::make_shared(output_node_it->second->node); out->set_friendly_name(output_node_it->first + (output_node_it->second->node.get_node()->get_output_size() == 1 ? "" : ".0")); -#endif outs.push_back(out); } CV_Assert_N(!inputs_vec.empty(), !outs.empty()); - ngraph_function = std::make_shared(outs, inputs_vec); + ngraph_function = std::make_shared(outs, inputs_vec); init(targetId); } } -#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2022_1) -static inline -InferenceEngine::Layout estimateLayout(size_t dims); -#endif - void InfEngineNgraphNet::init(Target targetId) { if (!hasNetOwner) { if (targetId == DNN_TARGET_OPENCL_FP16) { -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) ov::pass::ConvertFP32ToFP16().run_on_model(ngraph_function); -#else - auto nodes = ngraph_function->get_ordered_ops(); - for (auto& node : nodes) - { - auto parameter = std::dynamic_pointer_cast(node); - if (parameter && parameter->get_element_type() == ngraph::element::f32) - { - parameter->set_element_type(ngraph::element::f16); - } - auto constant = std::dynamic_pointer_cast(node); - if (constant && constant->get_element_type() == ngraph::element::f32) - { - const float* floatsData = constant->get_data_ptr(); - size_t total = ngraph::shape_size(constant->get_shape()); - Mat floats(1, total, CV_32F, (void*)floatsData); - Mat halfs; - floats.convertTo(halfs, CV_16F); - - auto new_const = std::make_shared(ngraph::element::f16, constant->get_shape(), halfs.data); - new_const->set_friendly_name(constant->get_friendly_name()); - ngraph::replace_node(constant, new_const); - } - } - ngraph_function->validate_nodes_and_infer_types(); -#endif // OpenVINO >= 2022.1 } - cnn = InferenceEngine::CNNNetwork(ngraph_function); + cnn = ngraph_function; if (DNN_IE_SERIALIZE) { @@ -520,7 +187,7 @@ void InfEngineNgraphNet::init(Target targetId) std::string dumpFileNameBase = netImpl_.getDumpFileNameBase(); try { - cnn.serialize(dumpFileNameBase + "_ngraph.xml", dumpFileNameBase + "_ngraph.bin"); + ov::pass::Serialize(dumpFileNameBase + "_ngraph.xml", dumpFileNameBase + "_ngraph.bin").run_on_model(cnn); } catch (const std::exception& e) { @@ -558,11 +225,9 @@ void InfEngineNgraphNet::init(Target targetId) CV_Error(Error::StsNotImplemented, "Unknown target"); }; -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) - auto model = cnn.getFunction(); - ov::preprocess::PrePostProcessor ppp(model); + ov::preprocess::PrePostProcessor ppp(cnn); int i = 0; - for (const auto& inp : model->inputs()) { // TODO: not sure why but ngraph_function->inputs() here causes segfault. + for (const auto& inp : cnn->inputs()) { // TODO: not sure why but ngraph_function->inputs() here causes segfault. const std::string& name = inp.get_node()->get_friendly_name(); auto blobIt = allBlobs.find(name); CV_Assert(blobIt != allBlobs.end()); @@ -574,7 +239,7 @@ void InfEngineNgraphNet::init(Target targetId) } i = 0; - for (const auto& it : model->outputs()) + for (const auto& it : cnn->outputs()) { const std::string& name = it.get_node()->get_friendly_name(); auto blobIt = allBlobs.find(name); @@ -595,47 +260,21 @@ void InfEngineNgraphNet::init(Target targetId) ppp.build(); -#else - - for (const auto& it : cnn.getInputsInfo()) - { - const std::string& name = it.first; - auto blobIt = allBlobs.find(name); - CV_Assert(blobIt != allBlobs.end()); - it.second->setPrecision(blobIt->second->getTensorDesc().getPrecision()); - } - - for (const auto& it : cnn.getOutputsInfo()) - { - const std::string& name = it.first; - auto blobIt = allBlobs.find(name); - CV_Assert(blobIt != allBlobs.end()); - InferenceEngine::TensorDesc& desc = blobIt->second->getTensorDesc(); - - auto outShape = it.second->getDims(); - if (outShape != desc.getDims()) { - desc.reshape(outShape, estimateLayout(outShape.size())); - } - - it.second->setPrecision(blobIt->second->getTensorDesc().getPrecision()); // Should be always FP32 - } -#endif // OpenVINO >= 2022.1 - initPlugin(cnn); } -ngraph::ParameterVector InfEngineNgraphNet::setInputs(const std::vector& inputs, +ov::ParameterVector InfEngineNgraphNet::setInputs(const std::vector& inputs, const std::vector& names) { CV_Assert_N(inputs.size() == names.size()); - ngraph::ParameterVector current_inp; + ov::ParameterVector current_inp; for (size_t i = 0; i < inputs.size(); i++) { std::vector shape = getShape(inputs[i]); - auto inp = std::make_shared(ngraph::element::f32, ngraph::Shape(shape)); + auto inp = std::make_shared(ov::element::f32, ov::Shape(shape)); inp->set_friendly_name(names[i]); auto it = std::find_if(inputs_vec.begin(), inputs_vec.end(), - [&inp](const std::shared_ptr& a) { + [&inp](const std::shared_ptr& a) { return a->get_friendly_name() == inp->get_friendly_name(); }); if (it == inputs_vec.end()) { @@ -649,14 +288,14 @@ ngraph::ParameterVector InfEngineNgraphNet::setInputs(const std::vector } -void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net) +void InfEngineNgraphNet::initPlugin(std::shared_ptr& net) { CV_Assert(!isInitialized()); try { AutoLock lock(getInitializationMutex()); - InferenceEngine::Core& ie = getCore(device_name); + ov::Core& ie = getCore(device_name); { isInit = true; std::vector candidates; @@ -671,18 +310,7 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net) const std::string& libName = candidates[i]; try { -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) ie.add_extension(libName); -#else - InferenceEngine::IExtensionPtr extension = -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4) - std::make_shared(libName); -#else - InferenceEngine::make_so_pointer(libName); -#endif - - ie.AddExtension(extension, "CPU"); -#endif CV_LOG_INFO(NULL, "DNN-IE: Loaded extension plugin: " << libName); found = true; break; @@ -693,30 +321,11 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net) { CV_LOG_WARNING(NULL, "DNN-IE: Can't load extension plugin (extra layers for some networks). Specify path via OPENCV_DNN_IE_EXTRA_PLUGIN_PATH parameter"); } -#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2022_1) - // Some of networks can work without a library of extra layers. - // OpenCV fallbacks as extensions. - try - { - ie.AddExtension(std::make_shared(), "CPU"); - } - catch(const std::exception& e) - { - CV_LOG_INFO(NULL, "DNN-IE: Can't register OpenCV custom layers nGraph extension: " << e.what()); - } -#endif // OpenVINO < 2022.1 #ifndef _WIN32 // Limit the number of CPU threads. if (device_name == "CPU") -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) ie.set_property(device_name, ov::inference_num_threads(getNumThreads())); -#else - ie.SetConfig({{ - InferenceEngine::PluginConfigParams::KEY_CPU_THREADS_NUM, format("%d", getNumThreads()), - }}, device_name); -#endif // OpenVINO >= 2022.1 #endif -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_2) if (device_name.find("GPU") == 0) { #if OPENCV_HAVE_FILESYSTEM_SUPPORT @@ -727,24 +336,13 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net) if (!cache_path.empty() && cache_path != "disabled") { CV_LOG_INFO(NULL, "OpenCV/nGraph: using GPU kernels cache: " << cache_path); -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) ie.set_property(device_name, ov::cache_dir(cache_path)); -#else - ie.SetConfig({{ - InferenceEngine::PluginConfigParams::KEY_CACHE_DIR, cache_path, - }}, device_name); -#endif // OpenVINO >= 2022.1 } } -#endif } - std::map config; + ov::AnyMap config; if (device_name == "MYRIAD" || device_name == "HDDL") { -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) config.emplace("MYRIAD_DETECT_NETWORK_BATCH", "NO"); -#else - config.emplace("VPU_DETECT_NETWORK_BATCH", "NO"); -#endif } bool isHetero = device_name == "FPGA"; @@ -752,7 +350,7 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net) // We do not check IR models because they can be with version less than IRv10 if (!isHetero && device_name != "CPU" && !hasNetOwner) { - for (auto& node : net.getFunction()->get_ops()) + for (auto& node : net->get_ops()) { if (node->description() == kOpenCVLayersType) { @@ -764,7 +362,7 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net) std::string ieDevice = isHetero ? ("HETERO:" + device_name + ",CPU") : device_name; CV_LOG_INFO(NULL, "DNN/IE: Calling LoadNetwork(device=" << ieDevice << ")..."); - netExec = ie.LoadNetwork(net, ieDevice, config); + netExec = ie.compile_model(net, ieDevice, config); } catch (const std::exception& ex) { @@ -782,14 +380,13 @@ bool NgraphBackendLayer::getMemoryShapes(const std::vector &inputs, std::vector &outputs, std::vector &internals) const { - auto ngraphFunction = t_net.getFunction(); bool equal_flag = true; - std::map > inShapes; + std::map inShapes; int i = 0; - for (const auto& inp : ngraphFunction->get_parameters()) + for (const auto& inp : t_net->get_parameters()) { - std::vector oldShape = inp->get_shape(); - std::vector newShape(inputs[i].begin(), inputs[i].end()); + ov::Shape oldShape = inp->get_shape(); + ov::Shape newShape(inputs[i].begin(), inputs[i].end()); inShapes.insert({inp->get_friendly_name(), newShape}); if (oldShape != newShape) { @@ -800,21 +397,17 @@ bool NgraphBackendLayer::getMemoryShapes(const std::vector &inputs, if (!equal_flag) { - InferenceEngine::CNNNetwork curr_t_net(t_net); - curr_t_net.reshape(inShapes); + std::shared_ptr curr_t_net(t_net); + curr_t_net->reshape(inShapes); } -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) std::vector dims; - for (const auto& it : ngraphFunction->outputs()) { + for (const auto& it : t_net->outputs()) { if (it.get_node()->get_friendly_name() == name) { dims = it.get_partial_shape().get_max_shape(); } } if (dims.empty()) CV_Error(Error::StsError, format("Unable find result with name %s", name.c_str())); -#else - std::vector dims = t_net.getOutputsInfo()[name]->getDims(); -#endif outputs.push_back(MatShape(dims.begin(), dims.end())); return false; } @@ -832,8 +425,6 @@ void NgraphBackendLayer::forward(InputArrayOfArrays inputs, OutputArrayOfArrays CV_Error(Error::StsInternal, "Choose Inference Engine as a preferable backend."); } -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) - ov::Tensor wrapToNgraphBlob(const Mat& m) { std::vector shape = getShape(m); if (m.type() == CV_32F) @@ -848,60 +439,6 @@ ov::Tensor wrapToNgraphBlob(const Mat& m) { CV_Error(Error::StsNotImplemented, format("Unsupported data type %s", typeToString(m.type()).c_str())); } -#else - -static InferenceEngine::Layout estimateLayout(int dims) -{ - if (dims == 4) - return InferenceEngine::Layout::NCHW; - else if (dims == 3) - return InferenceEngine::Layout::CHW; - else if (dims == 2) - return InferenceEngine::Layout::NC; - else if (dims == 1) - return InferenceEngine::Layout::C; - else if (dims == 5) - return InferenceEngine::Layout::NCDHW; - else - return InferenceEngine::Layout::ANY; -} -static inline -InferenceEngine::Layout estimateLayout(size_t dims) -{ - return estimateLayout((int)dims); -} - -static inline -InferenceEngine::Layout estimateLayout(const Mat& m) -{ - return estimateLayout(m.dims); -} - -InferenceEngine::Blob::Ptr wrapToNgraphBlob(const Mat& m, const std::vector& shape, - InferenceEngine::Layout layout) -{ - if (m.type() == CV_32F) - return InferenceEngine::make_shared_blob( - {InferenceEngine::Precision::FP32, shape, layout}, (float*)m.data); - else if (m.type() == CV_8U) - return InferenceEngine::make_shared_blob( - {InferenceEngine::Precision::U8, shape, layout}, (uint8_t*)m.data); - else if (m.type() == CV_32SC1) - return InferenceEngine::make_shared_blob( - {InferenceEngine::Precision::I32, shape, layout}, (int32_t*)m.data); - else - CV_Error(Error::StsNotImplemented, format("Unsupported data type %s", typeToString(m.type()).c_str())); -} - -InferenceEngine::Blob::Ptr wrapToNgraphBlob(const Mat& m, InferenceEngine::Layout layout) -{ - std::vector shape = getShape(m); - return wrapToNgraphBlob(m, shape, layout); -} - -InferenceEngine::Blob::Ptr wrapToNgraphBlob(const Mat& m) { return wrapToNgraphBlob(m, estimateLayout(m)); } - -#endif // OpenVINO >= 2022.1 NgraphBackendWrapper::NgraphBackendWrapper(int targetId, const cv::Mat& m) : BackendWrapper(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, targetId) @@ -941,36 +478,10 @@ void NgraphBackendWrapper::setHostDirty() //CV_Error(Error::StsNotImplemented, ""); } -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) ov::Tensor copyBlob(const ov::Tensor& blob) { return ov::Tensor(blob.get_element_type(), blob.get_shape()); } -#else -InferenceEngine::Blob::Ptr copyBlob(const InferenceEngine::Blob::Ptr& blob) -{ - InferenceEngine::Blob::Ptr copy; - auto description = blob->getTensorDesc(); - InferenceEngine::Precision precision = description.getPrecision(); - if (precision == InferenceEngine::Precision::FP32) - { - copy = InferenceEngine::make_shared_blob(description); - } - else if (precision == InferenceEngine::Precision::U8) - { - copy = InferenceEngine::make_shared_blob(description); - } - else - { - std::ostringstream msg; - msg << precision; - CV_Error_(Error::StsNotImplemented, ("Unsupported blob precision: %s", msg.str().c_str())); - } - copy->allocate(); - return copy; -} - -#endif // OpenVINO < 2022.1 void InfEngineNgraphNet::reset() { @@ -1022,7 +533,7 @@ void InfEngineNgraphNet::forward(const std::vector >& outBlo reqWrapper = Ptr(new NgraphReqWrapper()); try { - reqWrapper->req = netExec.CreateInferRequest(); + reqWrapper->req = netExec.create_infer_request(); } catch (const std::exception& ex) { @@ -1030,7 +541,6 @@ void InfEngineNgraphNet::forward(const std::vector >& outBlo } infRequests.push_back(reqWrapper); -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) int i = 0; for (const auto& it : netExec.inputs()) { @@ -1048,27 +558,7 @@ void InfEngineNgraphNet::forward(const std::vector >& outBlo CV_Assert(blobIt != allBlobs.end()); reqWrapper->req.set_output_tensor(i++, isAsync ? copyBlob(blobIt->second) : blobIt->second); } -#else - InferenceEngine::BlobMap inpBlobs, outBlobs; - for (const auto& it : cnn.getInputsInfo()) - { - const std::string& name = it.first; - auto blobIt = allBlobs.find(name); - CV_Assert(blobIt != allBlobs.end()); - inpBlobs[name] = isAsync ? copyBlob(blobIt->second) : blobIt->second; - } - for (const auto& it : cnn.getOutputsInfo()) - { - const std::string& name = it.first; - auto blobIt = allBlobs.find(name); - CV_Assert(blobIt != allBlobs.end()); - outBlobs[name] = isAsync ? copyBlob(blobIt->second) : blobIt->second; - } - reqWrapper->req.SetInput(inpBlobs); - reqWrapper->req.SetOutput(outBlobs); -#endif -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) if (isAsync) { bool* isReady = &reqWrapper->isReady; auto* promises = &reqWrapper->outProms; @@ -1112,86 +602,13 @@ void InfEngineNgraphNet::forward(const std::vector >& outBlo *isReady = true; }); } -#else // OpenVINO >= 2022.1 - -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4) - InferenceEngine::InferRequest infRequest = reqWrapper->req; - NgraphReqWrapper* wrapperPtr = reqWrapper.get(); - CV_Assert(wrapperPtr && "Internal error"); -#else - InferenceEngine::IInferRequest::Ptr infRequestPtr = reqWrapper->req; - CV_Assert(infRequestPtr); - InferenceEngine::IInferRequest& infRequest = *infRequestPtr.get(); - infRequest.SetUserData(reqWrapper.get(), 0); -#endif - -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4) - // do NOT capture 'reqWrapper' (smart ptr) in the lambda callback - infRequest.SetCompletionCallback>( - [wrapperPtr](InferenceEngine::InferRequest /*request*/, InferenceEngine::StatusCode status) -#else - infRequest.SetCompletionCallback( - [](InferenceEngine::IInferRequest::Ptr requestPtr, InferenceEngine::StatusCode status) -#endif - { - CV_LOG_DEBUG(NULL, "DNN(nGraph): completionCallback(" << (int)status << ")"); -#if !INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4) - CV_Assert(requestPtr); - InferenceEngine::IInferRequest& request = *requestPtr.get(); - - NgraphReqWrapper* wrapperPtr; - request.GetUserData((void**)&wrapperPtr, 0); - CV_Assert(wrapperPtr && "Internal error"); -#endif - NgraphReqWrapper& wrapper = *wrapperPtr; - - size_t processedOutputs = 0; - try - { - for (; processedOutputs < wrapper.outProms.size(); ++processedOutputs) - { - const std::string& name = wrapper.outsNames[processedOutputs]; - Mat m = infEngineBlobToMat(wrapper.req.GetBlob(name)); - - try - { - CV_Assert(status == InferenceEngine::StatusCode::OK); - wrapper.outProms[processedOutputs].setValue(m.clone()); - } - catch (...) - { - try { - wrapper.outProms[processedOutputs].setException(std::current_exception()); - } catch(...) { - CV_LOG_ERROR(NULL, "DNN: Exception occurred during async inference exception propagation"); - } - } - } - } - catch (...) - { - std::exception_ptr e = std::current_exception(); - for (; processedOutputs < wrapper.outProms.size(); ++processedOutputs) - { - try { - wrapper.outProms[processedOutputs].setException(e); - } catch(...) { - CV_LOG_ERROR(NULL, "DNN: Exception occurred during async inference exception propagation"); - } - } - } - wrapper.isReady = true; - } - ); -#endif // OpenVINO >= 2022.1 } -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) if (isAsync) { // Copy actual data to infer request's input blobs. int i = 0; - for (const auto& it : cnn.getFunction()->get_parameters()) + for (const auto& it : cnn->get_parameters()) { const std::string& name = it->get_friendly_name(); auto blobIt = allBlobs.find(name); @@ -1210,54 +627,30 @@ void InfEngineNgraphNet::forward(const std::vector >& outBlo { reqWrapper->req.infer(); } -#else - if (isAsync) - { - // Copy actual data to infer request's input blobs. - for (const auto& it : cnn.getInputsInfo()) - { - const std::string& name = it.first; - auto blobIt = allBlobs.find(name); - Mat srcMat = infEngineBlobToMat(blobIt->second); - Mat dstMat = infEngineBlobToMat(reqWrapper->req.GetBlob(name)); - srcMat.copyTo(dstMat); - } - - // Set promises to output blobs wrappers. - reqWrapper->makePromises(outBlobsWrappers); - - reqWrapper->isReady = false; - reqWrapper->req.StartAsync(); - } - else - { - reqWrapper->req.Infer(); - } -#endif // OpenVINO >= 2022.1 } -ngraph::Output ngraphQuantize(ngraph::Output input, float output_sc, float output_zp) { +ov::Output ngraphQuantize(ov::Output input, float output_sc, float output_zp) { float outLow = -128, outHigh = 127; float inpLow = output_sc * (outLow - output_zp); float inpHigh = output_sc * (outHigh - output_zp); - return std::make_shared(input, - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &inpLow), - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &inpHigh), - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &outLow), - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &outHigh), + return std::make_shared(input, + std::make_shared(ov::element::f32, ov::Shape{1}, &inpLow), + std::make_shared(ov::element::f32, ov::Shape{1}, &inpHigh), + std::make_shared(ov::element::f32, ov::Shape{1}, &outLow), + std::make_shared(ov::element::f32, ov::Shape{1}, &outHigh), 256 // levels ); } -ngraph::Output ngraphDequantize(ngraph::Output input, float input_sc, float input_zp) { +ov::Output ngraphDequantize(ov::Output input, float input_sc, float input_zp) { float inpLow = -128, inpHigh = 127; float outLow = input_sc * (inpLow - input_zp); float outHigh = input_sc * (inpHigh - input_zp); - return std::make_shared(input, - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &inpLow), - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &inpHigh), - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &outLow), - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &outHigh), + return std::make_shared(input, + std::make_shared(ov::element::f32, ov::Shape{1}, &inpLow), + std::make_shared(ov::element::f32, ov::Shape{1}, &inpHigh), + std::make_shared(ov::element::f32, ov::Shape{1}, &outLow), + std::make_shared(ov::element::f32, ov::Shape{1}, &outHigh), 256 // levels ); } diff --git a/modules/dnn/src/ie_ngraph.hpp b/modules/dnn/src/ie_ngraph.hpp index 8672f1a3c2..19e07d62ac 100644 --- a/modules/dnn/src/ie_ngraph.hpp +++ b/modules/dnn/src/ie_ngraph.hpp @@ -17,7 +17,8 @@ #pragma warning(disable : 4245) #pragma warning(disable : 4268) #endif -#include +#include +#include #ifdef _MSC_VER #pragma warning(pop) #endif @@ -30,12 +31,11 @@ namespace cv { namespace dnn { class InfEngineNgraphNode; - class InfEngineNgraphNet { public: InfEngineNgraphNet(detail::NetImplBase& netImpl); - InfEngineNgraphNet(detail::NetImplBase& netImpl, InferenceEngine::CNNNetwork& net); + InfEngineNgraphNet(detail::NetImplBase& netImpl, std::shared_ptr& net); void addOutput(const Ptr& node); @@ -44,8 +44,8 @@ public: void forward(const std::vector >& outBlobsWrappers, bool isAsync); - void initPlugin(InferenceEngine::CNNNetwork& net); - ngraph::ParameterVector setInputs(const std::vector& inputs, const std::vector& names); + void initPlugin(std::shared_ptr& net); + ov::ParameterVector setInputs(const std::vector& inputs, const std::vector& names); void addBlobs(const std::vector >& ptrs); @@ -56,15 +56,11 @@ public: //private: detail::NetImplBase& netImpl_; - ngraph::ParameterVector inputs_vec; - std::shared_ptr ngraph_function; + ov::ParameterVector inputs_vec; + std::shared_ptr ngraph_function; - InferenceEngine::ExecutableNetwork netExec; -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) + ov::CompiledModel netExec; std::map allBlobs; -#else - InferenceEngine::BlobMap allBlobs; -#endif std::string device_name; bool isInit = false; @@ -74,14 +70,14 @@ public: void makePromises(const std::vector >& outs); - InferenceEngine::InferRequest req; + ov::InferRequest req; std::vector outProms; std::vector outsNames; bool isReady; }; std::vector > infRequests; - InferenceEngine::CNNNetwork cnn; + std::shared_ptr cnn; bool hasNetOwner; std::unordered_map requestedOutputs; }; @@ -93,13 +89,13 @@ public: std::vector& inputs, std::vector& outputs, std::vector& internals); - InfEngineNgraphNode(ngraph::Output&& _node); - InfEngineNgraphNode(const ngraph::Output& _node); + InfEngineNgraphNode(ov::Output&& _node); + InfEngineNgraphNode(const ov::Output& _node); void setName(const std::string& name); // Inference Engine network object that allows to obtain the outputs of this layer. - ngraph::Output node; + ov::Output node; Ptr net; Ptr cvLayer; }; @@ -118,11 +114,7 @@ public: Mat* host; std::string name; -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) ov::Tensor blob; -#else - InferenceEngine::Blob::Ptr blob; -#endif AsyncArray futureMat; }; @@ -132,7 +124,7 @@ public: class NgraphBackendLayer : public Layer { public: - NgraphBackendLayer(const InferenceEngine::CNNNetwork &t_net_) : t_net(t_net_) {}; + NgraphBackendLayer(const std::shared_ptr &t_net_) : t_net(t_net_) {}; virtual bool getMemoryShapes(const std::vector &inputs, const int requiredOutputs, @@ -145,11 +137,11 @@ public: virtual bool supportBackend(int backendId) CV_OVERRIDE; private: - InferenceEngine::CNNNetwork t_net; + std::shared_ptr t_net; }; -ngraph::Output ngraphQuantize(ngraph::Output input, float output_sc, float output_zp); -ngraph::Output ngraphDequantize(ngraph::Output input, float input_sc, float input_zp); +ov::Output ngraphQuantize(ov::Output input, float output_sc, float output_zp); +ov::Output ngraphDequantize(ov::Output input, float input_sc, float input_zp); #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/int8layers/batch_norm_layer.cpp b/modules/dnn/src/int8layers/batch_norm_layer.cpp index 7ef169deea..3fbf8cd191 100644 --- a/modules/dnn/src/int8layers/batch_norm_layer.cpp +++ b/modules/dnn/src/int8layers/batch_norm_layer.cpp @@ -7,8 +7,6 @@ #include "../op_timvx.hpp" #include "../ie_ngraph.hpp" -#include - namespace cv { namespace dnn @@ -250,11 +248,11 @@ public: std::vector shape(input.get_shape().size(), 1); shape[1] = origin_weights.total(); - ngraph::Output res; - auto ieWeights = std::make_shared(ngraph::element::f32, shape, origin_weights.data); - auto ieBias = std::make_shared(ngraph::element::f32, shape, origin_bias.data); - res = std::make_shared(input, ieWeights); - res = std::make_shared(res, ieBias); + ov::Output res; + auto ieWeights = std::make_shared(ov::element::f32, shape, origin_weights.data); + auto ieBias = std::make_shared(ov::element::f32, shape, origin_bias.data); + res = std::make_shared(input, ieWeights); + res = std::make_shared(res, ieBias); res = ngraphQuantize(res, output_sc, output_zp); return new InfEngineNgraphNode(res); diff --git a/modules/dnn/src/int8layers/convolution_layer.cpp b/modules/dnn/src/int8layers/convolution_layer.cpp index a5a98c9764..603100ae11 100644 --- a/modules/dnn/src/int8layers/convolution_layer.cpp +++ b/modules/dnn/src/int8layers/convolution_layer.cpp @@ -573,8 +573,8 @@ public: auto ieInpNode = nodes[0].dynamicCast()->node; std::vector dims = ieInpNode.get_shape(); CV_Check(dims.size(), dims.size() >= 3 && dims.size() <= 5, ""); - CV_Assert(ieInpNode.get_element_type() == ngraph::element::f32); - ngraph::Output ieWeights; + CV_Assert(ieInpNode.get_element_type() == ov::element::f32); + ov::Output ieWeights; if (nodes.size() > 1) ieWeights = nodes[1].dynamicCast()->node; const int inpCn = dims[1]; @@ -592,18 +592,18 @@ public: if (nodes.size() == 1) { - ieWeights = std::make_shared(ngraph::element::i8, kernel_shape, blobs[0].data); + ieWeights = std::make_shared(ov::element::i8, kernel_shape, blobs[0].data); } else { - auto shape = std::make_shared(ngraph::element::i64, - ngraph::Shape{kernel_shape.size()}, std::vector(kernel_shape.begin(), kernel_shape.end())); - ieWeights = std::make_shared(ieWeights, shape, true); + auto shape = std::make_shared(ov::element::i64, + ov::Shape{kernel_shape.size()}, std::vector(kernel_shape.begin(), kernel_shape.end())); + ieWeights = std::make_shared(ieWeights, shape, true); } - ngraph::op::PadType pad_type = ngraph::op::PadType::EXPLICIT; + ov::op::PadType pad_type = ov::op::PadType::EXPLICIT; if (!padMode.empty()) - pad_type = padMode == "VALID" ? ngraph::op::PadType::VALID : ngraph::op::PadType::SAME_UPPER; + pad_type = padMode == "VALID" ? ov::op::PadType::VALID : ov::op::PadType::SAME_UPPER; ieInpNode = ngraphDequantize(ieInpNode, input_sc, input_zp); @@ -627,31 +627,31 @@ public: outLows[i] = low * outputMultiplier[i] * output_sc / input_sc; outHighs[i] = high * outputMultiplier[i] * output_sc / input_sc; } - ieWeights = std::make_shared(ieWeights, ngraph::element::f32); - ieWeights = std::make_shared(ieWeights, - std::make_shared(ngraph::element::f32, quantShape, inpLows.data()), - std::make_shared(ngraph::element::f32, quantShape, inpHighs.data()), - std::make_shared(ngraph::element::f32, quantShape, outLows.data()), - std::make_shared(ngraph::element::f32, quantShape, outHighs.data()), + ieWeights = std::make_shared(ieWeights, ov::element::f32); + ieWeights = std::make_shared(ieWeights, + std::make_shared(ov::element::f32, quantShape, inpLows.data()), + std::make_shared(ov::element::f32, quantShape, inpHighs.data()), + std::make_shared(ov::element::f32, quantShape, outLows.data()), + std::make_shared(ov::element::f32, quantShape, outHighs.data()), 256 // levels ); - ngraph::Output conv_node; + ov::Output conv_node; if (group != 1) { - conv_node = std::make_shared( + conv_node = std::make_shared( ieInpNode, ieWeights, - ngraph::Strides(strides), - ngraph::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), - ngraph::CoordinateDiff(std::vector(pads_end.begin(), pads_end.end())), - ngraph::Strides(dilations), + ov::Strides(strides), + ov::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), + ov::CoordinateDiff(std::vector(pads_end.begin(), pads_end.end())), + ov::Strides(dilations), pad_type); } else { - conv_node = std::make_shared( + conv_node = std::make_shared( ieInpNode, ieWeights, - ngraph::Strides(strides), - ngraph::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), - ngraph::CoordinateDiff(std::vector(pads_end.begin(), pads_end.end())), - ngraph::Strides(dilations), + ov::Strides(strides), + ov::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), + ov::CoordinateDiff(std::vector(pads_end.begin(), pads_end.end())), + ov::Strides(dilations), pad_type); } @@ -659,12 +659,12 @@ public: shape[1] = conv_node.get_shape()[1]; if (biasvec.size() || nodes.size() == 3) { - std::shared_ptr bias; + std::shared_ptr bias; if (nodes.size() == 3) { - auto bias_shape = std::make_shared(ngraph::element::i64, - ngraph::Shape{shape.size()}, std::vector(shape.begin(), shape.end())); - bias = std::make_shared(nodes[2].dynamicCast()->node, bias_shape, true); + auto bias_shape = std::make_shared(ov::element::i64, + ov::Shape{shape.size()}, std::vector(shape.begin(), shape.end())); + bias = std::make_shared(nodes[2].dynamicCast()->node, bias_shape, true); } else { @@ -672,9 +672,9 @@ public: for (int i = 0; i < numOutput; ++i) { ovBias[i] = (biasvec[i] + input_zp * cv::sum(blobs[0].row(i))[0]) * outputMultiplier[i] * output_sc; } - bias = std::make_shared(ngraph::element::f32, ngraph::Shape(shape), ovBias.data()); + bias = std::make_shared(ov::element::f32, ov::Shape(shape), ovBias.data()); } - conv_node = std::make_shared(conv_node, bias, ngraph::op::AutoBroadcastType::NUMPY); + conv_node = std::make_shared(conv_node, bias, ov::op::AutoBroadcastType::NUMPY); } conv_node = ngraphQuantize(conv_node, output_sc, output_zp); diff --git a/modules/dnn/src/int8layers/elementwise_layers.cpp b/modules/dnn/src/int8layers/elementwise_layers.cpp index 5c533840f3..f522efa0c1 100644 --- a/modules/dnn/src/int8layers/elementwise_layers.cpp +++ b/modules/dnn/src/int8layers/elementwise_layers.cpp @@ -253,26 +253,26 @@ public: input = ngraphDequantize(input, input_sc, input_zp); - ngraph::Output res; + ov::Output res; if (type == "ReLU6Int8") { - res = std::make_shared(input, 0.0f, 6.0f); + res = std::make_shared(input, 0.0f, 6.0f); } else if (type == "ReLUInt8") { if (slope) { - auto param = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &slope); - res = std::make_shared(input, param); + auto param = std::make_shared(ov::element::f32, ov::Shape{1}, &slope); + res = std::make_shared(input, param); } else { - res = std::make_shared(input); + res = std::make_shared(input); } } else if (type == "ELUInt8") { - res = std::make_shared(input, 1.0f); + res = std::make_shared(input, 1.0f); } else if (type == "MishInt8") { - res = std::make_shared(input); + res = std::make_shared(input); } else if (type == "HardSwishInt8") { - res = std::make_shared(input); + res = std::make_shared(input); } else if (type == "AbsValInt8") { - res = std::make_shared(input); + res = std::make_shared(input); } else if (type == "SigmoidInt8") { - res = std::make_shared(input); + res = std::make_shared(input); } else { CV_Error(Error::StsNotImplemented, type + " activation with OpenVINO"); } diff --git a/modules/dnn/src/int8layers/eltwise_layer.cpp b/modules/dnn/src/int8layers/eltwise_layer.cpp index a3bb6ec2d6..214d11525a 100644 --- a/modules/dnn/src/int8layers/eltwise_layer.cpp +++ b/modules/dnn/src/int8layers/eltwise_layer.cpp @@ -375,7 +375,7 @@ public: const std::vector >& nodes) CV_OVERRIDE { CV_Assert(nodes.size() >= 2); - std::vector> ieInpNodes(nodes.size()); + std::vector> ieInpNodes(nodes.size()); for (size_t i = 0; i < nodes.size(); i++) { ieInpNodes[i] = nodes[i].dynamicCast()->node; @@ -389,9 +389,9 @@ public: for (size_t i = 1; i < ieInpNodes.size(); i++) { switch (op) { - case SUM: res = std::make_shared(res, ieInpNodes[i]); break; - case PROD: res = std::make_shared(res, ieInpNodes[i]); break; - case MAX: res = std::make_shared(res, ieInpNodes[i]); break; + case SUM: res = std::make_shared(res, ieInpNodes[i]); break; + case PROD: res = std::make_shared(res, ieInpNodes[i]); break; + case MAX: res = std::make_shared(res, ieInpNodes[i]); break; default: CV_Error(Error::StsNotImplemented, "Unsupported eltwise operation"); } } diff --git a/modules/dnn/src/int8layers/fully_connected_layer.cpp b/modules/dnn/src/int8layers/fully_connected_layer.cpp index 3a560ddda6..6691128990 100644 --- a/modules/dnn/src/int8layers/fully_connected_layer.cpp +++ b/modules/dnn/src/int8layers/fully_connected_layer.cpp @@ -410,8 +410,8 @@ public: CV_CheckTypeEQ(blobs[1].type(), CV_32S, ""); // bias CV_CheckTypeEQ(outputMultiplier.type(), CV_32F, ""); - ngraph::Output input = nodes[0].dynamicCast()->node; - ngraph::Output ieWeights, ieBias, matmul; + ov::Output input = nodes[0].dynamicCast()->node; + ov::Output ieWeights, ieBias, matmul; bool transA = false, transB = true; size_t numOutput = blobs[0].size[0]; @@ -419,15 +419,15 @@ public: { CV_Error(Error::StsNotImplemented, ""); // auto inp2 = nodes[1].dynamicCast()->node; - // matmul = std::make_shared(ieInpNode, inp2, transA, transB); + // matmul = std::make_shared(ieInpNode, inp2, transA, transB); } else { std::vector shape(1 + normalize_axis(axis, input.get_shape().size()), 0); shape[shape.size() - 1] = -1; - input = std::make_shared( + input = std::make_shared( input, - std::make_shared(ngraph::element::i32, ngraph::Shape{shape.size()}, shape.data()), + std::make_shared(ov::element::i32, ov::Shape{shape.size()}, shape.data()), true ); @@ -444,16 +444,16 @@ public: } std::vector weight_shape{(size_t)blobs[0].size[0], (size_t)blobs[0].size[1]}; - ieWeights = std::make_shared(ngraph::element::i8, weight_shape, blobs[0].data); - ieWeights = std::make_shared(ieWeights, ngraph::element::f32); - ieWeights = std::make_shared(ieWeights, - std::make_shared(ngraph::element::f32, ngraph::Shape{numOutput, 1}, inpLows.data()), - std::make_shared(ngraph::element::f32, ngraph::Shape{numOutput, 1}, inpHighs.data()), - std::make_shared(ngraph::element::f32, ngraph::Shape{numOutput, 1}, outLows.data()), - std::make_shared(ngraph::element::f32, ngraph::Shape{numOutput, 1}, outHighs.data()), + ieWeights = std::make_shared(ov::element::i8, weight_shape, blobs[0].data); + ieWeights = std::make_shared(ieWeights, ov::element::f32); + ieWeights = std::make_shared(ieWeights, + std::make_shared(ov::element::f32, ov::Shape{numOutput, 1}, inpLows.data()), + std::make_shared(ov::element::f32, ov::Shape{numOutput, 1}, inpHighs.data()), + std::make_shared(ov::element::f32, ov::Shape{numOutput, 1}, outLows.data()), + std::make_shared(ov::element::f32, ov::Shape{numOutput, 1}, outHighs.data()), 256 // levels ); - matmul = std::make_shared(input, ieWeights, transA, transB); + matmul = std::make_shared(input, ieWeights, transA, transB); } if (blobs.size() > 1) { @@ -462,9 +462,9 @@ public: for (int i = 0; i < ovBias.size(); ++i) { ovBias[i] = (bias[i] + input_zp * cv::sum(blobs[0].row(i))[0]) * outputMultiplier.ptr()[i] * output_sc; } - auto bias_node = std::make_shared(ngraph::element::f32, - ngraph::Shape{blobs[1].total()}, ovBias.data()); - matmul = std::make_shared(matmul, bias_node); + auto bias_node = std::make_shared(ov::element::f32, + ov::Shape{blobs[1].total()}, ovBias.data()); + matmul = std::make_shared(matmul, bias_node); } matmul = ngraphQuantize(matmul, output_sc, output_zp); diff --git a/modules/dnn/src/int8layers/pooling_layer.cpp b/modules/dnn/src/int8layers/pooling_layer.cpp index b321d730f7..cfd04bd2f4 100644 --- a/modules/dnn/src/int8layers/pooling_layer.cpp +++ b/modules/dnn/src/int8layers/pooling_layer.cpp @@ -11,6 +11,7 @@ #include #include #include + using std::max; using std::min; @@ -284,22 +285,22 @@ public: input = ngraphDequantize(input, input_sc, input_zp); - ngraph::op::PadType pad_type = ngraph::op::PadType::EXPLICIT; + ov::op::PadType pad_type = ov::op::PadType::EXPLICIT; if (!padMode.empty()) - pad_type = padMode == "VALID" ? ngraph::op::PadType::VALID : ngraph::op::PadType::SAME_UPPER; + pad_type = padMode == "VALID" ? ov::op::PadType::VALID : ov::op::PadType::SAME_UPPER; - auto rounding_type = ceilMode ? ngraph::op::RoundingType::CEIL : ngraph::op::RoundingType::FLOOR; - ngraph::Output pool; + auto rounding_type = ceilMode ? ov::op::RoundingType::CEIL : ov::op::RoundingType::FLOOR; + ov::Output pool; if (type == MAX) { - pool = std::make_shared(input, ngraph::Strides(strides), - ngraph::Shape(pads_begin), ngraph::Shape(pads_end), ngraph::Shape(kernel_size), + pool = std::make_shared(input, ov::Strides(strides), + ov::Shape(pads_begin), ov::Shape(pads_end), ov::Shape(kernel_size), rounding_type, pad_type); } else if (type == AVE) { - pool = std::make_shared(input, ngraph::Strides(strides), - ngraph::Shape(pads_begin), ngraph::Shape(pads_end), ngraph::Shape(kernel_size), + pool = std::make_shared(input, ov::Strides(strides), + ov::Shape(pads_begin), ov::Shape(pads_end), ov::Shape(kernel_size), !avePoolPaddedArea, rounding_type, pad_type); } else if (type == SUM) { - ngraph::Shape inpShape = input.get_shape(); + ov::Shape inpShape = input.get_shape(); CV_Assert(inpShape.size() == 2 + kernel_size.size()); std::vector axes; for (size_t i = 0; i < kernel_size.size(); i++) @@ -307,8 +308,8 @@ public: if (inpShape[2 + i] == kernel_size[i]) axes.push_back(2 + i); } - auto reduction_axes = std::make_shared(ngraph::element::i64, ngraph::Shape{axes.size()}, axes); - pool = std::make_shared(input, reduction_axes, true); + auto reduction_axes = std::make_shared(ov::element::i64, ov::Shape{axes.size()}, axes); + pool = std::make_shared(input, reduction_axes, true); } else { CV_Error(Error::StsNotImplemented, format("INT8 Pooling type: %d", type)); } diff --git a/modules/dnn/src/int8layers/scale_layer.cpp b/modules/dnn/src/int8layers/scale_layer.cpp index e50c4cea0e..25d48e3d17 100644 --- a/modules/dnn/src/int8layers/scale_layer.cpp +++ b/modules/dnn/src/int8layers/scale_layer.cpp @@ -191,7 +191,7 @@ public: #ifdef HAVE_DNN_NGRAPH virtual Ptr initNgraph(const std::vector >& inputs, const std::vector >& nodes) CV_OVERRIDE { - std::vector> ieInpNodes(nodes.size()); + std::vector> ieInpNodes(nodes.size()); for (int i = 0; i < nodes.size(); ++i) { ieInpNodes[i] = nodes[i].dynamicCast()->node; } @@ -200,7 +200,7 @@ public: CV_Assert(!blobs.empty() || ieInpNodes.size() == 1 + (int)hasWeights + (int)hasBias); - ngraph::Output weights, bias; + ov::Output weights, bias; if (blobs.empty()) { if (hasWeights) weights = ieInpNodes[1]; @@ -222,17 +222,17 @@ public: } if (hasWeights) - weights = std::make_shared(ngraph::element::f32, shape, blobs[0].data); + weights = std::make_shared(ov::element::f32, shape, blobs[0].data); if (hasBias) - bias = std::make_shared(ngraph::element::f32, shape, blobs[(int)hasWeights].data); + bias = std::make_shared(ov::element::f32, shape, blobs[(int)hasWeights].data); } - ngraph::Output res = ieInpNodes[0]; + ov::Output res = ieInpNodes[0]; if (hasWeights) { - res = std::make_shared(res, weights); + res = std::make_shared(res, weights); } if (hasBias) { - res = std::make_shared(res, bias); + res = std::make_shared(res, bias); } res = ngraphQuantize(res, output_sc, output_zp); diff --git a/modules/dnn/src/int8layers/softmax_layer.cpp b/modules/dnn/src/int8layers/softmax_layer.cpp index 28c6837cca..e81b82b99f 100644 --- a/modules/dnn/src/int8layers/softmax_layer.cpp +++ b/modules/dnn/src/int8layers/softmax_layer.cpp @@ -204,11 +204,11 @@ public: input = ngraphDequantize(input, input_sc, input_zp); - ngraph::Output res; + ov::Output res; if (logSoftMax) { - res = std::make_shared(input, axis); + res = std::make_shared(input, axis); } else { - res = std::make_shared(input, axis); + res = std::make_shared(input, axis); } res = ngraphQuantize(res, output_sc, output_zp); diff --git a/modules/dnn/src/layers/batch_norm_layer.cpp b/modules/dnn/src/layers/batch_norm_layer.cpp index ccc8354b42..3cdbdc222b 100644 --- a/modules/dnn/src/layers/batch_norm_layer.cpp +++ b/modules/dnn/src/layers/batch_norm_layer.cpp @@ -18,8 +18,6 @@ Implementation of Batch Normalization layer. #include "../op_webnn.hpp" #include "../op_cann.hpp" -#include - #ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" #endif @@ -459,14 +457,10 @@ public: auto ieInpNode = nodes[0].dynamicCast()->node; std::vector shape(ieInpNode.get_shape().size(), 1); shape[1] = weights_.total(); - auto weight = std::make_shared(ngraph::element::f32, ngraph::Shape(shape), weights_.data); - auto bias = std::make_shared(ngraph::element::f32, ngraph::Shape(shape), bias_.data); -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2021_2) - auto scale_node = std::make_shared(ieInpNode, weight, ngraph::op::AutoBroadcastType::NUMPY); -#else - auto scale_node = std::make_shared(ieInpNode, weight, ngraph::op::AutoBroadcastType::NUMPY); -#endif - auto scale_shift = std::make_shared(scale_node, bias, ngraph::op::AutoBroadcastType::NUMPY); + auto weight = std::make_shared(ov::element::f32, ov::Shape(shape), weights_.data); + auto bias = std::make_shared(ov::element::f32, ov::Shape(shape), bias_.data); + auto scale_node = std::make_shared(ieInpNode, weight, ov::op::AutoBroadcastType::NUMPY); + auto scale_shift = std::make_shared(scale_node, bias, ov::op::AutoBroadcastType::NUMPY); return Ptr(new InfEngineNgraphNode(scale_shift)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/blank_layer.cpp b/modules/dnn/src/layers/blank_layer.cpp index 16de23b15e..9723975723 100644 --- a/modules/dnn/src/layers/blank_layer.cpp +++ b/modules/dnn/src/layers/blank_layer.cpp @@ -149,8 +149,8 @@ public: const std::vector >& nodes) CV_OVERRIDE { auto ieInpNode = nodes[0].dynamicCast()->node; - ngraph::OutputVector inp{ieInpNode}; - auto blank = std::make_shared(inp, 0); + ov::OutputVector inp{ieInpNode}; + auto blank = std::make_shared(inp, 0); return Ptr(new InfEngineNgraphNode(blank)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/concat_layer.cpp b/modules/dnn/src/layers/concat_layer.cpp index 3b4b622b2a..3a6466bd80 100644 --- a/modules/dnn/src/layers/concat_layer.cpp +++ b/modules/dnn/src/layers/concat_layer.cpp @@ -59,7 +59,6 @@ #include "../cuda4dnn/primitives/concat.hpp" using namespace cv::dnn::cuda4dnn; #endif - namespace cv { namespace dnn @@ -397,7 +396,7 @@ public: std::vector maxDims(numDims, 0); CV_Assert(inputs.size() == nodes.size()); - ngraph::OutputVector inp_nodes; + ov::OutputVector inp_nodes; for (int i = 0; i < nodes.size(); ++i) { auto inp = nodes[i].dynamicCast()->node; @@ -423,14 +422,14 @@ public: } if (needPadding) { - inp_nodes[i] = std::make_shared( + inp_nodes[i] = std::make_shared( inp_nodes[i], - std::make_shared(ngraph::element::i64, ngraph::Shape{begins.size()}, begins.data()), - std::make_shared(ngraph::element::i64, ngraph::Shape{ends.size()}, ends.data()), - ngraph::op::PadMode::CONSTANT); + std::make_shared(ov::element::i64, ov::Shape{begins.size()}, begins.data()), + std::make_shared(ov::element::i64, ov::Shape{ends.size()}, ends.data()), + ov::op::PadMode::CONSTANT); } } - auto concat = std::make_shared(inp_nodes, cAxis); + auto concat = std::make_shared(inp_nodes, cAxis); return Ptr(new InfEngineNgraphNode(concat)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/const_layer.cpp b/modules/dnn/src/layers/const_layer.cpp index a3f510c496..2246c16320 100644 --- a/modules/dnn/src/layers/const_layer.cpp +++ b/modules/dnn/src/layers/const_layer.cpp @@ -128,22 +128,22 @@ public: virtual Ptr initNgraph(const std::vector >& inputs, const std::vector >& nodes) CV_OVERRIDE { - ngraph::element::Type dType; + ov::element::Type dType; if (blobs[0].depth() == CV_32F) { - dType = ngraph::element::f32; + dType = ov::element::f32; } else if (blobs[0].depth() == CV_32S) { - dType = ngraph::element::i32; + dType = ov::element::i32; } else if (blobs[0].depth() == CV_8S) { - dType = ngraph::element::i8; + dType = ov::element::i8; } else { CV_Error(Error::StsNotImplemented, format("Unexpected Const data depth: %d", blobs[0].depth())); } - std::shared_ptr node = - std::make_shared(dType, + std::shared_ptr node = + std::make_shared(dType, getShape(blobs[0]), blobs[0].data); - if (node->get_element_type() != ngraph::element::f32) { - node = std::make_shared(node, ngraph::element::f32); + if (node->get_element_type() != ov::element::f32) { + node = std::make_shared(node, ov::element::f32); } return Ptr(new InfEngineNgraphNode(node)); } diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index 3f4c5e4069..a950ea18c2 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -822,7 +822,7 @@ public: auto& ieInpNode = nodes[0].dynamicCast()->node; std::vector dims = ieInpNode.get_shape(); CV_Check(dims.size(), dims.size() >= 3 && dims.size() <= 5, ""); - ngraph::Output ieWeights; + ov::Output ieWeights; if (nodes.size() > 1) ieWeights = nodes[1].dynamicCast()->node; const int inpCn = dims[1]; @@ -840,49 +840,49 @@ public: if (nodes.size() == 1) { - ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, blobs[0].data); + ieWeights = std::make_shared(ov::element::f32, kernel_shape, blobs[0].data); if (fusedWeights) { if (weightsMat.isContinuous()) { - ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, weightsMat.data); + ieWeights = std::make_shared(ov::element::f32, kernel_shape, weightsMat.data); } else { Mat newWeights; Mat cvWeights = weightsMat.colRange(0, blobs[0].total() / numOutput); cvWeights.copyTo(newWeights); - ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, newWeights.data); + ieWeights = std::make_shared(ov::element::f32, kernel_shape, newWeights.data); } } } else { - auto shape = std::make_shared(ngraph::element::i64, - ngraph::Shape{kernel_shape.size()}, std::vector(kernel_shape.begin(), kernel_shape.end())); - ieWeights = std::make_shared(ieWeights, shape, true); + auto shape = std::make_shared(ov::element::i64, + ov::Shape{kernel_shape.size()}, std::vector(kernel_shape.begin(), kernel_shape.end())); + ieWeights = std::make_shared(ieWeights, shape, true); } - ngraph::op::PadType pad_type = ngraph::op::PadType::EXPLICIT; + ov::op::PadType pad_type = ov::op::PadType::EXPLICIT; if (!padMode.empty()) - pad_type = padMode == "VALID" ? ngraph::op::PadType::VALID : ngraph::op::PadType::SAME_UPPER; + pad_type = padMode == "VALID" ? ov::op::PadType::VALID : ov::op::PadType::SAME_UPPER; - std::shared_ptr conv_node; + std::shared_ptr conv_node; if (group != 1) { - conv_node = std::make_shared( + conv_node = std::make_shared( ieInpNode, ieWeights, - ngraph::Strides(strides), - ngraph::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), - ngraph::CoordinateDiff(std::vector(pads_end.begin(), pads_end.end())), - ngraph::Strides(dilations), + ov::Strides(strides), + ov::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), + ov::CoordinateDiff(std::vector(pads_end.begin(), pads_end.end())), + ov::Strides(dilations), pad_type); } else { - conv_node = std::make_shared( + conv_node = std::make_shared( ieInpNode, ieWeights, - ngraph::Strides(strides), - ngraph::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), - ngraph::CoordinateDiff(std::vector(pads_end.begin(), pads_end.end())), - ngraph::Strides(dilations), + ov::Strides(strides), + ov::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), + ov::CoordinateDiff(std::vector(pads_end.begin(), pads_end.end())), + ov::Strides(dilations), pad_type); } @@ -890,18 +890,18 @@ public: { std::vector shape(conv_node->get_shape().size(), 1); shape[1] = conv_node->get_shape()[1]; - std::shared_ptr bias; + std::shared_ptr bias; if (nodes.size() == 3) { - auto bias_shape = std::make_shared(ngraph::element::i64, - ngraph::Shape{shape.size()}, std::vector(shape.begin(), shape.end())); - bias = std::make_shared(nodes[2].dynamicCast()->node, bias_shape, true); + auto bias_shape = std::make_shared(ov::element::i64, + ov::Shape{shape.size()}, std::vector(shape.begin(), shape.end())); + bias = std::make_shared(nodes[2].dynamicCast()->node, bias_shape, true); } else { - bias = std::make_shared(ngraph::element::f32, ngraph::Shape(shape), biasvec.data()); + bias = std::make_shared(ov::element::f32, ov::Shape(shape), biasvec.data()); } - auto conv_bias = std::make_shared(conv_node, bias, ngraph::op::AutoBroadcastType::NUMPY); + auto conv_bias = std::make_shared(conv_node, bias, ov::op::AutoBroadcastType::NUMPY); return Ptr(new InfEngineNgraphNode(conv_bias)); } return Ptr(new InfEngineNgraphNode(conv_node)); @@ -2252,13 +2252,13 @@ public: auto& ieInpNode = nodes[0].dynamicCast()->node; std::vector kernel_shape = getShape(blobs[0]); - auto ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, blobs[0].data); + auto ieWeights = std::make_shared(ov::element::f32, kernel_shape, blobs[0].data); if (fusedWeights) { Mat newWeights; transpose(weightsMat, newWeights); - ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, newWeights.data); + ieWeights = std::make_shared(ov::element::f32, kernel_shape, newWeights.data); } std::vector paddings_end; if (padMode == "SAME") @@ -2270,24 +2270,24 @@ public: } else { paddings_end = pads_end; } - ngraph::op::PadType pad_type = padMode == "VALID" ? ngraph::op::PadType::VALID : ngraph::op::PadType::EXPLICIT; + ov::op::PadType pad_type = padMode == "VALID" ? ov::op::PadType::VALID : ov::op::PadType::EXPLICIT; - auto deconv = std::make_shared( + auto deconv = std::make_shared( ieInpNode, ieWeights, - ngraph::Strides(strides), - ngraph::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), - ngraph::CoordinateDiff(std::vector(paddings_end.begin(), paddings_end.end())), - ngraph::Strides(dilations), + ov::Strides(strides), + ov::CoordinateDiff(std::vector(pads_begin.begin(), pads_begin.end())), + ov::CoordinateDiff(std::vector(paddings_end.begin(), paddings_end.end())), + ov::Strides(dilations), pad_type, - ngraph::CoordinateDiff(std::vector(adjust_pads.begin(), adjust_pads.end()))); + ov::CoordinateDiff(std::vector(adjust_pads.begin(), adjust_pads.end()))); if (hasBias() || fusedBias) { std::vector shape(deconv->get_shape().size(), 1); shape[1] = numOutput; - auto bias = std::make_shared(ngraph::element::f32, ngraph::Shape(shape), blobs[1].data); - auto deconv_bias = std::make_shared(deconv, bias, ngraph::op::AutoBroadcastType::NUMPY); + auto bias = std::make_shared(ov::element::f32, ov::Shape(shape), blobs[1].data); + auto deconv_bias = std::make_shared(deconv, bias, ov::op::AutoBroadcastType::NUMPY); return Ptr(new InfEngineNgraphNode(deconv_bias)); } diff --git a/modules/dnn/src/layers/crop_and_resize_layer.cpp b/modules/dnn/src/layers/crop_and_resize_layer.cpp index 43373ca4de..6c29d6b8f4 100644 --- a/modules/dnn/src/layers/crop_and_resize_layer.cpp +++ b/modules/dnn/src/layers/crop_and_resize_layer.cpp @@ -138,23 +138,23 @@ public: offsets[3] = 2; dims[3] = 7; - auto lower_bounds = std::make_shared(ngraph::element::i64, - ngraph::Shape{offsets.size()}, offsets.data()); - auto upper_bounds = std::make_shared(ngraph::element::i64, - ngraph::Shape{dims.size()}, dims.data()); - auto strides = std::make_shared(ngraph::element::i64, - ngraph::Shape{dims.size()}, std::vector((int64_t)dims.size(), 1)); - auto slice = std::make_shared(rois, + auto lower_bounds = std::make_shared(ov::element::i64, + ov::Shape{offsets.size()}, offsets.data()); + auto upper_bounds = std::make_shared(ov::element::i64, + ov::Shape{dims.size()}, dims.data()); + auto strides = std::make_shared(ov::element::i64, + ov::Shape{dims.size()}, std::vector((int64_t)dims.size(), 1)); + auto slice = std::make_shared(rois, lower_bounds, upper_bounds, strides, std::vector{}, std::vector{}); // Reshape rois from 4D to 2D std::vector shapeData = {dims[2], 5}; - auto shape = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, shapeData.data()); - auto reshape = std::make_shared(slice, shape, true); + auto shape = std::make_shared(ov::element::i64, ov::Shape{2}, shapeData.data()); + auto reshape = std::make_shared(slice, shape, true); auto roiPooling = - std::make_shared(input, reshape, - ngraph::Shape{(size_t)outHeight, (size_t)outWidth}, + std::make_shared(input, reshape, + ov::Shape{(size_t)outHeight, (size_t)outWidth}, 1.0f, "bilinear"); return Ptr(new InfEngineNgraphNode(roiPooling)); diff --git a/modules/dnn/src/layers/detection_output_layer.cpp b/modules/dnn/src/layers/detection_output_layer.cpp index 9a7a56fe7a..c7b2272550 100644 --- a/modules/dnn/src/layers/detection_output_layer.cpp +++ b/modules/dnn/src/layers/detection_output_layer.cpp @@ -55,11 +55,7 @@ #ifdef HAVE_DNN_NGRAPH #include "../ie_ngraph.hpp" -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) -#include -#else -#include -#endif +#include #endif #ifdef HAVE_CUDA @@ -1012,26 +1008,26 @@ public: if (_locPredTransposed) { // Convert box predictions from yxYX to xyXY - box_logits = std::make_shared(box_logits, - std::make_shared(ngraph::element::i32, ngraph::Shape{3}, std::vector{0, -1, 2}), + box_logits = std::make_shared(box_logits, + std::make_shared(ov::element::i32, ov::Shape{3}, std::vector{0, -1, 2}), true ); int axis = 2; - box_logits = std::make_shared(box_logits, - std::make_shared(ngraph::element::i32, ngraph::Shape{1}, &axis), - ngraph::op::v1::Reverse::Mode::INDEX + box_logits = std::make_shared(box_logits, + std::make_shared(ov::element::i32, ov::Shape{1}, &axis), + ov::op::v1::Reverse::Mode::INDEX ); } - auto shape = std::make_shared(ngraph::element::i32, ngraph::Shape{2}, std::vector{0, -1}); - box_logits = std::make_shared(box_logits, shape, true); - class_preds = std::make_shared(class_preds, shape, true); - proposals = std::make_shared(proposals, - std::make_shared(ngraph::element::i32, ngraph::Shape{3}, std::vector{0, _varianceEncodedInTarget ? 1 : 2, -1}), + auto shape = std::make_shared(ov::element::i32, ov::Shape{2}, std::vector{0, -1}); + box_logits = std::make_shared(box_logits, shape, true); + class_preds = std::make_shared(class_preds, shape, true); + proposals = std::make_shared(proposals, + std::make_shared(ov::element::i32, ov::Shape{3}, std::vector{0, _varianceEncodedInTarget ? 1 : 2, -1}), true ); - ngraph::op::DetectionOutputAttrs attrs; + ov::op::v0::DetectionOutput::Attributes attrs; attrs.num_classes = _numClasses; attrs.background_label_id = _backgroundLabelId; attrs.top_k = _topK > 0 ? _topK : _keepTopK; @@ -1044,7 +1040,7 @@ public: attrs.code_type = std::string{"caffe.PriorBoxParameter." + _codeType}; attrs.normalized = true; - auto det_out = std::make_shared(box_logits, class_preds, + auto det_out = std::make_shared(box_logits, class_preds, proposals, attrs); return Ptr(new InfEngineNgraphNode(det_out)); } diff --git a/modules/dnn/src/layers/elementwise_layers.cpp b/modules/dnn/src/layers/elementwise_layers.cpp index 7de854c179..6b7909b1b7 100644 --- a/modules/dnn/src/layers/elementwise_layers.cpp +++ b/modules/dnn/src/layers/elementwise_layers.cpp @@ -490,13 +490,13 @@ struct ReLUFunctor : public BaseFunctor #endif #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { if (slope) { - auto param = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &slope); - return std::make_shared(node, param); + auto param = std::make_shared(ov::element::f32, ov::Shape{1}, &slope); + return std::make_shared(node, param); } - return std::make_shared(node); + return std::make_shared(node); } #endif // HAVE_DNN_NGRAPH @@ -674,9 +674,9 @@ struct ReLU6Functor : public BaseFunctor #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - return std::make_shared(node, minValue, maxValue); + return std::make_shared(node, minValue, maxValue); } #endif // HAVE_DNN_NGRAPH @@ -796,7 +796,7 @@ struct BaseDefaultFunctor : public BaseFunctor #endif // HAVE_CANN #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { CV_Error(Error::StsNotImplemented, ""); } @@ -929,9 +929,9 @@ struct TanHFunctor : public BaseDefaultFunctor #endif // HAVE_CANN #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - return std::make_shared(node); + return std::make_shared(node); } #endif // HAVE_DNN_NGRAPH @@ -998,10 +998,10 @@ struct SwishFunctor : public BaseDefaultFunctor #endif // HAVE_CANN #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - auto sigmoid = std::make_shared(node); - return std::make_shared(node, sigmoid); + auto sigmoid = std::make_shared(node); + return std::make_shared(node, sigmoid); } #endif // HAVE_DNN_NGRAPH @@ -1074,9 +1074,9 @@ struct MishFunctor : public BaseDefaultFunctor #endif // HAVE_CANN #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - return std::make_shared(node); + return std::make_shared(node); } #endif // HAVE_DNN_NGRAPH @@ -1151,9 +1151,9 @@ struct SigmoidFunctor : public BaseDefaultFunctor #endif // HAVE_CANN #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - return std::make_shared(node); + return std::make_shared(node); } #endif // HAVE_DNN_NGRAPH @@ -1231,9 +1231,9 @@ struct ELUFunctor : public BaseDefaultFunctor #endif // HAVE_CANN #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - return std::make_shared(node, alpha); + return std::make_shared(node, alpha); } #endif // HAVE_DNN_NGRAPH @@ -1301,9 +1301,9 @@ struct AbsValFunctor : public BaseDefaultFunctor #endif // HAVE_CANN #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - return std::make_shared(node); + return std::make_shared(node); } #endif // HAVE_DNN_NGRAPH @@ -1594,9 +1594,9 @@ struct SqrtFunctor : public BaseDefaultFunctor #endif // HAVE_HALIDE #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - return std::make_shared(node); + return std::make_shared(node); } #endif // HAVE_DNN_NGRAPH @@ -2343,22 +2343,22 @@ struct PowerFunctor : public BaseFunctor #endif // HAVE_CANN #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - auto scale_node = std::make_shared(ngraph::element::f32, - ngraph::Shape{1}, &scale); - auto shift_node = std::make_shared(ngraph::element::f32, - ngraph::Shape{1}, &shift); + auto scale_node = std::make_shared(ov::element::f32, + ov::Shape{1}, &scale); + auto shift_node = std::make_shared(ov::element::f32, + ov::Shape{1}, &shift); - auto mul = std::make_shared(scale_node, node, ngraph::op::AutoBroadcastType::NUMPY); - auto scale_shift = std::make_shared(mul, shift_node, ngraph::op::AutoBroadcastType::NUMPY); + auto mul = std::make_shared(scale_node, node, ov::op::AutoBroadcastType::NUMPY); + auto scale_shift = std::make_shared(mul, shift_node, ov::op::AutoBroadcastType::NUMPY); if (power == 1) return scale_shift; - auto power_node = std::make_shared(ngraph::element::f32, - ngraph::Shape{1}, &power); - return std::make_shared(scale_shift, power_node, ngraph::op::AutoBroadcastType::NUMPY); + auto power_node = std::make_shared(ov::element::f32, + ov::Shape{1}, &power); + return std::make_shared(scale_shift, power_node, ov::op::AutoBroadcastType::NUMPY); } #endif // HAVE_DNN_NGRAPH @@ -2453,15 +2453,15 @@ struct ExpFunctor : public BaseDefaultFunctor #endif // HAVE_HALIDE #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { - auto scale_node = std::make_shared(ngraph::element::f32, - ngraph::Shape{1}, &normScale); - auto shift_node = std::make_shared(ngraph::element::f32, - ngraph::Shape{1}, &normShift); - auto mul = std::make_shared(scale_node, node, ngraph::op::AutoBroadcastType::NUMPY); - auto scale_shift = std::make_shared(mul, shift_node, ngraph::op::AutoBroadcastType::NUMPY); - return std::make_shared(scale_shift); + auto scale_node = std::make_shared(ov::element::f32, + ov::Shape{1}, &normScale); + auto shift_node = std::make_shared(ov::element::f32, + ov::Shape{1}, &normShift); + auto mul = std::make_shared(scale_node, node, ov::op::AutoBroadcastType::NUMPY); + auto scale_shift = std::make_shared(mul, shift_node, ov::op::AutoBroadcastType::NUMPY); + return std::make_shared(scale_shift); } #endif // HAVE_DNN_NGRAPH @@ -2612,11 +2612,11 @@ struct ChannelsPReLUFunctor : public BaseFunctor #endif // HAVE_CANN #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { const size_t numChannels = scale.total(); - auto slope = std::make_shared(ngraph::element::f32, ngraph::Shape{numChannels}, scale.data); - return std::make_shared(node, slope); + auto slope = std::make_shared(ov::element::f32, ov::Shape{numChannels}, scale.data); + return std::make_shared(node, slope); } #endif // HAVE_DNN_NGRAPH @@ -2692,11 +2692,11 @@ struct PReLUFunctor : public ChannelsPReLUFunctor } #ifdef HAVE_DNN_NGRAPH - std::shared_ptr initNgraphAPI(const ngraph::Output& node) + std::shared_ptr initNgraphAPI(const ov::Output& node) { auto shape = getShape(scale); - auto slope = std::make_shared(ngraph::element::f32, shape, scale.ptr()); - return std::make_shared(node, slope); + auto slope = std::make_shared(ov::element::f32, shape, scale.ptr()); + return std::make_shared(node, slope); } #endif // HAVE_DNN_NGRAPH }; diff --git a/modules/dnn/src/layers/eltwise_layer.cpp b/modules/dnn/src/layers/eltwise_layer.cpp index 32caf29530..e9363bcbea 100644 --- a/modules/dnn/src/layers/eltwise_layer.cpp +++ b/modules/dnn/src/layers/eltwise_layer.cpp @@ -899,24 +899,24 @@ public: CV_Assert(nodes.size() >= 2); auto curr_node = nodes[0].dynamicCast()->node; if (!coeffs.empty()) { - auto coeff = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &coeffs[0]); - curr_node = std::make_shared(curr_node, coeff, ngraph::op::AutoBroadcastType::NUMPY); + auto coeff = std::make_shared(ov::element::f32, ov::Shape{1}, &coeffs[0]); + curr_node = std::make_shared(curr_node, coeff, ov::op::AutoBroadcastType::NUMPY); } - std::shared_ptr res; + std::shared_ptr res; for (size_t i = 1; i < nodes.size(); i++) { auto next_node = nodes[i].dynamicCast()->node; if (!coeffs.empty()) { - auto coeff = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &coeffs[i]); - next_node = std::make_shared(next_node, coeff, ngraph::op::AutoBroadcastType::NUMPY); + auto coeff = std::make_shared(ov::element::f32, ov::Shape{1}, &coeffs[i]); + next_node = std::make_shared(next_node, coeff, ov::op::AutoBroadcastType::NUMPY); } switch (op) { - case SUM: res = std::make_shared(curr_node, next_node); break; - case PROD: res = std::make_shared(curr_node, next_node); break; - case DIV: res = std::make_shared(curr_node, next_node); break; - case MAX: res = std::make_shared(curr_node, next_node); break; - case MIN: res = std::make_shared(curr_node, next_node); break; + case SUM: res = std::make_shared(curr_node, next_node); break; + case PROD: res = std::make_shared(curr_node, next_node); break; + case DIV: res = std::make_shared(curr_node, next_node); break; + case MAX: res = std::make_shared(curr_node, next_node); break; + case MIN: res = std::make_shared(curr_node, next_node); break; default: CV_Error(Error::StsNotImplemented, "Unsupported eltwise operation"); } curr_node = res; diff --git a/modules/dnn/src/layers/flatten_layer.cpp b/modules/dnn/src/layers/flatten_layer.cpp index 9ff3bec38b..48950601f2 100644 --- a/modules/dnn/src/layers/flatten_layer.cpp +++ b/modules/dnn/src/layers/flatten_layer.cpp @@ -56,6 +56,7 @@ using namespace cv::dnn::cuda4dnn; #endif + namespace cv { namespace dnn @@ -224,9 +225,9 @@ public: outputShapeVec.push_back(flattenedDimensionSize); outputShapeVec.insert(outputShapeVec.end(), dims.begin() + endAxis + 1, dims.end()); - auto shape = std::make_shared(ngraph::element::i64, - ngraph::Shape({outputShapeVec.size()}), outputShapeVec.data()); - auto reshape = std::make_shared(ieInpNode, shape, true); + auto shape = std::make_shared(ov::element::i64, + ov::Shape({outputShapeVec.size()}), outputShapeVec.data()); + auto reshape = std::make_shared(ieInpNode, shape, true); return Ptr(new InfEngineNgraphNode(reshape)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/fully_connected_layer.cpp b/modules/dnn/src/layers/fully_connected_layer.cpp index 29090652e1..4ff6fc74a4 100644 --- a/modules/dnn/src/layers/fully_connected_layer.cpp +++ b/modules/dnn/src/layers/fully_connected_layer.cpp @@ -787,20 +787,20 @@ public: const std::vector >& nodes) CV_OVERRIDE { auto& ieInpNode = nodes[0].dynamicCast()->node; - std::shared_ptr matmul; + std::shared_ptr matmul; if (nodes.size() == 2) { auto& inp2 = nodes[1].dynamicCast()->node; - matmul = std::make_shared(ieInpNode, inp2, transA, transB); + matmul = std::make_shared(ieInpNode, inp2, transA, transB); } else { std::vector shape(1 + normalize_axis(axis, ieInpNode.get_shape().size()), 0); shape[shape.size() - 1] = -1; - auto inp = std::make_shared( + auto inp = std::make_shared( ieInpNode, - std::make_shared(ngraph::element::i32, ngraph::Shape{shape.size()}, shape.data()), + std::make_shared(ov::element::i32, ov::Shape{shape.size()}, shape.data()), true ); @@ -810,14 +810,14 @@ public: } else { weight_shape = {(size_t)blobs[0].size[0], (size_t)blobs[0].size[1]}; } - auto ieWeights = std::make_shared(ngraph::element::f32, weight_shape, blobs[0].data); - matmul = std::make_shared(inp, ieWeights, transA, transB); + auto ieWeights = std::make_shared(ov::element::f32, weight_shape, blobs[0].data); + matmul = std::make_shared(inp, ieWeights, transA, transB); } if (bias) { - auto bias_node = std::make_shared(ngraph::element::f32, - ngraph::Shape{(size_t)blobs[1].size[1]}, blobs[1].data); - matmul = std::make_shared(matmul, bias_node, ngraph::op::AutoBroadcastType::NUMPY); + auto bias_node = std::make_shared(ov::element::f32, + ov::Shape{(size_t)blobs[1].size[1]}, blobs[1].data); + matmul = std::make_shared(matmul, bias_node, ov::op::AutoBroadcastType::NUMPY); } return Ptr(new InfEngineNgraphNode(matmul)); } diff --git a/modules/dnn/src/layers/gemm_layer.cpp b/modules/dnn/src/layers/gemm_layer.cpp index 496d3871a2..fd10e9acdf 100644 --- a/modules/dnn/src/layers/gemm_layer.cpp +++ b/modules/dnn/src/layers/gemm_layer.cpp @@ -285,45 +285,45 @@ public: const std::vector >& nodes) CV_OVERRIDE { auto ieInpNode = nodes[0].dynamicCast()->node; - std::shared_ptr matmul; + std::shared_ptr matmul; if (nodes.size() == 2) { auto& inp2 = nodes[1].dynamicCast()->node; - matmul = std::make_shared(ieInpNode, inp2, trans_a, trans_b); + matmul = std::make_shared(ieInpNode, inp2, trans_a, trans_b); } else { - std::shared_ptr ieWeights = std::make_shared(ngraph::element::f32, getShape(blobs[0]), blobs[0].data); + std::shared_ptr ieWeights = std::make_shared(ov::element::f32, getShape(blobs[0]), blobs[0].data); int flatten_axis = ieInpNode.get_shape().size() - ieWeights->get_shape().size(); if (flatten_axis > 0) { std::vector shape(1 + flatten_axis, 0); shape[shape.size() - 1] = -1; - ieInpNode = std::make_shared( + ieInpNode = std::make_shared( ieInpNode, - std::make_shared(ngraph::element::i32, ngraph::Shape{shape.size()}, shape.data()), + std::make_shared(ov::element::i32, ov::Shape{shape.size()}, shape.data()), true ); } - matmul = std::make_shared(ieInpNode, ieWeights, trans_a, trans_b); + matmul = std::make_shared(ieInpNode, ieWeights, trans_a, trans_b); } if (alpha != 1.0f) { - matmul = std::make_shared(matmul, - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &alpha) + matmul = std::make_shared(matmul, + std::make_shared(ov::element::f32, ov::Shape{1}, &alpha) ); } if (have_bias && const_C) { Mat bias = blobs.back(); - auto shape = bias.total() == bias.size[0] ? ngraph::Shape{bias.total()} : getShape(bias); - std::shared_ptr bias_node = std::make_shared(ngraph::element::f32, shape, bias.data); + auto shape = bias.total() == bias.size[0] ? ov::Shape{bias.total()} : getShape(bias); + std::shared_ptr bias_node = std::make_shared(ov::element::f32, shape, bias.data); if (beta != 1.0f) { - bias_node = std::make_shared(bias_node, - std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &beta) + bias_node = std::make_shared(bias_node, + std::make_shared(ov::element::f32, ov::Shape{1}, &beta) ); } - matmul = std::make_shared(matmul, bias_node, ngraph::op::AutoBroadcastType::NUMPY); + matmul = std::make_shared(matmul, bias_node, ov::op::AutoBroadcastType::NUMPY); } return Ptr(new InfEngineNgraphNode(matmul)); } diff --git a/modules/dnn/src/layers/instance_norm_layer.cpp b/modules/dnn/src/layers/instance_norm_layer.cpp index b6427238f2..ae61f15656 100644 --- a/modules/dnn/src/layers/instance_norm_layer.cpp +++ b/modules/dnn/src/layers/instance_norm_layer.cpp @@ -225,33 +225,26 @@ public: auto ieInpNode = nodes[0].dynamicCast()->node; const auto &input_shape = ieInpNode.get_shape(); - std::shared_ptr mvn, result; + std::shared_ptr mvn, result; // mvn -#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2021_2) - // https://docs.openvino.ai/2021.4/api/ngraph_python_api/_autosummary/ngraph.opset3.mvn.html?highlight=mvn#ngraph.opset3.mvn - bool across_channels = false; - bool normalize_variance = true; - mvn = std::make_shared(ieInpNode, across_channels, normalize_variance, epsilon); -#else // https://docs.openvino.ai/2023.1/openvino_docs_ops_normalization_MVN_6.html std::vector axes_v(input_shape.size() - 2); std::iota(axes_v.begin(), axes_v.end(), 2); // {2, 3, ...} for nd input tensor, n>=3 - auto axes = std::make_shared(ngraph::element::i64, ngraph::Shape{axes_v.size()}, axes_v.data()); + auto axes = std::make_shared(ov::element::i64, ov::Shape{axes_v.size()}, axes_v.data()); bool normalize_variance = true; - mvn = std::make_shared(ieInpNode, axes, normalize_variance, epsilon, ngraph::op::MVNEpsMode::INSIDE_SQRT); -#endif + mvn = std::make_shared(ieInpNode, axes, normalize_variance, epsilon, ov::op::MVNEpsMode::INSIDE_SQRT); // instance norm = scale * mvn + bias auto scale = nodes[1].dynamicCast()->node; std::vector shared_shape_v(input_shape.size(), 1); shared_shape_v[1] = -1; - auto shared_shape = std::make_shared(ngraph::element::i64, ngraph::Shape{shared_shape_v.size()}, shared_shape_v.data()); - scale = std::make_shared(scale, shared_shape, true); - result = std::make_shared(mvn, scale); + auto shared_shape = std::make_shared(ov::element::i64, ov::Shape{shared_shape_v.size()}, shared_shape_v.data()); + scale = std::make_shared(scale, shared_shape, true); + result = std::make_shared(mvn, scale); auto bias = nodes[2].dynamicCast()->node; - bias = std::make_shared(bias, shared_shape, true); - result = std::make_shared(result, bias); + bias = std::make_shared(bias, shared_shape, true); + result = std::make_shared(result, bias); return Ptr(new InfEngineNgraphNode(result)); } diff --git a/modules/dnn/src/layers/layer_norm.cpp b/modules/dnn/src/layers/layer_norm.cpp index 6ea1bee42a..5ebebbd32d 100644 --- a/modules/dnn/src/layers/layer_norm.cpp +++ b/modules/dnn/src/layers/layer_norm.cpp @@ -263,42 +263,35 @@ public: const std::vector >& nodes) CV_OVERRIDE { auto ieInpNode = nodes[0].dynamicCast()->node; const auto &input_shape = ieInpNode.get_shape(); - std::shared_ptr mvn, result; + std::shared_ptr mvn, result; // mvn -#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2021_2) - // https://docs.openvino.ai/2021.4/api/ngraph_python_api/_autosummary/ngraph.opset3.mvn.html?highlight=mvn#ngraph.opset3.mvn - bool across_channels = false; - bool normalize_variance = true; - mvn = std::make_shared(ieInpNode, across_channels, normalize_variance, epsilon); -#else // https://docs.openvino.ai/2023.1/openvino_docs_ops_normalization_MVN_6.html std::vector axes_v(input_shape.size() - axis); std::iota(axes_v.begin(), axes_v.end(), axis); - auto axes = std::make_shared(ngraph::element::i64, ngraph::Shape{axes_v.size()}, axes_v.data()); + auto axes = std::make_shared(ov::element::i64, ov::Shape{axes_v.size()}, axes_v.data()); bool normalize_variance = true; - mvn = std::make_shared(ieInpNode, axes, normalize_variance, epsilon, ngraph::op::MVNEpsMode::INSIDE_SQRT); -#endif + mvn = std::make_shared(ieInpNode, axes, normalize_variance, epsilon, ov::op::MVNEpsMode::INSIDE_SQRT); // layer norm = scale * mvn + bias auto scale = nodes[1].dynamicCast()->node; - ngraph::Output bias; + ov::Output bias; if (nodes.size() == 3) { bias = nodes[2].dynamicCast()->node; } if (axis == -1 || axis == input_shape.size() - 1) { // special case for 1D tensor (2D mat) std::vector shared_shape_v(input_shape.size(), 1); shared_shape_v.back() = -1; - auto shared_shape = std::make_shared(ngraph::element::i64, ngraph::Shape{shared_shape_v.size()}, shared_shape_v.data()); - scale = std::make_shared(scale, shared_shape, true); + auto shared_shape = std::make_shared(ov::element::i64, ov::Shape{shared_shape_v.size()}, shared_shape_v.data()); + scale = std::make_shared(scale, shared_shape, true); if (nodes.size() == 3) { - bias = std::make_shared(bias, shared_shape, true); + bias = std::make_shared(bias, shared_shape, true); } } - result = std::make_shared(mvn, scale); + result = std::make_shared(mvn, scale); if (nodes.size() == 3) { - result = std::make_shared(result, bias); + result = std::make_shared(result, bias); } return Ptr(new InfEngineNgraphNode(result)); diff --git a/modules/dnn/src/layers/lrn_layer.cpp b/modules/dnn/src/layers/lrn_layer.cpp index 7d212dc888..4863be2e3d 100644 --- a/modules/dnn/src/layers/lrn_layer.cpp +++ b/modules/dnn/src/layers/lrn_layer.cpp @@ -483,8 +483,8 @@ public: axes.resize(ieInpNode.get_shape().size() - 2); std::iota(axes.begin(), axes.end(), 2); } - auto ngraph_axes = std::make_shared(ngraph::element::i64, ngraph::Shape{axes.size()}, axes.data()); - auto lrn = std::make_shared(ieInpNode, ngraph_axes, alphaSize, beta, bias, size); + auto ngraph_axes = std::make_shared(ov::element::i64, ov::Shape{axes.size()}, axes.data()); + auto lrn = std::make_shared(ieInpNode, ngraph_axes, alphaSize, beta, bias, size); return Ptr(new InfEngineNgraphNode(lrn)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/matmul_layer.cpp b/modules/dnn/src/layers/matmul_layer.cpp index 1e9a8dfebe..a571592dfb 100644 --- a/modules/dnn/src/layers/matmul_layer.cpp +++ b/modules/dnn/src/layers/matmul_layer.cpp @@ -216,15 +216,15 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { virtual Ptr initNgraph(const std::vector >& inputs, const std::vector >& nodes) CV_OVERRIDE { auto& input_A_node = nodes[0].dynamicCast()->node; - std::shared_ptr matmul; + std::shared_ptr matmul; if (nodes.size() == 2) { auto &input_B_node = nodes[1].dynamicCast()->node; - matmul = std::make_shared(input_A_node, input_B_node, trans_a, trans_b); + matmul = std::make_shared(input_A_node, input_B_node, trans_a, trans_b); } else { auto input_B_shape = getShape(blobs[0]); - auto input_B_node = std::make_shared(ngraph::element::f32, input_B_shape, blobs[0].data); - matmul = std::make_shared(input_A_node, input_B_node, trans_a, trans_b); + auto input_B_node = std::make_shared(ov::element::f32, input_B_shape, blobs[0].data); + matmul = std::make_shared(input_A_node, input_B_node, trans_a, trans_b); } return Ptr(new InfEngineNgraphNode(matmul)); diff --git a/modules/dnn/src/layers/max_unpooling_layer.cpp b/modules/dnn/src/layers/max_unpooling_layer.cpp index d00887db3c..aa645c17ae 100644 --- a/modules/dnn/src/layers/max_unpooling_layer.cpp +++ b/modules/dnn/src/layers/max_unpooling_layer.cpp @@ -200,29 +200,29 @@ public: getMemoryShapes(inpShapes, 1, outShapes, internals); Mat zeros = Mat::zeros(1, total(outShapes[0]), CV_32F); - auto zeroInp = std::make_shared(ngraph::element::f32, ngraph::Shape{zeros.total()}, zeros.data); + auto zeroInp = std::make_shared(ov::element::f32, ov::Shape{zeros.total()}, zeros.data); int newShape = -1; - features = std::make_shared( + features = std::make_shared( features, - std::make_shared(ngraph::element::i32, ngraph::Shape{1}, &newShape), + std::make_shared(ov::element::i32, ov::Shape{1}, &newShape), true ); - indices = std::make_shared( + indices = std::make_shared( indices, - std::make_shared(ngraph::element::i32, ngraph::Shape{1}, &newShape), + std::make_shared(ov::element::i32, ov::Shape{1}, &newShape), true ); - if (indices.get_element_type() != ngraph::element::i32 && indices.get_element_type() != ngraph::element::i64) { - indices = std::make_shared(indices, ngraph::element::i64); + if (indices.get_element_type() != ov::element::i32 && indices.get_element_type() != ov::element::i64) { + indices = std::make_shared(indices, ov::element::i64); } int axis = 0; - std::shared_ptr unpool = std::make_shared(zeroInp, indices, features, - std::make_shared(ngraph::element::i32, ngraph::Shape{1}, &axis)); + std::shared_ptr unpool = std::make_shared(zeroInp, indices, features, + std::make_shared(ov::element::i32, ov::Shape{1}, &axis)); - auto shape = std::make_shared(ngraph::element::i32, ngraph::Shape{outShapes[0].size()}, outShapes[0].data()); - unpool = std::make_shared(unpool, shape, true); + auto shape = std::make_shared(ov::element::i32, ov::Shape{outShapes[0].size()}, outShapes[0].data()); + unpool = std::make_shared(unpool, shape, true); return Ptr(new InfEngineNgraphNode(unpool)); } diff --git a/modules/dnn/src/layers/mvn_layer.cpp b/modules/dnn/src/layers/mvn_layer.cpp index 10ef1cfb34..d59e339ac4 100644 --- a/modules/dnn/src/layers/mvn_layer.cpp +++ b/modules/dnn/src/layers/mvn_layer.cpp @@ -336,15 +336,11 @@ public: const std::vector >& nodes) CV_OVERRIDE { auto& ieInpNode = nodes[0].dynamicCast()->node; -#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2021_2) - auto mvn = std::make_shared(ieInpNode, acrossChannels, normVariance, eps); -#else int64_t start_axis = acrossChannels ? 1 : 2; std::vector axes_v(ieInpNode.get_shape().size() - start_axis); std::iota(axes_v.begin(), axes_v.end(), start_axis); - auto axes = std::make_shared(ngraph::element::i64, ngraph::Shape{axes_v.size()}, axes_v.data()); - auto mvn = std::make_shared(ieInpNode, axes, normVariance, eps, ngraph::op::MVNEpsMode::INSIDE_SQRT); -#endif + auto axes = std::make_shared(ov::element::i64, ov::Shape{axes_v.size()}, axes_v.data()); + auto mvn = std::make_shared(ieInpNode, axes, normVariance, eps, ov::op::MVNEpsMode::INSIDE_SQRT); return Ptr(new InfEngineNgraphNode(mvn)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/nary_eltwise_layers.cpp b/modules/dnn/src/layers/nary_eltwise_layers.cpp index c369a710a6..e3a8b2a583 100644 --- a/modules/dnn/src/layers/nary_eltwise_layers.cpp +++ b/modules/dnn/src/layers/nary_eltwise_layers.cpp @@ -887,32 +887,32 @@ public: if (inp0.get_element_type() != inp1.get_element_type()) { auto dtype = preferableTarget == DNN_TARGET_OPENCL_FP16 || preferableTarget == DNN_TARGET_MYRIAD ? - ngraph::element::f16 : ngraph::element::f32; + ov::element::f16 : ov::element::f32; if (inp0.get_element_type() != dtype) - inp0 = std::make_shared(inp0, dtype); + inp0 = std::make_shared(inp0, dtype); if (inp1.get_element_type() != dtype) - inp1 = std::make_shared(inp1, dtype); + inp1 = std::make_shared(inp1, dtype); } - std::shared_ptr node; + std::shared_ptr node; if (op == OPERATION::ADD) - node = std::make_shared(inp0, inp1); + node = std::make_shared(inp0, inp1); else if (op == OPERATION::PROD) - node = std::make_shared(inp0, inp1); + node = std::make_shared(inp0, inp1); else if (op == OPERATION::GREATER_EQUAL) - node = std::make_shared(inp0, inp1); + node = std::make_shared(inp0, inp1); else if (op == OPERATION::LESS_EQUAL) - node = std::make_shared(inp0, inp1); + node = std::make_shared(inp0, inp1); // Ideally we should do this but int32 internal blobs are converted to float32 data type in inference. // TODO: Remove data type convertion when we have type inference. else if (op == OPERATION::MOD) { - auto inp0_i64 = std::make_shared(inp0, ngraph::element::i64); - auto inp1_i64 = std::make_shared(inp1, ngraph::element::i64); - auto mod = std::make_shared(inp0_i64, inp1_i64); - node = std::make_shared(mod, ngraph::element::f32); + auto inp0_i64 = std::make_shared(inp0, ov::element::i64); + auto inp1_i64 = std::make_shared(inp1, ov::element::i64); + auto mod = std::make_shared(inp0_i64, inp1_i64); + node = std::make_shared(mod, ov::element::f32); } else if (op == OPERATION::FMOD) - node = std::make_shared(inp0, inp1); + node = std::make_shared(inp0, inp1); else CV_Error(Error::StsNotImplemented, "Operation is not implemented for nGraph backend"); return Ptr(new InfEngineNgraphNode(node)); diff --git a/modules/dnn/src/layers/normalize_bbox_layer.cpp b/modules/dnn/src/layers/normalize_bbox_layer.cpp index 723d3c7f7f..d2324b2a94 100644 --- a/modules/dnn/src/layers/normalize_bbox_layer.cpp +++ b/modules/dnn/src/layers/normalize_bbox_layer.cpp @@ -283,8 +283,8 @@ public: axes_data.resize(ieInpNode.get_shape().size() - 1); std::iota(axes_data.begin(), axes_data.end(), 1); } - auto axes = std::make_shared(ngraph::element::i64, ngraph::Shape{axes_data.size()}, axes_data); - auto norm = std::make_shared(ieInpNode, axes, epsilon, ngraph::op::EpsMode::ADD); + auto axes = std::make_shared(ov::element::i64, ov::Shape{axes_data.size()}, axes_data); + auto norm = std::make_shared(ieInpNode, axes, epsilon, ov::op::EpsMode::ADD); CV_Assert(blobs.empty() || numChannels == blobs[0].total()); std::vector shape(ieInpNode.get_shape().size(), 1); @@ -292,13 +292,9 @@ public: shape[1] = numChannels; if (!blobs.empty()) { - auto weight = std::make_shared( - ngraph::element::f32, ngraph::Shape(shape), blobs[0].data); -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2021_2) - auto mul = std::make_shared(norm, weight, ngraph::op::AutoBroadcastType::NUMPY); -#else - auto mul = std::make_shared(norm, weight, ngraph::op::AutoBroadcastType::NUMPY); -#endif + auto weight = std::make_shared( + ov::element::f32, ov::Shape(shape), blobs[0].data); + auto mul = std::make_shared(norm, weight, ov::op::AutoBroadcastType::NUMPY); return Ptr(new InfEngineNgraphNode(mul)); } return Ptr(new InfEngineNgraphNode(norm)); diff --git a/modules/dnn/src/layers/padding_layer.cpp b/modules/dnn/src/layers/padding_layer.cpp index edb7f92413..947bca8618 100644 --- a/modules/dnn/src/layers/padding_layer.cpp +++ b/modules/dnn/src/layers/padding_layer.cpp @@ -268,14 +268,14 @@ public: begins[i] = static_cast(paddings[i].first); ends[i] = static_cast(paddings[i].second); } - auto padding_below = std::make_shared(ngraph::element::i64, ngraph::Shape{begins.size()}, begins.data()); - auto padding_above = std::make_shared(ngraph::element::i64, ngraph::Shape{ends.size()}, ends.data()); - auto pad_mode = paddingType == "constant" ? ngraph::op::PadMode::CONSTANT : ngraph::op::PadMode::REFLECT; // SYMMETRIC - auto arg_pad_value = std::make_shared(ngraph::element::f32, ngraph::Shape{}, &paddingValue);; + auto padding_below = std::make_shared(ov::element::i64, ov::Shape{begins.size()}, begins.data()); + auto padding_above = std::make_shared(ov::element::i64, ov::Shape{ends.size()}, ends.data()); + auto pad_mode = paddingType == "constant" ? ov::op::PadMode::CONSTANT : ov::op::PadMode::REFLECT; // SYMMETRIC + auto arg_pad_value = std::make_shared(ov::element::f32, ov::Shape{}, &paddingValue);; auto pad = paddingType == "constant" ? - std::make_shared(ieInpNode, padding_below, padding_above, arg_pad_value, pad_mode) : - std::make_shared(ieInpNode, padding_below, padding_above, pad_mode); + std::make_shared(ieInpNode, padding_below, padding_above, arg_pad_value, pad_mode) : + std::make_shared(ieInpNode, padding_below, padding_above, pad_mode); return Ptr(new InfEngineNgraphNode(pad)); } #endif diff --git a/modules/dnn/src/layers/permute_layer.cpp b/modules/dnn/src/layers/permute_layer.cpp index b7c8bcfdaf..7304302314 100644 --- a/modules/dnn/src/layers/permute_layer.cpp +++ b/modules/dnn/src/layers/permute_layer.cpp @@ -475,9 +475,9 @@ public: { auto& ieInpNode = nodes[0].dynamicCast()->node; std::vector order(_order.begin(), _order.end()); - auto tr_axes = std::make_shared(ngraph::element::i64, - ngraph::Shape({order.size()}), order.data()); - auto transpose = std::make_shared(ieInpNode, tr_axes); + auto tr_axes = std::make_shared(ov::element::i64, + ov::Shape({order.size()}), order.data()); + auto transpose = std::make_shared(ieInpNode, tr_axes); return Ptr(new InfEngineNgraphNode(transpose)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/pooling_layer.cpp b/modules/dnn/src/layers/pooling_layer.cpp index ba077bdcc4..fbf075f7d3 100644 --- a/modules/dnn/src/layers/pooling_layer.cpp +++ b/modules/dnn/src/layers/pooling_layer.cpp @@ -51,13 +51,8 @@ #ifdef HAVE_DNN_NGRAPH #include "../ie_ngraph.hpp" -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) -#include -#include -#else -#include -#include -#endif +#include +#include #endif #include "../op_vkcom.hpp" @@ -588,20 +583,20 @@ public: CV_Assert_N((inputs.size() == 1 && (type == MAX || type == AVE || type == SUM)) || inputs.size() == 2, nodes.size() == inputs.size()); auto& ieInpNode = nodes[0].dynamicCast()->node; - ngraph::op::PadType pad_type = ngraph::op::PadType::EXPLICIT; + ov::op::PadType pad_type = ov::op::PadType::EXPLICIT; if (!padMode.empty()) - pad_type = padMode == "VALID" ? ngraph::op::PadType::VALID : ngraph::op::PadType::SAME_UPPER; + pad_type = padMode == "VALID" ? ov::op::PadType::VALID : ov::op::PadType::SAME_UPPER; - auto rounding_type = ceilMode ? ngraph::op::RoundingType::CEIL : ngraph::op::RoundingType::FLOOR; + auto rounding_type = ceilMode ? ov::op::RoundingType::CEIL : ov::op::RoundingType::FLOOR; if (type == AVE) { auto exclude_pad = !avePoolPaddedArea; - auto ave_pool = std::make_shared(ieInpNode, ngraph::Strides(strides), - ngraph::Shape(pads_begin), ngraph::Shape(pads_end), ngraph::Shape(kernel_size), + auto ave_pool = std::make_shared(ieInpNode, ov::Strides(strides), + ov::Shape(pads_begin), ov::Shape(pads_end), ov::Shape(kernel_size), exclude_pad, rounding_type, pad_type); return Ptr(new InfEngineNgraphNode(ave_pool)); } else if (type == SUM) { - ngraph::Shape inpShape = ieInpNode.get_shape(); + ov::Shape inpShape = ieInpNode.get_shape(); CV_Assert(inpShape.size() == 2 + kernel_size.size()); std::vector axes; for (size_t i = 0; i < kernel_size.size(); i++) @@ -609,37 +604,33 @@ public: if (inpShape[2 + i] == kernel_size[i]) axes.push_back(2 + i); } - auto reduction_axes = std::make_shared(ngraph::element::i64, ngraph::Shape{axes.size()}, axes); - auto reduce_sum = std::make_shared(ieInpNode, reduction_axes, true); + auto reduction_axes = std::make_shared(ov::element::i64, ov::Shape{axes.size()}, axes); + auto reduce_sum = std::make_shared(ieInpNode, reduction_axes, true); return Ptr(new InfEngineNgraphNode(reduce_sum)); } else if (type == MAX) { - std::shared_ptr max_pool; + std::shared_ptr max_pool; if (computeMaxIdx) { -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) std::vector dilations(kernel_size.size(), 1); - max_pool = std::make_shared(ieInpNode, ngraph::Strides(strides), ngraph::Strides(dilations), - ngraph::Shape(pads_begin), ngraph::Shape(pads_end), ngraph::Shape(kernel_size), + max_pool = std::make_shared(ieInpNode, ov::Strides(strides), ov::Strides(dilations), + ov::Shape(pads_begin), ov::Shape(pads_end), ov::Shape(kernel_size), rounding_type, pad_type); -#else - CV_Error(Error::StsNotImplemented, "OpenVINO MaxPool with indices"); -#endif } else { - max_pool = std::make_shared(ieInpNode, ngraph::Strides(strides), - ngraph::Shape(pads_begin), ngraph::Shape(pads_end), ngraph::Shape(kernel_size), + max_pool = std::make_shared(ieInpNode, ov::Strides(strides), + ov::Shape(pads_begin), ov::Shape(pads_end), ov::Shape(kernel_size), rounding_type, pad_type); } return Ptr(new InfEngineNgraphNode(max_pool)); } else if (type == ROI) { auto& coords = nodes[1].dynamicCast()->node; - auto roi = std::make_shared(ieInpNode, coords, - ngraph::Shape{(size_t)pooledSize.height, (size_t)pooledSize.width}, spatialScale, "max"); + auto roi = std::make_shared(ieInpNode, coords, + ov::Shape{(size_t)pooledSize.height, (size_t)pooledSize.width}, spatialScale, "max"); return Ptr(new InfEngineNgraphNode(roi)); } else if (type == PSROI) { auto& coords = nodes[1].dynamicCast()->node; - auto psroi = std::make_shared(ieInpNode, coords, + auto psroi = std::make_shared(ieInpNode, coords, (size_t)psRoiOutChannels, (size_t)pooledSize.width, spatialScale, 1, 1, "average"); return Ptr(new InfEngineNgraphNode(psroi)); } diff --git a/modules/dnn/src/layers/prior_box_layer.cpp b/modules/dnn/src/layers/prior_box_layer.cpp index 1dc40b48ce..bb3aa99cd3 100644 --- a/modules/dnn/src/layers/prior_box_layer.cpp +++ b/modules/dnn/src/layers/prior_box_layer.cpp @@ -47,13 +47,8 @@ #ifdef HAVE_DNN_NGRAPH #include "../ie_ngraph.hpp" -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) -#include -#include -#else -#include -#include -#endif +#include +#include #endif #include "../op_vkcom.hpp" @@ -513,23 +508,23 @@ public: CV_Assert(nodes.size() == 2); auto layer = nodes[0].dynamicCast()->node; auto image = nodes[1].dynamicCast()->node; - auto layer_shape = std::make_shared(layer); - auto image_shape = std::make_shared(image); + auto layer_shape = std::make_shared(layer); + auto image_shape = std::make_shared(image); - auto lower_bounds = std::make_shared(ngraph::element::i64, ngraph::Shape{1}, std::vector{2}); - auto upper_bounds = std::make_shared(ngraph::element::i64, ngraph::Shape{1}, std::vector{4}); - auto strides = std::make_shared(ngraph::element::i64, ngraph::Shape{1}, std::vector{1}); + auto lower_bounds = std::make_shared(ov::element::i64, ov::Shape{1}, std::vector{2}); + auto upper_bounds = std::make_shared(ov::element::i64, ov::Shape{1}, std::vector{4}); + auto strides = std::make_shared(ov::element::i64, ov::Shape{1}, std::vector{1}); - auto slice_layer = std::make_shared(layer_shape, + auto slice_layer = std::make_shared(layer_shape, lower_bounds, upper_bounds, strides, std::vector{}, std::vector{}); - auto slice_image = std::make_shared(image_shape, + auto slice_image = std::make_shared(image_shape, lower_bounds, upper_bounds, strides, std::vector{}, std::vector{}); if (_explicitSizes) { CV_Assert_N(!_boxWidths.empty(), !_boxHeights.empty(), !_variance.empty()); CV_Assert(_boxWidths.size() == _boxHeights.size()); - ngraph::op::PriorBoxClusteredAttrs attrs; + ov::op::v0::PriorBoxClustered::Attributes attrs; attrs.widths = _boxWidths; attrs.heights = _boxHeights; attrs.clip = _clip; @@ -539,14 +534,14 @@ public: attrs.step_widths = _stepX; attrs.variances = _variance; - auto priorBox = std::make_shared(slice_layer, slice_image, attrs); - auto axis = std::make_shared(ngraph::element::i64, ngraph::Shape{1}, std::vector{0}); - auto unsqueeze = std::make_shared(priorBox, axis); + auto priorBox = std::make_shared(slice_layer, slice_image, attrs); + auto axis = std::make_shared(ov::element::i64, ov::Shape{1}, std::vector{0}); + auto unsqueeze = std::make_shared(priorBox, axis); return Ptr(new InfEngineNgraphNode(unsqueeze)); } else { - ngraph::op::PriorBoxAttrs attrs; + ov::op::v0::PriorBox::Attributes attrs; attrs.min_size = _minSize; attrs.max_size = _maxSize; // doesn't work with empty aspectRatio @@ -560,9 +555,9 @@ public: attrs.step = _stepX; attrs.scale_all_sizes = !_aspectRatios.empty(); - auto priorBox = std::make_shared(slice_layer, slice_image, attrs); - auto axis = std::make_shared(ngraph::element::i64, ngraph::Shape{1}, std::vector{0}); - auto unsqueeze = std::make_shared(priorBox, axis); + auto priorBox = std::make_shared(slice_layer, slice_image, attrs); + auto axis = std::make_shared(ov::element::i64, ov::Shape{1}, std::vector{0}); + auto unsqueeze = std::make_shared(priorBox, axis); return Ptr(new InfEngineNgraphNode(unsqueeze)); } } diff --git a/modules/dnn/src/layers/proposal_layer.cpp b/modules/dnn/src/layers/proposal_layer.cpp index d9df09c642..66559ab9ff 100644 --- a/modules/dnn/src/layers/proposal_layer.cpp +++ b/modules/dnn/src/layers/proposal_layer.cpp @@ -10,11 +10,7 @@ #ifdef HAVE_DNN_NGRAPH #include "../ie_ngraph.hpp" -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) -#include -#else -#include -#endif +#include #endif namespace cv { namespace dnn { @@ -344,7 +340,7 @@ public: const std::vector >& nodes) CV_OVERRIDE { CV_Assert(nodes.size() == 3); - ngraph::op::ProposalAttrs attr; + ov::op::v0::Proposal::Attributes attr; attr.base_size = baseSize; attr.nms_thresh = nmsThreshold; attr.feat_stride = featStride; @@ -367,12 +363,12 @@ public: auto& image_shape = nodes[2].dynamicCast()->node; CV_Assert_N(image_shape.get_shape().size() == 2, image_shape.get_shape().front() == 1); - auto shape = std::make_shared(ngraph::element::i64, - ngraph::Shape{1}, + auto shape = std::make_shared(ov::element::i64, + ov::Shape{1}, std::vector{(int64_t)image_shape.get_shape().back()}); - auto reshape = std::make_shared(image_shape, shape, true); + auto reshape = std::make_shared(image_shape, shape, true); - auto proposal = std::make_shared(class_probs, class_logits, reshape, attr); + auto proposal = std::make_shared(class_probs, class_logits, reshape, attr); return Ptr(new InfEngineNgraphNode(proposal)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/region_layer.cpp b/modules/dnn/src/layers/region_layer.cpp index 159fd5f7e1..409cdfa38b 100644 --- a/modules/dnn/src/layers/region_layer.cpp +++ b/modules/dnn/src/layers/region_layer.cpp @@ -60,7 +60,6 @@ using namespace cv::dnn::cuda4dnn; #endif - namespace cv { namespace dnn @@ -122,7 +121,7 @@ public: { #ifdef HAVE_DNN_NGRAPH if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) - return INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2) && preferableTarget != DNN_TARGET_MYRIAD && new_coords == 0; + return preferableTarget != DNN_TARGET_MYRIAD && new_coords == 0; #endif #ifdef HAVE_CUDA if (backendId == DNN_BACKEND_CUDA) @@ -473,55 +472,55 @@ public: int64_t cols = b * h * w * anchors; int64_t rows = c / anchors; - auto shape_node = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, std::vector{cols, rows}); - auto tr_axes = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, std::vector{1, 0}); + auto shape_node = std::make_shared(ov::element::i64, ov::Shape{2}, std::vector{cols, rows}); + auto tr_axes = std::make_shared(ov::element::i64, ov::Shape{2}, std::vector{1, 0}); - std::shared_ptr input2d; + std::shared_ptr input2d; { - input2d = std::make_shared(input, shape_node, true); - input2d = std::make_shared(input2d, tr_axes); + input2d = std::make_shared(input, shape_node, true); + input2d = std::make_shared(input2d, tr_axes); } - std::shared_ptr region; + std::shared_ptr region; { - auto new_axes = std::make_shared(ngraph::element::i64, ngraph::Shape{4}, std::vector{0, 3, 1, 2}); - auto tr_input = std::make_shared(input, new_axes); + auto new_axes = std::make_shared(ov::element::i64, ov::Shape{4}, std::vector{0, 3, 1, 2}); + auto tr_input = std::make_shared(input, new_axes); std::vector anchors_vec(blobs[0].ptr(), blobs[0].ptr() + blobs[0].total()); std::vector mask(anchors, 1); - region = std::make_shared(tr_input, coords, classes, anchors, useSoftmax, mask, 1, 3, anchors_vec); + region = std::make_shared(tr_input, coords, classes, anchors, useSoftmax, mask, 1, 3, anchors_vec); auto tr_shape = tr_input->get_shape(); - auto shape_as_inp = std::make_shared(ngraph::element::i64, - ngraph::Shape{tr_shape.size()}, + auto shape_as_inp = std::make_shared(ov::element::i64, + ov::Shape{tr_shape.size()}, std::vector(tr_shape.begin(), tr_shape.end())); - region = std::make_shared(region, shape_as_inp, true); - new_axes = std::make_shared(ngraph::element::i64, ngraph::Shape{4}, std::vector{0, 2, 3, 1}); - region = std::make_shared(region, new_axes); + region = std::make_shared(region, shape_as_inp, true); + new_axes = std::make_shared(ov::element::i64, ov::Shape{4}, std::vector{0, 2, 3, 1}); + region = std::make_shared(region, new_axes); - region = std::make_shared(region, shape_node, true); - region = std::make_shared(region, tr_axes); + region = std::make_shared(region, shape_node, true); + region = std::make_shared(region, tr_axes); } - auto strides = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, std::vector{1, 1}); + auto strides = std::make_shared(ov::element::i64, ov::Shape{2}, std::vector{1, 1}); std::vector boxes_shape{b, anchors, h, w}; - auto shape_3d = std::make_shared(ngraph::element::i64, ngraph::Shape{boxes_shape.size()}, boxes_shape.data()); + auto shape_3d = std::make_shared(ov::element::i64, ov::Shape{boxes_shape.size()}, boxes_shape.data()); - ngraph::Shape box_broad_shape{1, (size_t)anchors, (size_t)h, (size_t)w}; - auto scale_x_y_node = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &scale_x_y); - auto shift_node = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, std::vector{0.5}); + ov::Shape box_broad_shape{1, (size_t)anchors, (size_t)h, (size_t)w}; + auto scale_x_y_node = std::make_shared(ov::element::f32, ov::Shape{1}, &scale_x_y); + auto shift_node = std::make_shared(ov::element::f32, ov::Shape{1}, std::vector{0.5}); - auto axis = ngraph::op::Constant::create(ngraph::element::i64, ngraph::Shape{}, {0}); - auto splits = ngraph::op::Constant::create(ngraph::element::i64, ngraph::Shape{5}, {1, 1, 1, 1, rows - 4}); - auto split = std::make_shared(input2d, axis, splits); - std::shared_ptr box_x; + auto axis = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{}, {0}); + auto splits = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{5}, {1, 1, 1, 1, rows - 4}); + auto split = std::make_shared(input2d, axis, splits); + std::shared_ptr box_x; { - box_x = std::make_shared(split->output(0)); - box_x = std::make_shared(box_x, shift_node, ngraph::op::AutoBroadcastType::NUMPY); - box_x = std::make_shared(box_x, scale_x_y_node, ngraph::op::AutoBroadcastType::NUMPY); - box_x = std::make_shared(box_x, shift_node, ngraph::op::AutoBroadcastType::NUMPY); - box_x = std::make_shared(box_x, shape_3d, true); + box_x = std::make_shared(split->output(0)); + box_x = std::make_shared(box_x, shift_node, ov::op::AutoBroadcastType::NUMPY); + box_x = std::make_shared(box_x, scale_x_y_node, ov::op::AutoBroadcastType::NUMPY); + box_x = std::make_shared(box_x, shift_node, ov::op::AutoBroadcastType::NUMPY); + box_x = std::make_shared(box_x, shape_3d, true); std::vector x_indices(w * h * anchors); auto begin = x_indices.begin(); @@ -534,20 +533,20 @@ public: { std::copy(begin, begin + w * anchors, begin + j * w * anchors); } - auto horiz = std::make_shared(ngraph::element::f32, box_broad_shape, x_indices.data()); - box_x = std::make_shared(box_x, horiz, ngraph::op::AutoBroadcastType::NUMPY); + auto horiz = std::make_shared(ov::element::f32, box_broad_shape, x_indices.data()); + box_x = std::make_shared(box_x, horiz, ov::op::AutoBroadcastType::NUMPY); - auto cols_node = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, std::vector{float(w)}); - box_x = std::make_shared(box_x, cols_node, ngraph::op::AutoBroadcastType::NUMPY); + auto cols_node = std::make_shared(ov::element::f32, ov::Shape{1}, std::vector{float(w)}); + box_x = std::make_shared(box_x, cols_node, ov::op::AutoBroadcastType::NUMPY); } - std::shared_ptr box_y; + std::shared_ptr box_y; { - box_y = std::make_shared(split->output(1)); - box_y = std::make_shared(box_y, shift_node, ngraph::op::AutoBroadcastType::NUMPY); - box_y = std::make_shared(box_y, scale_x_y_node, ngraph::op::AutoBroadcastType::NUMPY); - box_y = std::make_shared(box_y, shift_node, ngraph::op::AutoBroadcastType::NUMPY); - box_y = std::make_shared(box_y, shape_3d, true); + box_y = std::make_shared(split->output(1)); + box_y = std::make_shared(box_y, shift_node, ov::op::AutoBroadcastType::NUMPY); + box_y = std::make_shared(box_y, scale_x_y_node, ov::op::AutoBroadcastType::NUMPY); + box_y = std::make_shared(box_y, shift_node, ov::op::AutoBroadcastType::NUMPY); + box_y = std::make_shared(box_y, shape_3d, true); std::vector y_indices(h * anchors); for (int i = 0; i < h; i++) @@ -555,13 +554,13 @@ public: std::fill(y_indices.begin() + i * anchors, y_indices.begin() + (i + 1) * anchors, i); } - auto vert = std::make_shared(ngraph::element::f32, ngraph::Shape{1, (size_t)anchors, (size_t)h, 1}, y_indices.data()); - box_y = std::make_shared(box_y, vert, ngraph::op::AutoBroadcastType::NUMPY); - auto rows_node = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, std::vector{float(h)}); - box_y = std::make_shared(box_y, rows_node, ngraph::op::AutoBroadcastType::NUMPY); + auto vert = std::make_shared(ov::element::f32, ov::Shape{1, (size_t)anchors, (size_t)h, 1}, y_indices.data()); + box_y = std::make_shared(box_y, vert, ov::op::AutoBroadcastType::NUMPY); + auto rows_node = std::make_shared(ov::element::f32, ov::Shape{1}, std::vector{float(h)}); + box_y = std::make_shared(box_y, rows_node, ov::op::AutoBroadcastType::NUMPY); } - std::shared_ptr box_w, box_h; + std::shared_ptr box_w, box_h; { int hNorm, wNorm; if (nodes.size() > 1) @@ -596,53 +595,53 @@ public: std::copy(bias_h.begin(), bias_h.begin() + h * anchors, bias_h.begin() + i * h * anchors); } - box_w = std::make_shared(split->output(2)); - box_w = std::make_shared(box_w, shape_3d, true); - auto anchor_w_node = std::make_shared(ngraph::element::f32, box_broad_shape, bias_w.data()); - box_w = std::make_shared(box_w, anchor_w_node, ngraph::op::AutoBroadcastType::NUMPY); + box_w = std::make_shared(split->output(2)); + box_w = std::make_shared(box_w, shape_3d, true); + auto anchor_w_node = std::make_shared(ov::element::f32, box_broad_shape, bias_w.data()); + box_w = std::make_shared(box_w, anchor_w_node, ov::op::AutoBroadcastType::NUMPY); - box_h = std::make_shared(split->output(3)); - box_h = std::make_shared(box_h, shape_3d, true); - auto anchor_h_node = std::make_shared(ngraph::element::f32, box_broad_shape, bias_h.data()); - box_h = std::make_shared(box_h, anchor_h_node, ngraph::op::AutoBroadcastType::NUMPY); + box_h = std::make_shared(split->output(3)); + box_h = std::make_shared(box_h, shape_3d, true); + auto anchor_h_node = std::make_shared(ov::element::f32, box_broad_shape, bias_h.data()); + box_h = std::make_shared(box_h, anchor_h_node, ov::op::AutoBroadcastType::NUMPY); } - auto region_splits = ngraph::op::Constant::create(ngraph::element::i64, ngraph::Shape{3}, {4, 1, rows - 5}); - auto region_split = std::make_shared(region, axis, region_splits); + auto region_splits = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{3}, {4, 1, rows - 5}); + auto region_split = std::make_shared(region, axis, region_splits); - std::shared_ptr scale; + std::shared_ptr scale; { float thr = classfix == -1 ? 0.5 : 0; - auto thresh_node = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, std::vector{thr}); - auto mask = std::make_shared(region_split->output(1), thresh_node); - auto zero_node = std::make_shared(ngraph::element::f32, mask->get_shape(), std::vector(cols, 0)); - scale = std::make_shared(mask, zero_node, region_split->output(1)); + auto thresh_node = std::make_shared(ov::element::f32, ov::Shape{1}, std::vector{thr}); + auto mask = std::make_shared(region_split->output(1), thresh_node); + auto zero_node = std::make_shared(ov::element::f32, mask->get_shape(), std::vector(cols, 0)); + scale = std::make_shared(mask, zero_node, region_split->output(1)); } - std::shared_ptr probs; + std::shared_ptr probs; { - probs = std::make_shared(region_split->output(2), scale, ngraph::op::AutoBroadcastType::NUMPY); - auto thresh_node = std::make_shared(ngraph::element::f32, ngraph::Shape{1}, &thresh); - auto mask = std::make_shared(probs, thresh_node); - auto zero_node = std::make_shared(ngraph::element::f32, mask->get_shape(), std::vector((rows - 5) * cols, 0)); - probs = std::make_shared(mask, probs, zero_node); + probs = std::make_shared(region_split->output(2), scale, ov::op::AutoBroadcastType::NUMPY); + auto thresh_node = std::make_shared(ov::element::f32, ov::Shape{1}, &thresh); + auto mask = std::make_shared(probs, thresh_node); + auto zero_node = std::make_shared(ov::element::f32, mask->get_shape(), std::vector((rows - 5) * cols, 0)); + probs = std::make_shared(mask, probs, zero_node); } - auto concat_shape = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, std::vector{1, cols}); - box_x = std::make_shared(box_x, concat_shape, true); - box_y = std::make_shared(box_y, concat_shape, true); - box_w = std::make_shared(box_w, concat_shape, true); - box_h = std::make_shared(box_h, concat_shape, true); + auto concat_shape = std::make_shared(ov::element::i64, ov::Shape{2}, std::vector{1, cols}); + box_x = std::make_shared(box_x, concat_shape, true); + box_y = std::make_shared(box_y, concat_shape, true); + box_w = std::make_shared(box_w, concat_shape, true); + box_h = std::make_shared(box_h, concat_shape, true); - ngraph::NodeVector inp_nodes{box_x, box_y, box_w, box_h, scale, probs}; - std::shared_ptr result = std::make_shared(inp_nodes, 0); - result = std::make_shared(result, tr_axes); + ov::NodeVector inp_nodes{box_x, box_y, box_w, box_h, scale, probs}; + std::shared_ptr result = std::make_shared(inp_nodes, 0); + result = std::make_shared(result, tr_axes); if (b > 1) { std::vector sizes{b, static_cast(result->get_shape()[0]) / b, static_cast(result->get_shape()[1])}; - auto shape_node = std::make_shared(ngraph::element::i64, ngraph::Shape{sizes.size()}, sizes.data()); - result = std::make_shared(result, shape_node, true); + auto shape_node = std::make_shared(ov::element::i64, ov::Shape{sizes.size()}, sizes.data()); + result = std::make_shared(result, shape_node, true); } return Ptr(new InfEngineNgraphNode(result)); diff --git a/modules/dnn/src/layers/reorg_layer.cpp b/modules/dnn/src/layers/reorg_layer.cpp index 7281190cdd..986bb64c82 100644 --- a/modules/dnn/src/layers/reorg_layer.cpp +++ b/modules/dnn/src/layers/reorg_layer.cpp @@ -52,11 +52,7 @@ #include "../op_inf_engine.hpp" #ifdef HAVE_DNN_NGRAPH #include "../ie_ngraph.hpp" -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) -#include -#else -#include -#endif +#include #endif #include "../op_cuda.hpp" @@ -205,7 +201,7 @@ public: const std::vector >& nodes) CV_OVERRIDE { auto& ieInpNode = nodes[0].dynamicCast()->node; - auto reorg = std::make_shared(ieInpNode, ngraph::Strides{(size_t)reorgStride}); + auto reorg = std::make_shared(ieInpNode, ov::Strides{(size_t)reorgStride}); return Ptr(new InfEngineNgraphNode(reorg)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/reshape_layer.cpp b/modules/dnn/src/layers/reshape_layer.cpp index a72236c472..f259629e96 100644 --- a/modules/dnn/src/layers/reshape_layer.cpp +++ b/modules/dnn/src/layers/reshape_layer.cpp @@ -369,9 +369,9 @@ public: auto& ieInpNode = nodes[0].dynamicCast()->node; std::vector out(outShapes[0].begin(), outShapes[0].end()); - auto shape = std::make_shared(ngraph::element::i64, - ngraph::Shape{out.size()}, out.data()); - auto reshape = std::make_shared(ieInpNode, shape, true); + auto shape = std::make_shared(ov::element::i64, + ov::Shape{out.size()}, out.data()); + auto reshape = std::make_shared(ieInpNode, shape, true); return Ptr(new InfEngineNgraphNode(reshape)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/resize_layer.cpp b/modules/dnn/src/layers/resize_layer.cpp index 5b8b9f812f..bf8f1b674c 100644 --- a/modules/dnn/src/layers/resize_layer.cpp +++ b/modules/dnn/src/layers/resize_layer.cpp @@ -13,11 +13,7 @@ #ifdef HAVE_DNN_NGRAPH #include "../ie_ngraph.hpp" -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) -#include -#else -#include -#endif +#include #endif #ifdef HAVE_CUDA @@ -376,81 +372,39 @@ public: { auto& ieInpNode = nodes[0].dynamicCast()->node; -#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2021_2) - ngraph::op::InterpolateAttrs attrs; - attrs.pads_begin.push_back(0); - attrs.pads_end.push_back(0); - attrs.axes = ngraph::AxisSet{2, 3}; - attrs.align_corners = alignCorners; + ov::op::v4::Interpolate::InterpolateAttrs attrs; if (interpolation == "nearest") { - attrs.mode = "nearest"; - attrs.antialias = false; + attrs.mode = ov::op::v4::Interpolate::InterpolateMode::NEAREST; + attrs.coordinate_transformation_mode = ov::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL; } else if (interpolation == "bilinear") { - attrs.mode = "linear"; - } else { - CV_Error(Error::StsNotImplemented, "Unsupported interpolation: " + interpolation); - } - - std::vector shape = {outHeight, outWidth}; - auto out_shape = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, shape.data()); - auto interp = std::make_shared(ieInpNode, out_shape, attrs); -#else - ngraph::op::v4::Interpolate::InterpolateAttrs attrs; - -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) - if (interpolation == "nearest") { - attrs.mode = ngraph::op::v4::Interpolate::InterpolateMode::NEAREST; - attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL; - } else if (interpolation == "bilinear") { - attrs.mode = ngraph::op::v4::Interpolate::InterpolateMode::LINEAR_ONNX; - attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::ASYMMETRIC; + attrs.mode = ov::op::v4::Interpolate::InterpolateMode::LINEAR_ONNX; + attrs.coordinate_transformation_mode = ov::op::v4::Interpolate::CoordinateTransformMode::ASYMMETRIC; } else { CV_Error(Error::StsNotImplemented, format("Unsupported interpolation: %s", interpolation.c_str())); } - attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::SIZES; + attrs.shape_calculation_mode = ov::op::v4::Interpolate::ShapeCalcMode::SIZES; CV_Assert(!halfPixelCenters || !alignCorners); if (halfPixelCenters) { - attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL; + attrs.coordinate_transformation_mode = ov::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL; } else if (alignCorners) { - attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS; + attrs.coordinate_transformation_mode = ov::op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS; } - attrs.nearest_mode = ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR; -#else - if (interpolation == "nearest") { - attrs.mode = ngraph::op::v4::Interpolate::InterpolateMode::nearest; - attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel; - } else if (interpolation == "bilinear") { - attrs.mode = ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx; - attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::asymmetric; - } else { - CV_Error(Error::StsNotImplemented, format("Unsupported interpolation: %s", interpolation.c_str())); - } - attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::sizes; + attrs.nearest_mode = ov::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR; - CV_Assert(!halfPixelCenters || !alignCorners); - if (halfPixelCenters) { - attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel; - } else if (alignCorners) { - attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners; - } - - attrs.nearest_mode = ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor; -#endif // OpenVINO >= 2022.1 std::vector shape = {outHeight, outWidth}; - auto out_shape = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, shape.data()); + auto out_shape = std::make_shared(ov::element::i64, ov::Shape{2}, shape.data()); auto& input_shape = ieInpNode.get_shape(); CV_Assert_N(input_shape[2] != 0, input_shape[3] != 0); std::vector scales = {static_cast(outHeight) / input_shape[2], static_cast(outWidth) / input_shape[3]}; - auto scales_shape = std::make_shared(ngraph::element::f32, ngraph::Shape{2}, scales.data()); + auto scales_shape = std::make_shared(ov::element::f32, ov::Shape{2}, scales.data()); - auto axes = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, std::vector{2, 3}); - auto interp = std::make_shared(ieInpNode, out_shape, scales_shape, axes, attrs); -#endif + auto axes = std::make_shared(ov::element::i64, ov::Shape{2}, std::vector{2, 3}); + auto interp = std::make_shared(ieInpNode, out_shape, scales_shape, axes, attrs); return Ptr(new InfEngineNgraphNode(interp)); } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/layers/scale_layer.cpp b/modules/dnn/src/layers/scale_layer.cpp index 00b1281399..4c2d585ce0 100644 --- a/modules/dnn/src/layers/scale_layer.cpp +++ b/modules/dnn/src/layers/scale_layer.cpp @@ -331,7 +331,7 @@ public: virtual Ptr initNgraph(const std::vector >& inputs, const std::vector >& nodes) CV_OVERRIDE { auto ieInpNode0 = nodes[0].dynamicCast()->node; - ngraph::Output ieInpNode1; + ov::Output ieInpNode1; if (nodes.size() > 1) ieInpNode1 = nodes[1].dynamicCast()->node; @@ -346,31 +346,26 @@ public: int cAxis = normalize_axis(axis, shape.size()); shape[cAxis] = numChannels; - std::shared_ptr node; + std::shared_ptr node; if (hasWeights) { - ngraph::Output weight = blobs.empty() ? ieInpNode1 : - std::make_shared(ngraph::element::f32, ngraph::Shape(shape), blobs[0].data); - -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2021_2) - node = std::make_shared(ieInpNode0, weight, ngraph::op::AutoBroadcastType::NUMPY); -#else - node = std::make_shared(ieInpNode0, weight, ngraph::op::AutoBroadcastType::NUMPY); -#endif + ov::Output weight = blobs.empty() ? ieInpNode1 : + std::make_shared(ov::element::f32, ov::Shape(shape), blobs[0].data); + node = std::make_shared(ieInpNode0, weight, ov::op::AutoBroadcastType::NUMPY); } if (hasBias || !hasWeights) { - ngraph::Output bias; + ov::Output bias; if (hasBias) { bias = blobs.empty() ? ieInpNode1 : - std::make_shared(ngraph::element::f32, - ngraph::Shape(shape), blobs.back().data); + std::make_shared(ov::element::f32, + ov::Shape(shape), blobs.back().data); } else - bias = std::make_shared(ngraph::element::f32, - ngraph::Shape(shape), std::vector(numChannels, 0).data()); - node = std::make_shared(node, bias, ngraph::op::AutoBroadcastType::NUMPY); + bias = std::make_shared(ov::element::f32, + ov::Shape(shape), std::vector(numChannels, 0).data()); + node = std::make_shared(node, bias, ov::op::AutoBroadcastType::NUMPY); } return Ptr(new InfEngineNgraphNode(node)); } diff --git a/modules/dnn/src/layers/slice_layer.cpp b/modules/dnn/src/layers/slice_layer.cpp index 08172f3cdb..de302ec291 100644 --- a/modules/dnn/src/layers/slice_layer.cpp +++ b/modules/dnn/src/layers/slice_layer.cpp @@ -768,14 +768,14 @@ public: dims.push_back(finalSliceRanges[0][i].end); } - auto lower_bounds = std::make_shared(ngraph::element::i64, - ngraph::Shape{offsets.size()}, offsets.data()); - auto upper_bounds = std::make_shared(ngraph::element::i64, - ngraph::Shape{dims.size()}, dims.data()); - auto strides = std::make_shared(ngraph::element::i64, - ngraph::Shape{dims.size()}, std::vector((int64_t)dims.size(), 1)); + auto lower_bounds = std::make_shared(ov::element::i64, + ov::Shape{offsets.size()}, offsets.data()); + auto upper_bounds = std::make_shared(ov::element::i64, + ov::Shape{dims.size()}, dims.data()); + auto strides = std::make_shared(ov::element::i64, + ov::Shape{dims.size()}, std::vector((int64_t)dims.size(), 1)); - auto slice = std::make_shared(ieInpNode, + auto slice = std::make_shared(ieInpNode, lower_bounds, upper_bounds, strides, std::vector{}, std::vector{}); return Ptr(new InfEngineNgraphNode(slice)); diff --git a/modules/dnn/src/layers/softmax_layer.cpp b/modules/dnn/src/layers/softmax_layer.cpp index 18f4d6b61e..239ad1574b 100644 --- a/modules/dnn/src/layers/softmax_layer.cpp +++ b/modules/dnn/src/layers/softmax_layer.cpp @@ -314,9 +314,9 @@ public: auto& ieInpNode = nodes[0].dynamicCast()->node; int axis = normalize_axis(axisRaw, ieInpNode.get_shape().size()); if (logSoftMax) { - return new InfEngineNgraphNode(std::make_shared(ieInpNode, axis)); + return new InfEngineNgraphNode(std::make_shared(ieInpNode, axis)); } else { - return new InfEngineNgraphNode(std::make_shared(ieInpNode, axis)); + return new InfEngineNgraphNode(std::make_shared(ieInpNode, axis)); } } #endif // HAVE_DNN_NGRAPH diff --git a/modules/dnn/src/net_openvino.cpp b/modules/dnn/src/net_openvino.cpp index adcfea60f0..501a596e5d 100644 --- a/modules/dnn/src/net_openvino.cpp +++ b/modules/dnn/src/net_openvino.cpp @@ -9,6 +9,12 @@ #include #include +#include "op_inf_engine.hpp" + +#ifdef HAVE_INF_ENGINE +#include +#endif + #include "net_impl.hpp" #include "backend.hpp" @@ -146,7 +152,7 @@ public: //string dump(bool forceAllocation = false) const override; static - Net createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNet); + Net createNetworkFromModelOptimizer(std::shared_ptr& ieNet); }; // NetImplOpenVINO @@ -320,11 +326,6 @@ void NetImplOpenVINO::initBackend(const std::vector& blobsToKeep_) return; } -#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2022_1) - bool supportsCPUFallback = !isArmComputePlugin() && (preferableTarget == DNN_TARGET_CPU || - openvino::checkTarget(DNN_TARGET_CPU)); -#endif - // Build Inference Engine networks from sets of layers that support this // backend. Split a whole model on several Inference Engine networks if // some of layers are not implemented. @@ -342,49 +343,8 @@ void NetImplOpenVINO::initBackend(const std::vector& blobsToKeep_) bool fused = ld.skip; Ptr layer = ld.layerInstance; -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) if (ld.id == 0) continue; -#else - if (!fused && !layer->supportBackend(preferableBackend)) - { - CV_LOG_DEBUG(NULL, "DNN/IE: NOT supported!"); - bool customizable = ld.id != 0 && supportsCPUFallback; - - // TODO: there is a bug in Myriad plugin with custom layers shape infer. - if (preferableTarget == DNN_TARGET_MYRIAD || preferableTarget == DNN_TARGET_HDDL) - { - for (int i = 0; customizable && i < ld.inputBlobs.size(); ++i) - { - customizable = ld.inputBlobs[i]->size[0] == 1; - } - } - - if (preferableTarget == DNN_TARGET_OPENCL) - customizable &= ld.type != "Eltwise"; - - if (!customizable) - { - CV_LOG_DEBUG(NULL, "DNN/IE: NOT customizable!"); - addNgraphOutputs(ld); - net = Ptr(); - layer->preferableTarget = DNN_TARGET_CPU; - - for (int i = 0; i < ld.inputBlobsId.size(); ++i) - { - LayerData& inpLd = layers[ld.inputBlobsId[i].lid]; - Ptr inpNode = inpLd.backendNodes[preferableBackend]; - if (!inpNode.empty()) - { - Ptr ieNode = inpNode.dynamicCast(); - CV_Assert(!ieNode.empty()); - ieNode->net->addOutput(ieNode); - } - } - continue; - } - } -#endif ld.skip = true; // Initially skip all Inference Engine supported layers. // Create a new network if one of inputs from different Inference Engine graph. @@ -480,25 +440,14 @@ void NetImplOpenVINO::initBackend(const std::vector& blobsToKeep_) continue; // Handle parameters from other subnets. Output port is not used in this case -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) - if ((ngraph::op::is_parameter(ngraph_input_node) || ngraph::op::is_constant(ngraph_input_node)) && -#else - if ((ngraph_input_node->is_parameter() || ngraph_input_node->is_constant()) && -#endif - - ngraph_input_node->get_output_size() == 1) + if ((ov::op::util::is_parameter(ngraph_input_node) || ov::op::util::is_constant(ngraph_input_node)) && + ngraph_input_node->get_output_size() == 1) { inputNodes[i] = Ptr(new InfEngineNgraphNode(ngraph_input_node)); continue; } CV_CheckLT((size_t)oid, ngraph_input_node->get_output_size(), ""); -#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) inputNodes[i] = new InfEngineNgraphNode(ngraph_input_node->output(oid)); -#elif INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_3) - inputNodes[i] = Ptr(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid))); -#else - inputNodes[i] = Ptr(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid, false))); -#endif } if (layer->supportBackend(preferableBackend)) @@ -606,9 +555,7 @@ void NetImplOpenVINO::initBackend(const std::vector& blobsToKeep_) } } } -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) CV_Assert(uniqueNets.size() == 1); -#endif } @@ -708,18 +655,15 @@ void switchToOpenVINOBackend(Net& net) /*static*/ -Net NetImplOpenVINO::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNet) +Net NetImplOpenVINO::createNetworkFromModelOptimizer(std::shared_ptr& ieNet) { CV_TRACE_FUNCTION(); CV_TRACE_REGION("register_inputs"); - auto ngraphFunction = ieNet.getFunction(); - CV_Assert(ngraphFunction); - std::vector inputsNames; std::vector inp_shapes; - for (auto& it : ngraphFunction->get_parameters()) + for (auto& it : ieNet->get_parameters()) { inputsNames.push_back(it->get_friendly_name()); std::vector dims = it->get_shape(); @@ -728,16 +672,9 @@ Net NetImplOpenVINO::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork // nGraph models produce output "Result" layers which have "/sink_port" suffix in their names. // Their inputs are actual model outputs and we change friendly name to it. // By this workaround, we produce similar outputs names comparing to ieNet.getOutputsInfo() - for (int i = 0; i < ngraphFunction->get_output_size(); ++i) { - auto res = ngraphFunction->output(i); -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) + for (int i = 0; i < ieNet->get_output_size(); ++i) { + auto res = ieNet->output(i); const std::string& name = res.get_any_name(); -#else - auto out = res.get_node()->input(0).get_source_output(); - std::string name = out.get_node()->get_friendly_name(); - if (out.get_node()->get_output_size() > 1) - name += "." + std::to_string(out.get_index()); -#endif if (res.get_node()->get_friendly_name() != name) res.get_node()->set_friendly_name(name); } @@ -759,7 +696,7 @@ Net NetImplOpenVINO::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork Ptr backendNode; { - auto fake_node = std::make_shared(ngraph::element::f32, ngraph::Shape {}); + auto fake_node = std::make_shared(ov::element::f32, ov::Shape {}); Ptr backendNodeNGraph(new InfEngineNgraphNode(fake_node)); backendNodeNGraph->net = Ptr(new InfEngineNgraphNet(openvino_impl, ieNet)); backendNode = backendNodeNGraph; @@ -767,9 +704,9 @@ Net NetImplOpenVINO::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork CV_TRACE_REGION_NEXT("register_outputs"); - std::vector> ngraphOperations = ngraphFunction->get_ops(); + std::vector> ngraphOperations = ieNet->get_ops(); - for (auto& it : ngraphFunction->get_results()) + for (auto& it : ieNet->get_results()) { CV_TRACE_REGION("output"); const auto& outputName = it->get_friendly_name(); @@ -834,11 +771,11 @@ Net openvino_readNetwork(const String& modelPath, const String& binPath) { FPDenormalsIgnoreHintScope fp_denormals_ignore_scope; - InferenceEngine::Core& ie = getCore(""); - InferenceEngine::CNNNetwork ieNet; + ov::Core& ie = getCore(""); + std::shared_ptr ieNet; try { - ieNet = ie.ReadNetwork(modelPath, binPath); + ieNet = ie.read_model(modelPath, binPath); } catch (const std::exception& e) { @@ -857,22 +794,15 @@ Net openvino_readNetwork( { FPDenormalsIgnoreHintScope fp_denormals_ignore_scope; - InferenceEngine::Core& ie = getCore(""); + ov::Core& ie = getCore(""); std::string model; model.assign((char*)bufferModelConfigPtr, bufferModelConfigSize); - InferenceEngine::CNNNetwork ieNet; + std::shared_ptr ieNet; try { -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) ov::Tensor weights_blob(ov::element::u8, {bufferWeightsSize}, (void*)bufferWeightsPtr); ieNet = ie.read_model(model, weights_blob); -#else - InferenceEngine::TensorDesc tensorDesc(InferenceEngine::Precision::U8, { bufferWeightsSize }, InferenceEngine::Layout::C); - InferenceEngine::Blob::CPtr weights_blob = InferenceEngine::make_shared_blob(tensorDesc, (uint8_t*)bufferWeightsPtr, bufferWeightsSize); - - ieNet = ie.ReadNetwork(model, weights_blob); -#endif } catch (const std::exception& e) { diff --git a/modules/dnn/src/op_inf_engine.cpp b/modules/dnn/src/op_inf_engine.cpp index f9e3993d20..04f1da7c71 100644 --- a/modules/dnn/src/op_inf_engine.cpp +++ b/modules/dnn/src/op_inf_engine.cpp @@ -10,7 +10,7 @@ #include #ifdef HAVE_INF_ENGINE -#include +#include #elif defined(ENABLE_PLUGINS) // using plugin API #include "backend.hpp" @@ -39,60 +39,6 @@ cv::String setInferenceEngineBackendType(const cv::String& newBackendType) CV__DNN_INLINE_NS_END -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) -namespace InferenceEngine { - -CNNNetwork::CNNNetwork() {} - -CNNNetwork::CNNNetwork(std::shared_ptr model) : model(model) {} - -std::shared_ptr CNNNetwork::getFunction() const { - return model; -} - -void CNNNetwork::serialize(const std::string& xmlPath, const std::string& binPath) { - ov::pass::Serialize(xmlPath, binPath).run_on_model(model); -} - -void CNNNetwork::reshape(const std::map >& shapes) { - std::map partialShapes; - for (const auto& it : shapes) { - ov::PartialShape shape; - shape.insert(shape.begin(), it.second.begin(), it.second.end()); - partialShapes.insert({it.first, shape}); - } - model->reshape(partialShapes); -} - -std::vector Core::GetAvailableDevices() { - return get_available_devices(); -} - -void Core::UnregisterPlugin(const std::string& id) { - unload_plugin(id); -} - -CNNNetwork Core::ReadNetwork(const std::string& xmlPath, const std::string& binPath) { - return read_model(xmlPath, binPath); -} - -ExecutableNetwork Core::LoadNetwork(CNNNetwork net, const std::string& device, - const std::map& config) { - ov::AnyMap props; - for (const auto& it : config) { - props.insert(it); - } - return compile_model(net.getFunction(), device, props); -} - -ExecutableNetwork::ExecutableNetwork() {} - -ExecutableNetwork::ExecutableNetwork(const ov::CompiledModel& copy) : CompiledModel(copy) {} - -ov::InferRequest ExecutableNetwork::CreateInferRequest() { return create_infer_request(); } - -} // namespace InferenceEngine - Mat infEngineBlobToMat(const ov::Tensor& blob) { std::vector dims = blob.get_shape(); @@ -118,67 +64,40 @@ void infEngineBlobsToMats(const ov::TensorVector& blobs, mats[i] = infEngineBlobToMat(blobs[i]); } -#else - -Mat infEngineBlobToMat(const InferenceEngine::Blob::Ptr& blob) -{ - // NOTE: Inference Engine sizes are reversed. - std::vector dims = blob->getTensorDesc().getDims(); - std::vector size(dims.begin(), dims.end()); - auto precision = blob->getTensorDesc().getPrecision(); - - int type = -1; - switch (precision) - { - case InferenceEngine::Precision::FP32: type = CV_32F; break; - case InferenceEngine::Precision::U8: type = CV_8U; break; - default: - CV_Error(Error::StsNotImplemented, "Unsupported blob precision"); - } - return Mat(size, type, (void*)blob->buffer()); -} - -void infEngineBlobsToMats(const std::vector& blobs, - std::vector& mats) -{ - mats.resize(blobs.size()); - for (int i = 0; i < blobs.size(); ++i) - mats[i] = infEngineBlobToMat(blobs[i]); -} -#endif // OpenVINO >= 2022.1 static bool init_IE_plugins() { // load and hold IE plugins - static InferenceEngine::Core* init_core = new InferenceEngine::Core(); // 'delete' is never called - (void)init_core->GetAvailableDevices(); + static ov::Core* init_core = new ov::Core(); // 'delete' is never called + (void)init_core->get_available_devices(); return true; } -static InferenceEngine::Core& retrieveIECore(const std::string& id, std::map >& cores) +static ov::Core& retrieveIECore(const std::string& id, std::map >& cores) { AutoLock lock(getInitializationMutex()); - std::map >::iterator i = cores.find(id); + std::map >::iterator i = cores.find(id); if (i == cores.end()) { - std::shared_ptr core = std::make_shared(); + std::shared_ptr core = std::make_shared(); cores[id] = core; return *core.get(); } return *(i->second).get(); } -static InferenceEngine::Core& create_IE_Core_instance(const std::string& id) +static ov::Core& create_IE_Core_instance(const std::string& id) { - static std::map > cores; + static std::map > cores; return retrieveIECore(id, cores); } -static InferenceEngine::Core& create_IE_Core_pointer(const std::string& id) +static ov::Core& create_IE_Core_pointer(const std::string& id) { // load and hold IE plugins - static std::map >* cores = - new std::map >(); + static std::map >* cores = + new std::map >(); return retrieveIECore(id, *cores); } -InferenceEngine::Core& getCore(const std::string& id) + +ov::Core& getCore(const std::string& id) { // to make happy memory leak tools use: // - OPENCV_DNN_INFERENCE_ENGINE_HOLD_PLUGINS=0 @@ -195,7 +114,7 @@ InferenceEngine::Core& getCore(const std::string& id) #endif ); - InferenceEngine::Core& core = param_DNN_INFERENCE_ENGINE_CORE_LIFETIME_WORKAROUND + ov::Core& core = param_DNN_INFERENCE_ENGINE_CORE_LIFETIME_WORKAROUND ? create_IE_Core_pointer(id) : create_IE_Core_instance(id); return core; @@ -204,17 +123,13 @@ InferenceEngine::Core& getCore(const std::string& id) static bool detectArmPlugin_() { - InferenceEngine::Core& ie = getCore("CPU"); - const std::vector devices = ie.GetAvailableDevices(); + ov::Core& ie = getCore("CPU"); + const std::vector devices = ie.get_available_devices(); for (std::vector::const_iterator i = devices.begin(); i != devices.end(); ++i) { if (i->find("CPU") != std::string::npos) { -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) const std::string name = ie.get_property(*i, ov::device::full_name); -#else - const std::string name = ie.GetMetric(*i, METRIC_KEY(FULL_DEVICE_NAME)).as(); -#endif CV_LOG_INFO(NULL, "CPU plugin: " << name); return name.find("arm_compute::NEON") != std::string::npos; } @@ -228,17 +143,13 @@ static bool detectMyriadX_(const std::string& device) AutoLock lock(getInitializationMutex()); // Lightweight detection - InferenceEngine::Core& ie = getCore(device); - const std::vector devices = ie.GetAvailableDevices(); + ov::Core& ie = getCore(device); + const std::vector devices = ie.get_available_devices(); for (std::vector::const_iterator i = devices.begin(); i != devices.end(); ++i) { if (i->find(device) != std::string::npos) { -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) const std::string name = ie.get_property(*i, ov::device::full_name); -#else - const std::string name = ie.GetMetric(*i, METRIC_KEY(FULL_DEVICE_NAME)).as(); -#endif CV_LOG_INFO(NULL, "Myriad device: " << name); return name.find("MyriadX") != std::string::npos || name.find("Myriad X") != std::string::npos || name.find("HDDL") != std::string::npos; } @@ -259,11 +170,11 @@ void resetMyriadDevice() AutoLock lock(getInitializationMutex()); - InferenceEngine::Core& ie = getCore("MYRIAD"); + ov::Core& ie = getCore("MYRIAD"); try { - ie.UnregisterPlugin("MYRIAD"); - ie.UnregisterPlugin("HETERO"); + ie.unload_plugin("MYRIAD"); + ie.unload_plugin("HETERO"); } catch (...) {} #endif // HAVE_INF_ENGINE @@ -276,11 +187,11 @@ void releaseHDDLPlugin() AutoLock lock(getInitializationMutex()); - InferenceEngine::Core& ie = getCore("HDDL"); + ov::Core& ie = getCore("HDDL"); try { - ie.UnregisterPlugin("HDDL"); - ie.UnregisterPlugin("HETERO"); + ie.unload_plugin("HDDL"); + ie.unload_plugin("HETERO"); } catch (...) {} #endif // HAVE_INF_ENGINE @@ -351,7 +262,7 @@ namespace openvino { bool checkTarget(Target target) { // Lightweight detection - const std::vector devices = getCore("").GetAvailableDevices(); + const std::vector devices = getCore("").get_available_devices(); for (std::vector::const_iterator i = devices.begin(); i != devices.end(); ++i) { if (std::string::npos != i->find("MYRIAD") && target == DNN_TARGET_MYRIAD) diff --git a/modules/dnn/src/op_inf_engine.hpp b/modules/dnn/src/op_inf_engine.hpp index c5a2e58683..236b21b1a3 100644 --- a/modules/dnn/src/op_inf_engine.hpp +++ b/modules/dnn/src/op_inf_engine.hpp @@ -19,19 +19,13 @@ #ifdef HAVE_INF_ENGINE -#define INF_ENGINE_RELEASE_2020_2 2020020000 -#define INF_ENGINE_RELEASE_2020_3 2020030000 -#define INF_ENGINE_RELEASE_2020_4 2020040000 -#define INF_ENGINE_RELEASE_2021_1 2021010000 -#define INF_ENGINE_RELEASE_2021_2 2021020000 -#define INF_ENGINE_RELEASE_2021_3 2021030000 -#define INF_ENGINE_RELEASE_2021_4 2021040000 #define INF_ENGINE_RELEASE_2022_1 2022010000 #define INF_ENGINE_RELEASE_2023_0 2023000000 +#define INF_ENGINE_RELEASE_2024_0 2024000000 #ifndef INF_ENGINE_RELEASE -#warning("IE version have not been provided via command-line. Using 2021.4 by default") -#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2021_4 +#warning("IE version have not been provided via command-line. Using 2022.1 by default") +#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2022_1 #endif #define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000)) @@ -45,13 +39,9 @@ #pragma GCC diagnostic ignored "-Wsuggest-override" #endif -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) #include #include #include -#else -#include -#endif #if defined(__GNUC__) && __GNUC__ >= 5 //#pragma GCC diagnostic pop @@ -76,18 +66,10 @@ CV__DNN_INLINE_NS_END Backend& getInferenceEngineBackendTypeParam(); -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) Mat infEngineBlobToMat(const ov::Tensor& blob); void infEngineBlobsToMats(const ov::TensorVector& blobs, std::vector& mats); -#else -Mat infEngineBlobToMat(const InferenceEngine::Blob::Ptr& blob); - -void infEngineBlobsToMats(const std::vector& blobs, - std::vector& mats); -#endif // OpenVINO >= 2022.1 - CV__DNN_INLINE_NS_BEGIN @@ -99,54 +81,7 @@ bool isArmComputePlugin(); CV__DNN_INLINE_NS_END -// A series of wrappers for classes from OpenVINO API 2.0. -// Need just for less conditional compilation inserts. -#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1) -namespace InferenceEngine { - -class CNNNetwork { -public: - CNNNetwork(); - - CNNNetwork(std::shared_ptr model); - - std::shared_ptr getFunction() const; - - void serialize(const std::string& xmlPath, const std::string& binPath); - - void reshape(const std::map >& shapes); - -private: - std::shared_ptr model = nullptr; -}; - -typedef ov::InferRequest InferRequest; - -class ExecutableNetwork : public ov::CompiledModel { -public: - ExecutableNetwork(); - - ExecutableNetwork(const ov::CompiledModel& copy); - - ov::InferRequest CreateInferRequest(); -}; - -class Core : public ov::Core { -public: - std::vector GetAvailableDevices(); - - void UnregisterPlugin(const std::string& id); - - CNNNetwork ReadNetwork(const std::string& xmlPath, const std::string& binPath); - - ExecutableNetwork LoadNetwork(CNNNetwork net, const std::string& device, - const std::map& config); -}; - -} -#endif // OpenVINO >= 2022.1 - -InferenceEngine::Core& getCore(const std::string& id); +ov::Core& getCore(const std::string& id); template static inline std::vector getShape(const Mat& mat) diff --git a/modules/dnn/src/op_webnn.hpp b/modules/dnn/src/op_webnn.hpp index 5b77b10827..6f96289b80 100644 --- a/modules/dnn/src/op_webnn.hpp +++ b/modules/dnn/src/op_webnn.hpp @@ -111,7 +111,7 @@ public: void addBlobs(const std::vector >& ptrs); void createNet(Target targetId); - // void setNodePtr(std::shared_ptr* ptr); + // void setNodePtr(std::shared_ptr* ptr); void reset(); diff --git a/modules/dnn/test/test_ie_models.cpp b/modules/dnn/test/test_ie_models.cpp index c6667c7ad2..eff389035d 100644 --- a/modules/dnn/test/test_ie_models.cpp +++ b/modules/dnn/test/test_ie_models.cpp @@ -9,7 +9,6 @@ #ifdef HAVE_INF_ENGINE #include - // // Synchronize headers include statements with src/op_inf_engine.hpp // @@ -26,14 +25,11 @@ #pragma GCC visibility push(default) #endif -#include -#include -#include - #if defined(__GNUC__) #pragma GCC visibility pop #endif +#include namespace opencv_test { namespace { @@ -62,7 +58,6 @@ static void initDLDTDataPath() using namespace cv; using namespace cv::dnn; -using namespace InferenceEngine; struct OpenVINOModelTestCaseInfo { @@ -161,27 +156,6 @@ inline static std::string getOpenVINOModel(const std::string &modelName, bool is return std::string(); } -static inline void genData(const InferenceEngine::TensorDesc& desc, Mat& m, Blob::Ptr& dataPtr) -{ - const std::vector& dims = desc.getDims(); - if (desc.getPrecision() == InferenceEngine::Precision::FP32) - { - m.create(std::vector(dims.begin(), dims.end()), CV_32F); - randu(m, -1, 1); - dataPtr = make_shared_blob(desc, (float*)m.data); - } - else if (desc.getPrecision() == InferenceEngine::Precision::I32) - { - m.create(std::vector(dims.begin(), dims.end()), CV_32S); - randu(m, -100, 100); - dataPtr = make_shared_blob(desc, (int*)m.data); - } - else - { - FAIL() << "Unsupported precision: " << desc.getPrecision(); - } -} - void runIE(Target target, const std::string& xmlPath, const std::string& binPath, std::map& inputsMap, std::map& outputsMap) { @@ -189,25 +163,12 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath std::string device_name; -#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000) - Core ie; -#else - InferenceEnginePluginPtr enginePtr; - InferencePlugin plugin; -#endif + ov::Core core; -#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019030000) - CNNNetwork net = ie.ReadNetwork(xmlPath, binPath); -#else - CNNNetReader reader; - reader.ReadNetwork(xmlPath); - reader.ReadWeights(binPath); + auto model = core.read_model(xmlPath, binPath); - CNNNetwork net = reader.getNetwork(); -#endif - - ExecutableNetwork netExec; - InferRequest infRequest; + ov::CompiledModel compiledModel; + ov::InferRequest infRequest; try { @@ -230,10 +191,6 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath CV_Error(Error::StsNotImplemented, "Unknown target"); }; -#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2019010000) - auto dispatcher = InferenceEngine::PluginDispatcher({""}); - enginePtr = dispatcher.getPluginByDevice(device_name); -#endif if (target == DNN_TARGET_CPU || target == DNN_TARGET_FPGA) { std::string suffixes[] = {"_avx2", "_sse4", ""}; @@ -255,68 +212,90 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath #endif // _WIN32 try { - IExtensionPtr extension = make_so_pointer(libName); -#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000) - ie.AddExtension(extension, device_name); -#else - enginePtr->AddExtension(extension, 0); -#endif + core.add_extension(libName); break; } catch(...) {} } // Some of networks can work without a library of extra layers. } -#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000) - netExec = ie.LoadNetwork(net, device_name); -#else - plugin = InferencePlugin(enginePtr); - netExec = plugin.LoadNetwork(net, {}); -#endif - infRequest = netExec.CreateInferRequest(); + compiledModel = core.compile_model(model, device_name); + infRequest = compiledModel.create_infer_request(); } catch (const std::exception& ex) { CV_Error(Error::StsAssert, format("Failed to initialize Inference Engine backend: %s", ex.what())); } - // Fill input blobs. + // Fill input tensors. inputsMap.clear(); - BlobMap inputBlobs; - for (auto& it : net.getInputsInfo()) + for (auto&& it : model->inputs()) { - const InferenceEngine::TensorDesc& desc = it.second->getTensorDesc(); - genData(desc, inputsMap[it.first], inputBlobs[it.first]); + auto type = it.get_element_type(); + auto shape = it.get_shape(); + auto& m = inputsMap[it.get_any_name()]; + + auto tensor = ov::Tensor(type, shape); + if (type == ov::element::f32) + { + m.create(std::vector(shape.begin(), shape.end()), CV_32F); + randu(m, -1, 1); + } + else if (type == ov::element::i32) + { + m.create(std::vector(shape.begin(), shape.end()), CV_32S); + randu(m, -100, 100); + } + else + { + FAIL() << "Unsupported precision: " << type; + } + std::memcpy(tensor.data(), m.data, tensor.get_byte_size()); + if (cvtest::debugLevel > 0) { - const std::vector& dims = desc.getDims(); - std::cout << "Input: '" << it.first << "' precision=" << desc.getPrecision() << " dims=" << dims.size() << " ["; - for (auto d : dims) + std::cout << "Input: '" << it.get_any_name() << "' precision=" << type << " dims=" << shape << " ["; + for (auto d : shape) std::cout << " " << d; - std::cout << "] ocv_mat=" << inputsMap[it.first].size << " of " << typeToString(inputsMap[it.first].type()) << std::endl; + std::cout << "] ocv_mat=" << inputsMap[it.get_any_name()].size << " of " << typeToString(inputsMap[it.get_any_name()].type()) << std::endl; } + infRequest.set_tensor(it, tensor); } - infRequest.SetInput(inputBlobs); + infRequest.infer(); - // Fill output blobs. + + // Fill output tensors. outputsMap.clear(); - BlobMap outputBlobs; - for (auto& it : net.getOutputsInfo()) + for (const auto& it : model->outputs()) { - const InferenceEngine::TensorDesc& desc = it.second->getTensorDesc(); - genData(desc, outputsMap[it.first], outputBlobs[it.first]); + auto type = it.get_element_type(); + auto shape = it.get_shape(); + auto& m = outputsMap[it.get_any_name()]; + + auto tensor = infRequest.get_tensor(it); + if (type == ov::element::f32) + { + m.create(std::vector(shape.begin(), shape.end()), CV_32F); + } + else if (type == ov::element::i32) + { + m.create(std::vector(shape.begin(), shape.end()), CV_32S); + } + else + { + FAIL() << "Unsupported precision: " << type; + } + std::memcpy(m.data, tensor.data(), tensor.get_byte_size()); + if (cvtest::debugLevel > 0) { - const std::vector& dims = desc.getDims(); - std::cout << "Output: '" << it.first << "' precision=" << desc.getPrecision() << " dims=" << dims.size() << " ["; - for (auto d : dims) + std::cout << "Output: '" << it.get_any_name() << "' precision=" << type << " dims=" << shape << " ["; + for (auto d : shape) std::cout << " " << d; - std::cout << "] ocv_mat=" << outputsMap[it.first].size << " of " << typeToString(outputsMap[it.first].type()) << std::endl; + std::cout << "] ocv_mat=" << outputsMap[it.get_any_name()].size << " of " << typeToString(outputsMap[it.get_any_name()].type()) << std::endl; } - } - infRequest.SetOutput(outputBlobs); - infRequest.Infer(); + } } void runCV(Backend backendId, Target targetId, const std::string& xmlPath, const std::string& binPath, From 2fd011b6ff5b96a1b6bf2c449dfa0d26fce59103 Mon Sep 17 00:00:00 2001 From: Giorgos Karagounis Date: Mon, 18 Mar 2024 16:37:26 +0100 Subject: [PATCH 25/56] Fix for jpegturbo Windows build --- 3rdparty/libjpeg-turbo/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/libjpeg-turbo/CMakeLists.txt b/3rdparty/libjpeg-turbo/CMakeLists.txt index ac0aaf63e1..6e508c8860 100644 --- a/3rdparty/libjpeg-turbo/CMakeLists.txt +++ b/3rdparty/libjpeg-turbo/CMakeLists.txt @@ -16,7 +16,7 @@ endif() message(STATUS "libjpeg-turbo: VERSION = ${VERSION}, BUILD = ${BUILD}") math(EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8") -string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} CMAKE_SYSTEM_PROCESSOR_LC) +string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" CMAKE_SYSTEM_PROCESSOR_LC) if(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "x86_64" OR CMAKE_SYSTEM_PROCESSOR_LC MATCHES "amd64" OR From 8d5dd2e5c2fb1356bd845a090b3979beb826ad4d Mon Sep 17 00:00:00 2001 From: Carlos Azevedo Date: Thu, 21 Mar 2024 18:54:27 +0000 Subject: [PATCH 26/56] Added support for V4L2_PIX_FMT_SGRBG8 pixel format to V4L2 backend --- modules/videoio/src/cap_v4l.cpp | 94 +++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/modules/videoio/src/cap_v4l.cpp b/modules/videoio/src/cap_v4l.cpp index 5b282f1966..48cc0062da 100644 --- a/modules/videoio/src/cap_v4l.cpp +++ b/modules/videoio/src/cap_v4l.cpp @@ -613,6 +613,7 @@ bool CvCaptureCAM_V4L::autosetup_capture_mode_v4l2() V4L2_PIX_FMT_NV21, V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SGBRG8, + V4L2_PIX_FMT_SGRBG8, V4L2_PIX_FMT_XBGR32, V4L2_PIX_FMT_ABGR32, V4L2_PIX_FMT_SN9C10X, @@ -679,6 +680,7 @@ bool CvCaptureCAM_V4L::convertableToRgb() const case V4L2_PIX_FMT_SBGGR8: case V4L2_PIX_FMT_SN9C10X: case V4L2_PIX_FMT_SGBRG8: + case V4L2_PIX_FMT_SGRBG8: case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_Y16: case V4L2_PIX_FMT_Y16_BE: @@ -1487,6 +1489,94 @@ static void sgbrg2rgb24(long int WIDTH, long int HEIGHT, unsigned char *src, uns } } +// SGRBG to RGB24 +static void sgrbg2rgb24(long int WIDTH, long int HEIGHT, unsigned char *src, unsigned char *dst) +{ + long int i; + unsigned char *rawpt, *scanpt; + long int size; + + rawpt = src; + scanpt = dst; + size = WIDTH*HEIGHT; + + for ( i = 0; i < size; i++ ) + { + if ( (i/WIDTH) % 2 == 0 ) //even row + { + if ( (i % 2) == 0 ) //even pixel + { + if ( (i > WIDTH) && ((i % WIDTH) > 0) ) + { + *scanpt++ = (*(rawpt-WIDTH) + *(rawpt+WIDTH))/2; /* R */ + *scanpt++ = *(rawpt); /* G */ + *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* B */ + } else + { + /* first line or left column */ + + *scanpt++ = *(rawpt+WIDTH); /* R */ + *scanpt++ = *(rawpt); /* G */ + *scanpt++ = *(rawpt+1); /* B */ + } + } else //odd pixel + { + if ( (i > WIDTH) && ((i % WIDTH) < (WIDTH-1)) ) + { + *scanpt++ = (*(rawpt-WIDTH-1) + *(rawpt-WIDTH+1) + + *(rawpt+WIDTH-1) + *(rawpt+WIDTH+1)) / 4; /* R */ + *scanpt++ = (*(rawpt-1) + *(rawpt+1) + + *(rawpt-WIDTH) + *(rawpt+WIDTH)) / 4; /* G */ + *scanpt++ = *(rawpt); /* B */ + } else + { + /* first line or right column */ + + *scanpt++ = *(rawpt+WIDTH-1); /* R */ + *scanpt++ = (*(rawpt-1)+*(rawpt+WIDTH))/2; /* G */ + *scanpt++ = *(rawpt); /* B */ + } + } + } else + { //odd row + if ( (i % 2) == 0 ) //even pixel + { + if ( (i < (WIDTH*(HEIGHT-1))) && ((i % WIDTH) > 0) ) + { + *scanpt++ = *(rawpt); /* R */ + *scanpt++ = (*(rawpt-1) + *(rawpt+1)+ + *(rawpt-WIDTH) + *(rawpt+WIDTH)) / 4; /* G */ + *scanpt++ = (*(rawpt-WIDTH-1) + *(rawpt-WIDTH+1) + + *(rawpt+WIDTH-1) + *(rawpt+WIDTH+1)) / 4; /* B */ + } else + { + /* bottom line or left column */ + + *scanpt++ = *(rawpt); /* R */ + *scanpt++ = (*(rawpt+1)+*(rawpt-WIDTH))/2; /* G */ + *scanpt++ = *(rawpt-WIDTH+1); /* B */ + } + } else + { //odd pixel + if ( i < (WIDTH*(HEIGHT-1)) && ((i % WIDTH) < (WIDTH-1)) ) + { + *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* R */ + *scanpt++ = *(rawpt); /* G */ + *scanpt++ = (*(rawpt-WIDTH)+*(rawpt+WIDTH))/2; /* B */ + } else + { + /* bottom line or right column */ + + *scanpt++ = (*(rawpt-1)); /* R */ + *scanpt++ = *(rawpt); /* G */ + *scanpt++ = (*(rawpt-WIDTH)); /* B */ + } + } + } + rawpt++; + } +} + #define CLAMP(x) ((x)<0?0:((x)>255)?255:(x)) typedef struct { @@ -1706,6 +1796,10 @@ void CvCaptureCAM_V4L::convertToRgb(const Buffer ¤tBuffer) sgbrg2rgb24(imageSize.width, imageSize.height, start, (unsigned char*)frame.imageData); return; + case V4L2_PIX_FMT_SGRBG8: + sgrbg2rgb24(imageSize.width, imageSize.height, + start, (unsigned char*)frame.imageData); + return; default: break; } From 3afe8ddaf85d1389d2e63d027de36199c4eedf09 Mon Sep 17 00:00:00 2001 From: Yuantao Feng Date: Fri, 22 Mar 2024 04:44:19 +0800 Subject: [PATCH 27/56] core: Rename `cv::float16_t` to `cv::hfloat` (#25217) * rename cv::float16_t to cv::fp16_t * add typedef fp16_t float16_t * remove zero(), bits() from fp16_t class * fp16_t -> hfloat * remove cv::float16_t::fromBits; add hfloatFromBits * undo changes in conv_winograd_f63.simd.hpp and conv_block.simd.hpp * undo some changes in dnn --- modules/core/include/opencv2/core/cvdef.h | 66 ++++++++----------- modules/core/include/opencv2/core/hal/hal.hpp | 4 +- .../core/include/opencv2/core/hal/intrin.hpp | 2 +- .../include/opencv2/core/hal/intrin_avx.hpp | 6 +- .../opencv2/core/hal/intrin_avx512.hpp | 4 +- .../include/opencv2/core/hal/intrin_cpp.hpp | 10 +-- .../include/opencv2/core/hal/intrin_lasx.hpp | 6 +- .../include/opencv2/core/hal/intrin_lsx.hpp | 6 +- .../include/opencv2/core/hal/intrin_msa.hpp | 10 +-- .../include/opencv2/core/hal/intrin_neon.hpp | 10 +-- .../include/opencv2/core/hal/intrin_rvv.hpp | 10 +-- .../opencv2/core/hal/intrin_rvv071.hpp | 8 +-- .../opencv2/core/hal/intrin_rvv_scalable.hpp | 10 +-- .../include/opencv2/core/hal/intrin_sse.hpp | 4 +- .../include/opencv2/core/hal/intrin_vsx.hpp | 4 +- .../include/opencv2/core/hal/intrin_wasm.hpp | 12 ++-- .../core/include/opencv2/core/saturate.hpp | 22 +++---- modules/core/include/opencv2/core/traits.hpp | 6 +- modules/core/src/convert.dispatch.cpp | 4 +- modules/core/src/convert.hpp | 10 +-- modules/core/src/convert.simd.hpp | 38 +++++------ modules/core/src/convert_scale.simd.hpp | 30 ++++----- modules/core/src/copy.cpp | 2 +- modules/core/src/norm.cpp | 6 +- modules/core/src/ocl.cpp | 2 +- modules/core/src/out.cpp | 2 +- modules/core/src/persistence.cpp | 16 ++--- modules/core/src/rand.cpp | 2 +- modules/core/test/test_intrin_utils.hpp | 6 +- modules/gapi/src/backends/ie/giebackend.cpp | 2 +- .../gapi/test/common/gapi_tests_common.hpp | 2 +- 31 files changed, 156 insertions(+), 166 deletions(-) diff --git a/modules/core/include/opencv2/core/cvdef.h b/modules/core/include/opencv2/core/cvdef.h index 03f65ad328..65f2f3d7db 100644 --- a/modules/core/include/opencv2/core/cvdef.h +++ b/modules/core/include/opencv2/core/cvdef.h @@ -809,40 +809,20 @@ using std::uint64_t; namespace cv { -class float16_t +class hfloat { public: #if CV_FP16_TYPE - float16_t() : h(0) {} - explicit float16_t(float x) { h = (__fp16)x; } + hfloat() : h(0) {} + explicit hfloat(float x) { h = (__fp16)x; } operator float() const { return (float)h; } - static float16_t fromBits(ushort w) - { - Cv16suf u; - u.u = w; - float16_t result; - result.h = u.h; - return result; - } - static float16_t zero() - { - float16_t result; - result.h = (__fp16)0; - return result; - } - ushort bits() const - { - Cv16suf u; - u.h = h; - return u.u; - } protected: __fp16 h; #else - float16_t() : w(0) {} - explicit float16_t(float x) + hfloat() : w(0) {} + explicit hfloat(float x) { #if CV_FP16 && CV_AVX2 __m128 v = _mm_load_ss(&x); @@ -893,25 +873,35 @@ protected: #endif } - static float16_t fromBits(ushort b) - { - float16_t result; - result.w = b; - return result; - } - static float16_t zero() - { - float16_t result; - result.w = (ushort)0; - return result; - } - ushort bits() const { return w; } protected: ushort w; #endif }; +inline hfloat hfloatFromBits(ushort w) { +#if CV_FP16_TYPE + Cv16suf u; + u.u = w; + hfloat res(float(u.h)); + return res; +#else + Cv32suf out; + + unsigned t = ((w & 0x7fff) << 13) + 0x38000000; + unsigned sign = (w & 0x8000) << 16; + unsigned e = w & 0x7c00; + + out.u = t + (1 << 23); + out.u = (e >= 0x7c00 ? t + 0x38000000 : + e == 0 ? (static_cast(out.f -= 6.103515625e-05f), out.u) : t) | sign; + hfloat res(out.f); + return res; +#endif +} + +typedef hfloat float16_t; + } #endif diff --git a/modules/core/include/opencv2/core/hal/hal.hpp b/modules/core/include/opencv2/core/hal/hal.hpp index 0d68078d98..24a6077101 100644 --- a/modules/core/include/opencv2/core/hal/hal.hpp +++ b/modules/core/include/opencv2/core/hal/hal.hpp @@ -195,8 +195,8 @@ CV_EXPORTS void addWeighted32s( const int* src1, size_t step1, const int* src2, CV_EXPORTS void addWeighted32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scalars ); CV_EXPORTS void addWeighted64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scalars ); -CV_EXPORTS void cvt16f32f( const float16_t* src, float* dst, int len ); -CV_EXPORTS void cvt32f16f( const float* src, float16_t* dst, int len ); +CV_EXPORTS void cvt16f32f( const hfloat* src, float* dst, int len ); +CV_EXPORTS void cvt32f16f( const float* src, hfloat* dst, int len ); CV_EXPORTS void addRNGBias32f( float* arr, const float* scaleBiasPairs, int len ); CV_EXPORTS void addRNGBias64f( double* arr, const double* scaleBiasPairs, int len ); diff --git a/modules/core/include/opencv2/core/hal/intrin.hpp b/modules/core/include/opencv2/core/hal/intrin.hpp index 7897fb503f..27beccd9ab 100644 --- a/modules/core/include/opencv2/core/hal/intrin.hpp +++ b/modules/core/include/opencv2/core/hal/intrin.hpp @@ -708,7 +708,7 @@ namespace CV__SIMD_NAMESPACE { inline v_int32 vx_load_expand(const short* ptr) { return VXPREFIX(_load_expand)(ptr); } inline v_int64 vx_load_expand(const int* ptr) { return VXPREFIX(_load_expand)(ptr); } inline v_uint64 vx_load_expand(const unsigned* ptr) { return VXPREFIX(_load_expand)(ptr); } - inline v_float32 vx_load_expand(const float16_t * ptr) { return VXPREFIX(_load_expand)(ptr); } + inline v_float32 vx_load_expand(const hfloat * ptr) { return VXPREFIX(_load_expand)(ptr); } //! @} //! @name Wide load with quad expansion diff --git a/modules/core/include/opencv2/core/hal/intrin_avx.hpp b/modules/core/include/opencv2/core/hal/intrin_avx.hpp index 979b6163d8..eed609f80e 100644 --- a/modules/core/include/opencv2/core/hal/intrin_avx.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_avx.hpp @@ -3137,7 +3137,7 @@ OPENCV_HAL_IMPL_AVX_LOADSTORE_INTERLEAVE(v_float64x4, double, f64, v_uint64x4, u // FP16 // -inline v_float32x8 v256_load_expand(const float16_t* ptr) +inline v_float32x8 v256_load_expand(const hfloat* ptr) { #if CV_FP16 return v_float32x8(_mm256_cvtph_ps(_mm_loadu_si128((const __m128i*)ptr))); @@ -3149,7 +3149,7 @@ inline v_float32x8 v256_load_expand(const float16_t* ptr) #endif } -inline void v_pack_store(float16_t* ptr, const v_float32x8& a) +inline void v_pack_store(hfloat* ptr, const v_float32x8& a) { #if CV_FP16 __m128i ah = _mm256_cvtps_ph(a.val, 0); @@ -3158,7 +3158,7 @@ inline void v_pack_store(float16_t* ptr, const v_float32x8& a) float CV_DECL_ALIGNED(32) buf[8]; v_store_aligned(buf, a); for (int i = 0; i < 8; i++) - ptr[i] = float16_t(buf[i]); + ptr[i] = hfloat(buf[i]); #endif } diff --git a/modules/core/include/opencv2/core/hal/intrin_avx512.hpp b/modules/core/include/opencv2/core/hal/intrin_avx512.hpp index d20d6dd1ff..e59b8d92eb 100644 --- a/modules/core/include/opencv2/core/hal/intrin_avx512.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_avx512.hpp @@ -506,12 +506,12 @@ inline v_float64x8 v_reinterpret_as_f64(const v_float32x16& a) { return v_float64x8(_mm512_castps_pd(a.val)); } // FP16 -inline v_float32x16 v512_load_expand(const float16_t* ptr) +inline v_float32x16 v512_load_expand(const hfloat* ptr) { return v_float32x16(_mm512_cvtph_ps(_mm256_loadu_si256((const __m256i*)ptr))); } -inline void v_pack_store(float16_t* ptr, const v_float32x16& a) +inline void v_pack_store(hfloat* ptr, const v_float32x16& a) { __m256i ah = _mm512_cvtps_ph(a.val, 0); _mm256_storeu_si256((__m256i*)ptr, ah); diff --git a/modules/core/include/opencv2/core/hal/intrin_cpp.hpp b/modules/core/include/opencv2/core/hal/intrin_cpp.hpp index e9a09d12ae..8619fec60c 100644 --- a/modules/core/include/opencv2/core/hal/intrin_cpp.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_cpp.hpp @@ -3251,7 +3251,7 @@ template inline v_reg v_dotprod_expand_fast(const v_reg -v_load_expand(const float16_t* ptr) +v_load_expand(const hfloat* ptr) { v_reg v; for( int i = 0; i < v.nlanes; i++ ) @@ -3262,7 +3262,7 @@ v_load_expand(const float16_t* ptr) } #if CV_SIMD256 inline v_reg -v256_load_expand(const float16_t* ptr) +v256_load_expand(const hfloat* ptr) { v_reg v; for (int i = 0; i < v.nlanes; i++) @@ -3274,7 +3274,7 @@ v256_load_expand(const float16_t* ptr) #endif #if CV_SIMD512 inline v_reg -v512_load_expand(const float16_t* ptr) +v512_load_expand(const hfloat* ptr) { v_reg v; for (int i = 0; i < v.nlanes; i++) @@ -3286,11 +3286,11 @@ v512_load_expand(const float16_t* ptr) #endif template inline void -v_pack_store(float16_t* ptr, const v_reg& v) +v_pack_store(hfloat* ptr, const v_reg& v) { for( int i = 0; i < v.nlanes; i++ ) { - ptr[i] = float16_t(v.s[i]); + ptr[i] = hfloat(v.s[i]); } } diff --git a/modules/core/include/opencv2/core/hal/intrin_lasx.hpp b/modules/core/include/opencv2/core/hal/intrin_lasx.hpp index 6546d6db7d..4a98dbf96e 100644 --- a/modules/core/include/opencv2/core/hal/intrin_lasx.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_lasx.hpp @@ -2983,7 +2983,7 @@ OPENCV_HAL_IMPL_LASX_LOADSTORE_INTERLEAVE(v_float64x4, double, f64, v_uint64x4, // FP16 // -inline v_float32x8 v256_load_expand(const float16_t* ptr) +inline v_float32x8 v256_load_expand(const hfloat* ptr) { #if CV_FP16 //1-load128, 2-permi, 3-cvt @@ -2996,7 +2996,7 @@ inline v_float32x8 v256_load_expand(const float16_t* ptr) #endif } -inline void v_pack_store(float16_t* ptr, const v_float32x8& a) +inline void v_pack_store(hfloat* ptr, const v_float32x8& a) { #if CV_FP16 __m256i ah = __lasx_xvfcvt_h_s(a.val, a.val); @@ -3005,7 +3005,7 @@ inline void v_pack_store(float16_t* ptr, const v_float32x8& a) float CV_DECL_ALIGNED(32) buf[8]; v_store_aligned(buf, a); for (int i = 0; i < 8; i++) - ptr[i] = float16_t(buf[i]); + ptr[i] = hfloat(buf[i]); #endif } diff --git a/modules/core/include/opencv2/core/hal/intrin_lsx.hpp b/modules/core/include/opencv2/core/hal/intrin_lsx.hpp index ef83a2e466..6e3290426f 100644 --- a/modules/core/include/opencv2/core/hal/intrin_lsx.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_lsx.hpp @@ -2498,7 +2498,7 @@ OPENCV_HAL_IMPL_LSX_LOADSTORE_INTERLEAVE(v_float64x2, double, f64, v_uint64x2, u // FP16 // -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { #if CV_FP16 return v_float32x4(__lsx_vfcvtl_s_h((__m128)__lsx_vld(ptr, 0))); @@ -2510,7 +2510,7 @@ inline v_float32x4 v_load_expand(const float16_t* ptr) #endif } -inline void v_pack_store(float16_t* ptr, const v_float32x4& a) +inline void v_pack_store(hfloat* ptr, const v_float32x4& a) { #if CV_FP16 __m128i res = (__m218i)__lsx_vfcvt_h_s(a.val, a.val); @@ -2519,7 +2519,7 @@ inline void v_pack_store(float16_t* ptr, const v_float32x4& a) float CV_DECL_ALIGNED(32) buf[4]; v_store_aligned(buf, a); for (int i = 0; i < 4; i++) - ptr[i] = float16_t(buf[i]); + ptr[i] = hfloat(buf[i]); #endif } diff --git a/modules/core/include/opencv2/core/hal/intrin_msa.hpp b/modules/core/include/opencv2/core/hal/intrin_msa.hpp index c035fdad60..23d6ebd3d1 100644 --- a/modules/core/include/opencv2/core/hal/intrin_msa.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_msa.hpp @@ -1838,7 +1838,7 @@ inline v_float32x4 v_broadcast_element(const v_float32x4& a) ////// FP16 support /////// #if CV_FP16 -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { #ifndef msa_ld1_f16 v4f16 v = (v4f16)msa_ld1_s16((const short*)ptr); @@ -1848,7 +1848,7 @@ inline v_float32x4 v_load_expand(const float16_t* ptr) return v_float32x4(msa_cvt_f32_f16(v)); } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { v4f16 hv = msa_cvt_f16_f32(v.val); @@ -1859,7 +1859,7 @@ inline void v_pack_store(float16_t* ptr, const v_float32x4& v) #endif } #else -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { float buf[4]; for( int i = 0; i < 4; i++ ) @@ -1867,12 +1867,12 @@ inline v_float32x4 v_load_expand(const float16_t* ptr) return v_load(buf); } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { float buf[4]; v_store(buf, v); for( int i = 0; i < 4; i++ ) - ptr[i] = (float16_t)buf[i]; + ptr[i] = (hfloat)buf[i]; } #endif diff --git a/modules/core/include/opencv2/core/hal/intrin_neon.hpp b/modules/core/include/opencv2/core/hal/intrin_neon.hpp index 85b62a58f0..6e843d68ea 100644 --- a/modules/core/include/opencv2/core/hal/intrin_neon.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_neon.hpp @@ -2605,7 +2605,7 @@ inline void v_lut_deinterleave(const double* tab, const v_int32x4& idxvec, v_flo ////// FP16 support /////// #if CV_FP16 -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { float16x4_t v = #ifndef vld1_f16 // APPLE compiler defines vld1_f16 as macro @@ -2616,7 +2616,7 @@ inline v_float32x4 v_load_expand(const float16_t* ptr) return v_float32x4(vcvt_f32_f16(v)); } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { float16x4_t hv = vcvt_f16_f32(v.val); @@ -2627,7 +2627,7 @@ inline void v_pack_store(float16_t* ptr, const v_float32x4& v) #endif } #else -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { const int N = 4; float buf[N]; @@ -2635,12 +2635,12 @@ inline v_float32x4 v_load_expand(const float16_t* ptr) return v_load(buf); } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { const int N = 4; float buf[N]; v_store(buf, v); - for( int i = 0; i < N; i++ ) ptr[i] = float16_t(buf[i]); + for( int i = 0; i < N; i++ ) ptr[i] = hfloat(buf[i]); } #endif diff --git a/modules/core/include/opencv2/core/hal/intrin_rvv.hpp b/modules/core/include/opencv2/core/hal/intrin_rvv.hpp index d70660249c..d446a05db5 100644 --- a/modules/core/include/opencv2/core/hal/intrin_rvv.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_rvv.hpp @@ -2873,17 +2873,17 @@ inline v_float32x4 v_pack_triplets(const v_float32x4& vec) { return vec; } ////// FP16 support /////// #if CV_FP16 -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { return v_float32x4(vfwcvt_f_f_v_f32m1(vle16_v_f16mf2(ptr, 4), 4)); } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { vse16_v_f16mf2(ptr, vfncvt_f_f_w_f16mf2(v, 4), 4); } #else -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { const int N = 4; float buf[N]; @@ -2891,12 +2891,12 @@ inline v_float32x4 v_load_expand(const float16_t* ptr) return v_load(buf); } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { const int N = 4; float buf[N]; v_store(buf, v); - for( int i = 0; i < N; i++ ) ptr[i] = float16_t(buf[i]); + for( int i = 0; i < N; i++ ) ptr[i] = hfloat(buf[i]); } #endif diff --git a/modules/core/include/opencv2/core/hal/intrin_rvv071.hpp b/modules/core/include/opencv2/core/hal/intrin_rvv071.hpp index 9f6657760e..5681ae211d 100644 --- a/modules/core/include/opencv2/core/hal/intrin_rvv071.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_rvv071.hpp @@ -2858,14 +2858,14 @@ inline v_float64x2 v_dotprod_expand_fast(const v_int32x4& a, const v_int32x4& b, #endif ////// FP16 support /////// #if __riscv_v == 7000 -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { vfloat16m1_t v = vle16_v_f16m1((__fp16*)ptr, 4); vfloat32m2_t v32 = vfwcvt_f_f_v_f32m2(v, 4); return v_float32x4(vget_v_f32m2_f32m1(v32, 0)); } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { vfloat32m2_t v32 = vundefined_f32m2(); v32 = vset_v_f32m1_f32m2(v32, 0, v.val); @@ -2873,14 +2873,14 @@ inline void v_pack_store(float16_t* ptr, const v_float32x4& v) vse16_v_f16m1((__fp16*)ptr, hv, 4); } #else -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { vfloat16mf2_t v = vle16_v_f16mf2((__fp16*)ptr, 4); vfloat32m1_t v32 = vfwcvt_f_f_v_f32m1(v, 4); return v_float32x4(v32); } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { //vfloat32m2_t v32 = vundefined_f32m2(); //v32 = vset_f32m2(v32, 0, v.val); diff --git a/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp b/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp index 9724ea27b8..87531ede1e 100644 --- a/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_rvv_scalable.hpp @@ -1810,28 +1810,28 @@ OPENCV_HAL_IMPL_RVV_PACK_TRIPLETS(v_float64, vlmul_trunc_u8mf8) ////// FP16 support /////// #if defined(__riscv_zfh) && __riscv_zfh -inline v_float32 v_load_expand(const float16_t* ptr) +inline v_float32 v_load_expand(const hfloat* ptr) { return vfwcvt_f(vle16_v_f16mf2((_Float16*)ptr, VTraits::vlanes()) ,VTraits::vlanes());; } -inline void v_pack_store(float16_t* ptr, const v_float32& v) +inline void v_pack_store(hfloat* ptr, const v_float32& v) { vse16_v_f16mf2((_Float16*)ptr, vfncvt_f_f_w_f16mf2(v, VTraits::vlanes()), VTraits::vlanes()); } #else -inline v_float32 v_load_expand(const float16_t* ptr) +inline v_float32 v_load_expand(const hfloat* ptr) { float buf[32]; for( int i = 0; i < VTraits::vlanes(); i++ ) buf[i] = (float)ptr[i]; return v_load(buf); } -inline void v_pack_store(float16_t* ptr, const v_float32& v) +inline void v_pack_store(hfloat* ptr, const v_float32& v) { float buf[32]; v_store(buf, v); - for( int i = 0; i < VTraits::vlanes(); i++ ) ptr[i] = float16_t(buf[i]); + for( int i = 0; i < VTraits::vlanes(); i++ ) ptr[i] = hfloat(buf[i]); } #endif ////////////// Rounding ////////////// diff --git a/modules/core/include/opencv2/core/hal/intrin_sse.hpp b/modules/core/include/opencv2/core/hal/intrin_sse.hpp index 9d17f71666..68b5a67bbc 100644 --- a/modules/core/include/opencv2/core/hal/intrin_sse.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_sse.hpp @@ -3407,7 +3407,7 @@ inline v_float32x4 v_broadcast_element(const v_float32x4& v) ////////////// FP16 support /////////////////////////// -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { #if CV_FP16 return v_float32x4(_mm_cvtph_ps(_mm_loadu_si128((const __m128i*)ptr))); @@ -3427,7 +3427,7 @@ inline v_float32x4 v_load_expand(const float16_t* ptr) #endif } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { #if CV_FP16 __m128i fp16_value = _mm_cvtps_ph(v.val, 0); diff --git a/modules/core/include/opencv2/core/hal/intrin_vsx.hpp b/modules/core/include/opencv2/core/hal/intrin_vsx.hpp index b198643cc6..e66563bede 100644 --- a/modules/core/include/opencv2/core/hal/intrin_vsx.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_vsx.hpp @@ -1361,7 +1361,7 @@ inline v_float32x4 v_pack_triplets(const v_float32x4& vec) /////// FP16 support //////// -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { vec_ushort8 vf16 = vec_ld_l8((const ushort*)ptr); #if CV_VSX3 && defined(vec_extract_fp_from_shorth) @@ -1388,7 +1388,7 @@ inline v_float32x4 v_load_expand(const float16_t* ptr) #endif } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { // fixme: Is there any builtin op or intrinsic that cover "xvcvsphp"? #if CV_VSX3 && !defined(CV_COMPILER_VSX_BROKEN_ASM) diff --git a/modules/core/include/opencv2/core/hal/intrin_wasm.hpp b/modules/core/include/opencv2/core/hal/intrin_wasm.hpp index db3cb2a9ae..5d470d9419 100644 --- a/modules/core/include/opencv2/core/hal/intrin_wasm.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_wasm.hpp @@ -2754,7 +2754,7 @@ inline v_float32x4 v_broadcast_element(const v_float32x4& a) ////////////// FP16 support /////////////////////////// -inline v_float32x4 v_load_expand(const float16_t* ptr) +inline v_float32x4 v_load_expand(const hfloat* ptr) { float a[4]; for (int i = 0; i < 4; i++) @@ -2762,14 +2762,14 @@ inline v_float32x4 v_load_expand(const float16_t* ptr) return v_float32x4(wasm_v128_load(a)); } -inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +inline void v_pack_store(hfloat* ptr, const v_float32x4& v) { double v_[4]; wasm_v128_store(v_, v.val); - ptr[0] = float16_t(v_[0]); - ptr[1] = float16_t(v_[1]); - ptr[2] = float16_t(v_[2]); - ptr[3] = float16_t(v_[3]); + ptr[0] = hfloat(v_[0]); + ptr[1] = hfloat(v_[1]); + ptr[2] = hfloat(v_[2]); + ptr[3] = hfloat(v_[3]); } inline void v_cleanup() {} diff --git a/modules/core/include/opencv2/core/saturate.hpp b/modules/core/include/opencv2/core/saturate.hpp index e0cc965ab6..18ffd1c7af 100644 --- a/modules/core/include/opencv2/core/saturate.hpp +++ b/modules/core/include/opencv2/core/saturate.hpp @@ -158,20 +158,20 @@ template<> inline uint64 saturate_cast(int64 v) { return (uint64)st template<> inline int64 saturate_cast(uint64 v) { return (int64)std::min(v, (uint64)LLONG_MAX); } /** @overload */ -template static inline _Tp saturate_cast(float16_t v) { return saturate_cast<_Tp>((float)v); } +template static inline _Tp saturate_cast(hfloat v) { return saturate_cast<_Tp>((float)v); } // in theory, we could use a LUT for 8u/8s->16f conversion, // but with hardware support for FP32->FP16 conversion the current approach is preferable -template<> inline float16_t saturate_cast(uchar v) { return float16_t((float)v); } -template<> inline float16_t saturate_cast(schar v) { return float16_t((float)v); } -template<> inline float16_t saturate_cast(ushort v) { return float16_t((float)v); } -template<> inline float16_t saturate_cast(short v) { return float16_t((float)v); } -template<> inline float16_t saturate_cast(unsigned v){ return float16_t((float)v); } -template<> inline float16_t saturate_cast(int v) { return float16_t((float)v); } -template<> inline float16_t saturate_cast(uint64 v) { return float16_t((float)v); } -template<> inline float16_t saturate_cast(int64 v) { return float16_t((float)v); } -template<> inline float16_t saturate_cast(float v) { return float16_t(v); } -template<> inline float16_t saturate_cast(double v) { return float16_t((float)v); } +template<> inline hfloat saturate_cast(uchar v) { return hfloat((float)v); } +template<> inline hfloat saturate_cast(schar v) { return hfloat((float)v); } +template<> inline hfloat saturate_cast(ushort v) { return hfloat((float)v); } +template<> inline hfloat saturate_cast(short v) { return hfloat((float)v); } +template<> inline hfloat saturate_cast(unsigned v){ return hfloat((float)v); } +template<> inline hfloat saturate_cast(int v) { return hfloat((float)v); } +template<> inline hfloat saturate_cast(uint64 v) { return hfloat((float)v); } +template<> inline hfloat saturate_cast(int64 v) { return hfloat((float)v); } +template<> inline hfloat saturate_cast(float v) { return hfloat(v); } +template<> inline hfloat saturate_cast(double v) { return hfloat((float)v); } //! @} diff --git a/modules/core/include/opencv2/core/traits.hpp b/modules/core/include/opencv2/core/traits.hpp index 52ab083ca4..522519389b 100644 --- a/modules/core/include/opencv2/core/traits.hpp +++ b/modules/core/include/opencv2/core/traits.hpp @@ -261,10 +261,10 @@ public: }; }; -template<> class DataType +template<> class DataType { public: - typedef float16_t value_type; + typedef hfloat value_type; typedef float work_type; typedef value_type channel_type; typedef value_type vec_type; @@ -347,7 +347,7 @@ template<> class TypeDepth template<> class TypeDepth { enum { depth = CV_16F }; - typedef float16_t value_type; + typedef hfloat value_type; }; #endif diff --git a/modules/core/src/convert.dispatch.cpp b/modules/core/src/convert.dispatch.cpp index 58ca43187a..2b4035285f 100644 --- a/modules/core/src/convert.dispatch.cpp +++ b/modules/core/src/convert.dispatch.cpp @@ -11,13 +11,13 @@ namespace cv { namespace hal { -void cvt16f32f(const float16_t* src, float* dst, int len) +void cvt16f32f(const hfloat* src, float* dst, int len) { CV_INSTRUMENT_REGION(); CV_CPU_DISPATCH(cvt16f32f, (src, dst, len), CV_CPU_DISPATCH_MODES_ALL); } -void cvt32f16f(const float* src, float16_t* dst, int len) +void cvt32f16f(const float* src, hfloat* dst, int len) { CV_INSTRUMENT_REGION(); CV_CPU_DISPATCH(cvt32f16f, (src, dst, len), diff --git a/modules/core/src/convert.hpp b/modules/core/src/convert.hpp index 65a998bd8f..177f236ee7 100644 --- a/modules/core/src/convert.hpp +++ b/modules/core/src/convert.hpp @@ -31,7 +31,7 @@ static inline void vx_load_as(const int* ptr, v_float32& a) static inline void vx_load_as(const float* ptr, v_float32& a) { a = vx_load(ptr); } -static inline void vx_load_as(const float16_t* ptr, v_float32& a) +static inline void vx_load_as(const hfloat* ptr, v_float32& a) { a = vx_load_expand(ptr); } static inline void v_store_as(ushort* ptr, const v_float32& a) @@ -46,7 +46,7 @@ static inline void v_store_as(int* ptr, const v_float32& a) static inline void v_store_as(float* ptr, const v_float32& a) { v_store(ptr, a); } -static inline void v_store_as(float16_t* ptr, const v_float32& a) +static inline void v_store_as(hfloat* ptr, const v_float32& a) { v_pack_store(ptr, a); } static inline void vx_load_pair_as(const uchar* ptr, v_uint16& a, v_uint16& b) @@ -150,7 +150,7 @@ static inline void vx_load_pair_as(const int* ptr, v_float32& a, v_float32& b) static inline void vx_load_pair_as(const float* ptr, v_float32& a, v_float32& b) { a = vx_load(ptr); b = vx_load(ptr + VTraits::vlanes()); } -static inline void vx_load_pair_as(const float16_t* ptr, v_float32& a, v_float32& b) +static inline void vx_load_pair_as(const hfloat* ptr, v_float32& a, v_float32& b) { a = vx_load_expand(ptr); b = vx_load_expand(ptr + VTraits::vlanes()); @@ -294,7 +294,7 @@ static inline void vx_load_pair_as(const double* ptr, v_float64& a, v_float64& b b = vx_load(ptr + VTraits::vlanes()); } -static inline void vx_load_pair_as(const float16_t* ptr, v_float64& a, v_float64& b) +static inline void vx_load_pair_as(const hfloat* ptr, v_float64& a, v_float64& b) { v_float32 v0 = vx_load_expand(ptr); a = v_cvt_f64(v0); @@ -348,7 +348,7 @@ static inline void v_store_pair_as(float* ptr, const v_float64& a, const v_float v_store(ptr, v); } -static inline void v_store_pair_as(float16_t* ptr, const v_float64& a, const v_float64& b) +static inline void v_store_pair_as(hfloat* ptr, const v_float64& a, const v_float64& b) { v_float32 v = v_cvt_f32(a, b); v_pack_store(ptr, v); diff --git a/modules/core/src/convert.simd.hpp b/modules/core/src/convert.simd.hpp index c126450a13..524c43a16e 100644 --- a/modules/core/src/convert.simd.hpp +++ b/modules/core/src/convert.simd.hpp @@ -14,8 +14,8 @@ namespace cv { namespace hal { CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN -void cvt16f32f(const float16_t* src, float* dst, int len); -void cvt32f16f(const float* src, float16_t* dst, int len); +void cvt16f32f(const hfloat* src, float* dst, int len); +void cvt32f16f(const float* src, hfloat* dst, int len); void addRNGBias32f(float* arr, const float* scaleBiasPairs, int len); void addRNGBias64f(double* arr, const double* scaleBiasPairs, int len); @@ -35,7 +35,7 @@ CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN BinaryFunc getConvertFunc(int sdepth, int ddepth); -void cvt16f32f( const float16_t* src, float* dst, int len ) +void cvt16f32f( const hfloat* src, float* dst, int len ) { CV_INSTRUMENT_REGION(); int j = 0; @@ -56,7 +56,7 @@ void cvt16f32f( const float16_t* src, float* dst, int len ) dst[j] = (float)src[j]; } -void cvt32f16f( const float* src, float16_t* dst, int len ) +void cvt32f16f( const float* src, hfloat* dst, int len ) { CV_INSTRUMENT_REGION(); int j = 0; @@ -74,7 +74,7 @@ void cvt32f16f( const float* src, float16_t* dst, int len ) } #endif for( ; j < len; j++ ) - dst[j] = float16_t(src[j]); + dst[j] = hfloat(src[j]); } void addRNGBias32f( float* arr, const float* scaleBiasPairs, int len ) @@ -188,7 +188,7 @@ DEF_CVT_FUNC(8u16s, cvt_, uchar, short, v_int16) DEF_CVT_FUNC(8u32s, cvt_, uchar, int, v_int32) DEF_CVT_FUNC(8u32f, cvt_, uchar, float, v_float32) DEF_CVT_FUNC(8u64f, cvt_, uchar, double, v_int32) -DEF_CVT_FUNC(8u16f, cvt1_, uchar, float16_t, v_float32) +DEF_CVT_FUNC(8u16f, cvt1_, uchar, hfloat, v_float32) ////////////////////// 8s -> ... //////////////////////// @@ -198,7 +198,7 @@ DEF_CVT_FUNC(8s16s, cvt_, schar, short, v_int16) DEF_CVT_FUNC(8s32s, cvt_, schar, int, v_int32) DEF_CVT_FUNC(8s32f, cvt_, schar, float, v_float32) DEF_CVT_FUNC(8s64f, cvt_, schar, double, v_int32) -DEF_CVT_FUNC(8s16f, cvt1_, schar, float16_t, v_float32) +DEF_CVT_FUNC(8s16f, cvt1_, schar, hfloat, v_float32) ////////////////////// 16u -> ... //////////////////////// @@ -208,7 +208,7 @@ DEF_CVT_FUNC(16u16s, cvt_, ushort, short, v_int32) DEF_CVT_FUNC(16u32s, cvt_, ushort, int, v_int32) DEF_CVT_FUNC(16u32f, cvt_, ushort, float, v_float32) DEF_CVT_FUNC(16u64f, cvt_, ushort, double, v_int32) -DEF_CVT_FUNC(16u16f, cvt1_,ushort, float16_t, v_float32) +DEF_CVT_FUNC(16u16f, cvt1_,ushort, hfloat, v_float32) ////////////////////// 16s -> ... //////////////////////// @@ -218,7 +218,7 @@ DEF_CVT_FUNC(16s16u, cvt_, short, ushort, v_int32) DEF_CVT_FUNC(16s32s, cvt_, short, int, v_int32) DEF_CVT_FUNC(16s32f, cvt_, short, float, v_float32) DEF_CVT_FUNC(16s64f, cvt_, short, double, v_int32) -DEF_CVT_FUNC(16s16f, cvt1_,short, float16_t, v_float32) +DEF_CVT_FUNC(16s16f, cvt1_,short, hfloat, v_float32) ////////////////////// 32s -> ... //////////////////////// @@ -228,7 +228,7 @@ DEF_CVT_FUNC(32s16u, cvt_, int, ushort, v_int32) DEF_CVT_FUNC(32s16s, cvt_, int, short, v_int32) DEF_CVT_FUNC(32s32f, cvt_, int, float, v_float32) DEF_CVT_FUNC(32s64f, cvt_, int, double, v_int32) -DEF_CVT_FUNC(32s16f, cvt1_,int, float16_t, v_float32) +DEF_CVT_FUNC(32s16f, cvt1_,int, hfloat, v_float32) ////////////////////// 32f -> ... //////////////////////// @@ -238,7 +238,7 @@ DEF_CVT_FUNC(32f16u, cvt_, float, ushort, v_float32) DEF_CVT_FUNC(32f16s, cvt_, float, short, v_float32) DEF_CVT_FUNC(32f32s, cvt_, float, int, v_float32) DEF_CVT_FUNC(32f64f, cvt_, float, double, v_float32) -DEF_CVT_FUNC(32f16f, cvt1_,float, float16_t, v_float32) +DEF_CVT_FUNC(32f16f, cvt1_,float, hfloat, v_float32) ////////////////////// 64f -> ... //////////////////////// @@ -248,17 +248,17 @@ DEF_CVT_FUNC(64f16u, cvt_, double, ushort, v_int32) DEF_CVT_FUNC(64f16s, cvt_, double, short, v_int32) DEF_CVT_FUNC(64f32s, cvt_, double, int, v_int32) DEF_CVT_FUNC(64f32f, cvt_, double, float, v_float32) -DEF_CVT_FUNC(64f16f, cvt1_,double, float16_t, v_float32) +DEF_CVT_FUNC(64f16f, cvt1_,double, hfloat, v_float32) ////////////////////// 16f -> ... //////////////////////// -DEF_CVT_FUNC(16f8u, cvt_, float16_t, uchar, v_float32) -DEF_CVT_FUNC(16f8s, cvt_, float16_t, schar, v_float32) -DEF_CVT_FUNC(16f16u, cvt1_, float16_t, ushort, v_float32) -DEF_CVT_FUNC(16f16s, cvt1_, float16_t, short, v_float32) -DEF_CVT_FUNC(16f32s, cvt1_, float16_t, int, v_float32) -DEF_CVT_FUNC(16f32f, cvt1_, float16_t, float, v_float32) -DEF_CVT_FUNC(16f64f, cvt1_, float16_t, double, v_float32) +DEF_CVT_FUNC(16f8u, cvt_, hfloat, uchar, v_float32) +DEF_CVT_FUNC(16f8s, cvt_, hfloat, schar, v_float32) +DEF_CVT_FUNC(16f16u, cvt1_, hfloat, ushort, v_float32) +DEF_CVT_FUNC(16f16s, cvt1_, hfloat, short, v_float32) +DEF_CVT_FUNC(16f32s, cvt1_, hfloat, int, v_float32) +DEF_CVT_FUNC(16f32f, cvt1_, hfloat, float, v_float32) +DEF_CVT_FUNC(16f64f, cvt1_, hfloat, double, v_float32) ///////////// "conversion" w/o conversion /////////////// diff --git a/modules/core/src/convert_scale.simd.hpp b/modules/core/src/convert_scale.simd.hpp index c79a33f1b1..ef6aa343e2 100644 --- a/modules/core/src/convert_scale.simd.hpp +++ b/modules/core/src/convert_scale.simd.hpp @@ -232,7 +232,7 @@ DEF_CVT_SCALE_FUNC(16s8u, cvt_32f, short, uchar, float) DEF_CVT_SCALE_FUNC(32s8u, cvt_32f, int, uchar, float) DEF_CVT_SCALE_FUNC(32f8u, cvt_32f, float, uchar, float) DEF_CVT_SCALE_FUNC(64f8u, cvt_32f, double, uchar, float) -DEF_CVT_SCALE_FUNC(16f8u, cvt_32f, float16_t, uchar, float) +DEF_CVT_SCALE_FUNC(16f8u, cvt_32f, hfloat, uchar, float) DEF_CVT_SCALE_FUNC(8u8s, cvt_32f, uchar, schar, float) DEF_CVT_SCALE_FUNC(8s, cvt_32f, schar, schar, float) @@ -241,7 +241,7 @@ DEF_CVT_SCALE_FUNC(16s8s, cvt_32f, short, schar, float) DEF_CVT_SCALE_FUNC(32s8s, cvt_32f, int, schar, float) DEF_CVT_SCALE_FUNC(32f8s, cvt_32f, float, schar, float) DEF_CVT_SCALE_FUNC(64f8s, cvt_32f, double, schar, float) -DEF_CVT_SCALE_FUNC(16f8s, cvt_32f, float16_t, schar, float) +DEF_CVT_SCALE_FUNC(16f8s, cvt_32f, hfloat, schar, float) DEF_CVT_SCALE_FUNC(8u16u, cvt_32f, uchar, ushort, float) DEF_CVT_SCALE_FUNC(8s16u, cvt_32f, schar, ushort, float) @@ -250,7 +250,7 @@ DEF_CVT_SCALE_FUNC(16s16u, cvt_32f, short, ushort, float) DEF_CVT_SCALE_FUNC(32s16u, cvt_32f, int, ushort, float) DEF_CVT_SCALE_FUNC(32f16u, cvt_32f, float, ushort, float) DEF_CVT_SCALE_FUNC(64f16u, cvt_32f, double, ushort, float) -DEF_CVT_SCALE_FUNC(16f16u, cvt1_32f, float16_t, ushort, float) +DEF_CVT_SCALE_FUNC(16f16u, cvt1_32f, hfloat, ushort, float) DEF_CVT_SCALE_FUNC(8u16s, cvt_32f, uchar, short, float) DEF_CVT_SCALE_FUNC(8s16s, cvt_32f, schar, short, float) @@ -259,7 +259,7 @@ DEF_CVT_SCALE_FUNC(16s, cvt_32f, short, short, float) DEF_CVT_SCALE_FUNC(32s16s, cvt_32f, int, short, float) DEF_CVT_SCALE_FUNC(32f16s, cvt_32f, float, short, float) DEF_CVT_SCALE_FUNC(64f16s, cvt_32f, double, short, float) -DEF_CVT_SCALE_FUNC(16f16s, cvt1_32f, float16_t, short, float) +DEF_CVT_SCALE_FUNC(16f16s, cvt1_32f, hfloat, short, float) DEF_CVT_SCALE_FUNC(8u32s, cvt_32f, uchar, int, float) DEF_CVT_SCALE_FUNC(8s32s, cvt_32f, schar, int, float) @@ -268,7 +268,7 @@ DEF_CVT_SCALE_FUNC(16s32s, cvt_32f, short, int, float) DEF_CVT_SCALE_FUNC(32s, cvt_64f, int, int, double) DEF_CVT_SCALE_FUNC(32f32s, cvt_32f, float, int, float) DEF_CVT_SCALE_FUNC(64f32s, cvt_64f, double, int, double) -DEF_CVT_SCALE_FUNC(16f32s, cvt1_32f, float16_t, int, float) +DEF_CVT_SCALE_FUNC(16f32s, cvt1_32f, hfloat, int, float) DEF_CVT_SCALE_FUNC(8u32f, cvt_32f, uchar, float, float) DEF_CVT_SCALE_FUNC(8s32f, cvt_32f, schar, float, float) @@ -277,7 +277,7 @@ DEF_CVT_SCALE_FUNC(16s32f, cvt_32f, short, float, float) DEF_CVT_SCALE_FUNC(32s32f, cvt_32f, int, float, float) DEF_CVT_SCALE_FUNC(32f, cvt_32f, float, float, float) DEF_CVT_SCALE_FUNC(64f32f, cvt_64f, double, float, double) -DEF_CVT_SCALE_FUNC(16f32f, cvt1_32f, float16_t, float, float) +DEF_CVT_SCALE_FUNC(16f32f, cvt1_32f, hfloat, float, float) DEF_CVT_SCALE_FUNC(8u64f, cvt_64f, uchar, double, double) DEF_CVT_SCALE_FUNC(8s64f, cvt_64f, schar, double, double) @@ -286,16 +286,16 @@ DEF_CVT_SCALE_FUNC(16s64f, cvt_64f, short, double, double) DEF_CVT_SCALE_FUNC(32s64f, cvt_64f, int, double, double) DEF_CVT_SCALE_FUNC(32f64f, cvt_64f, float, double, double) DEF_CVT_SCALE_FUNC(64f, cvt_64f, double, double, double) -DEF_CVT_SCALE_FUNC(16f64f, cvt_64f, float16_t, double, double) +DEF_CVT_SCALE_FUNC(16f64f, cvt_64f, hfloat, double, double) -DEF_CVT_SCALE_FUNC(8u16f, cvt1_32f, uchar, float16_t, float) -DEF_CVT_SCALE_FUNC(8s16f, cvt1_32f, schar, float16_t, float) -DEF_CVT_SCALE_FUNC(16u16f, cvt1_32f, ushort, float16_t, float) -DEF_CVT_SCALE_FUNC(16s16f, cvt1_32f, short, float16_t, float) -DEF_CVT_SCALE_FUNC(32s16f, cvt1_32f, int, float16_t, float) -DEF_CVT_SCALE_FUNC(32f16f, cvt1_32f, float, float16_t, float) -DEF_CVT_SCALE_FUNC(64f16f, cvt_64f, double, float16_t, double) -DEF_CVT_SCALE_FUNC(16f, cvt1_32f, float16_t, float16_t, float) +DEF_CVT_SCALE_FUNC(8u16f, cvt1_32f, uchar, hfloat, float) +DEF_CVT_SCALE_FUNC(8s16f, cvt1_32f, schar, hfloat, float) +DEF_CVT_SCALE_FUNC(16u16f, cvt1_32f, ushort, hfloat, float) +DEF_CVT_SCALE_FUNC(16s16f, cvt1_32f, short, hfloat, float) +DEF_CVT_SCALE_FUNC(32s16f, cvt1_32f, int, hfloat, float) +DEF_CVT_SCALE_FUNC(32f16f, cvt1_32f, float, hfloat, float) +DEF_CVT_SCALE_FUNC(64f16f, cvt_64f, double, hfloat, double) +DEF_CVT_SCALE_FUNC(16f, cvt1_32f, hfloat, hfloat, float) BinaryFunc getCvtScaleAbsFunc(int depth) { diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index f4c98b49c0..5c8af185b5 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -93,7 +93,7 @@ void scalarToRawData(const Scalar& s, void* _buf, int type, int unroll_to) scalarToRawData_(s, (double*)_buf, cn, unroll_to); break; case CV_16F: - scalarToRawData_(s, (float16_t*)_buf, cn, unroll_to); + scalarToRawData_(s, (hfloat*)_buf, cn, unroll_to); break; default: CV_Error(cv::Error::StsUnsupportedFormat,""); diff --git a/modules/core/src/norm.cpp b/modules/core/src/norm.cpp index 31178dbcda..49d781fcb0 100644 --- a/modules/core/src/norm.cpp +++ b/modules/core/src/norm.cpp @@ -752,7 +752,7 @@ double norm( InputArray _src, int normType, InputArray _mask ) for (int j = 0; j < total; j += blockSize) { int bsz = std::min(total - j, blockSize); - hal::cvt16f32f((const float16_t*)ptrs[0], data0, bsz * cn); + hal::cvt16f32f((const hfloat*)ptrs[0], data0, bsz * cn); func((uchar*)data0, ptrs[1], (uchar*)&result.f, bsz, cn); ptrs[0] += bsz*esz; if (ptrs[1]) @@ -1222,8 +1222,8 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask for (int j = 0; j < total; j += blockSize) { int bsz = std::min(total - j, blockSize); - hal::cvt16f32f((const float16_t*)ptrs[0], data0, bsz * cn); - hal::cvt16f32f((const float16_t*)ptrs[1], data1, bsz * cn); + hal::cvt16f32f((const hfloat*)ptrs[0], data0, bsz * cn); + hal::cvt16f32f((const hfloat*)ptrs[1], data1, bsz * cn); func((uchar*)data0, (uchar*)data1, ptrs[2], (uchar*)&result.f, bsz, cn); ptrs[0] += bsz*esz; ptrs[1] += bsz*esz; diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index 5eac178316..8d7d7faf44 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -7210,7 +7210,7 @@ String kernelToStr(InputArray _kernel, int ddepth, const char * name) typedef std::string (* func_t)(const Mat &); static const func_t funcs[] = { kerToStr, kerToStr, kerToStr, kerToStr, - kerToStr, kerToStr, kerToStr, kerToStr }; + kerToStr, kerToStr, kerToStr, kerToStr }; const func_t func = funcs[ddepth]; CV_Assert(func != 0); diff --git a/modules/core/src/out.cpp b/modules/core/src/out.cpp index 8a7d7e1636..342cc8a2bb 100644 --- a/modules/core/src/out.cpp +++ b/modules/core/src/out.cpp @@ -77,7 +77,7 @@ namespace cv void valueToStr32s() { snprintf(buf, sizeof(buf), "%d", mtx.ptr(row, col)[cn]); } void valueToStr32f() { snprintf(buf, sizeof(buf), floatFormat, mtx.ptr(row, col)[cn]); } void valueToStr64f() { snprintf(buf, sizeof(buf), floatFormat, mtx.ptr(row, col)[cn]); } - void valueToStr16f() { snprintf(buf, sizeof(buf), floatFormat, (float)mtx.ptr(row, col)[cn]); } + void valueToStr16f() { snprintf(buf, sizeof(buf), floatFormat, (float)mtx.ptr(row, col)[cn]); } void valueToStrOther() { buf[0] = 0; } public: diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index 6a71c1ff03..5f7f638397 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -270,7 +270,7 @@ int calcStructSize( const char* dt, int initial_size ) case 'i': { elem_max_size = std::max( elem_max_size, sizeof(int ) ); break; } case 'f': { elem_max_size = std::max( elem_max_size, sizeof(float ) ); break; } case 'd': { elem_max_size = std::max( elem_max_size, sizeof(double) ); break; } - case 'h': { elem_max_size = std::max(elem_max_size, sizeof(float16_t)); break; } + case 'h': { elem_max_size = std::max(elem_max_size, sizeof(hfloat)); break; } default: CV_Error_(Error::StsNotImplemented, ("Unknown type identifier: '%c' in '%s'", (char)(*type), dt)); } @@ -1129,8 +1129,8 @@ void FileStorage::Impl::writeRawData(const std::string &dt, const void *_data, s data += sizeof(double); break; case CV_16F: /* reference */ - ptr = fs::floatToString(buf, sizeof(buf), (float) *(float16_t *) data, true, explicitZero); - data += sizeof(float16_t); + ptr = fs::floatToString(buf, sizeof(buf), (float) *(hfloat *) data, true, explicitZero); + data += sizeof(hfloat); break; default: CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported type"); @@ -1809,7 +1809,7 @@ char *FileStorage::Impl::parseBase64(char *ptr, int indent, FileNode &collection node_type = FileNode::REAL; break; case CV_16F: - fval = (float) float16_t::fromBits(base64decoder.getUInt16()); + fval = float(hfloatFromBits(base64decoder.getUInt16())); node_type = FileNode::REAL; break; default: @@ -2600,8 +2600,8 @@ FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, void* _data0, si data += sizeof(double); break; case CV_16F: - *(float16_t*)data = float16_t((float)ival); - data += sizeof(float16_t); + *(hfloat*)data = hfloat((float)ival); + data += sizeof(hfloat); break; default: CV_Error( Error::StsUnsupportedFormat, "Unsupported type" ); @@ -2642,8 +2642,8 @@ FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, void* _data0, si data += sizeof(double); break; case CV_16F: - *(float16_t*)data = float16_t((float)fval); - data += sizeof(float16_t); + *(hfloat*)data = hfloat((float)fval); + data += sizeof(hfloat); break; default: CV_Error( Error::StsUnsupportedFormat, "Unsupported type" ); diff --git a/modules/core/src/rand.cpp b/modules/core/src/rand.cpp index e39acce529..a6301afe34 100644 --- a/modules/core/src/rand.cpp +++ b/modules/core/src/rand.cpp @@ -195,7 +195,7 @@ randf_64f( double* arr, int len, uint64* state, const Vec2d* p, void*, bool ) hal::addRNGBias64f(arr, &p[0][0], len); } -static void randf_16f( float16_t* arr, int len, uint64* state, const Vec2f* p, float* fbuf, bool ) +static void randf_16f( hfloat* arr, int len, uint64* state, const Vec2f* p, float* fbuf, bool ) { uint64 temp = *state; for( int i = 0; i < len; i++ ) diff --git a/modules/core/test/test_intrin_utils.hpp b/modules/core/test/test_intrin_utils.hpp index be4f7beac7..a8c565ec46 100644 --- a/modules/core/test/test_intrin_utils.hpp +++ b/modules/core/test/test_intrin_utils.hpp @@ -1557,14 +1557,14 @@ template struct TheTest AlignedData data_f32; data_f32.a.clear(); AlignedData out; - R r1 = vx_load_expand((const cv::float16_t*)data.a.d); + R r1 = vx_load_expand((const cv::hfloat*)data.a.d); R r2(r1); EXPECT_EQ(1.0f, v_get0(r1)); v_store(data_f32.a.d, r2); EXPECT_EQ(-2.0f, data_f32.a.d[VTraits::vlanes() - 1]); out.a.clear(); - v_pack_store((cv::float16_t*)out.a.d, r2); + v_pack_store((cv::hfloat*)out.a.d, r2); for (int i = 0; i < VTraits::vlanes(); ++i) { EXPECT_EQ(data.a[i], out.a[i]) << "i=" << i; @@ -1588,7 +1588,7 @@ template struct TheTest // check some initialization methods R r1 = data.u; - R r2 = vx_load_expand((const float16_t*)data.a.d); + R r2 = vx_load_expand((const hfloat*)data.a.d); R r3(r2); EXPECT_EQ(data.u[0], v_get0(r1)); EXPECT_EQ(data.a[0], v_get0(r2)); diff --git a/modules/gapi/src/backends/ie/giebackend.cpp b/modules/gapi/src/backends/ie/giebackend.cpp index 000021d898..4fc4fe9a8d 100644 --- a/modules/gapi/src/backends/ie/giebackend.cpp +++ b/modules/gapi/src/backends/ie/giebackend.cpp @@ -381,7 +381,7 @@ inline void copyFromIE(const IE::Blob::Ptr &blob, MatType &mat) { HANDLE(U8, uint8_t); HANDLE(FP32, float); HANDLE(I32, int); - HANDLE(FP16, cv::float16_t); + HANDLE(FP16, cv::hfloat); #undef HANDLE case IE::Precision::I64: { GAPI_LOG_WARNING(NULL, "INT64 isn't supported for cv::Mat. Conversion to INT32 is used."); diff --git a/modules/gapi/test/common/gapi_tests_common.hpp b/modules/gapi/test/common/gapi_tests_common.hpp index f84ee05f49..2b8ee25512 100644 --- a/modules/gapi/test/common/gapi_tests_common.hpp +++ b/modules/gapi/test/common/gapi_tests_common.hpp @@ -370,7 +370,7 @@ public: initMatByPointsVectorRandU>(sz_in); break; case CV_16F: - initMatByPointsVectorRandU>(sz_in); + initMatByPointsVectorRandU>(sz_in); break; default: GAPI_Error("Unsupported depth"); From 52f3f5a3f617e8b1fa708bdfc37a6bc58a13ebb7 Mon Sep 17 00:00:00 2001 From: Michael Klatis Date: Thu, 21 Mar 2024 18:08:16 -0700 Subject: [PATCH 28/56] libtiff upgrade to version 4.6.0 (#25096) * libtiff upgrade to version 4.6.0 * fix tiffvers.h cmake generation * temp: force build 3rd party deps from source * remove libport.h and spintf.c * cmake fixes * don't use tiff_dummy_namespace on windows * introduce numeric_types namespace alias * include cstdint * uint16_t is not a numeric_types type * fix uint16 and uint32 type defs * use standard c++ types * remove unused files * remove more unused files * revert build 3rd party code from source --------- Co-authored-by: Misha Klatis --- 3rdparty/libtiff/CMakeLists.txt | 40 +- 3rdparty/libtiff/ChangeLog | 4823 ++++++++- 3rdparty/libtiff/README.md | 69 + 3rdparty/libtiff/libport.h | 71 - 3rdparty/libtiff/snprintf.c | 42 - 3rdparty/libtiff/t4.h | 464 +- 3rdparty/libtiff/tif_aux.c | 649 +- 3rdparty/libtiff/tif_close.c | 172 +- 3rdparty/libtiff/tif_codec.c | 142 +- 3rdparty/libtiff/tif_color.c | 383 +- 3rdparty/libtiff/tif_compress.c | 412 +- 3rdparty/libtiff/tif_config.h.cmake.in | 182 +- 3rdparty/libtiff/tif_dir.c | 3667 ++++--- 3rdparty/libtiff/tif_dir.h | 467 +- 3rdparty/libtiff/tif_dirinfo.c | 2280 ++-- 3rdparty/libtiff/tif_dirread.c | 12973 +++++++++++++---------- 3rdparty/libtiff/tif_dirwrite.c | 5916 +++++------ 3rdparty/libtiff/tif_dumpmode.c | 159 +- 3rdparty/libtiff/tif_error.c | 148 +- 3rdparty/libtiff/tif_extension.c | 62 +- 3rdparty/libtiff/tif_fax3.c | 2743 ++--- 3rdparty/libtiff/tif_fax3.h | 901 +- 3rdparty/libtiff/tif_flush.c | 135 +- 3rdparty/libtiff/tif_getimage.c | 4757 +++++---- 3rdparty/libtiff/tif_hash_set.c | 603 ++ 3rdparty/libtiff/tif_hash_set.h | 100 + 3rdparty/libtiff/tif_jbig.c | 294 +- 3rdparty/libtiff/tif_jpeg.c | 4101 +++---- 3rdparty/libtiff/tif_jpeg_12.c | 88 +- 3rdparty/libtiff/tif_lerc.c | 1206 +++ 3rdparty/libtiff/tif_luv.c | 2882 ++--- 3rdparty/libtiff/tif_lzma.c | 743 +- 3rdparty/libtiff/tif_lzw.c | 2234 ++-- 3rdparty/libtiff/tif_next.c | 301 +- 3rdparty/libtiff/tif_ojpeg.c | 4884 +++++---- 3rdparty/libtiff/tif_open.c | 1230 ++- 3rdparty/libtiff/tif_packbits.c | 516 +- 3rdparty/libtiff/tif_pixarlog.c | 2510 +++-- 3rdparty/libtiff/tif_predict.c | 1485 +-- 3rdparty/libtiff/tif_predict.h | 55 +- 3rdparty/libtiff/tif_print.c | 1319 +-- 3rdparty/libtiff/tif_read.c | 2535 +++-- 3rdparty/libtiff/tif_stream.cxx | 578 +- 3rdparty/libtiff/tif_strip.c | 491 +- 3rdparty/libtiff/tif_swab.c | 445 +- 3rdparty/libtiff/tif_thunder.c | 294 +- 3rdparty/libtiff/tif_tile.c | 415 +- 3rdparty/libtiff/tif_unix.c | 462 +- 3rdparty/libtiff/tif_version.c | 29 +- 3rdparty/libtiff/tif_warning.c | 122 +- 3rdparty/libtiff/tif_webp.c | 1349 ++- 3rdparty/libtiff/tif_win32.c | 593 +- 3rdparty/libtiff/tif_write.c | 1359 +-- 3rdparty/libtiff/tif_zip.c | 1055 +- 3rdparty/libtiff/tif_zstd.c | 676 +- 3rdparty/libtiff/tiff.h | 1381 +-- 3rdparty/libtiff/tiffconf.h.cmake.in | 42 +- 3rdparty/libtiff/tiffio.h | 833 +- 3rdparty/libtiff/tiffio.hxx | 33 +- 3rdparty/libtiff/tiffiop.h | 662 +- 3rdparty/libtiff/tiffvers.h | 9 - 3rdparty/libtiff/tiffvers.h.cmake.in | 36 + 3rdparty/libtiff/uvcode.h | 269 +- modules/imgcodecs/src/grfmt_tiff.cpp | 50 +- 64 files changed, 45226 insertions(+), 34700 deletions(-) create mode 100644 3rdparty/libtiff/README.md delete mode 100644 3rdparty/libtiff/libport.h delete mode 100644 3rdparty/libtiff/snprintf.c create mode 100644 3rdparty/libtiff/tif_hash_set.c create mode 100644 3rdparty/libtiff/tif_hash_set.h create mode 100644 3rdparty/libtiff/tif_lerc.c delete mode 100644 3rdparty/libtiff/tiffvers.h create mode 100644 3rdparty/libtiff/tiffvers.h.cmake.in diff --git a/3rdparty/libtiff/CMakeLists.txt b/3rdparty/libtiff/CMakeLists.txt index 826c5e2316..30a052861f 100644 --- a/3rdparty/libtiff/CMakeLists.txt +++ b/3rdparty/libtiff/CMakeLists.txt @@ -124,17 +124,17 @@ elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL 8) endif() if(SIZEOF_UNSIGNED_INT EQUAL SIZEOF_SIZE_T) - set(TIFF_SIZE_T "unsigned int") + set(TIFF_SIZE_T "uint32_t") set(TIFF_SIZE_FORMAT "%u") - set(TIFF_SSIZE_T "signed int") + set(TIFF_SSIZE_T "int32_t") set(TIFF_SSIZE_FORMAT "%d") elseif(SIZEOF_UNSIGNED_LONG EQUAL SIZEOF_SIZE_T) - set(TIFF_SIZE_T "unsigned long") + set(TIFF_SIZE_T "uint64_t") set(TIFF_SIZE_FORMAT "%lu") - set(TIFF_SSIZE_T "signed long") + set(TIFF_SSIZE_T "int64_t") set(TIFF_SSIZE_FORMAT "%ld") elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL SIZEOF_SIZE_T) - set(TIFF_SIZE_T "unsigned long") + set(TIFF_SIZE_T "uint64_t") if(MINGW) set(TIFF_SIZE_FORMAT "%I64u") set(TIFF_SSIZE_FORMAT "%I64d") @@ -198,20 +198,6 @@ check_function_exists(strtol HAVE_STRTOUL) check_function_exists(strtoull HAVE_STRTOULL) check_function_exists(lfind HAVE_LFIND) -# May be inlined, so check it compiles: -check_c_source_compiles(" -#include -int main(void) { - char buf[10]; - snprintf(buf, 10, \"Test %d\", 1); - return 0; -}" - HAVE_SNPRINTF) - -if(NOT HAVE_SNPRINTF) - add_definitions(-DNEED_LIBPORT) -endif() - # CPU bit order set(fillorder FILLORDER_MSB2LSB) if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i.*86.*" OR @@ -371,7 +357,12 @@ if(LIBLZMA_LIBRARIES) list(APPEND TIFF_LIBRARY_DEPS ${LIBLZMA_LIBRARIES}) endif() +set(LIBTIFF_MAJOR_VERSION "4") +set(LIBTIFF_MINOR_VERSION "6") +set(LIBTIFF_MICRO_VERSION "0") +set(LIBTIFF_VERSION "${LIBTIFF_MAJOR_VERSION}.${LIBTIFF_MINOR_VERSION}.${LIBTIFF_MICRO_VERSION}") +set(TIFF_MAX_DIR_COUNT "1048576") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tif_config.h.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/tif_config.h" @@ -379,6 +370,9 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tif_config.h.cmake.in" configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tiffconf.h.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/tiffconf.h" @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tiffvers.h.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/tiffvers.h" + @ONLY) ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" ${ZLIB_INCLUDE_DIRS}) @@ -399,6 +393,7 @@ set(lib_srcs tif_fax3sm.c tif_flush.c tif_getimage.c + tif_hash_set.c tif_jbig.c tif_jpeg_12.c tif_jpeg.c @@ -427,21 +422,18 @@ set(lib_srcs t4.h tif_dir.h tif_fax3.h + tif_hash_set.h + tif_predict.h tiff.h tiffio.h tiffiop.h tiffvers.h - tif_predict.h uvcode.h tiffio.hxx "${CMAKE_CURRENT_BINARY_DIR}/tif_config.h" "${CMAKE_CURRENT_BINARY_DIR}/tiffconf.h" ) -if(WIN32 AND NOT HAVE_SNPRINTF) - list(APPEND lib_srcs snprintf.c libport.h) -endif() - if(WIN32 AND NOT WINRT) list(APPEND lib_srcs tif_win32.c) else() diff --git a/3rdparty/libtiff/ChangeLog b/3rdparty/libtiff/ChangeLog index 452dcb3a18..87b5f126bb 100644 --- a/3rdparty/libtiff/ChangeLog +++ b/3rdparty/libtiff/ChangeLog @@ -1,3 +1,4732 @@ +2023-09-05 Even Rouault + + libtiff v4.6.0 released + +2023-09-05 Even Rouault + + Merge branch 'fix_600' into 'master' + CMake: fix build with -Dstrip-chopping=off (fixes #600) + + See merge request libtiff/libtiff!527 + +2023-09-05 Even Rouault + + Merge branch 'georgthegreat-master-patch-87447' into 'master' + Fix using __attribute__ libtiff with clang-for-windows + + See merge request libtiff/libtiff!525 + +2023-09-05 Yuriy Chernyshov + + Fix using __attribute__ libtiff with clang-for-windows. + +2023-09-05 Even Rouault + + Merge branch 'manpage_TIFFField_docu_update' into 'master' + manpages: TiffField functions documentation updated with return behaviour for... + + See merge request libtiff/libtiff!526 + +2023-09-05 Even Rouault + + CMake: fix build with -Dstrip-chopping=off (fixes #600) + +2023-09-03 Even Rouault + + Merge branch 'consistently_update_TIFF-version_from_configure-ac' into 'master' + Update CMake and autoconf scripts to consistently update LibTIFF version... + + See merge request libtiff/libtiff!456 + +2023-09-03 Su Laus + + Update CMake and autoconf scripts to consistently update LibTIFF version defines and references in various files when version definition in configure.ac has been changed. + - Move in tiffvers.h from .\libtiff source directory to .\libtiff build directory. + - Remove unused version information from tif_config.h + - With every CMake build the version defines (e.g. 4.5.1) within tiffvers.h are consistently updated from configure.ac. The version release-date is taken from file RELEASE-DATE. + - The files VERSION and RELEASE-DATE are only updated with a special CMake target build: cmake --build . --target tiff_release. + + - For autotools, version information is updated from configure.ac with ./autogen.sh. LIBTIFF_RELEASE_DATE is taken form file RELEASE-DATE. + - ./configure generates tiffvers.h with the cached version information and LIBTIFF_RELEASE_DATE. + - "make release" updates tiffvers.h and VERSION file with cached version info and RELEASE-DATE file and tiffves.h with the current date. + +2023-08-28 Su_Laus + + manpages: TiffField functions documentation updated with return behaviour for not defined tags and determination of write-/read-count size. + +2023-08-22 Even Rouault + + Merge branch 'change_long_to_int32_t_in_two_test_apps' into 'master' + Change "long" to "int32_t" in two test apps, because can be either int32_t or... + + See merge request libtiff/libtiff!524 + +2023-08-21 Su_Laus + + Change "long" to "int32_t" in two test apps, because can be either int32_t or int64_t, depending on compiler and system. + +2023-08-16 Even Rouault + + Merge branch 'CI_CMake_static_build' into 'master' + Add static build for CI/CD to run testcases which need private interface functions. + + See merge request libtiff/libtiff!521 + +2023-08-16 Even Rouault + + Merge branch 'fix_#597_tiffset_different_signedness' into 'master' + tiffset fix #597: warning: comparison of integer expressions of different signedness. + + Closes #597 + + See merge request libtiff/libtiff!523 + +2023-08-16 Even Rouault + + Merge branch 'tiffcp_remove_i_option' into 'master' + tiffcp: remove -i option (ignore errors) + + See merge request libtiff/libtiff!522 + +2023-08-16 Even Rouault + + Merge branch 'move_tools_to_unsupported_a_archive' into 'master' + Move most TIFF tools to archive and keep some as unsupported (see #580). + + See merge request libtiff/libtiff!520 + +2023-08-16 Su Laus + + Move most TIFF tools to archive and keep some as unsupported (see #580). + +2023-08-12 Su_Laus + + Add static build for CI/CD to run testcases which need private interface functions. + + tiffset fix #597: warning: comparison of integer expressions of different signedness. + + Remove -i option (ignore errors) from tiffcp, because almost all fuzzer issues were consequential errors from ignored errors because of the "-i" option. + +2023-08-11 Even Rouault + + Merge branch 'fix_585_test_write_read_tags_autoconf' into 'master' + Add missing test_write_read_tags.c and test_transferfunction_write_read.c in... + + Closes #585 + + See merge request libtiff/libtiff!519 + +2023-07-24 Even Rouault + + Fix copy paste error. + +2023-07-23 Su_Laus + + Add missing test_write_read_tags.c and test_transferfunction_write_read.c in tarball (fixes #585) and correct „long“ issue. + Don't use "long" because can be int32_t or int64_t, depending on compiler and system. + +2023-07-20 Even Rouault + + Merge branch 'clang-format-tools' into 'master' + Automatically format with clang-format + + See merge request libtiff/libtiff!518 + +2023-07-20 Timothy Lyanguzov + + Automatically format with clang-format. + +2023-07-20 Even Rouault + + Merge branch 'fix_589' into 'master' + TiffConfig.cmake.in: set TIFF_INCLUDE_DIR, TIFF_INCLUDE_DIRS and... + + Closes #589 + + See merge request libtiff/libtiff!514 + +2023-07-20 Even Rouault + + TiffConfig.cmake.in: set TIFF_INCLUDE_DIR, TIFF_INCLUDE_DIRS and... + +2023-07-19 Even Rouault + + Merge branch 'master-patch-6fc6' into 'master' + raw2tiff: fix integer overflow and bypass of the check (fixes #592) + + See merge request libtiff/libtiff!516 + +2023-07-19 Arie Haenel + + raw2tiff: fix integer overflow and bypass of the check (fixes #592) + +2023-07-19 Even Rouault + + Merge branch 'master-patch-05a4' into 'master' + tiffcp: fix memory corruption (overflow) on hostile images (fixes #591) + + See merge request libtiff/libtiff!515 + +2023-07-19 Arie Haenel + + tiffcp: fix memory corruption (overflow) on hostile images (fixes #591) + +2023-07-17 Even Rouault + + Merge branch 'fix-numtrunc' into 'master' + fix numtrunc at tiff_dirread.c + + See merge request libtiff/libtiff!512 + +2023-07-17 headshog + + TIFFReadDirectoryCheckOrder: avoid integer overflow. + When it occurs, it should be harmless in practice though + +2023-07-17 Even Rouault + + Merge branch 'webp_lossless_exact' into 'master' + WebP codec: turn exact mode when creating lossless files to avoid altering... + + See merge request libtiff/libtiff!511 + +2023-07-11 Even Rouault + + WebP codec: turn exact mode when creating lossless files to avoid altering R,G,B values in areas where alpha=0 + Fixes https://github.com/OSGeo/gdal/issues/8038 + +2023-07-05 Even Rouault + + Merge branch 'webp_reg_fix' into 'master' + WebP decoder: fix error when reading a 3-band blob in a RGBA image + + See merge request libtiff/libtiff!510 + +2023-07-05 Even Rouault + + WebP decoder: fix error when reading a 3-band blob in a RGBA image. + Fixes regression of 350ff161c8a61b6483a1e4689e09cd47dd0dd5f9 (master only) + +2023-06-26 Even Rouault + + Merge branch 'appveyor_fix' into 'master' + .appveyor.yml: workaround build error + + See merge request libtiff/libtiff!509 + +2023-06-26 Even Rouault + + .appveyor.yml: workaround build error. + +2023-06-26 Even Rouault + + Merge branch 'tif_webp_warning_fixes' into 'master' + tif_webp.c: fix signed vs unsigned comparison warnings (fix previous commit) + + See merge request libtiff/libtiff!508 + +2023-06-26 Even Rouault + + tif_webp.c: fix signed vs unsigned comparison warnings (fix previous commit) + +2023-06-26 Even Rouault + + Merge branch 'fix_TransferFunction_writing' into 'master' + Fix TransferFunction writing of only two transfer functions. + + See merge request libtiff/libtiff!502 + +2023-06-26 Even Rouault + + Merge branch 'fix_581_582' into 'master' + WebP decoder: validate WebP blob width, height, band count against TIFF parameters + + Closes #582 et #581 + + See merge request libtiff/libtiff!507 + +2023-06-19 Even Rouault + + Merge branch 'warning_cmake_config_file' into 'master' + v4.5.1 release note: add warning about CMake config file being preview + + See merge request libtiff/libtiff!506 + +2023-06-17 Even Rouault + + WebP decoder: validate WebP blob width, height, band count against TIFF parameters + to avoid use of uninitialized variable, or decoding corrupted content + without explicit error + + Fixes #581, fixes #582 + +2023-06-15 Even Rouault + + v4.5.1 release note: add warning about CMake config file being preview. + +2023-06-14 Even Rouault + + Merge branch 'HOWTO-RELEASE-gitlab-release' into 'master' + HOWTO-RELEASE: mention creating a gitlab release + + See merge request libtiff/libtiff!505 + +2023-06-14 Even Rouault + + HOWTO-RELEASE: mention creating a gitlab release. + +2023-06-10 Even Rouault + + Merge branch 'TIFFOpenWExt_O_RDWR' into 'master' + TIFFOpenWExt(): mode r+ in the Windows implementation adjusted to that of Linux + + See merge request libtiff/libtiff!504 + +2023-06-10 Even Rouault + + TIFFOpenWExt(): mode r+ in the Windows implementation adjusted to that of Linux + +2023-06-10 Even Rouault + + Merge branch 'fix_ossfuzz_59751' into 'master' + TIFFReadDirectory(): fix crash when reading tag TIFFTAG_EP_BATTERYLEVEL + + See merge request libtiff/libtiff!503 + +2023-06-10 Even Rouault + + TIFFReadDirectory(): fix crash when reading tag TIFFTAG_EP_BATTERYLEVEL. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=59751 + + In 738e0409 (refs #575), we disabled DNG / EP tags, but there was a + special proessing for TIFFTAG_EP_BATTERYLEVEL that must be disabled + since the tag is no longer defined. + +2023-06-09 Su_Laus + + Fix TransferFunction writing of only two transfer functions. The TIFFWriteDirectoryTagTransferfunction() function writes in some cases only two transfer functions, although only exactly one or exactly three transfer functions are allowed. This then leads to an error when reading. --> TIFFReadDirectory: Warning, Incorrect count for "TransferFunction"; tag ignored. + This MR corrects the behaviour of TIFFWriteDirectoryTagTransferfunction() accordingly. Furthermore, a possible buffer overflow is avoided. + +2023-06-09 Even Rouault + + Merge branch 'fix_win_build' into 'master' + Fix Windows build + + Closes #578 + + See merge request libtiff/libtiff!501 + +2023-06-09 Even Rouault + + cmake/PkgConfig.cmake: avoid CMake error when prefix or suffix is empty. + + Add tif_win32_versioninfo.rc and tif_tools_versioninfo.rc to EXTRA_DIST. + +2023-06-09 Even Rouault + + Merge branch 'fix_coverity_build' into 'master' + build/gitlab-ci: fix coverity_build() + + See merge request libtiff/libtiff!499 + +2023-06-09 Even Rouault + + build/gitlab-ci: fix coverity_build() + +2023-06-09 Even Rouault + + Merge branch 'v4.5.1rc1_preparation' into 'master' + Prepare release 4.5.1 + + See merge request libtiff/libtiff!498 + +2023-06-09 Even Rouault + + Prepare for v4.5.1 release. + + Merge remote-tracking branch 'sulaus/Rel_4.5.1_preparation' + +2023-06-09 Even Rouault + + Merge branch 'disable_dng_tags' into 'master' + tif_dirinfo.c: disable DNG 1.2->1.6 tags + + Closes #575 + + See merge request libtiff/libtiff!497 + +2023-06-09 Even Rouault + + Merge branch 'fix_577' into 'master' + CMake related fixes + + Closes #577 + + See merge request libtiff/libtiff!496 + +2023-06-09 Even Rouault + + libtiff v4.5.1 released + +2023-06-09 Even Rouault + + Merge remote-tracking branch 'sulaus/Rel_4.5.1_preparation' + +2023-06-09 Even Rouault + + Merge branch 'disable_dng_tags' into 'master' + tif_dirinfo.c: disable DNG 1.2->1.6 tags + + Closes #575 + + See merge request libtiff/libtiff!497 + +2023-06-09 Even Rouault + + Merge branch 'fix_577' into 'master' + CMake related fixes + + Closes #577 + + See merge request libtiff/libtiff!496 + +2023-06-07 Even Rouault + + tif_dirinfo.c: disable DNG 1.2->1.6 tags. + They were added per b90b20d36d7833f54a1f3014c324f6c21b988006 but it has + been found in https://gitlab.com/libtiff/libtiff/-/issues/575 that it + could cause compatibity issues with libtiff users, so this addition + should be defered for a feature release (likely 4.6.0) and not a patch one. + + Fixes #575 + +2023-06-06 Timothy Lyanguzov + + Apply 1 suggestion(s) to 1 file(s) + +2023-06-05 Even Rouault + + CI: add testing of find_package(Tiff CONFIG) + + CMake: export TiffConfig.cmake and TiffConfigVersion.cmake files. + + libtiff/CMakeLists.txt: fix export of INTERFACE_INCLUDE_DIRECTORIES. + + libtiff/CMakeLists.txt: correctly define TIFF::tiff alias (fixes #577) + +2023-06-05 Even Rouault + + Merge branch 'TIFFField_downgrade_errors_to_warnings' into 'master' + TIFFFieldWithName() and TIFFFieldWithTag() downgrade errors to warnings. + + See merge request libtiff/libtiff!495 + +2023-05-28 Su_Laus + + TIFFFieldWithName() and TIFFFieldWithTag() downgrade errors to warnings. see https://gitlab.com/libtiff/libtiff/-/issues/575#note_1407633888 + +2023-05-25 Even Rouault + + Merge branch 'bebuch-master-patch-58347' into 'master' + check if upstream lzma (xz) config was used and bind to it if so + + See merge request libtiff/libtiff!494 + +2023-05-25 Benjamin Buch + + check if upstream lzma (xz) config was used and bind to it if so. + +2023-05-25 Even Rouault + + Merge branch 'upstream-zstd-config' into 'master' + check if upstream zstd config was used and bind to it if so + + See merge request libtiff/libtiff!493 + +2023-05-25 Even Rouault + + Merge branch 'cmake_FindDeflate_bugs_see_526' into 'master' + CMake: FindDeflate several errors fixed (see #526) + + See merge request libtiff/libtiff!491 + +2023-05-24 Su_Laus + + CMake: FindDeflate several errors (see #526) + There are CMake issues if the library is not included in the environment path and only set with CMake -D option. + - For FindDeflate.cmake, FindJBIG.cmake, FindLERC.cmake, FindWebP.cmake, FindZSTD.cmake: + Set IMPORTED_LOCATION (without debug or release) if neither _LIBRARY_RELEASE nor _LIBRARY_DEBUG were set. + - FindDeflate.cmake: Correct code to retrieve library version information from libdeflate.h + - FindLERC.cmake version string return added. + +2023-05-24 Benjamin Buch + + prefer shared over static. + + check if upstream zstd config was used and bind to it if so. + +2023-05-24 Even Rouault + + Merge branch 'master' into 'master' + make WebP component name compatible with upstream ConfigWebP.cmake + + See merge request libtiff/libtiff!492 + +2023-05-24 Benjamin Buch + + CMake: make WebP component name compatible with upstream ConfigWebP.cmake + +2023-05-18 Su_Laus + + Prepare release 4.5.1 - Update till 18.05.23 after fix_559_DNG_1.6_passcount_error + + Prepare release 4.5.1. + +2023-05-18 Even Rouault + + Merge branch 'fix_559_DNG_1.6_passcount_error' into 'master' + Fix #559 DNG 1.6 passcount assertion + + Closes #574 et #559 + + See merge request libtiff/libtiff!489 + +2023-05-18 Even Rouault + + Merge branch 'fix_557_TagExtender_for_CustomDirectories_not_possible' into 'master' + manpage: TIFFSetTagExtender() cannot add tags to custom directories. Closes #557. + + Closes #557 + + See merge request libtiff/libtiff!490 + +2023-05-18 Even Rouault + + Merge branch 'fix_559_DNG_1.6_passcount_error' into 'master' + Fix #559 DNG 1.6 passcount assertion + + Closes #574 et #559 + + See merge request libtiff/libtiff!489 + +2023-05-18 Even Rouault + + Merge branch 'fix_557_TagExtender_for_CustomDirectories_not_possible' into 'master' + manpage: TIFFSetTagExtender() cannot add tags to custom directories. Closes #557. + + Closes #557 + + See merge request libtiff/libtiff!490 + +2023-05-17 Su_Laus + + Documentation update: TIFFSetTagExtender() cannot add tags to custom directories. + Closes #557. + +2023-05-16 Even Rouault + + Merge branch 'fix_558' into 'master' + Hardcode HOST_FILLORDER to FILLORDER_LSB2MSB, and make 'H' flag of TIFFOpen()... + + See merge request libtiff/libtiff!488 + +2023-05-16 Su_Laus + + Fix #559 DNG 1.6 passcount assertion. + Amend DNG tags definition introduced with MR 482: + - DNG 1.6 tags specified as UTF-8 strings are defined as variable TIFF_BYTE with passcount=TRUE. + - For all tags with TIFF_SETGET_C32_UINT8 the readcount and writecount were corrected to -3 (TIFF_VARIABLE2). + + Testprogram to write and read all tags defined within LibTIFF is introduced. + It also checks for valid passcount flag setting for the defined tags but some special tags are excluded from that check. + + Closes #559. + +2023-05-09 Even Rouault + + Hardcode HOST_FILLORDER to FILLORDER_LSB2MSB, and make 'H' flag of TIFFOpen() to warn and an alias of FILLORDER_MSB2LSB + + tif_lerc.c: use WORDS_BIGENDIAN instead of HOST_BIGENDIAN. + +2023-05-07 Even Rouault + + Merge branch 'fix_484_TIFFDirectory_32_64_bit' into 'master' + Fix 484 TIFFDirectory td_fieldsset uses unsigned long which can be 32 or 64 bits. + + Closes #484 + + See merge request libtiff/libtiff!471 + +2023-05-07 Even Rouault + + Merge branch 'DNG_1.6_EP_tags' into 'master' + Add DNG tags up to version 1.6.0.0 and some TIFF/EP tags and update documentation + + See merge request libtiff/libtiff!482 + +2023-05-07 Even Rouault + + Merge branch 'issue547' into 'master' + do not install libtiff-4.pc when tiff-install is reset + + Closes #547 + + See merge request libtiff/libtiff!481 + +2023-05-06 Even Rouault + + Merge branch 'fix_548' into 'master' + LZWDecode(): avoid crash when trying to read again from a strip whith a... + + Closes #548 + + See merge request libtiff/libtiff!484 + +2023-05-06 Even Rouault + + Merge branch 'tiffcrop_fix_553_multi-image-errors' into 'master' + tiffcrop: fix 553 by considering error return of writeSelections() + + Closes #553 + + See merge request libtiff/libtiff!485 + +2023-05-06 Even Rouault + + Merge branch 'tif_ojpeg_fix-554_FPE' into 'master' + tif_ojpeg.c fix 554 by checking for division by zero + + Closes #554 + + See merge request libtiff/libtiff!486 + +2023-05-06 Su Laus + + tif_ojpeg.c fix 554 by checking for division by zero. + +2023-05-05 Su_Laus + + Consider error return of writeSelections(). Fixes #553. + +2023-04-29 Even Rouault + + LZWDecode(): avoid crash when trying to read again from a strip whith a missing end-of-information marker (fixes #548) + +2023-04-25 Su_Laus + + Add DNG tags up to version 1.6.0.0 and some TIFF/EP tags and update documentation + Amend MR !337 'Add support for DNG tags up to version 1.6.0.0 and some TIFF/EP tags' from Sami Liedes: + - Set most tags to OkToChange=1. + - Define BATTERYLEVEL tag as ASCII and convert values of rational variant to ASCII. + - TIFF documentation updated for tags recognized by LibTiff (DNG 1.6 and others). + - TIFF/EP tags added, which are equivalent to EXIF tags. This addresses part of #418 as well. + - Definition of tags reformatted (clang-format off) for better readability of tag comments in tiff.h and tif_dirinfo.c + +2023-04-23 Roman + + do not install libtiff-4.pc when tiff-install is reset. + +2023-04-21 Even Rouault + + Merge branch 'mymaster1' into 'master' + fix runtime error: applying zero offset to null pointer + + See merge request libtiff/libtiff!479 + +2023-04-21 xiaoxiaoafeifei + + countInkNamesString(): fix `UndefinedBehaviorSanitizer`: applying zero offset to null pointer + +2023-03-26 Even Rouault + + Merge branch 'tif_ovrcache_TIFFSetSubDirectory' into 'master' + tif_ovrcache.c: check TIFFSetSubDirectory() return value (CID 1524573) + + See merge request libtiff/libtiff!478 + +2023-03-26 Even Rouault + + tif_ovrcache.c: check TIFFSetSubDirectory() return value (CID 1524573) + +2023-03-26 Even Rouault + + Merge branch 'even_faster_setdirectory_with_IFDlist' into 'master' + Even faster TIFFSetDirectory() using IFD list. + + See merge request libtiff/libtiff!477 + +2023-03-26 Su Laus + + Even faster TIFFSetDirectory() using IFD list. + +2023-03-12 Even Rouault + + Merge branch 'faster-setdirectory_newMR' into 'master' + Optimize relative seeking with TIFFSetDirectory + + See merge request libtiff/libtiff!474 + +2023-03-12 Su Laus + + Optimize relative seeking with TIFFSetDirectory. + +2023-03-11 Even Rouault + + Merge branch 'master' into 'master' + Fix memory leak in tiffcrop.c + + See merge request libtiff/libtiff!475 + +2023-03-08 zhailiangliang + + Fix memory leak in tiffcrop.c. + +2023-02-23 Even Rouault + + Merge branch 'skip-thumbnail-test' into 'master' + test: avoid running tool tests if not built + + Closes #421 + + See merge request libtiff/libtiff!334 + +2023-02-22 Sam James + + test (cmake): skip script tests if tools aren't built. + In Gentoo, we avoid building the tools for multilib (32-bit, x86) builds on + amd64/x86_64 because we only need the library to keep binary applications working. + + This causes a test failure in e.g. tiffcp-thumbnail.sh as the 'thumbnail' + binary isn't built. Skip it if unavailable. + + Fixes: https://gitlab.com/libtiff/libtiff/-/issues/421 + +2023-02-22 Sam James + + test (autotools): skip script tests if tools aren't built. + In Gentoo, we avoid building the tools for multilib (32-bit, x86) builds on + amd64/x86_64 because we only need the library to keep binary applications working. + + This causes a test failure in e.g. tiffcp-thumbnail.sh as the 'thumbnail' + binary isn't built. Skip it if unavailable. + + Fixes: https://gitlab.com/libtiff/libtiff/-/issues/421 + +2023-02-16 Even Rouault + + Merge branch 'fix_Unlink_first_directory_0' into 'master' + Fix TIFFUnlinkDirectory(0) case and unlink of first directory. + + See merge request libtiff/libtiff!460 + +2023-02-16 Even Rouault + + Merge branch 'tif_luv_check_NaN_fix_#530' into 'master' + tif_luv: Check and correct for NaN data in uv_encode(). + + Closes #530 + + See merge request libtiff/libtiff!473 + +2023-02-16 Su_Laus + + tif_luv: Check and correct for NaN data in uv_encode(). + Closes #530 + + See merge request !473 + +2023-02-14 Even Rouault + + Merge branch 'tiffcrop_dont_reuse_input_buffer_fix_527' into 'master' + tiffcrop: Do not reuse input buffer for subsequent images. Fix issue 527 + + Closes #527 + + See merge request libtiff/libtiff!472 + +2023-02-14 Su_Laus + + tiffcrop: Do not reuse input buffer for subsequent images. Fix issue 527 + Reuse of read_buff within loadImage() from previous image is quite unsafe, because other functions (like rotateImage() etc.) reallocate that buffer with different size without updating the local prev_readsize value. + + Closes #527 + +2023-02-08 Su_Laus + + Fix 484 TIFFDirectory td_fieldsset uses unsigned long which can be 32 or 64 bits. + Closes #484 + +2023-02-08 Even Rouault + + Merge branch 'test_ifd_loop_detection_fix_CoverityScan_ln_55' into 'master' + test_ifd_loop_detection: fix Coverity Scan issue CID 1520750: Null pointer... + + See merge request libtiff/libtiff!470 + +2023-02-08 Su_Laus + + test_ifd_loop_detection: fix Coverity Scan issue CID 1520750: Null pointer dereferences (NULL_RETURNS) line 55. + +2023-02-06 Even Rouault + + Merge branch 'tiffcrop_fix_CoverityScan_line_9676' into 'master' + Fix Coverity Scan issue CID 1520761: Integer handling issues... + + See merge request libtiff/libtiff!469 + +2023-02-06 Su_Laus + + Fix Coverity Scan issue CID 1520761: Integer handling issues (OVERFLOW_BEFORE_WIDEN) tiffcrop.c: 9676 in rotateImage() + +2023-02-05 Even Rouault + + Merge branch 'tiffcrop_R270_fix#492' into 'master' + tiffcrop: Amend rotateImage() not to toggle the input (main) image width and... + + Closes #519, #518, #499, #495, #494, #493 et #492 + + See merge request libtiff/libtiff!465 + +2023-02-05 Su_Laus + + tiffcrop: Amend rotateImage() not to toggle the input (main) image width and length parameters when only cropped image sections are rotated. Remove buffptr from region structure because never used. + Closes #492 #493 #494 #495 #499 #518 #519 + +2023-02-05 Even Rouault + + Merge branch 'tiffcrop_correctly_update_buffersize_after_rotate_fix#520' into 'master' + tiffcrop correctly update buffersize after rotateImage() fix#520 + + Closes #520 + + See merge request libtiff/libtiff!467 + +2023-02-05 Even Rouault + + Merge branch 'tiffcrop_composite_image_assumption_test_fix#496' into 'master' + tiffcrop: added check for assumption on composite images (fixes #496) + + Closes #501, #500, #498, #497 et #496 + + See merge request libtiff/libtiff!466 + +2023-02-05 Su Laus + + tiffcrop: added check for assumption on composite images (fixes #496) + tiffcrop: For composite images with more than one region, the combined_length or combined_width always needs to be equal, respectively. Otherwise, even the first section/region copy action might cause buffer overrun. This is now checked before the first copy action. + + Closes #496, #497, #498, #500, #501. + +2023-02-04 Su_Laus + + tiffcrop correctly update buffersize after rotateImage() fix#520 -- enlarge buffsize and check integer overflow within rotateImage(). + +2023-02-04 Even Rouault + + Merge branch 'test_subidf_loop' into 'master' + test_ifd_loop_detection: Added test to check loops in SubIFDs that are chained. + + See merge request libtiff/libtiff!464 + +2023-02-04 Su Laus + + test_ifd_loop_detection: Added test to check loops in SubIFDs that are chained. + +2023-02-04 Su_Laus + + Fix TIFFUnlinkDirectory(0) case and unlink of first directory. + If directory number 0 is unlinked, then the base offset variables within LibTiff are not updated. As a result, a subsequent TIFFSetDirectory() first goes to the unlinked former directory number 0. + + In addition, the error case for dirn=0 is handled. + + This MR fixes that by updating the base offset variables tif->tif_header.classic.tiff_diroff and tif->tif_header.big.tiff_diroff. + +2023-02-03 Even Rouault + + Merge branch 'TiffClose_NULL_ptr_dereferencing_fix_515' into 'master' + TIFFClose() avoid NULL pointer dereferencing. fix#515 + + Closes #515 + + See merge request libtiff/libtiff!468 + +2023-02-03 Su_Laus + + TIFFClose() avoid NULL pointer dereferencing. fix#515. + Closes #515 + + tiffcrop correctly update buffersize after rotateImage() fix#520 rotateImage() set up a new buffer and calculates its size individually. Therefore, seg_buffs[] size needs to be updated accordingly. Before this fix, the seg_buffs buffer size was calculated with a different formula than within rotateImage(). + Closes #520. + +2023-01-25 Even Rouault + + Merge branch 'add_windows_DLL_versioninfo' into 'master' + Add versioninfo resource files for DLL and tools compiled with Windows MSVC and MINGW. + + See merge request libtiff/libtiff!455 + +2023-01-25 Su Laus + + Add versioninfo resource files for DLL and tools compiled with Windows MSVC and MINGW. + +2023-01-22 Even Rouault + + Merge branch 'tif_hash_set_order_include' into 'master' + tif_hash_set.c: include tif_hash_set.h after tif_config.h to let a chance for... + + See merge request libtiff/libtiff!462 + +2023-01-22 Even Rouault + + tif_hash_set.c: include tif_hash_set.h after tif_config.h to let a chance for GDAL symbol renaming trick + +2023-01-22 Even Rouault + + Merge branch 'fix_513' into 'master' + Fax3: fix failure to decode some fax3 images (fixes #513) + + Closes #513 + + See merge request libtiff/libtiff!461 + +2023-01-21 Even Rouault + + Add test for Fax3 decoding issues (refs #513) + +2023-01-21 Even Rouault + + Merge branch 'tiffcrop_fix_#488' into 'master' + tiffcrop: Correct simple copy paste error. Fix #488. + + Closes #488 + + See merge request libtiff/libtiff!459 + +2023-01-21 Su Laus + + tiffcrop: Correct simple copy paste error. Fix #488. + +2023-01-21 Even Rouault + + Fax3: fix failure to decode some fax3 images (fixes #513) + Patch by @jsummers26 + +2023-01-12 Even Rouault + + Merge branch 'tiffmedian_fix_#477' into 'master' + tiffmedian: avoid zero num_colors, fixes #477 + + Closes #477 + + See merge request libtiff/libtiff!458 + +2023-01-12 Even Rouault + + Merge branch 'fax2ps_fixes_#475' into 'master' + fax2ps: fixes #475 buffer overflow in qsort function pcompar. + + Closes #475 + + See merge request libtiff/libtiff!457 + +2023-01-12 Su_Laus + + tiffmedian: avoid zero num_colors, fixes #477. + + fax2ps: fixes #475 buffer overflow in qsort function pcompar. + +2023-01-09 Even Rouault + + Merge branch 'fix_241_tiffset_file_size_limit' into 'master' + tiffset: get filesize to allocate only the required memory. Fixes issue #241 + + Closes #241 + + See merge request libtiff/libtiff!451 + +2023-01-09 Su Laus + + tiffset: get filesize to allocate only the required memory. Fixes issue #241 + +2023-01-09 Even Rouault + + Merge branch '_TIFFCleanupIFDOffsetAndNumberMaps' into 'master' + Add _TIFFCleanupIFDOffsetAndNumberMaps() and call it from TIFFUnlinkDirectory() + + See merge request libtiff/libtiff!454 + +2023-01-06 Even Rouault + + Remove use of tif_dirnumber. + + TIFFSetSubDirectory(): call _TIFFCleanupIFDOffsetAndNumberMaps() + + struct tiff: remove unused tif_dirlistoff. + + TIFFUnlinkDirectory(): reset tif_dirnumber. + + Add _TIFFCleanupIFDOffsetAndNumberMaps() and call it from TIFFUnlinkDirectory() + +2022-12-29 Even Rouault + + Merge branch 'cmake_in_files_formatting_sensitive' into 'master' + Disable clang-formatting for tif_config.h.cmake.in and tiffconf.h.cmake.in... + + See merge request libtiff/libtiff!452 + +2022-12-28 Su_Laus + + Disable clang-formatting for tif_config.h.cmake.in and tiffconf.h.cmake.in because sensitive for CMake scripts. - explanation added + +2022-12-26 Su_Laus + + Disable clang-formatting for tif_config.h.cmake.in and tiffconf.h.cmake.in because sensitive for CMake scripts. + +2022-12-19 Even Rouault + + Merge branch 'manpage_multi-page-TIFF' into 'master' + manpage: Add multi page TIFF and SubIFDs description and read / write example. + + See merge request libtiff/libtiff!450 + +2022-12-19 Su Laus + + manpage: Add multi page TIFF and SubIFDs description and read / write example. + +2022-12-18 Even Rouault + + Merge branch 'TIFFOpen_r+_windows_behaviour' into 'master' + Behavior of TIFFOpen() mode "r+" in the Windows implementation adjusted to that of Linux. + + See merge request libtiff/libtiff!449 + +2022-12-16 Su_Laus + + Behavior of TIFFOpen() mode "r+" in the Windows implementation adjusted to that of Linux. + +2022-12-15 Even Rouault + + Merge branch 'ossfuzz_54343' into 'master' + TIFFSetDirectory: avoid harmless unsigned-integer-overflow + + See merge request libtiff/libtiff!447 + +2022-12-15 Even Rouault + + TIFFSetDirectory: avoid harmless unsigned-integer-overflow. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54343 + +2022-12-14 Even Rouault + + Merge branch 'ossfuzz_54311' into 'master' + TIFFWriteDirectorySec(): avoid harmless unsigned-integer-overflow + + See merge request libtiff/libtiff!446 + +2022-12-14 Even Rouault + + TIFFWriteDirectorySec(): avoid harmless unsigned-integer-overflow. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54311 + +2022-12-14 Even Rouault + + libtiff v4.5.0rc2 preparation + +2022-12-14 Su_Laus + + tiffinfo: update curdir from uint16_t to tdir_t for more than 64k IFD handling. + +2022-12-13 Even Rouault + + Merge branch 'fix_502' into 'master' + Make TIFFSetDirectory(tiff, 65534) work again (fixes #502) + + Closes #502 + + See merge request libtiff/libtiff!436 + +2022-12-13 Even Rouault + + Add tests for IFD loop detection. + + Fix IFD loop detection. + + Use UINT_MAX. + + Make TIFF_MAX_DIR_COUNT a autoconf/CMake setting. + +2022-12-13 Even Rouault + + Merge branch 'build-shared-by-default' into 'master' + Restore shared libraries by default + + See merge request libtiff/libtiff!437 + +2022-12-13 shaun walbridge + + CMake: restore shared libraries by default for top-level build. + +2022-12-12 Even Rouault + + Add a TIFF_MAX_DIR_COUNT public #define. + + TIFFCurrentDirectory(), TIFFNumberOfDirectories(), TIFFSetDirectory(), TIFFUnlinkDirectory(): use tdir_t that is now a uint32_t, and raise limit of IFDs to 1048576 + + IFD loop checking: use hashmap to avoid quadratic performance. + + Add a hashset/hashmap implementation (ported from GDAL's CPLHashSet) + + Make TIFFSetDirectory(tiff, 65534) work again (fixes #502) + +2022-12-11 Even Rouault + + Merge branch 'do_not_format_tiffvers_h' into 'master' + Revert formatting of tiffvers.h and add TIFFLIB_MAJOR_VERSION, TIFFLIB_MINOR_VERSION, TIFFLIB_MICRO_VERSION defines + + See merge request libtiff/libtiff!434 + +2022-12-11 Even Rouault + + Merge branch 'tiffcrop_exclude_some_comment_from_clang-format' into 'master' + tiffcrop: Exclude some comments from clang-format + + See merge request libtiff/libtiff!435 + +2022-12-11 Su Laus + + tiffcrop: Exclude some comments from clang-format. + +2022-12-11 Even Rouault + + tiffvers.h.in: add clang-format off/on. + +2022-12-10 Even Rouault + + tiffvers.h: add TIFFLIB_MAJOR_VERSION, TIFFLIB_MINOR_VERSION, TIFFLIB_MICRO_VERSION defines + Also add a TIFFLIB_AT_LEAST() macro + + tiffvers.h: revert formatting. + + Exclude reformatting of tiffvers.h which breaks version detection for FindTIFF.cmake + +2022-12-09 Even Rouault + + Merge branch 'release_4_5_0' into 'master' + Prepare v4.5.0 release + + See merge request libtiff/libtiff!433 + +2022-12-09 Even Rouault + + libtiff v4.5.0rc1 preparation + +2022-12-08 Even Rouault + + Merge branch 'reformat' into 'master' + Whole code-base reformatting + + See merge request libtiff/libtiff!431 + +2022-12-08 Even Rouault + + Add .git-blame-ignore-revs. + + tiffcrop: remove version_id and rev_date. + +2022-12-08 pre-commit run by Even Rouault + + Reformatting in all other directories using 'pre-commit run' + + Reformatting in test/ using 'pre-commit run' + + Reformatting in tools/ using 'pre-commit run' + + Reformatting in libtiff/ using 'pre-commit run' + +2022-12-08 Even Rouault + + Add .clang-format, .pre-commit-config.yaml and CONTRIBUTING.md. + + Remove vim/emacs formatting footers. + +2022-11-29 Even Rouault + + Merge branch 'fix_489' into 'master' + TIFFWriteRawStrip(): restore capabilities to append data in the current strip (fixes #489) + + Closes #489 + + See merge request libtiff/libtiff!430 + +2022-11-29 Even Rouault + + Add test case for scenario of issue #489. + + TIFFWriteRawStrip(): restore capabilities to append data in the current strip (fixes #489) + This fixes a regression of libtiff 4.4.0 + +2022-11-29 Even Rouault + + Merge branch 'manpage_re-entrant_error_handler' into 'master' + manpage update for re-entrant error handler TIFFErrorExtR(), TIFFOpenExt() and... + + See merge request libtiff/libtiff!427 + +2022-11-29 Su Laus + + manpage update for re-entrant error handler TIFFErrorExtR(), TIFFOpenExt() and... + +2022-11-27 Even Rouault + + Merge branch 'tiffcrop_fix_#169' into 'master' + tiffcrop: Add check if (bps != 1) in writeSingleSection() for... + + Closes #169 + + See merge request libtiff/libtiff!429 + +2022-11-27 Su Laus + + tiffcrop: Add check if (bps != 1) in writeSingleSection() for... + +2022-11-26 Even Rouault + + Merge branch 'TIFFErrorExtR_fix_missing_calls' into 'master' + TIFFErrorExt() was not replaced with TIFFErrorExtR() everywhere in libtiff.... + + See merge request libtiff/libtiff!428 + +2022-11-26 Su Laus + + TIFFErrorExt() was not replaced with TIFFErrorExtR() everywhere in libtiff.... + +2022-11-25 Even Rouault + + Merge branch 'tif_jpeg_build_fix' into 'master' + tif_jpeg.c: fix compilation with MSVC (fixes commit 0fd1a81d3547acb8f5be50bbbc3e44bde01c014b) + + See merge request libtiff/libtiff!426 + +2022-11-25 Even Rouault + + tif_jpeg.c: fix compilation with MSVC (fixes commit 0fd1a81d3547acb8f5be50bbbc3e44bde01c014b) + +2022-11-25 Even Rouault + + Merge branch 'fix_0fd1a81d3547acb8f5be50bbbc3e44bde01c014b' into 'master' + JPEGEncode(): fix wrong pointer data type with libjpeg-turbo 2.2dev in 12-bit mode + + See merge request libtiff/libtiff!425 + +2022-11-25 Even Rouault + + JPEGEncode(): fix wrong pointer data type with libjpeg-turbo 2.2dev in 12-bit mode + (fixes commit 0fd1a81d3547acb8f5be50bbbc3e44bde01c014b) + +2022-11-25 Even Rouault + + Merge branch 'libjpegturbo_dual' into 'master' + Add support for libjpeg-turbo 2.2-dev 8/12 bit dual mode + + See merge request libtiff/libtiff!422 + +2022-11-25 Even Rouault + + Add support for libjpeg-turbo 2.2-dev 8/12 bit dual mode. + +2022-11-23 Even Rouault + + Merge branch 'windows-fix' into 'master' + libtiff: Fix TIFFOpen* for the Windows platform in tif_unix.c + + See merge request libtiff/libtiff!424 + +2022-11-23 Francois Bleibel + + libtiff: Fix TIFFOpen* for the Windows platform in tif_unix.c. + I'm not sure where this change was made, but it must have been in a recent update. TIFFOpenWEx is now TIFFOpenWExt, and _TIFFgetMode takes additional arguments. + + Verified: Tested libtiff on a local Windows build. + +2022-11-23 Even Rouault + + Merge branch 'tiffcrop_signed_vs_unsigned' into 'master' + tiffcrop.c: fix warning about signed vs unsigned comparison + + See merge request libtiff/libtiff!423 + +2022-11-23 Even Rouault + + tiffcrop.c: fix warning about signed vs unsigned comparison. + +2022-11-23 Even Rouault + + Merge branch 'TIFFClientOpenExt_warning_fix' into 'master' + TIFFClientOpenExt(): fix warning on 32-bit platforms (master only) + + See merge request libtiff/libtiff!421 + +2022-11-23 Even Rouault + + TIFFClientOpenExt(): fix warning on 32-bit platforms (master only) + +2022-11-23 Even Rouault + + Merge branch 'tiffcp_TIFFOpenOptionsFree_memleak_fix' into 'master' + tiffcp: fix leak of TIFFOpenOptionsAlloc() introduced in latest commit (master only) + + See merge request libtiff/libtiff!420 + +2022-11-23 Even Rouault + + tiffcp: fix leak of TIFFOpenOptionsAlloc() introduced in latest commit (master only) + Fixes Coverity CID 1517032 + +2022-11-23 Even Rouault + + Merge branch 'TIFFOpenOptionsSetMaxSingleMemAlloc' into 'master' + Add TIFFOpenOptionsSetMaxSingleMemAlloc() to define a limit in bytes for a single memory allocation done by libtiff + + See merge request libtiff/libtiff!419 + +2022-11-23 Even Rouault + + Emit explicit error message when tif_max_single_mem_alloc is exceeded. + + test_open_options: test TIFFOpenOptionsSetMaxSingleMemAlloc() + + Rename test_error_handlers to test_open_options. + + tiffinfo, tiffcp, tiffcrop, tiffsplit, tiff2rgba, tiff2ps: use TIFFOpenOptionsSetMaxSingleMemAlloc() + + Convert uses of _TIFFmalloc/realloc/calloc/free to the Ext functions. + +2022-11-22 Even Rouault + + Add TIFFOpenOptionsSetMaxSingleMemAlloc() + to define a limit in bytes for a single memory allocation done by libtiff. + + Also add internal functions used in replacement of the non Ext ones: + void* _TIFFmallocExt(TIFF* tif, tmsize_t s); + void* _TIFFcallocExt(TIFF* tif, tmsize_t nmemb, tmsize_t siz); + void* _TIFFreallocExt(TIFF* tif, void* p, tmsize_t s); + void _TIFFfreeExt(TIFF* tif, void* p); + +2022-11-22 Even Rouault + + Merge branch 'TIFFOpenEx' into 'master' + Add TIFFOpenExt(), TIFFOpenWExt() and TIFFFdOpenExt() with re-entrant error handlers + + See merge request libtiff/libtiff!413 + +2022-11-21 Even Rouault + + Remove TIFFSetErrorHandlerExtR() and TIFFSetWarningHandlerExtR() that were temporarily added in master + + Add a _TIFFErrorEarly() function to be able to use the re-entrant error handler, even before TIFF* is valid + + Rework TIFFOpenExt() and similar to use an opaque TIFFOpenOptions* opts argument, with alloc, free and setters + + Document TIFFOpenExt, TIFFOpenWExt, TIFFFdOpenExt, TIFFClientOpenExt, TIFFSetErrorHandlerExtR, TIFFSetWarningHandlerExtR + +2022-11-21 Even Rouault + + Add TIFFOpenExt(), TIFFOpenWExt() and TIFFFdOpenExt() with re-entrant error handlers + Rename TIFFClientOpenEx() to TIFFClientOpenExt() + + Rework signature of the re-entrant error handlers and of + TIFFSetWarningHandlerExt() and TIFFSetErrorHandlerExt() + + Use structures that can be extended as extra argument. + + Leverages and ammends https://gitlab.com/libtiff/libtiff/-/merge_requests/409 + +2022-11-21 Even Rouault + + Merge branch 'manpage_fix485_file-descriptor_clientdata' into 'master' + manpage: Correct description of file handle/descriptors tif_fd and tif_clientdata. Closes #485. + + Closes #485 + + See merge request libtiff/libtiff!418 + +2022-11-21 Su Laus + + manpage: Correct description of file handle/descriptors tif_fd and tif_clientdata. Closes #485. + +2022-11-20 Even Rouault + + Merge branch 'manpage_fix440_fix28_TIFFOpen_SubIFD_update' into 'master' + manpage: fix28, fix440, update TIFFOpen and SubIFD + + Closes #440 et #28 + + See merge request libtiff/libtiff!417 + +2022-11-20 Su Laus + + manpage: fix28, fix440, update TIFFOpen and SubIFD. + +2022-11-17 Even Rouault + + Merge branch 'cmake_tiff_install_warning' into 'master' + CMakeLists.txt: fix warning with -Wdev + + See merge request libtiff/libtiff!416 + +2022-11-13 Even Rouault + + CMakeLists.txt: fix warning with -Wdev. + ``` + CMake Warning (dev) at CMakeLists.txt:62 (option): + Policy CMP0077 is not set: option() honors normal variables. Run "cmake + --help-policy CMP0077" for policy details. Use the cmake_policy command to + set the policy and suppress this warning. + + For compatibility with older versions of CMake, option is clearing the + normal variable 'tiff-install'. + This warning is for project developers. Use -Wno-dev to suppress it. + ``` + +2022-11-12 Even Rouault + + Merge branch 'fix_479' into 'master' + _TIFFReadEncodedTileAndAllocBuffer(): avoid excessive memory allocation on... + + See merge request libtiff/libtiff!412 + +2022-11-12 Even Rouault + + Merge branch 'typo_fix' into 'master' + tif_dirread.c: fix typo in comment + + See merge request libtiff/libtiff!414 + +2022-11-12 Even Rouault + + tif_dirread.c: fix typo in comment. + +2022-11-11 Even Rouault + + _TIFFReadEncodedTileAndAllocBuffer(): avoid excessive memory allocation on broken files (fixes #479) + +2022-11-10 Even Rouault + + Merge branch 'bugfix/tiff2pdf-stdout' into 'master' + tiff2pdf Don't try to seek into stdout. + + See merge request libtiff/libtiff!367 + +2022-11-10 Claus-Justus Heine + + tiff2pdf: Don't try to seek into stdout. + Fixes #441 + +2022-11-08 Even Rouault + + Merge branch 'fix_coverity_1516759' into 'master' + TIFFErrorExtR(): fix Dereference after null check (CID 1516759) + + See merge request libtiff/libtiff!411 + +2022-11-08 Even Rouault + + Merge branch 'fix_ossfuzz_53137' into 'master' + TIFFReadRGBATileExt(): fix (unsigned) integer overflow on strips/tiles > 2 GB + + See merge request libtiff/libtiff!410 + +2022-11-08 Even Rouault + + TIFFErrorExtR(): fix Dereference after null check (CID 1516759) + +2022-11-08 Even Rouault + + Merge branch 'no_sprintf' into 'master' + Replace sprintf calls with snprintf + + See merge request libtiff/libtiff!408 + +2022-11-08 Mark Mentovai + + Replace sprintf calls with snprintf. + This makes it possible to build libtiff without warnings using the macOS + 13 SDK. Calls to sprintf are replaced with snprintf, passing appropriate + buffer sizes. + + It doesn’t appear that any of the changed uses of sprintf were actually + unsafe, so no behavior change is expected aside from SDK compatibility. + + The macOS 13 SDK deprecates sprintf as it’s difficult to use safely. The + deprecation warning message is visible when building C++, but it is not + normally visible when building plain C code due to a quirk in how + sprintf is declared in the SDK. However, the deprecation message is + visible when building plain C under Address Sanitizer + (-fsanitize=address). This discrepancy was discovered at + https://crbug.com/1381706 and reported to Apple with a copy at + https://openradar.appspot.com/FB11761475. + + The macOS 13 SDK is packaged in Xcode 14.1, released on 2022-11-01. This + also affects the iOS 16 SDK and other 2022-era Apple OS SDKs packaged in + Xcode 14.0, released on 2022-09-12. + + libtiff is visible to the Chromium build via PDFium, and this change is + needed to allow Chromium to move forward to the macOS 13 SDK. + + This change is limited to the libtiff directory. Other uses of sprintf + were found in contrib, test, and tools. + +2022-11-08 Even Rouault + + Merge branch 'reentrant' into 'master' + Add reentrant error functions + + See merge request libtiff/libtiff!409 + +2022-11-08 Even Rouault + + TIFFReadRGBATileExt(): fix (unsigned) integer overflow on strips/tiles > 2 GB + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53137 + +2022-11-08 Laramie Leavitt + + Add reentrant error functions. + Prior to this change, libtiff relied on global error handlers, + which is problematic when libtiff used by multiple independent + libraries from within the same process, as they may unwittingly + clobber the error handling, introduce race conditions when setting + handlers, or otherwise have unintended side effects. + + This change adds error handlers to the TIFF struct, which are + used preferentially when available. The error handlers are invoked + when the re-entrant error functions are called: + + void TIFFErrorExtR(TIFF*, const char* module, const char* fmt, ...) + void TIFFWarningExtR(TIFF*, const char* module, const char* fmt, ...) + + The handlers have a similar signature to the existing extended + handlers, additionally returning an int: + + int TIFFErrorHandlerExtR(thandle_t, const char*, const char*, va_list) + + thandle_t is the userdata passed to TIFFOpen + When the handler returns 1, the global handlers are not called. + + Custom error/warning handlers may be installed on a per-file + basis by calling the Set functions: + + TIFF* tif = TIFFOpen(...); + TIFFSetErrorHandlerExtR(tif, MyErrorHandler); + TIFFSetWarningHandlerExtR(tif, MyWarningHandler); + + Additionally, the callsites to TIFFErrorExt and TIFFWarningExt + have been updated to call the reentrant versions. + +2022-11-08 Even Rouault + + Merge branch 'tiffcrop_fix_CoverityScan_tmsize_issue' into 'master' + tiffcrop: should fix some Coverity Scan issues OVERFLOW_BEFORE_WIDEN + + See merge request libtiff/libtiff!403 + +2022-11-08 Su Laus + + tiffcrop: should fix some Coverity Scan issues OVERFLOW_BEFORE_WIDEN. + +2022-11-02 Even Rouault + + Merge branch 'typo_fix' into 'master' + tif_dirread.c: fix typo in comment + + See merge request libtiff/libtiff!407 + +2022-11-02 Even Rouault + + tif_dirread.c: fix typo in comment. + +2022-10-23 Even Rouault + + Merge branch 'tiffcrop_formatting_fix' into 'master' + tiffcrop: add casts in TIFFError() to fix compiler warnings + + See merge request libtiff/libtiff!406 + +2022-10-23 Even Rouault + + Merge branch 'fix_482' into 'master' + CMake: correctly set default value of 'lzma' option when liblzma is detected (fixes #482) + + Closes #482 + + See merge request libtiff/libtiff!404 + +2022-10-23 Even Rouault + + tiffcrop: add casts in TIFFError() to fix compiler warnings. + + CMake: correctly set default value of 'lzma' option when liblzma is detected (fixes #482) + +2022-10-20 Even Rouault + + Merge branch 'fix_480' into 'master' + Fix incorrect printf() formatters introduced in recent commits (fixes #480) + + Closes #480 + + See merge request libtiff/libtiff!401 + +2022-10-19 Even Rouault + + Fix incorrect printf() formatters introduced in recent commits (fixes #480) + +2022-10-13 Even Rouault + + Merge branch 'CLIPPATH_tags_corrected' into 'master' + CLIPPATH tags defined twice but differently and also wrongly (#439) - corrected + + Closes #439 + + See merge request libtiff/libtiff!366 + +2022-10-13 Even Rouault + + Merge branch 'FIELD_IGNORE_warning-messages' into 'master' + Warning messages for FIELD_IGNORE tags for writing and for TIFF_SETGET_UNDEFINED for reading added. (#438) + + Closes #438 + + See merge request libtiff/libtiff!365 + +2022-10-13 Su Laus + + Warning messages for FIELD_IGNORE tags for writing and for TIFF_SETGET_UNDEFINED for reading added. (#438) + +2022-10-13 Even Rouault + + Merge branch 'tag-def_COMPRESSION_corrected' into 'master' + tif_dirinfo.c TIFFTAG_COMPRESSION and _BITSPERSAMPLE definition corrected + + See merge request libtiff/libtiff!364 + +2022-10-13 Even Rouault + + Merge branch 'fix_getopt_included_twice' into 'master' + Fix including module getopt.c twice with CMake and HAVE_GETOPT=false + + See merge request libtiff/libtiff!381 + +2022-10-13 Even Rouault + + Merge branch 'tiffcrop_CoverityScan_fix_PRINTF_ARGS' into 'master' + tiffcrop: fix Coverity Scan issues about PRINTF_ARGS. + + See merge request libtiff/libtiff!400 + +2022-10-13 Su_Laus + + tiffcrop fix Coverity Scan issues about PRINTF_ARGS. + +2022-10-13 Even Rouault + + Merge branch 'tiffcrop_fix_#450_too-many-mode-options' into 'master' + tiffcrop: fix #450 too many 'mode' options on command line. + + Closes #470 et #450 + + See merge request libtiff/libtiff!384 + +2022-10-13 Su Laus + + tiffcrop: fix #450 too many 'mode' options on command line. + +2022-10-13 Even Rouault + + Merge branch 'tiffcrop_fix_#435' into 'master' + tiffcrop subroutines require a larger buffer (fixes #271, #381, #386, #388, #389, #435) + + Closes #465, #464, #435, #389, #388, #386, #381 et #271 + + See merge request libtiff/libtiff!382 + +2022-10-13 Su Laus + + tiffcrop subroutines require a larger buffer (fixes #271, #381, #386, #388, #389, #435) + +2022-10-12 Even Rouault + + Merge branch 'InkNames_NumberOfInks_handling_revised' into 'master' + Revised handling of TIFFTAG_INKNAMES and related TIFFTAG_NUMBEROFINKS value (fixes #149, #150, #152, #168, #250, #269, #398 and #456) + + Closes #474, #463, #387, #456, #398, #269, #250, #168, #152, #150 et #149 + + See merge request libtiff/libtiff!385 + +2022-10-12 Even Rouault + + Merge branch 'tiffcrop_fix_#411_#413' into 'master' + tiffcrop: disable incompatibility of -Z, -X, -Y, -z options with any PAGE_MODE_x option (fixes #411, #413 and #426) + + Closes #426, #413 et #411 + + See merge request libtiff/libtiff!383 + +2022-10-10 Even Rouault + + Merge branch 'TIFFAdvanceDirectory_mapped_uio' into 'master' + TIFFAdvanceDirectory(): fix unsigned-integer-overflow in mapped case + + See merge request libtiff/libtiff!398 + +2022-10-10 Even Rouault + + TIFFAdvanceDirectory(): fix unsigned-integer-overflow in mapped case. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52309 + +2022-10-08 Even Rouault + + Merge branch 'tiffinfo_parse_SubIFDs' into 'master' + tiffinfo: Updated to parse through SubIFDs and show their tags. + + See merge request libtiff/libtiff!396 + +2022-10-08 Su Laus + + tiffinfo: Updated to parse through SubIFDs and show their tags. + +2022-10-07 Roger Leigh + + Merge branch 'master' into 'master' + Moved linking of CMath::CMath into CMath_LIBRARY check + + See merge request libtiff/libtiff!397 + +2022-10-07 Frei Herr + + Moved linking of CMath::CMath into CMath_LIBRARY check. + +2022-10-06 Even Rouault + + Merge branch 'rational_precision2double_coverity-fix' into 'master' + rational_precision2double.c: Fix issue from Coverity Scan. + + See merge request libtiff/libtiff!395 + +2022-10-06 Su_Laus + + rational_precision2double.c: Fix issue from Coverity Scan. + + Fix including module getopt.c twice with CMake and HAVE_GETOPT=false. + The "make-files" for the tools- and test- programmes include the module getopt.c once directly as additional source and then again by including port.lib. + This can be avoided by including getopt.c as source in port.lib within port\CMakeLists.txt not with PUBLIC but with PRIVATE. + +2022-10-06 Even Rouault + + Merge branch 'fix-455_Improved-IFD-loop-handling' into 'master' + Improved IFD-Loop Handling (fixes #455) + + Closes #455 + + See merge request libtiff/libtiff!386 + +2022-10-06 Su Laus + + Improved IFD-Loop Handling (fixes #455) + IFD infinite looping was not fixed by MR 20 (see #455). + An improved IFD loop handling is proposed. + + Basic approach: + + - The order in the entire chain must be checked, and not only whether an offset has already been read once. + - To do this, pairs of directory number and offset are stored and checked. + - The offset of a directory number can change. + - TIFFAdvanceDirectory() must also perform an IFD loop check. + - TIFFCheckDirOffset() is replaced by _TIFFCheckDirNumberAndOffset(). + + Rules for the check: + + - If an offset is already in the list, it must have the same IFD number. Otherwise it is an IDF loop. + - If the offset is not in the list and the IFD number is greater than there are list entries, a new list entry is added. + - Otherwise, the offset of the IFD number is updated. + + Reference is also made to old bugzilla bug 2772 and MR 20, which did not solve the general issue. + This MR closes #455 + +2022-10-05 Roger Leigh + + Merge branch 'fix-cmake-subproject' into 'master' + Fix CMake build to be compatible with FetchContent + + See merge request libtiff/libtiff!394 + +2022-10-04 Timothy Lyanguzov + + Apply 9 suggestion(s) to 3 file(s) + +2022-10-04 Jeremy Maitin-Shepard + + Fix CMake build to be compatible with FetchContent. + Recent versions of CMake have improved support for including + dependencies, using the FetchContent module, which allows a dependency + to be imported as a subproject and then later found automatically by + calls to `find_package`. + + This change makes libtiff's CMake better behaved when used as a + sub-project: + + - CMake has a single global namespace for all target names in all + sub-projects. This commit renames the following CMake targets: + + - port -> tiff_port + - mkg3states -> tiff_mkg3states + - faxtable -> tiff_faxtable + - release -> tiff_release + + - When building TIFF as a sub-project, it is not normally useful to + create install rules for its targets. This commit adds a + `tiff-install` option that controls whether the install rules are + added and defaults to OFF when libtiff is included as a sub-project. + + - Previously, libtiff set `BUILD_SHARED_LIBS` to ON by default. With + this commit, that default is only set if libtiff is the top-level + project. + + - When using `find_package(TIFF)`, the targets `TIFF::TIFF` and + `TIFF::CXX` are defined. This commit makes libtiff itself define + those targets as aliases, to allow other cmake projects to use + either `find_package` or `FetchContent` interchangeably. + + - Adds ZSTD_HAVE_DECOMPRESS_STREAM variable which may be set to bypass + `check_symbol_exists` call. Fixes + https://gitlab.com/libtiff/libtiff/-/issues/472. + +2022-09-27 Even Rouault + + Merge branch 'getimage_overflow' into 'master' + Update getimage to support reading large raster images + + See merge request libtiff/libtiff!389 + +2022-09-26 Even Rouault + + Merge branch 'MinGW-warnings_ipctutil' into 'master' + Fix #458: MinGW Windows 64: warning because 'long' is a 32 bits type in... + + Closes #458 + + See merge request libtiff/libtiff!391 + +2022-09-26 Su Laus + + Fix #458: MinGW Windows 64: warning because 'long' is a 32 bits type in... + +2022-09-16 Eric Siegel + + Update getimage to support large raster images. + +2022-09-08 Even Rouault + + Merge branch 'typo_fix' into 'master' + tif_lzw.c: fix typo in code comment + + See merge request libtiff/libtiff!387 + +2022-09-08 Even Rouault + + tif_lzw.c: fix typo in code comment. + +2022-08-30 Su_Laus + + Revised handling of TIFFTAG_INKNAMES and related TIFFTAG_NUMBEROFINKS value + In order to solve the buffer overflow issues related to TIFFTAG_INKNAMES and related TIFFTAG_NUMBEROFINKS value, a revised handling of those tags within LibTiff is proposed: + + Behaviour for writing: + `NumberOfInks` MUST fit to the number of inks in the `InkNames` string. + `NumberOfInks` is automatically set when `InkNames` is set. + If `NumberOfInks` is different to the number of inks within `InkNames` string, that will be corrected and a warning is issued. + If `NumberOfInks` is not equal to samplesperpixel only a warning will be issued. + + Behaviour for reading: + When reading `InkNames` from a TIFF file, the `NumberOfInks` will be set automatically to the number of inks in `InkNames` string. + If `NumberOfInks` is different to the number of inks within `InkNames` string, that will be corrected and a warning is issued. + If `NumberOfInks` is not equal to samplesperpixel only a warning will be issued. + + This allows the safe use of the NumberOfInks value to read out the InkNames without buffer overflow + + This MR will close the following issues: #149, #150, #152, #168 (to be checked), #250, #269, #398 and #456. + + It also fixes the old bug at http://bugzilla.maptools.org/show_bug.cgi?id=2599, for which the limitation of `NumberOfInks = SPP` was introduced, which is in my opinion not necessary and does not solve the general issue. + +2022-08-25 Su_Laus + + tiffcrop: disable incompatibility of -Z, -X, -Y, -z options with any PAGE_MODE_x option (fixes #411 and #413) + tiffcrop does not support –Z, -z, -X and –Y options together with any other PAGE_MODE_x options like -H, -V, -P, -J, -K or –S. + + Code analysis: + + With the options –Z, -z, the crop.selections are set to a value > 0. Within main(), this triggers the call of processCropSelections(), which copies the sections from the read_buff into seg_buffs[]. + In the following code in main(), the only supported step, where that seg_buffs are further handled are within an if-clause with if (page.mode == PAGE_MODE_NONE) . + + Execution of the else-clause often leads to buffer-overflows. + + Therefore, the above option combination is not supported and will be disabled to prevent those buffer-overflows. + + The MR solves issues #411 and #413. + +2022-08-21 Even Rouault + + Merge branch 'tiffcrop_S-option_mutually_exclusive' into 'master' + tiffcrop: -S option mutually exclusive (fixes #349, #414, #422, #423, #424) + + Closes #424, #423, #422, #414 et #349 + + See merge request libtiff/libtiff!378 + +2022-08-20 Su_Laus + + tiffcrop -S option: Make decision simpler. + +2022-08-20 Even Rouault + + Merge branch 'remove_death_commented_code' into 'master' + Remove dead code from tif_dirread.c, tif_dirwrite.c and tif_getimage.c + + See merge request libtiff/libtiff!380 + +2022-08-20 Su Laus + + Remove dead code from tif_dirread.c, tif_dirwrite.c and tif_getimage.c. + +2022-08-16 Even Rouault + + Merge branch 'coverity_fixes' into 'master' + Silence Coverity Scan false positive warnings about out-of-bounds access + + See merge request libtiff/libtiff!379 + +2022-08-16 Even Rouault + + tif_zip.c: silence Coverity Scan false positive warnings about out-of-bounds access (CID 1491190, 1491197, 1491201) + + tif_dirread.c: silence Coverity Scan false positive warnings about out-of-bounds access (CID 1491182, 1491186) + +2022-08-16 Even Rouault + + Merge branch 'default_tag_values_extended' into 'master' + Presetting of default tag values extended (e.g. PlanarConfig). (fixes #449) + + Closes #449 + + See merge request libtiff/libtiff!377 + +2022-08-16 Su Laus + + Presetting of default tag values extended (e.g. PlanarConfig). (fixes #449) + +2022-08-15 Su_Laus + + According to Richard Nolde https://gitlab.com/libtiff/libtiff/-/issues/401#note_877637400 the tiffcrop option „-S“ is also mutually exclusive to the other crop options (-X|-Y), -Z and -z. + This is now checked and ends tiffcrop if those arguments are not mutually exclusive. + + This MR will fix the following tiffcrop issues: #349, #414, #422, #423, #424 + +2022-08-09 Even Rouault + + Merge branch 'warning_fix' into 'master' + Fix warning about shadowing + + See merge request libtiff/libtiff!376 + +2022-08-09 Even Rouault + + Fix warning about shadowing. + +2022-08-09 Even Rouault + + Merge branch 'fix_225' into 'master' + Deal with RichTIFFIPTC tag written with LONG type (fixes #225) + + Closes #225 + + See merge request libtiff/libtiff!374 + +2022-08-09 Even Rouault + + Merge branch 'Writing_IFD8_to_ClassicTIFF_bugfix' into 'master' + Correcting defects reported by Coverity Scan for MR !369 + + See merge request libtiff/libtiff!375 + +2022-08-09 Su Laus + + Correcting defects reported by Coverity Scan for MR !369. + +2022-08-09 Even Rouault + + Merge branch 'fix_442_Writing_IFD8_to_ClassicTIFF' into 'master' + TIFFSetValue(): Writing IFD8 & LONG8 tags to ClassicTIFF corrected (fixes #442) + + Closes #442 + + See merge request libtiff/libtiff!369 + +2022-08-09 Su Laus + + TIFFSetValue(): Writing IFD8 & LONG8 tags to ClassicTIFF corrected (fixes #442) + +2022-08-09 Even Rouault + + Deal with RichTIFFIPTC tag written with LONG type (fixes #225) + +2022-08-07 Roger Leigh + + Merge branch 'manpage-functions-added' into 'master' + doc: Missing public functions added to TIFF documentation in Sphinx + + See merge request libtiff/libtiff!372 + +2022-08-07 Su Laus + + doc: Missing public functions added to TIFF documentation in Sphinx. + +2022-07-29 Even Rouault + + Merge branch 'tifjpeg_version_check' into 'master' + tif_jpeg.c: allow to pass -DEXPECTED_JPEG_LIB_VERSION=number to do optional... + + See merge request libtiff/libtiff!373 + +2022-07-29 Even Rouault + + tif_jpeg.c: allow to pass -DEXPECTED_JPEG_LIB_VERSION=number to do optional compile-time version check + +2022-07-21 Even Rouault + + Merge branch 'TIFFReadFromUserBuffer_fix' into 'master' + TIFFReadFromUserBuffer(): fix clearing of TIFF_CODERSETUP flag that could... + + See merge request libtiff/libtiff!371 + +2022-07-21 Even Rouault + + TIFFReadFromUserBuffer(): fix clearing of TIFF_CODERSETUP flag that could cause issues with reading JPEG compressed files + +2022-07-21 Roger Leigh + + Merge branch 'vs2022-fixes' into 'master' + cmake: Correct duplicate definition of _CRT_SECURE_NO_WARNINGS + + Closes #443 + + See merge request libtiff/libtiff!370 + +2022-07-13 Roger Leigh + + cmake: Correct duplicate definition of _CRT_SECURE_NO_WARNINGS. + +2022-07-13 Even Rouault + + Merge branch 'vs2022-fixes' into 'master' + cmake: Fixes for Visual Studio 2022 + + See merge request libtiff/libtiff!368 + +2022-07-13 Roger Leigh + + cmake: Fixes for Visual Studio 2022. + +2022-07-03 Roger Leigh + + Merge branch 'elf-symbol-export' into 'master' + Explicit export of versioned ELF symbols + + Closes #437 + + See merge request libtiff/libtiff!361 + +2022-07-03 Even Rouault + + Merge branch 'fix_433' into 'master' + _TIFFCheckFieldIsValidForCodec(): return FALSE when passed a codec-specific... + + Closes #433 + + See merge request libtiff/libtiff!363 + +2022-07-01 Su_Laus + + CLIPPATH tags defined twice but differently and also wrongly. + In tif_dirinfo.c the tags for clippath are wrongly defined and the tag TIFFTAG_XCLIPPATHUNITS is even different twice. Therefore, those tags cannot be written / read correctly and may even lead to buffer overflow. + E.g.: In the case of TIFFSetField(YCLIPPATHUNITS), a 1 byte storage space is allocated because of TIFF_SETGET_UNDEFINED, in which an int32_t value should be stored because of TIFF_SLONG type definition. Then, an int32_t value is read from that 1 byte storage location. + + The current definition is: + + { TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL }, + { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, + { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, + { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL }, + + Whereas the correct definition according to TIFF Specification Supplement 1 (https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf) should be: + + { TIFFTAG_CLIPPATH, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL }, + { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, + { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL }, + + Also the set_get_field of the following tag should be corrected from + + { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL }, + to + { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL }, + + However, if those tags schould not be handled by LibTiff because they are deamed as abandoned or unwanted tags, those tags need to be defined with FIELD_IGNORE instead of FIELD_CUSTOM and keeping set_field_type = TIFF_SETGET_UNDEFINED + +2022-07-01 Su_Laus + + In tif_dirinfo.c the definition for TIFFTAG_COMPRESSION has different settings of field_readcount=TIFF_VARIABLE (-1) and field_writecount=1. The tag is defined with Count=1, thus field_readcount is wrong and should also be 1. Although TIFFTAG_BITSPERSAMPLE is defined with Count:N=SamplesPerPixel, only ONE uint16_t value is passed with TIFFSetField() and TIFFGetField(). However, an array with N=SamplesPerPixel equal values is written into the TIFF file. Shouldn't field_readcount = field_writecount = 1 then? The behaviour of TiffLib does not change, because the handling is coded directly. + +2022-06-27 Even Rouault + + _TIFFCheckFieldIsValidForCodec(): return FALSE when passed a codec-specific tag and the codec is not configured (fixes #433) + This avoids crashes when querying such tags + +2022-06-27 Even Rouault + + Merge branch '16bit_cielab' into 'master' + add basic 16bit-cielab support + + See merge request libtiff/libtiff!336 + +2022-06-27 Caolán McNamara + + Add basic 16bit-cielab support. + just a copy of putcontig8bitCIELab that reads 16bit vals but divide l by + 257, a and b by 256 before passing to TIFFCIELabToXYZ + + motivation: https://bugs.documentfoundation.org/show_bug.cgi?id=131199 + the "clavijo16bitlab.tiff" example where tiffinfo says: + ``` + Image Width: 2601 Image Length: 3503 + Resolution: 96, 96 pixels/inch + Bits/Sample: 16 + Compression Scheme: AdobeDeflate + Photometric Interpretation: CIE L*a*b* + Orientation: row 0 top, col 0 lhs + Samples/Pixel: 3 + Rows/Strip: 1 + Planar Configuration: single image plane + DateTime: 2020:03:07 10:20:42 + ``` + +2022-06-24 Roger Leigh + + Merge branch 'manpage-fixes' into 'master' + Sphinx documentation fixes + + See merge request libtiff/libtiff!362 + +2022-06-24 Roger Leigh + + doc: Correct types and cross-references. + + doc: Correct manual page path. + + build: Make rational2double static only for automake. + This copies the same logic as used by CMake. + + build: Update autoconf version to 4.5.0 and soname to 6.0.0. + + build: Update autoconf ld-version-script default. + + libtiff: Correct version script for changes since v4.4.0. + + libtiff: Update version script documentation. + + libtiff: Add symbol versioning of all exported symbols. + +2022-06-24 Even Rouault + + Merge branch 'webp_mem_improvements' into 'master' + WEBP codec: avoid temporary buffer and memcpy() on whole tile/strip decoding + + See merge request libtiff/libtiff!360 + +2022-06-24 Roger Leigh + + build: Enable symbol versioning by default. + +2022-06-24 Roger Leigh + + Merge branch 'sphinx-manpages' into 'master' + doc: Add Sphinx conversion of all manpages + + Closes #361 + + See merge request libtiff/libtiff!356 + +2022-06-24 Roger Leigh + + Merge branch 'remove-wince' into 'master' + Remove obsolete WinCE source file + + See merge request libtiff/libtiff!357 + +2022-06-23 Even Rouault + + WEBP codec: avoid temporary buffer and memcpy() on whole tile/strip decoding + +2022-06-22 Even Rouault + + Merge branch 'horAcc8_fix' into 'master' + tif_predict.c: make horAcc8() work with icc (ICC) 2021.6.0 20220226 -O2 + + See merge request libtiff/libtiff!359 + +2022-06-22 Even Rouault + + tif_predict.c: make horAcc8() work with icc (ICC) 2021.6.0 20220226 -O2. + For a reason I don't understand, recent ICC generates wrong code in -O2 + mode for the stride = 3 and 4 cases. The modified code is more + straightfoward, so go for it. + +2022-06-19 Roger Leigh + + Merge branch 'ci-restore-old' into 'master' + ci: Restore testing with Ubuntu 20.04 + + See merge request libtiff/libtiff!358 + +2022-06-19 Roger Leigh + + ci: Restore testing with Ubuntu 20.04. + + Remove obsolete WinCE source file. + + doc: Add missing punctuation. + + doc: Remove semicolon from c:function definition. + + doc: Remove remaining HTML entities. + + doc: Improve the build page. + +2022-06-18 Roger Leigh + + doc: Add Sphinx conversion of all manpages. + +2022-06-18 Roger Leigh + + Merge branch 'dist-html' into 'master' + build: Distribute and install HTML documentation + + See merge request libtiff/libtiff!352 + +2022-06-13 Even Rouault + + Merge branch 'pkgconfig' into 'master' + Adding Requires.private generation + + See merge request libtiff/libtiff!355 + +2022-06-13 Yishen Miao + + Adding Requires.private generation. + Adds Requires.private generation so that pkg-config can correctly find + the dependencies of libtiff. + +2022-06-11 Roger Leigh + + Merge branch 'ci-dist' into 'master' + ci: Archive distribution tar and zip files + + See merge request libtiff/libtiff!354 + +2022-06-11 Roger Leigh + + ci: Archive distribution tar and zip files. + +2022-06-11 Even Rouault + + Merge branch 'export_TIFFClampDoubleToUInt32' into 'master' + libtiff.def: export _TIFFClampDoubleToUInt32 + + See merge request libtiff/libtiff!353 + +2022-06-11 Even Rouault + + libtiff.def: export _TIFFClampDoubleToUInt32. + +2022-06-11 Even Rouault + + Merge branch 'issue-415+427+428' into 'master' + fix the FPE in tiffcrop (#415, #427, and #428) + + Closes #428, #427 et #415 + + See merge request libtiff/libtiff!346 + +2022-06-11 4ugustus + + fix the FPE in tiffcrop (#415, #427, and #428) + +2022-06-11 Roger Leigh + + build: Distribute and install HTML documentation. + +2022-06-10 Even Rouault + + Merge branch 'tif_jpeg_warning_fix' into 'master' + tif_jpeg.c: fix error message + + See merge request libtiff/libtiff!351 + +2022-06-10 Even Rouault + + tif_jpeg.c: fix error message. + +2022-06-10 Roger Leigh + + Merge branch 'android_libm' into 'master' + Fix dependency on libm on Android + + See merge request libtiff/libtiff!350 + +2022-06-09 Matthias Kuhn + + Always link to libm if available. + +2022-06-05 Roger Leigh + + Merge branch 'vasyl5-master-patch-97651' into 'master' + libtoolize: command not found on macOS. + + See merge request libtiff/libtiff!289 + +2022-06-05 Roger Leigh + + Merge branch 'rst-docs' into 'master' + Convert HTML documentation to Sphinx RST + + See merge request libtiff/libtiff!349 + +2022-06-05 Roger Leigh + + Merge remote-tracking branch 'origin/master' into rst-docs. + +2022-06-05 Roger Leigh + + Merge branch 'cmake-xc-faxtable' into 'master' + cmake: Do not build faxtable target when cross-compiling + + See merge request libtiff/libtiff!342 + +2022-06-05 Roger Leigh + + Merge branch 'cmake-disable-options' into 'master' + Add options for disabling tools, tests, contrib and docs + + See merge request libtiff/libtiff!343 + +2022-06-05 Roger Leigh + + Merge branch 'cmake-msvc-options' into 'master' + cmake: Add MSVC options when building all libraries and executables + + See merge request libtiff/libtiff!344 + +2022-06-05 Roger Leigh + + Merge branch 'cmake-win32-libtiffxx-static' into 'master' + cmake: libtiffxx is static on win32 + + See merge request libtiff/libtiff!338 + +2022-06-05 Roger Leigh + + Merge branch 'licence-file' into 'master' + Rename COPYRIGHT to LICENSE.md + + See merge request libtiff/libtiff!345 + +2022-06-05 Roger Leigh + + Rename COPYRIGHT to LICENSE.md. + + doc: Fix make distcheck. + + doc: Update automake configuration. + + doc: Do not pass srcdir and builddir to sphinx-build. + + doc: Additional top-level tidying. + + doc: Tidy top-level index. + + doc: Move bugs to project. + + doc: Move misc to project. + + doc: Move all BigTIFF documentation into specification directory. + * Remove the BigTIFF proposal since this has long been completed + * Update the BigTIFF PR to note completion of the work and replace + present with past tense. + + doc: Split release history. + This permits the newer releases to be included in the top-level + toctree without polluting it with dozens of old releases. + + doc: Correct accents. + + doc: BigTIFF design markup improvements. + + Add doc/_static. + + doc: Move TIFF specification and design notes into subdirectory. + + doc: Move releases into subdirectory. + + doc: Mark up TIFF tech note 2. + + doc: Use sphinxdox theme. + The sphix_rtd_theme formats complex tables badly. + + doc: Clean up HTML tags. + +2022-06-04 Roger Leigh + + ci: Install Sphinx manual for use by GitLab pages. + + doc: Use sphinx_rtd_theme. + + Convert HTML documentation to Sphinx RST. + * Add CMake build logic + * Add Autotools build logic + * Move from html/ to doc/ + * Manual pages are still generated HTML for the time being + + git: Ignore common IDE build files. + +2022-06-04 Roger Leigh + + Merge branch 'ci-ubuntu-22.04' into 'master' + ci: Update to use Ubuntu 22.04 CI images + + Closes #429 + + See merge request libtiff/libtiff!348 + +2022-06-04 Roger Leigh + + Merge branch 'opengl-option' into 'master' + cmake: Add tiff-opengl option + + See merge request libtiff/libtiff!340 + +2022-06-04 Roger Leigh + + tiffdump: Avoid overflow warning when reading. + + ci: Update to use Ubuntu 22.04 CI images. + +2022-06-04 Even Rouault + + Merge branch 'master' into 'master' + Include stdlib.h in tif_lzw.c. + + See merge request libtiff/libtiff!347 + +2022-06-04 Brian Ledger + + Merge branch 'master' of https://gitlab.com/libtiff/libtiff. + +2022-06-04 Brian Ledger + + Include stdlib.h in tif_lzw.c. + In `tif_lzw.c`, a call is made to `_byteswap_uint64`. This is declared in `stdlib.h`. `stdlib.h` is not included in `tib_lzw.c`, so a name error may occur. + + This change adds `#include stdlib.h` to `tif_lzw.c`, to prevent a name error from occuring when `stdlib.h` is not included. + +2022-05-29 Roger Leigh + + Add options for disabling tools, tests, contrib and docs. + + cmake: Add MSVC options when building all libraries and executables. + + cmake: Do not build faxtable target when cross-compiling. + + cmake: Use add_compile_definitions and add_compile_options. + It seems that some CMake versions can't export targets using PRIVATE + linking, even though the private target is never used. + + Merge remote-tracking branch 'origin/master' into cmake-msvc-options. + + Merge remote-tracking branch 'origin/master' into cmake-win32-libtiffxx-static + +2022-05-29 Roger Leigh + + Merge branch 'ci-x64' into 'master' + ci: Remove arm64 temporarily + + See merge request libtiff/libtiff!341 + +2022-05-29 Roger Leigh + + ci: Remove arm64 temporarily. + + autoconf: Add --disable-opengl option. + + cmake: Add tiff-opengl option. + + cmake: Add MSVC options when building all libraries and executables. + + cmake: libtiffxx is static on win32. + +2022-05-22 Even Rouault + + html/Makefile.am: add v4.4.0.html to docfiles. + +2022-05-20 Even Rouault + + Update HOWTO-RELEASE with .tar.xz. + + Prepare for release 4.4.0. + +2022-05-16 Even Rouault + + libtiff v4.4.0 released + +2022-05-16 Even Rouault + + Merge branch 'pkgconf_abs_path' into 'master' + Handle absolute paths in pkg-config file + + See merge request libtiff/libtiff!333 + +2022-05-16 Miloš Komarčević + + Handle absolute paths in pkg-config file. + +2022-05-15 Even Rouault + + Merge branch 'fix-tests-with-ro-source-dir' into 'master' + cmake: allow running the tests with a read-only source directory + + See merge request libtiff/libtiff!332 + +2022-05-15 Alex Richardson + + cmake: allow running the tests with a read-only source directory. + Prior to this commit CTest would invoke all simple_tests tests with the + current working directory set to the source directory. However, some of + the tests (e.g. rewrite) will output files to the current working + directory and will therefore fail when run with a read-only source + directory. This can happen e.g. when testing a cross-compiled version of + libtiff where the sources are mounted read-only in the virtual machine. + + Simply changing the working directory to CMAKE_CURRENT_BINARY_DIR allows + all but raw_decode to pass. The raw_decode test looks for files in the + source directory, and uses the `srcdir` environment variable to find, so + we also have to add a set_tests_properties() call to specify that env var. + +2022-05-14 Even Rouault + + Merge branch 'tiffcrop_pipeline_error' into 'master' + tiffcrop: Fixes complain of pipeline "cmake-ninja-arm64" about abs() on... + + See merge request libtiff/libtiff!331 + +2022-05-14 Su Laus + + tiffcrop: Fixes complain of pipeline "cmake-ninja-arm64" about abs() on... + +2022-05-14 Even Rouault + + Merge branch 'TIFFField_SetGetSize_CountSize' into 'master' + Public functions TIFFFieldSetGetSize() and TIFFieldSetGetCountSize() added. + + See merge request libtiff/libtiff!284 + +2022-05-14 Su Laus + + Public functions TIFFFieldSetGetSize() and TIFFieldSetGetCountSize() added. + +2022-05-13 Even Rouault + + Merge branch 'jondo-master-patch-87274' into 'master' + Replace add_compile_definitions for CMake versions before 3.12 (#238) + + See merge request libtiff/libtiff!330 + +2022-05-13 Robert Pollak + + Replace add_compile_definitions for CMake versions before 3.12 (#238) + +2022-05-13 Even Rouault + + Merge branch 'master' into 'master' + Remove incorrect assert. + + See merge request libtiff/libtiff!329 + +2022-05-13 Ben Laurie + + Remove incorrect assert. + +2022-05-10 Even Rouault + + Merge branch 'Fix_Issue#330' into 'master' + tiffcrop: Fix issue #330 and some more from 320 to 349 + + Closes #330 + + See merge request libtiff/libtiff!298 + +2022-05-10 Su Laus + + tiffcrop: Fix issue #330 and some more from 320 to 349. + +2022-05-10 Even Rouault + + test_signed_tags.c: fix CID 1504376. + +2022-05-10 Even Rouault + + Merge branch 'fix_#29_tiffcp_orientationTag' into 'master' + tiffcp: Fix incomprehensible setting of orientation tag (fixes #29) + + Closes #29 + + See merge request libtiff/libtiff!327 + +2022-05-10 Even Rouault + + Merge branch 'palette-8bit' into 'master' + tiff2pdf: handle 8-bit palette colormap + + See merge request libtiff/libtiff!328 + +2022-05-09 Jay Berkenbilt + + tiff2pdf: handle 8-bit palette colormap. + If all the colors in a palette are in the range [0, 255], treat the + palette as an 8-bit colormap. This workaround already exists elsewhere + in the software including in tiff2ps. + +2022-05-08 Even Rouault + + Merge branch 'fix_#40_ReadSignedTags' into 'master' + Reading of signed tags added (fixes #40) + + Closes #40 + + See merge request libtiff/libtiff!326 + +2022-05-08 Su Laus + + Reading of signed tags added (fixes #40) + +2022-05-08 Even Rouault + + Fix typos in comments. + +2022-05-08 Even Rouault + + Merge branch 'fix_400' into 'master' + tiffcp: avoid buffer overflow in "mode" string (fixes #400) + + Closes #400 + + See merge request libtiff/libtiff!323 + +2022-05-08 Even Rouault + + Merge branch 'CheckForBigTiff' into 'master' + TIFFIsBigTiff() function added. + + See merge request libtiff/libtiff!325 + +2022-05-08 Su Laus + + TIFFIsBigTiff() function added. + +2022-05-01 Su_Laus + + tiffcp: Fix incomprehensible setting of orientation tag (fixes #29) + +2022-04-23 Even Rouault + + Merge branch 'fix_#8_FreeAnonTag' into 'master' + extra flag for anonymous (unknown) tags (fixes #8) + + Closes #400 et #8 + + See merge request libtiff/libtiff!324 + +2022-04-22 Even Rouault + + tif_lzw.c: fix potential out-of-bounds error when trying to read in the same tile/strip after an error has occured (fixes #410) + +2022-04-06 Su_Laus + + extra flag for anonymous (unknown) tags (fixes #8) + +2022-04-02 Su_Laus + + tiffcp: avoid buffer overflow in "mode" string (fixes #400) + +2022-03-21 Even Rouault + + avoid hang in TIFFRewriteDirectory() if a classic file > 4 GB is attempted to be created + Fixes https://github.com/OSGeo/gdal/issues/5479 + +2022-03-19 Even Rouault + + Merge branch 'Correct_tag_auto-registration_description' into 'master' + Correct reading description for anonymous tag auto-registration in addingtags.html (closes 353) + + Closes #353 + + See merge request libtiff/libtiff!320 + +2022-03-19 Su Laus + + Correct reading description for anonymous tag auto-registration in addingtags.html (closes 353) + +2022-03-18 Even Rouault + + tif_lzw.c: avoid harmless unsigned-integer-overflow (https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45741) + +2022-03-17 Even Rouault + + Merge branch 'fix_396' into 'master' + tiffcp: do not try to fetch compressor-specific tags when not appropriate (fixes #396) + + Closes #396 + + See merge request libtiff/libtiff!316 + +2022-03-17 Even Rouault + + Merge branch 'Fix_cmake_warnings' into 'master' + Fix some CMake warnings + + See merge request libtiff/libtiff!319 + +2022-03-17 Su Laus + + Fix some CMake warnings. + +2022-03-17 Even Rouault + + Merge branch 'lzw_decode_improvements' into 'master' + LZWDecode(): major speed improvements + + See merge request libtiff/libtiff!318 + +2022-03-16 Even Rouault + + LZWDecode(): major speed improvements. + This mostly comes from dealing specifically with codes that expand to + 2, 3 and 4 bytes or more to avoid branches, and dealing with longer + repeated sequences (e.g. lots of bytes to 0). + + With the following bench.c, execution time is 32% faster on a 8000x8000 + 4 bands uint16 predictor=2 image that has a 1.6x compression ratio. with + gcc 9.4.0, on x86_64 + + bench.c: + ``` + #include "tiffio.h" + #include + #include + + int main(int argc, char* argv[]) + { + if( argc != 2 ) + { + fprintf(stderr, "Usage: ./bench my.tif\n"); + exit(1); + } + TIFF* tif = TIFFOpen(argv[1], "r"); + if( tif == NULL ) + { + fprintf(stderr, "Cannot open %s\n", argv[1]); + exit(1); + } + if( !TIFFIsTiled(tif) ) + { + fprintf(stderr, "Only tiled image supported\n"); + exit(1); + } + int tilesize = (int)TIFFTileSize(tif); + char* c = malloc(tilesize); + if( c == NULL ) + { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + const uint32_t numtiles = TIFFNumberOfTiles(tif); + //int numloops = 4 * (int)(1e9 / ((double)tilesize * numtiles)); + //printf("Number of loops: %d\n", numloops); + int numloops = 1; + for(int i =0; i< numloops; i++) + { + for(uint32_t tileindex = 0; tileindex < numtiles; tileindex++ ) + { + TIFFReadEncodedTile(tif, tileindex, c, tilesize); + } + } + free(c); + TIFFClose(tif); + return 0; + } + ``` + +2022-03-16 Even Rouault + + LZWDecode(): modest speed improvement: fetch input data by chunks of the largest natural integer of the architecture + +2022-03-14 Even Rouault + + Merge branch 'kmilos-master-patch-45885' into 'master' + Correct fix for the pkgconf file relative paths + + See merge request libtiff/libtiff!317 + +2022-03-10 Even Rouault + + tif_lzw.c: make LZW_CHECKEOS non-optional. + + tiffsplit.c: fix compiler warning on 32-bit. + +2022-03-10 Miloš Komarčević + + Correct fix for the pkgconf file relative paths. + +2022-03-10 Even Rouault + + Merge branch 'issue-278' into 'master' + fix heap buffer overflow in tiffcp (#278) + + Closes #278 + + See merge request libtiff/libtiff!311 + +2022-03-10 4ugustus + + fix heap buffer overflow in tiffcp (#278) + +2022-03-09 Even Rouault + + tiffcp: do not try to fetch compressor-specific tags when not appropriate (fixes #396) + +2022-03-09 Even Rouault + + Merge branch 'i_am_a_unsympathetic_person' into 'master' + index.html: make it clear that I'm a unsympathetic person + + See merge request libtiff/libtiff!315 + +2022-03-09 Even Rouault + + index.html: make it clear that I'm a unsympathetic person. + +2022-03-08 Even Rouault + + Merge branch 'Fix_Issue#395' into 'master' + tiffcrop: fix issue #395: generation of strange section images. + + Closes #395 + + See merge request libtiff/libtiff!312 + +2022-03-08 Su Laus + + tiffcrop: fix issue #395: generation of strange section images. + +2022-03-08 Even Rouault + + Merge branch 'Fix_Issue#380' into 'master' + tiffcrop: fix issue #380 and #382 heap buffer overflow in extractImageSection + + Closes #382 et #380 + + See merge request libtiff/libtiff!307 + +2022-03-08 Su Laus + + tiffcrop: fix issue #380 and #382 heap buffer overflow in extractImageSection + +2022-03-08 Even Rouault + + Merge branch 'issue-392' into 'master' + add checks for return value of limitMalloc (#392) + + Closes #392 + + See merge request libtiff/libtiff!314 + +2022-03-08 Even Rouault + + Merge branch 'issue-393' into 'master' + fix the FPE in tiffcrop (#393) + + Closes #393 + + See merge request libtiff/libtiff!310 + +2022-03-08 4ugustus + + fix the FPE in tiffcrop (#393) + +2022-03-08 Even Rouault + + Merge branch 'kmilos-master-patch-56785' into 'master' + Fix pkgconf file relative paths + + Closes #394 + + See merge request libtiff/libtiff!309 + +2022-03-07 Augustus + + add checks for return value of limitMalloc (#392) + +2022-03-02 Miloš Komarčević + + Fix pkgconf file relative paths. + +2022-02-25 Even Rouault + + Merge branch 'fix_385' into 'master' + tif_jbig.c: fix crash when reading a file with multiple IFD in memory-mapped... + + Closes #385 + + See merge request libtiff/libtiff!306 + +2022-02-24 Even Rouault + + tif_jbig.c: fix crash when reading a file with multiple IFD in memory-mapped mode and when bit reversal is needed (fixes #385) + +2022-02-24 Even Rouault + + Merge branch 'string_size_limit' into 'master' + _TIFFVSetField(): when passing a string without explicit length, check that... + + See merge request libtiff/libtiff!304 + +2022-02-24 Even Rouault + + Merge branch 'TIFFClientOpen_cleanup' into 'master' + TIFFClientOpen(): remove useless initializations of tif_rawcc and tif_flags... + + See merge request libtiff/libtiff!303 + +2022-02-20 Even Rouault + + Remove extra word in comment. + + TIFFPrintDirectory(): avoid potential multi-threading issue when reading the DotRange tag + The severity of the issue would be low (mix of values displayed) and the + time window where that would occur would be short. + + Constify signature of _TIFFsetXXXXArray() functions, and remove unused _TIFFsetString() + + _TIFFVSetField(): when passing a string without explicit length, check that the length doesn't except the 1 << 31 maximum bytes we support + +2022-02-19 Even Rouault + + tiffsplit.c: fix use after free introduced in master per commit 8ed97f401552a2b4300d3c489b03dcada86a21fd (related to #290) + +2022-02-19 Even Rouault + + Merge branch 'Fix_Issue#284' into 'master' + tiff2ps: In limitMalloc() check for negative size (fixes #284) + + Closes #284 + + See merge request libtiff/libtiff!300 + +2022-02-19 Su Laus + + tiff2ps: In limitMalloc() check for negative size (fixes #284) + +2022-02-19 Even Rouault + + Merge branch 'fix_288' into 'master' + tiffinfo: limit more memory allocations using -M switch (fixes #288) + + Closes #288 + + See merge request libtiff/libtiff!299 + +2022-02-19 Even Rouault + + Merge branch 'Fix_Issue#290' into 'master' + tiffsplit: limitMalloc() and getopt() introduced and more error messages. (fixes #290) + + Closes #290 + + See merge request libtiff/libtiff!301 + +2022-02-19 Su Laus + + tiffsplit: limitMalloc() and getopt() introduced and more error messages. (fixes #290) + +2022-02-19 Even Rouault + + Merge branch 'Fix_Issue#273_#275' into 'master' + tiffcrop: buffsize check formula in loadImage() amended (fixes #273,#275) + + Closes #275 et #273 + + See merge request libtiff/libtiff!302 + +2022-02-19 Su Laus + + tiffcrop: buffsize check formula in loadImage() amended (fixes #273,#275) + +2022-02-19 Even Rouault + + TIFFClientOpen(): remove useless initializations of tif_rawcc and tif_flags after TIFFReadDirectory() + Those initializations date back to the initial commit of libtiff, but I + strongly suspect there are no longer needed those days. + Setting tif_rawcc to (tmsize_t)-1 is weird. AFAICS, nowhere else in the library + -1 is used as a special markeri for that field. Immediately after TIFFReadDirectory() + returns it is set to 0, and this is the value used in tif_read.c/tif_write.c to + reset it. + And setting the TIFF_BUFFERSETUP bit of tif_flags is even more + suspicious as the only place where it is set otherwise is in + TIFFWriteBufferSetup(). I suspect this bogus setting of the flag was the + reason for commit dbf2339a1 where BUFFERCHECK() in addition to checking + the bit also checked the tif_rawdata against nullptr. + + If setting those 2 fields was needed, it would mean that TIFFClientOpen() with the + 'h' hint to disable automatic TIFFReadDirectory() would be broken, + because someone issuing a manual TIFFReadDirectory() couldn't set them, + as being private members. + + The libtiff test suite is happy with that change, and the GDAL one too. + +2022-02-19 Even Rouault + + TIFFFetchNormalTag(): speed optimization when reading a (very large) nul-terminated ASCII tag + + TIFFWriteDirectoryTagData(): turn assertion on data length into a runtime check + For example, the assertion could actually be triggered when writing an + ASCII tag with more than 1 << 31 bytes. + +2022-02-17 Even Rouault + + TIFFFetchNormalTag(): avoid calling memcpy() with a null source pointer and size of zero (fixes #383) + +2022-02-15 Roger Leigh + + Merge branch 'tl/fix-cpack' into 'master' + Fix packaging with CPack + + See merge request libtiff/libtiff!292 + +2022-02-11 Even Rouault + + tiffinfo: limit more memory allocations using -M switch (fixes #288) + + tif_dirwrite.c: take into account COMPRESSION_JXL. + +2022-02-11 Even Rouault + + Merge branch 'predictor_2_64bit' into 'master' + Predictor 2 (horizontal differenciation): support 64-bit + + See merge request libtiff/libtiff!296 + +2022-02-10 Even Rouault + + Merge branch 'Fix_Issue#365' into 'master' + tiff2pdf: Fixes issues #365, #258 and #257 related to initializing 't2p->pdf_compressionquality'. + + Closes #257, #258 et #365 + + See merge request libtiff/libtiff!297 + +2022-02-10 Su Laus + + tiff2pdf: Fixes issues #365, #258 and #257 related to initializing 't2p->pdf_compressionquality'. + +2022-02-09 Even Rouault + + Predictor 2 (horizontal differenciation): support 64-bit. + There's no reason not to support 64-bit. The TIFF 6 specification + doesn't say anything about that (and even mention 4-bit, which we don't + support) + +2022-02-09 Even Rouault + + Merge branch 'Fix_Issue#352' into 'master' + tiffcrop.c: Fix issue #352 heap-buffer-overflow by correcting uint32_t underflow. + + Closes #352 + + See merge request libtiff/libtiff!294 + +2022-02-09 Su Laus + + tiffcrop.c: Fix issue #352 heap-buffer-overflow by correcting uint32_t underflow. + +2022-02-08 Even Rouault + + Merge branch 'custom_dir_EXIF_Coverity_fixes' into 'master' + Fix Coverity Scan report issues for custom_dir_EXIF_231.c and test_directory.c + + See merge request libtiff/libtiff!295 + +2022-02-08 Su Laus + + Fix Coverity Scan report issues for custom_dir_EXIF_231.c and test_directory.c + +2022-02-06 Roger Leigh + + Merge branch 'cmake-test' into 'master' + Correct CMake testing + + Closes #317 + + See merge request libtiff/libtiff!291 + +2022-02-06 Even Rouault + + LogLuvEncode32(): avoid undefined behaviour of left shift on a signed integer + + TIFFFetchStripThing(): avoid calling memcpy() with a null source pointer and size of zero (fixes #362) + +2022-02-05 Even Rouault + + TIFFReadDirectory(): avoid calling memcpy() with a null source pointer and size of zero (fixes #362) + +2022-01-29 Even Rouault + + Merge branch 'Jamaika1-master-patch-68264' into 'master' + Added stdlib.h + + See merge request libtiff/libtiff!293 + +2022-01-29 Jamaika + + tif_win32.c: include stdlib.h. + +2022-01-28 Timothy Lyanguzov + + Fix packaging with CPack. + Replace all CMAKE_INSTALL_FULL_ with CMAKE_INSTALL_ to allow CPack setting CMAKE_INSTALL_PREFIX + +2022-01-25 Even Rouault + + Merge branch 'master' into 'master' + Fix the global-buffer-overflow in tiffset + + See merge request libtiff/libtiff!287 + +2022-01-25 4ugustus + + tiffset: fix global-buffer-overflow for ASCII tags where count is required (fixes #355) + +2022-01-23 Roger Leigh + + Merge branch 'autogen' into 'master' + Fix autogen.sh permissions issues during mv + + See merge request libtiff/libtiff!290 + +2022-01-23 Roger Leigh + + Correct CMake testing. + * Use functions rather than macros to avoid problems with variables in + conditions (since macro arguments are not variables) + * Conditionally add to file lists and test program lists based upon the + configuration options (e.g. JPEG and old-JPEG availability) + * Sync tests, files and option usage with current automake usage + +2022-01-19 Will Cohen + + autogen.sh: mv -f for config.sub and config.guess. + +2022-01-12 Even Rouault + + TIFFYCbCrToRGBInit(): avoid Integer-overflow in gdal_TIFFYCbCrToRGBInit. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43559 + +2022-01-10 Even Rouault + + Merge branch 'fix_TIFFFillStrip_wrong_check' into 'master' + Fix sanity check in TIFFFillStrip()/TIFFFillStrile() + + See merge request libtiff/libtiff!288 + +2022-01-10 Even Rouault + + TIFFFillStrip()/TIFFFillStrile(): remove useless test. + + Fix sanity check in TIFFFillStrip()/TIFFFillStrile() + A sanity check comparing the compressed vs uncompressed file that was + originally written 'correctly' but relied on undefined behaviour was + changed in 1b5e3b6a23827c33acf19ad50ce5ce78f12b3773 in an incorrect way. + Fix that. Credits to @burn for spotting this in + https://gitlab.com/libtiff/libtiff/-/issues/343#note_806089714 + +2021-12-29 Even Rouault + + Merge branch 'Fix_FieldName_NULL' into 'master' + Fix Issue #354 Segmentation Fault due to field_name=NULL + + See merge request libtiff/libtiff!285 + +2021-12-29 Even Rouault + + Merge branch 'mingw-static' into 'master' + build: Fix static library imports in mingw + + See merge request libtiff/libtiff!286 + +2021-12-29 Biswapriyo Nath + + build: Fix static library imports in mingw. + This defines LERC_STATIC while creating libtiff static library + in Win32 platform in presence of lerc library. Otherwise, the + static library import lerc APIs with dllimport attribute and + thus linked with shared lerc library. + +2021-12-28 Su_Laus + + Fix Issue #354 Segmentation Fault due to field_name=NULL. + +2021-12-17 Even Rouault + + Merge branch 'fix_342' into 'master' + TIFFGetField(TIFFTAG_STRIPBYTECOUNTS/TIFFTAG_STRIPOFFSETS): return error if... + + Closes #342 + + See merge request libtiff/libtiff!283 + +2021-12-16 Even Rouault + + TIFFGetField(TIFFTAG_STRIPBYTECOUNTS/TIFFTAG_STRIPOFFSETS): return error if returned pointer is NULL (fixes #342) + + tiff2pdf: validate TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc) return (fixes #342) + +2021-12-16 Even Rouault + + Merge branch 'master' into 'master' + fix raw2tiff floating point exception(fixes #338) + + Closes #338 + + See merge request libtiff/libtiff!282 + +2021-12-16 t.feng + + raw2tiff: check that band number if not zero to avoid floating point exception(fixes #338) + +2021-12-14 Even Rouault + + Merge branch 'fix_337' into 'master' + OJPEG: avoid assertion when using TIFFReadScanline() (fixes #337) + + Closes #337 + + See merge request libtiff/libtiff!280 + +2021-12-13 Even Rouault + + OJPEG: avoid assertion when using TIFFReadScanline() (fixes #337) + Note: my analyis of the issue would be that the use of the scanline API + is currently propably broken with OJPEG. + +2021-12-10 Even Rouault + + JPEG 12bit: make it easier for GDAL's RENAME_INTERNAL_LIBTIFF_SYMBOLS mode + +2021-12-09 Even Rouault + + tif_lzw.c: other warning fixes. + + tif_lzw.c: fix warnings of previous commit. + +2021-12-09 Even Rouault + + Merge branch 'lzw_2gb_windows' into 'master' + LZW codec: fix support for strips/tiles > 2 GB on Windows + + See merge request libtiff/libtiff!279 + +2021-12-08 Even Rouault + + LZW codec: fix support for strips/tiles > 2 GB on Windows. + +2021-12-07 Even Rouault + + Merge branch 'fix_287' into 'master' + tiffinfo: add a -M switch to define the maximum heap allocation, and default... + + Closes #287 + + See merge request libtiff/libtiff!278 + +2021-12-06 Even Rouault + + Merge branch 'fix_319' into 'master' + TIFFReadDirectory: fix OJPEG hack (fixes #319) + + Closes #319 + + See merge request libtiff/libtiff!277 + +2021-12-06 Even Rouault + + Merge branch 'fix_309' into 'master' + TIFFAppendToStrip(): fix rewrite-in-place logic (fixes #309) + + Closes #309 + + See merge request libtiff/libtiff!276 + +2021-12-05 Even Rouault + + Merge branch 'b1' into 'master' + Fix resource leak on error path + + See merge request libtiff/libtiff!263 + +2021-12-05 bonniegong + + rast2tiff: Fix resource leak on error path. + +2021-12-05 Even Rouault + + Merge branch 'tiffsplit-leak' into 'master' + tiffsplit.c: Fix memleak before exit + + See merge request libtiff/libtiff!270 + +2021-12-05 Even Rouault + + tiffinfo: add a -M switch to define the maximum heap allocation, and default it to 256 MiB (fixes #287) + + tiffinfo: fix read of invalid pointer in TIFFReadRawDataTiled() (fixes #295) + +2021-12-05 Even Rouault + + TIFFReadDirectory: fix OJPEG hack (fixes #319) + to avoid having the size of the strip arrays inconsistent with the + number of strips returned by TIFFNumberOfStrips(), which may cause + out-ouf-bounds array read afterwards. + + One of the OJPEG hack that alters SamplesPerPixel may influence the + number of strips. Hence compute tif_dir.td_nstrips only afterwards. + +2021-12-04 Even Rouault + + TIFFAppendToStrip(): fix rewrite-in-place logic (fixes #309) + Properly reset tif_curoff when writing strips/tiles + +2021-12-03 Even Rouault + + TIFFReInitJPEG_12(): avoid warning about unused variable in -DNDEBUG. + +2021-12-01 Even Rouault + + Merge branch 'fix_316' into 'master' + TIFFReadCustomDirectory(): avoid crash when reading SubjectDistance tag on a non EXIF directory + + Closes #316 + + See merge request libtiff/libtiff!273 + +2021-12-01 Even Rouault + + Merge branch 'VisualStudio_warnings_suppress' into 'master' + Suppress unnecessary warnings in Visual Studio in AppVeyor test. + + See merge request libtiff/libtiff!234 + +2021-11-30 Even Rouault + + TIFFReadCustomDirectory(): avoid crash when reading SubjectDistance tag on a non EXIF directory + Fixes #316 + + The Valgrind trace was + ``` + TIFFReadCustomDirectory: Warning, Unknown field with tag 37382 (0x9206) encountered. + ==3277355== Invalid read of size 1 + ==3277355== at 0x4842B60: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) + ==3277355== by 0x48BB799: _TIFFmemcpy (tif_unix.c:346) + ==3277355== by 0x485B3CB: _TIFFVSetField (tif_dir.c:647) + ==3277355== by 0x485C125: TIFFVSetField (tif_dir.c:890) + ==3277355== by 0x485BEDC: TIFFSetField (tif_dir.c:834) + ==3277355== by 0x486DA9A: TIFFFetchSubjectDistance (tif_dirread.c:5826) + ==3277355== by 0x4869E35: TIFFReadCustomDirectory (tif_dirread.c:4530) + ==3277355== by 0x4869F0A: TIFFReadGPSDirectory (tif_dirread.c:4564) + ==3277355== by 0x10AA7A: main (tiffinfo.c:171) + ==3277355== Address 0x3fc856aaaaaaaaab is not stack'd, malloc'd or (recently) free'd + ==3277355== + ``` + +2021-11-29 Even Rouault + + Merge branch 'add-null-check' into 'master' + Added missing null check. + + See merge request libtiff/libtiff!274 + +2021-11-28 Dirk Lemstra + + Added missing null check. + +2021-11-26 Even Rouault + + tif_print.c: remove duplicated if() in previous commit. + +2021-11-26 Even Rouault + + Merge branch 'GPS_Print_BugFix' into 'master' + Fix Segmentation fault printing GPS directory if Altitude tag is present (tif_print.c/tiffinfo.c) + + See merge request libtiff/libtiff!272 + +2021-11-26 Su Laus + + Fix Segmentation fault printing GPS directory if Altitude tag is present (tif_print.c/tiffinfo.c) + +2021-11-01 Even Rouault + + Merge branch 'cmake_tiffconf' into 'master' + Fix STRIPCHOP_DEFAULT value in CMake builds + + See merge request libtiff/libtiff!271 + +2021-11-01 Even Rouault + + Fix STRIPCHOP_DEFAULT value in CMake builds. + CMake builds erroneously used value 1 instead of TIFF_STRIPCHOP, which + resulted in strip chopping not being enabled by default. + +2021-10-26 Even Rouault + + tif_jpeg.c: typo fix. + +2021-10-24 Han Han + + tiffsplit.c: Fix memleak before exit. + Details of the memleak: + $ valgrind --leak-check=full tiffsplit id:001763,sync:fuzzer07,src:001641,+cov + + ==2090657== + ==2090657== HEAP SUMMARY: + ==2090657== in use at exit: 13,517 bytes in 17 blocks + ==2090657== total heap usage: 41 allocs, 24 frees, 29,351 bytes allocated + ==2090657== + ==2090657== 2,473 (1,249 direct, 1,224 indirect) bytes in 1 blocks are definitely lost in loss record 10 of 13 + ==2090657== at 0x484086F: malloc (vg_replace_malloc.c:381) + ==2090657== by 0x48BF35C: TIFFClientOpen (tif_open.c:118) + ==2090657== by 0x48CF058: TIFFFdOpen (tif_unix.c:209) + ==2090657== by 0x48CF0C4: TIFFOpen (tif_unix.c:248) + ==2090657== by 0x10954C: main (tiffsplit.c:91) + ==2090657== + ==2090657== 11,044 (1,300 direct, 9,744 indirect) bytes in 1 blocks are definitely lost in loss record 13 of 13 + ==2090657== at 0x484086F: malloc (vg_replace_malloc.c:381) + ==2090657== by 0x48BF35C: TIFFClientOpen (tif_open.c:118) + ==2090657== by 0x48CF058: TIFFFdOpen (tif_unix.c:209) + ==2090657== by 0x48CF0C4: TIFFOpen (tif_unix.c:248) + ==2090657== by 0x1093D9: main (tiffsplit.c:75) + ==2090657== + ==2090657== LEAK SUMMARY: + ==2090657== definitely lost: 2,549 bytes in 2 blocks + ==2090657== indirectly lost: 10,968 bytes in 15 blocks + ==2090657== possibly lost: 0 bytes in 0 blocks + ==2090657== still reachable: 0 bytes in 0 blocks + ==2090657== suppressed: 0 bytes in 0 blocks + ==2090657== + ==2090657== For lists of detected and suppressed errors, rerun with: -s + ==2090657== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) + +2021-10-20 Even Rouault + + tif_webp.c: add explicit cast to please MSVC verbose warnings. + + tif_webp.c: white space fixing. + +2021-10-04 Even Rouault + + Merge branch 'work/amyspark/psd-blobs' into 'master' + Enable writing Photoshop blobs + + See merge request libtiff/libtiff!269 + +2021-10-04 L. E. Segovia + + Enable writing Photoshop blobs. + +2021-09-29 Even Rouault + + Merge branch 'remove_packbits_hack' into 'master' + PackBitsDecode: remove hack for when char is unsigned. + + See merge request libtiff/libtiff!267 + +2021-09-28 Even Rouault + + PackBitsDecode: remove hack for when char is unsigned. + The function has a hack for platforms where char is unsigned. This is + better replaced by making bp a int8_t* pointer, which is guaranteed to + be signed. + +2021-09-27 Even Rouault + + tiffcrop.c: remove useless 'set but not read' variables. + +2021-09-23 Even Rouault + + Merge branch 'fix_gdal_4538' into 'master' + TIFFAppendToStrip(): fix rewrite-in-place logic + + See merge request libtiff/libtiff!266 + +2021-09-23 Even Rouault + + TIFFAppendToStrip(): fix rewrite-in-place logic. + reproducable in particular with packbits compression. + + Fixes https://github.com/OSGeo/gdal/issues/4538 + +2021-09-17 Even Rouault + + tif_lzw.c: silence compiler warning about set but not used variable with recent clang + +2021-09-07 Even Rouault + + Merge branch 'fix_cygwin' into 'master' + Fix build warnings on cygwin about 'argument 1 of type 'float[3]' with... + + See merge request libtiff/libtiff!265 + +2021-09-06 Even Rouault + + test/rational_precision2double.c: add missing curly braces to fix -Werror=misleading-indentation + +2021-09-05 Even Rouault + + Fix build warnings on cygwin about 'argument 1 of type 'float[3]' with mismatched bound [-Werror=array-parameter=]' + +2021-09-05 Even Rouault + + Merge branch 'rewrite-fix' into 'master' + Fix TIFFRewriteDirectory discarding directories after the rewritten one + + See merge request libtiff/libtiff!264 + +2021-09-05 Facundo Tuesca + + tif_dirwrite.c: Fix TIFFRewriteDirectory discarding directories. + This fixes a bug caused by the `tif_lastdiroff` optimization when + rewriting directories. + + Rewriting the Nth directory temporarily zeroes the pointer to it + (located in the N-1th directory) and relies on `TIFFLinkDirectory` + traversing the whole directory list to find the zeroed pointer and + linking the rewritten directory to it. Since `TIFFLinkDirectory` skips + the traversal when `tif_lastdiroff` is set, this change unsets it + to force the full traversal when rewriting a directory. + + A test to catch this particular issue is also added. + +2021-09-01 Even Rouault + + test_directory.c: fix compiler warnings. + +2021-09-01 Even Rouault + + Merge branch 'multipage-optimization' into 'master' + Keep track of last directory to improve performance for large multi-page files + + See merge request libtiff/libtiff!262 + +2021-08-28 Facundo Tuesca + + Add field to keep track of last written directory. + This adds a new `tif_lastdiroff` field to the TIFF data structure + and uses it to store the offset of the last written directory. + + Appending a new directory required traversing the whole file + to find the last directory. By keeping track of its offset in this + new field, the search is no longer necessary. + + Since this offset is only stored in-memory, the first directory + append after opening a file will have to transverse the whole + directory list. Subsequent calls will have access to the last + offset, avoiding the transversal. + +2021-08-13 Even Rouault + + tif_jpeg.c: fix memory leak on error code path for JPEG 12 bit (CID 1086702) + +2021-07-29 Even Rouault + + Merge branch 'jpeg12' into 'master' + Enable JPEG 12bit support with a libjpeg that has a different ABI than the one for 8bit support + + See merge request libtiff/libtiff!261 + +2021-07-28 Even Rouault + + Reformat tif_jpeg.c and tif_jpeg_12.c with clang-format-10. + +2021-07-27 Even Rouault + + Enable JPEG 12bit support with a libjpeg that has a different ABI than the one for 8bit support + See https://github.com/OSGeo/gdal/pull/4139 for more details + + Note: this hasn't been tested for standalone libtiff builds. + +2021-07-09 Even Rouault + + Merge branch 'wip/export-targets' into 'master' + Export tiff targets + + See merge request libtiff/libtiff!258 + +2021-07-09 Even Rouault + + Merge branch 'pkgconfig' into 'master' + Add version and requirements to pc file + + See merge request libtiff/libtiff!256 + +2021-07-09 Kai Pastor <8989969-dg0yt@users.noreply.gitlab.com> + + Fix version in libtiff-4.pc.in, and CMake build: Add requirements to pc file + +2021-07-09 Even Rouault + + Merge branch 'cmake' into 'master' + Fix build issues with CMake 3.10 + + See merge request libtiff/libtiff!260 + +2021-07-04 Kai Pastor + + Fix reconfiguration with cmake. + + Fix build with CMake 3.10. + +2021-06-28 Milian Wolff + + Export tiff targets. + Fixes build when including libtiff as a cmake subproject into + another project and then installing a target from there which + depends on tiff. For example we could end up with: + + ``` + CMake Error in 3rdParty/diplib/CMakeLists.txt: + export called with target "DIP" which requires target "tiff" that is not in + any export set. + ``` + +2021-06-21 Even Rouault + + Merge branch 'libjpeg9d_support_simplification' into 'master' + tif_jpeg.c: simplify libjpeg 9d support (refs #266) + + See merge request libtiff/libtiff!257 + +2021-06-20 Even Rouault + + tif_jpeg.c: simplify libjpeg 9d support (refs #266) + Credits to Guido Vollbeding for the suggestion + +2021-06-15 Even Rouault + + Merge branch 'jpeg_in_tiff_jpeg_9d' into 'master' + tif_jpeg.c: workaround bug of libjpeg 9d that defers Huffman table creation + + Closes #266 + + See merge request libtiff/libtiff!255 + +2021-06-15 Even Rouault + + Merge branch 'jpeg_disable_progressive_with_mozjpeg' into 'master' + tif_jpeg.c: do not emit progressive scans with mozjpeg and force optimize_coding + + See merge request libtiff/libtiff!254 + +2021-06-12 Even Rouault + + tif_jpeg.c: with mozjpeg, disable emission of Huffman tables in JpegTables tag, and use optimize_coding + +2021-06-10 Even Rouault + + tif_jpeg.c: workaround bug of libjpeg 9d that defers Huffman table creation + Fixes #266 + + libjpeg-9d no longer creates default Huffman tables in + jpeg_set_defaults(), which make their emission in the JpegTables tag no + longer possible. Workaround that by borrowing code from libjpeg to + manually create them when they are not initialized. + +2021-06-10 Even Rouault + + tif_jpeg.c: do not emit progressive scans with mozjpeg. + Relates to #266 + + - On writing, explicitly disable progressive scans, which is normally + not enabled, except with mozjpeg. + - On reading, emit a warning when encountering progressive scans. + +2021-06-10 Even Rouault + + Merge branch 'fix-263' into 'master' + Fix memory leak in tiff2pdf + + See merge request libtiff/libtiff!249 + +2021-06-09 Even Rouault + + Merge branch 'diizzyy-master-patch-20521' into 'master' + html: Add missing pages when using CMake + + See merge request libtiff/libtiff!242 + +2021-06-09 Daniel E + + html: Add missing pages when using CMake. + +2021-06-07 Even Rouault + + Merge branch 'ci-reenable-cygwin' into 'master' + ci: Re-enable cygwin builds + + See merge request libtiff/libtiff!252 + +2021-06-06 Roger Leigh + + ci: Re-enable cygwin builds. + +2021-06-06 Even Rouault + + Merge branch 'ci-arm64' into 'master' + ci: Add arm64 build + + See merge request libtiff/libtiff!251 + +2021-06-06 Roger Leigh + + ci: Add arm64 build. + +2021-06-05 Even Rouault + + _TIFFRewriteField(): fix when writing a IFD with a single tile that is a sparse one, on big endian hosts + +2021-06-02 Timothy Lyanguzov + + Fix memory leak in tiff2pdf. + +2021-06-01 Even Rouault + + Merge branch 'lzw_cleanup' into 'master' + tif_lzw.c: cleanup, no functional change + + See merge request libtiff/libtiff!248 + +2021-05-31 Even Rouault + + tif_lzw.c: cleanup, no functional change. + +2021-05-22 Even Rouault + + Merge branch 'appveyor_disable_cygwin' into 'master' + .appveyor.yml: disable cygwin configs for now as they are broken + + See merge request libtiff/libtiff!247 + +2021-05-22 Even Rouault + + Merge branch 'zstd_reuse_objects' into 'master' + ZSTD codec: reuse compressor/decompressor objects + + See merge request libtiff/libtiff!246 + +2021-05-22 Even Rouault + + .appveyor.yml: disable cygwin configs for now as they are broken. + + ZSTD codec: reuse compressor/decompressor objects. + No need to recreate them each time in the PreEncode/Decode functions. + They can be reused if already existing. + +2021-05-08 Even Rouault + + Merge branch 'adobedeflate-fix' into 'master' + Fix all remaining uses of legacy Deflate compression id and warn on use + + See merge request libtiff/libtiff!245 + +2021-05-08 David Ryskalczyk + + Fix all remaining uses of legacy Deflate compression id and warn on use. + +2021-05-06 Even Rouault + + Merge branch 'improve_tiffinfo_tiffdump_for_gdal_tags' into 'master' + tiffinfo/tiffdump: improve output for GDAL tags + + See merge request libtiff/libtiff!244 + +2021-05-03 Even Rouault + + Merge branch 'issue-252' into 'master' + Prevent adding root directory to include list + + Closes #252 et #218 + + See merge request libtiff/libtiff!243 + +2021-05-03 Even Rouault + + tiffinfo/tiffdump: improve output for GDAL tags. + +2021-04-29 Timothy Lyanguzov + + Prevent adding root directory to include list. + there is a file VERSION in the root directory which clashes with C++20 standard header + "config.h" file is created in "config" subdirectory to prevent adding "-I.." to generated Makefile + + closes #218, #252 + +2021-04-23 Laszlo Boszormenyi (GCS) + + fix TIFFReadRawStrip man and HTML page typo. + From https://github.com/conda-forge/libtiff-feedstock/blob/master/recipe/patches/fix_TIFFReadRawStrip_man_page_typo.patch + +2021-04-20 Even Rouault + + HOWTO-RELEASE: update. + +2021-04-18 Even Rouault + + Merge branch 'lerc_zstd_deflate' into 'master' + Make LERC_SUPPORT conditional on ZLIB_SUPPORT. Make display of lerc options in tiffcp depend on actual zstd support. + + See merge request libtiff/libtiff!239 + +2021-04-18 Miguel Medalha + + Make LERC_SUPPORT conditional on ZLIB_SUPPORT. Make display of lerc options in tiffcp depend on actual zstd support. + +2021-04-17 Even Rouault + + Merge branch 'vtorri_xz' into 'master' + automatic creation of xz archive when running make distcheck + + See merge request libtiff/libtiff!238 + +2021-04-16 Even Rouault + + iptcutil.c: fix bug in EOF comparison, spotted on NetBSD 9 earmv7hf-el. + +2021-04-16 Even Rouault + + libtiff v4.3.0 released + +2021-04-15 Even Rouault + + Merge branch 'libjpeg12_cmake' into 'master' + libtiff/tif_config.h.cmake.in: surround LIBJPEG_12_PATH by double quotes + + See merge request libtiff/libtiff!237 + +2021-04-15 Even Rouault + + libtiff/tif_config.h.cmake.in: surround LIBJPEG_12_PATH by double quotes + +2021-04-14 Even Rouault + + Merge branch 'lerc_api_change' into 'master' + tif_lerc.c: cope with API breakage in liblerc master + + See merge request libtiff/libtiff!236 + +2021-04-14 Even Rouault + + tif_lerc.c: cope with API breakage in liblerc master. + +2021-04-08 Even Rouault + + libtiff: remove remaining #ifdef WIN32 and use PRI formatting. + +2021-03-10 Even Rouault + + Merge branch 'kmilos-master-patch-73187' into 'master' + tiffcp: Remove LZW help text, preset not supported + + See merge request libtiff/libtiff!229 + +2021-03-10 Miloš Komarčević + + tiffcp: Remove LZW help text, preset not supported. + +2021-03-10 Even Rouault + + Merge branch 'feature/lerc' into 'master' + Add LERC Compression Plugin (closes: #213) + + Closes #213 + + See merge request libtiff/libtiff!228 + +2021-03-10 Even Rouault + + Merge branch 'cmake-fixes' into 'master' + CMake fixes + + Closes #246 et #245 + + See merge request libtiff/libtiff!232 + +2021-03-09 Roger Leigh + + cmake: Correct FindCMath. + + cmake: Correct ZSTD_USABLE typo. + +2021-03-07 Roger Leigh + + Merge branch 'cmake-find-lib-prefixes' into 'master' + cmake: Correct find lib prefixes for Deflate and JBIG + + See merge request libtiff/libtiff!231 + +2021-03-07 Roger Leigh + + cmake: FindJBIG uses lib prefix on Windows. + + cmake: FindDeflate uses lib prefix on Windows. + +2021-03-07 Even Rouault + + TWebPDecode(): avoid potential overflow on multiplication (CID 1472928) + + TIFFReadDirEntryArrayWithLimit(): avoid false positive from Coverity Scan regarding out-of-bounds access (CID 1472927) + + tif_dirwrite.c: avoid setting a variable that is not read afterwards. + +2021-03-07 Even Rouault + + Merge branch 'coverity-fixes' into 'master' + Coverity fixes (high impact) + + See merge request libtiff/libtiff!227 + +2021-03-07 Roger Leigh + + Fix high-impact Coverity issues (resource leaks). + The issues are in the tests and tiffcrop, not the core library. Real issues, but not high risk. + + Use to test if Coverity integration is performing properly on merge. + +2021-03-07 Even Rouault + + Merge branch 'fix_tif_fax3_encoder_regression' into 'master' + tif_fax3.c: fix master regression in encoder + + See merge request libtiff/libtiff!230 + +2021-03-07 Even Rouault + + tif_fax3.c: fix master regression in encoder. + Fix issue introduced in 39a74eede0455ec8ee334dcddf71f5354d508d8b + + Spotted by gdal's tiff_write_76 test + +2021-03-07 Antonio Valentino + + Add LERC support in CMake. + +2021-03-07 Antonio Valentino + + Add LERC support in configure.ac and Makefile.am. + +2021-03-07 Antonio Valentino + + Add LERC support to tiffcp. + +2021-03-07 Antonio Valentino + + Add LERC plugin. + The lerc plugin code has been copyed form GDAL. + +2021-03-06 Roger Leigh + + Merge branch 'display_tool_purpose' into 'master' + TIFF tools: insert a line of text summarizing each tool's purpose + + See merge request libtiff/libtiff!214 + +2021-03-06 Even Rouault + + Merge branch 'cmake-update' into 'master' + CMake updates + + See merge request libtiff/libtiff!224 + +2021-03-06 Even Rouault + + tiff.h: typo fix in comment. + +2021-02-15 Roger Leigh + + Merge branch 'remove-travis' into 'master' + ci: Remove unused Travis-CI support + + See merge request libtiff/libtiff!226 + +2021-02-14 Roger Leigh + + ci: Remove unused Travis-CI support. + +2021-02-14 Roger Leigh + + Merge branch 'ci-coverity' into 'master' + Enable Coverity static analysis with CI pipeline + + See merge request libtiff/libtiff!225 + +2021-02-14 Roger Leigh + + ci: Add Coverity static analysis job. + + ci: Use custom libtiff CI image. + +2021-02-13 Roger Leigh + + cmake: Add release target. + + cmake: Remove empty contrib files. + + cmake: Tidy toplevel. + + cmake: Move pkg-config support to PkgConfig.cmake. + + cmake: Move library feature options to CXXLibraryFeatures.cmake. + + cmake: Move C++ support to CXXLibrary.cmake. + + cmake: Add FindCMath to handle libm linking portably. + + cmake: Tidy unused includes. + + cmake: Rename release date to build date. + + cmake: Compute timestamp portably. + + cmake: Remove remaining uses of report_values() + + cmake: Move JPEG12 checks to JPEGCodec.cmake. + + cmake: Move OpenGL checks to OpenGLChecks.cmake. + + cmake: Move OpenGL checks to OpenGLChecks.cmake. + + cmake: Move WebP codec support to WebPCodec.cmake. + + cmake: Use imported targets for WebP. + + cmake: Add FindWebP. + + cmake: Move ZSTD codec support to ZSTDCodec.cmake. + + cmake: Use imported targets for ZSTD. + + cmake: Add FindZSTD. + + cmake: Move LZMA codec support to LZMACodec.cmake. + + cmake: Use imported targets for LibLZMA. + + cmake: Move JBIG codec support to JBIGCodec.cmake. + + cmake: Use imported targets for JBIG. + + cmake: Add FindJBIG. + + cmake: Move PixarLog codec support to PixarLogCodec.cmake. + + cmake: Report system name in configuration report. + + cmake: Move JPEG codec support to JPEGCodec.cmake. + + cmake: Use imported targets for JPEG. + + cmake: Move Deflate codec support to DeflateCodec.cmake. + + cmake: Use imported targets for ZLIB and Deflate. + + cmake: Add FindDeflate. + + cmake: Move symbol checks to SymbolChecks.cmake. + + cmake: Move include checks to IncludeChecks.cmake. + + cmake: Move all autotools logic to separate files. + + cmake: Move internal codec options to InternalCodecs.cmake. + + cmake: Move LFS check to LargeFileSupport.cmake. + + cmake: Move Win32 IO feature to WindowsIOFeature.cmake. + + cmake: Move processor capability checks to ProcessorChecks.cmake. + + cmake: Move type size checks to TypeSizeChecks.cmake. + + cmake: Move linker checks to LinkerChecks.cmake. + + cmake: Move warning options to CompilerChecks. + + cmake: Move version introspection to AutotoolsVersion.cmake. + + cmake: Move compiler checks to CompilerChecks.cmake. + + cmake: Split into helper scripts. + +2021-02-08 Roger Leigh + + cmake: Use target_sources. + + libport: Adjust header and library to only define and link if required. + * Make libport an OBJECT library when in use, otherwise a dummy + INTERFACE library + * libport.h will work if getopt is present or not present. If + present, will fall back to , else will define + symbols + * Add generated libport_config.h to define HAVE_GETOPT and HAVE_UNISTD_H + * dummy.c no longer needed with CMake + * libtiff/libtiffxx no longer link with libport + + cmake: Remove unnecessary extra_dist usage. + Only makes sense in the context of Automake. Was carried over + for reference while porting, but is not needed. + + cmake: Update minimum version and policy version to 3.9. + +2021-02-08 Roger Leigh + + Merge branch 'remove-nmake' into 'master' + Remove NMake build support + + See merge request libtiff/libtiff!223 + +2021-02-08 Roger Leigh + + Remove NMake build support. + The functionality provided by the NMake build is now completely + superseded by the CMake build. + +2021-02-08 Even Rouault + + Merge branch 'warning-fixes' into 'master' + Warning fixes + + See merge request libtiff/libtiff!222 + +2021-02-07 Miguel Medalha + + Update tiffsplit.c. + + Reinsert summary line lost after conflicting merge. + + Merge branch 'master' into 'display_tool_purpose' + # Conflicts: + # tools/tiffsplit.c + +2021-02-06 Roger Leigh + + ci: Enable fatal warnings with -Werror for AppVeyor/GCC. + + ci: Enable fatal warnings with -Werror for GitLab CI. + + tif_zstd.c: Remove unused variable warning. + + custom_dir_EXIF_231: Remove case statement fallthrough. + + custom_dir_EXIF_231: Correct use of strncpy. + + Correct include order. + + Eliminate implict fallthrough usage. + Use simple loops in place of manual loop unrolling. Rely on + the compiler optimiser to unroll loops when appropriate. + + Suppress potential unused variable warning. + + Suppress warnings or avoid case statement fallthrough. + +2021-02-05 Roger Leigh + + Merge branch 'c99-ssize_t-fixes' into 'master' + C99 ssize_t fixes + + Closes #239 + + See merge request libtiff/libtiff!219 + +2021-02-05 Even Rouault + + Merge branch 'tiffsplit-too-many-args' into 'master' + tiffsplit.c: exit with EXIT_FAILURE if there are extra args on the command line + + See merge request libtiff/libtiff!209 + +2021-02-05 Roger Leigh + + Add additional TIFF_SSIZE_FORMAT uses. + +2021-02-04 Roger Leigh + + NMake fixes for size type formatting. + + Add TIFF_SIZE_FORMAT for portable use of %z. + MinGW64 does support %z, but it issues a compiler warning. + + Align Autoconf tif_config.h and CMake tif_config.cmake.in. + + Use TIFF_SSIZE_FORMAT for formatting tmsize_t. + +2021-02-04 Even Rouault + + Merge branch 'remove-lcc' into 'master' + Remove Makefile.lcc + + See merge request libtiff/libtiff!221 + +2021-02-04 Even Rouault + + Merge branch 'remove-scons' into 'master' + Remove SCons build + + See merge request libtiff/libtiff!220 + +2021-02-03 Even Rouault + + Merge branch 'c99-snprintf' into 'master' + Use C99 snprintf + + See merge request libtiff/libtiff!217 + +2021-02-03 Roger Leigh + + Merge branch 'tiff2ps-const' into 'master' + tiff2ps.c: string literals must be const char *, not char * + + See merge request libtiff/libtiff!202 + +2021-02-03 Roger Leigh + + Remove SCons build. + Unmaintained for 16 years. + +2021-02-03 Roger Leigh + + Merge branch 'codec_summary' into 'master' + Modify 'CMakeLists.txt' to produce a meaningful summary of external codecs + + See merge request libtiff/libtiff!192 + +2021-02-03 Roger Leigh + + Remove Makefile.lcc. + Unmaintained for 22 years. + +2021-02-02 Roger Leigh + + Merge branch 'ci-32-bit' into 'master' + ci: Build 32- and 64-bit MSVC variants + + See merge request libtiff/libtiff!218 + +2021-02-01 Roger Leigh + + ci: Build 32- and 64-bit MSVC variants. + + Use C99 snprintf. + +2021-02-01 Even Rouault + + Merge branch 'c99-strtol' into 'master' + Use C99 strtol, strtoul, strtoll and strtoull + + See merge request libtiff/libtiff!216 + +2021-01-31 Even Rouault + + Merge branch 'c99-inline' into 'master' + Use C99 inline + + See merge request libtiff/libtiff!215 + +2021-01-31 Roger Leigh + + Use C99 strtol, strtoul, strtoll and strtoull. + + tif_fax3: Use C99 inline. + + Remove inline feature tests and defines. + Available as a standard feature with C99. + +2021-01-30 Miguel Medalha + + Update raw2tiff.c (remove duplicate description of tool) + +2021-01-30 Roger Leigh + + Merge branch 'c99-format-strings' into 'master' + C99 format strings + + See merge request libtiff/libtiff!211 + +2021-01-29 Miguel Medalha + + Update tiffdither.c (2 tabs caused slight misalignment of lines in usage info output) + +2021-01-28 Miguel Medalha + + Update ppm2tiff.c (slight misalignment of lines in usage info output) + + Update tiffset.c (small misalignment of lines in usage info output) + +2021-01-28 Medalha + + Display tool purpose. + +2021-01-28 Thomas Bernard + + tiff2ps.c: string literals must be const char *, not char * + +2021-01-28 Roger Leigh + + libtiff: Use PRI format flags and remove unnecessary casts. + +2021-01-27 Roger Leigh + + ascii_tag: Use PRI format flags and remove unnecessary casts. + + check_tag: Use PRI format flags and remove unnecessary casts. + + custom_dir_EXIF_231: Use PRI format flags and remove unnecessary casts. + + short_tag: Use PRI format flags and remove unnecessary casts. + + strip_rw: Use PRI format flags and remove unnecessary casts. + + fax2tiff: Use PRI format flags and remove unnecessary casts. + + ppm2tiff: Correct format strings. + + raw2tiff: Use PRI format flags and remove unnecessary casts. + + rgb2ycbcr: Use PRI format flags and remove unnecessary casts. + + tiff2pdf: Use PRI format flags and remove unnecessary casts. + + tiff2ps: Use PRI format flags and remove unnecessary casts. + + tiff2rgba: Use PRI format flags and remove unnecessary casts. + + tiffcmp: Use PRI format flags and remove unnecessary casts. + + tiffcp: Use PRI format flags and remove unnecessary casts. + + tiffcrop: Use PRI format flags and remove unnecessary casts. + + tiffinfo: Use PRI format flags and remove unnecessary casts. + + tiffdump: Use PRI format flags and remove unnecessary casts. + +2021-01-27 Even Rouault + + Merge branch 'c99-require-stdtypes' into 'master' + Use standard C99 integer types + + See merge request libtiff/libtiff!205 + +2021-01-26 Even Rouault + + Merge branch 'reserve_COMPRESSION_JXL' into 'master' + tiff.h: reserve COMPRESSION_JXL=50002 for JPEGXL + + See merge request libtiff/libtiff!210 + +2021-01-22 Even Rouault + + tiff.h: reserve COMPRESSION_JXL=50002 for JPEGXL. + +2021-01-22 Kurt Schwehr + + tiffsplit.c: exit with EXIT_FAILURE if there are extra args on the command line + e.g. tiffsplit in.tif a_prefix_ junk + +2021-01-22 Roger Leigh + + Add and enable TIFF_DISABLE_DEPRECATED for internal use. + + Add typedef deprecations for GCC/Clang and MSVC. + + Use standard C99 integer types. + +2021-01-20 Even Rouault + + Merge branch 'ubuntu-zstd-wepb' into 'master' + gitlab-ci : use libzstd-dev and libwebp-dev ubuntu packages + + See merge request libtiff/libtiff!208 + +2021-01-20 Thomas Bernard + + gitlab-ci : use libzstd-dev and libwebp-dev ubuntu packages. + should replace !206 + +2021-01-20 Even Rouault + + Merge branch 'issue-232' into 'master' + tiff2ps: exit the loop in case of error + + Closes #232 + + See merge request libtiff/libtiff!201 + +2021-01-20 Even Rouault + + Merge branch 'tiffsplit-exit-status' into 'master' + tiffsplit: Exit with EXIT_FAILURE if unable to open the input file. + + See merge request libtiff/libtiff!207 + +2021-01-20 Even Rouault + + Merge branch 'config-cleanup' into 'master' + Remove HAVE_INTTYPES_H, HAVE_LFIND & lfind, HAVE_SEARCH_H & include + + See merge request libtiff/libtiff!203 + +2021-01-19 Kurt Schwehr + + tiffsplit: Exit with EXIT_FAILURE if unable to open the input file. + +2021-01-18 Even Rouault + + Merge branch 'tiffcmp' into 'master' + tiffcmp: fix comparaison with pixels that are fractional number of bytes + + Closes #53 + + See merge request libtiff/libtiff!141 + +2021-01-15 Kurt Schwehr + + CMakeLists.txt: Remove search for lfind. + + Remove HAVE_INTTYPES_H, HAVE_LFIND & lfind, HAVE_SEARCH_H & include + - HAVE_INTTYPES_H is replaced with TIFF_HAVE_INTTYPES_H + - tif_dirinfo.c has a static td_lfind + +2021-01-15 Thomas Bernard + + tiffcmp: fix comparaison with pixels that are fractional number of bytes + For exemple : 4bits per sample + 3 samples per pixel => 1.5 bytes per pixel + + tiff2ps: exit the loop in case of error. + fixes #232 + +2021-01-15 Even Rouault + + Merge branch 'rm-strcasecmp' into 'master' + Remove port/strcasecmp.c as strcasecmp is not currently used in libtiff. + + Closes #235 + + See merge request libtiff/libtiff!199 + +2021-01-15 Even Rouault + + Merge branch 'std-int-types' into 'master' + Use standard C99 integer types + + See merge request libtiff/libtiff!185 + +2021-01-13 Kurt Schwehr + + Remove port/strcasecmp.c as strcasecmp is not currently used in libtiff. + Fixes #235 + +2021-01-10 Miguel Medalha + + Update CMakeLists.txt. Delete unnecessary line from libdeflate codec support section + +2021-01-10 Roger Leigh + + Merge branch 'include_libport' into 'master' + tiff tools and libtiff/mkg3states: include 'libport.h', remove local definition of 'getopt()' + + See merge request libtiff/libtiff!198 + +2021-01-09 Miguel Medalha + + Update CMakeLists.txt. Cleanup of indentation space. Removal of leading '/' from webp include dir. + +2021-01-09 miguel + + cmake: Use target_include_directories correctly. + +2021-01-09 Roger Leigh + + cmake: Use target_include_directories correctly. + + cmake: Drop unnecessary TOOL_INCLUDES. + +2021-01-07 Roger Leigh + + cmake: Use target_include_directories correctly. + +2021-01-07 miguel + + tiff tools and libtiff/mkg3states: include 'libport.h', remove local definition of 'getopt()' + +2021-01-07 Miguel Medalha + + Update CMakeLists.txt. + +2021-01-07 miguel + + tiff tools: include 'libport.h', remove local definition of 'getopt()' + +2021-01-06 Roger Leigh + + Remove conditional use of + + cmake: Drop dlfcn.h check. + + cmake: Remove duplicate line. + + Use stdint.h types when available. + +2021-01-05 Olivier Paquet + + Merge branch 'iptcutil' into 'master' + contrib/iptcutil.c: set '#ifdef _WIN32' (was '#ifdef WIN32', which failed at build time) + + See merge request libtiff/libtiff!197 + +2021-01-05 miguel + + tiff tools: include 'libport.h', remove local definition of 'getopt()' + + contrib/iptcutil.c - set '#ifdef _WIN32' (was '#ifdef WIN32', which failed at build time) + +2021-01-04 Even Rouault + + tools/CMakeLists.txt: add comment about rgb2ycbcr and thumbnail not to be installed + +2021-01-04 Even Rouault + + Merge branch 'revert-5331ed49' into 'master' + Revert "Merge branch 'install_targets' into 'master'" + + See merge request libtiff/libtiff!196 + +2021-01-04 Even Rouault + + Merge branch 'drop-wince' into 'master' + Remove non-functional WinCE support + + See merge request libtiff/libtiff!188 + +2021-01-04 Even Rouault + + Merge branch 'drop-vms' into 'master' + Remove non-functional VMS support + + See merge request libtiff/libtiff!187 + +2021-01-03 Even Rouault + + Revert "Merge branch 'install_targets' into 'master'" + This reverts merge request !193 + +2021-01-03 Even Rouault + + Merge branch 'tiffcp_b_parameter' into 'master' + tiffcp: Remove unnecessary reference to compression from usage info for -b parameter + + See merge request libtiff/libtiff!189 + +2021-01-03 Even Rouault + + Merge branch 'cmake-faxtable' into 'master' + cmake: Add faxtable target + + See merge request libtiff/libtiff!186 + +2021-01-03 Roger Leigh + + Merge branch 'install_targets' into 'master' + Update 'CMakeLists.txt' from 'tools'. + + See merge request libtiff/libtiff!193 + +2021-01-03 Miguel Medalha + + Update 'CMakeLists.txt' from 'tools'. + + Update CMakeLists.txt. + +2021-01-03 Roger Leigh + + Merge branch 'usage_info' into 'master' + thumbnail: Rename constant variable 'stuff' to 'usage_info' + + See merge request libtiff/libtiff!190 + +2021-01-03 Miguel Medalha + + Modified 'CMakeLists.txt' to produce a meaningful summary of external codecs support. + + Removed unnecessary reference to compression from usage info for -b parameter + + Constant variable 'stuff' renamed to 'usage_info' for consistency with the other tools + +2021-01-02 Roger Leigh + + Remove non-functional VMS support. + + Remove non-functional WinCE support. + +2021-01-02 Roger Leigh + + Merge branch 'codespell' into 'master' + Fix spelling mistakes. + + See merge request libtiff/libtiff!183 + +2021-01-02 Kurt Schwehr + + ChangeLog: Remove extraneous character from prior commit - 00fe7828. + +2021-01-02 Roger Leigh + + Merge branch 'codespell-custom_dir_EXIF_231' into 'master' + custom_dir_EXIF_231.c: dos2unix and codespell + + See merge request libtiff/libtiff!184 + +2021-01-01 Roger Leigh + + mkg3states: Sync generator with current generated file content. + + cmake: Add faxtable and mkg3states targets. + +2020-12-31 Kurt Schwehr + + custom_dir_EXIF_231.c: dos2unix and codespell. + additonal, Varable, greather, alwasy + +2020-12-31 Kurt Schwehr + + Fix spelling mistakes. + Found with: + + codespell --version + 1.17.1 + +2020-12-29 Even Rouault + + Merge branch 'remove-some-vms-ifdef' into 'master' + Remove "ifdef VMS" that are no longer necessary. + + See merge request libtiff/libtiff!181 + +2020-12-29 Kurt Schwehr + + Remove "ifdef VMS" that are no longer necessary. + Both sides of the if are now the same. + +2020-12-29 Bob Friesenhahn + + _TIFFBuiltinCODECS should be const. + +2020-12-28 Even Rouault + + Merge branch 'issue-202' into 'master' + tiff2pdf.c: check that tiff_datasize fits in a signed tsize_t + + Closes #202 + + See merge request libtiff/libtiff!166 + +2020-12-28 Even Rouault + + Merge branch 'w_report-when-libdeflate-is-found' into 'master' + CMakeLists.txt: Report when libdeflate is found + + See merge request libtiff/libtiff!175 + +2020-12-28 Bob Friesenhahn + + Declare gpsFields as static const. + +2020-12-28 Bob Friesenhahn + + Merge branch 'tools-reduce-initialized-data' into 'master' + Reduce initialized data by making more data const and simplifying usage() implementation. + + See merge request libtiff/libtiff!180 + +2020-12-28 Bob Friesenhahn + + Reduce initialized data by making more data const and simplifying usage() implementation. + +2020-12-27 Bob Friesenhahn + + Merge branch 'master' into 'master' + tiff tools: display of compression methods is now conditional instead of hard-coded + + See merge request libtiff/libtiff!176 + +2020-12-27 Bob Friesenhahn + + Merge branch 'build' into 'master' + Fix wrong URL for fetching config.guess and config.sub + + See merge request libtiff/libtiff!177 + +2020-12-26 Chocobo1 + + Fix wrong URL for fetching config.guess and config.sub. + +2020-12-25 miguel + + tiff tools: made display of compression methods and their parameters conditional on their actual availability + +2020-12-20 Bob Friesenhahn + + autogen.sh now updates config.guess and config.sub from master gnulib version. + +2020-12-19 Bob Friesenhahn + + Add a https://libtiff.gitlab.io/libtiff/ link. + + Remove stray character in URL area. + + Changes for 4.2.0 release. + + Changes for 4.2.0 release. + 2020-12-19 Bob Friesenhahn * libtiff 4.2.0 released. @@ -469,7 +5198,7 @@ see #17 tiffmedian: shopw usage on stdout when -h is used. - aslo use EXIT_SUCCESS/EXIT_FAILURE + also use EXIT_SUCCESS/EXIT_FAILURE see #17 tiffinfo: print usage on stdout when -h is used. @@ -674,7 +5403,7 @@ 2020-03-27 Thomas Bernard tiff2pdf: fix "raw" copy of Deflate streams. - The Predictor parametter was not copied from the source tiff to the PDF. + The Predictor parameter was not copied from the source tiff to the PDF. fixes #48 / http://bugzilla.maptools.org/show_bug.cgi?id=2442 2020-03-26 Thomas Bernard @@ -982,7 +5711,7 @@ - EXIF_GPS_upgrade rebased onto c8c5309b765ef4ff097d2aaffbdb8f403db8967d (Merge branch 'Rational2DoublePrecision_correction' into 'master') and adapted: - tif_dirinfo.c: All rational tags set to TIFF_SETGET_FLOAT but only the GPSTAG_ tags set to TIFF_SETGET_DOUBLE. - - custom_dir_EXIF_231.c: Editorials amended and gcc warnigs fixed. + - custom_dir_EXIF_231.c: Editorials amended and gcc warnings fixed. - CMakeLists.txt: add_test(NAME "custom_dir_EXIF_231" COMMAND "custom_dir_EXIF_231") added. 2020-03-07 Even Rouault @@ -1006,7 +5735,7 @@ fix #55 http://bugzilla.maptools.org/show_bug.cgi?id=2505 - Patch originally submited by Ludolf Holzheid + Patch originally submitted by Ludolf Holzheid 2020-03-06 Even Rouault @@ -1129,7 +5858,7 @@ 2020-02-29 Su_Laus - tif_dirwrite.c: bugfix DoubleToSrational(), which returns plain signed interger values always as unsigned rationals. Add a test into rational_precision2double.c for "-1.0" and some editorials in tif_dirwrite.c. (code is related to 6df997c786928757caea0dd68d26ea5f098f49df changes). + tif_dirwrite.c: bugfix DoubleToSrational(), which returns plain signed integer values always as unsigned rationals. Add a test into rational_precision2double.c for "-1.0" and some editorials in tif_dirwrite.c. (code is related to 6df997c786928757caea0dd68d26ea5f098f49df changes). 2020-02-29 Even Rouault @@ -1174,7 +5903,7 @@ Rational with Double Precision Upgrade. Unfortunately, custom rational tags (TIFF_RATIONAL with field_bit=FIELD_CUSTOM) are defined as TIFF_SETGET_DOUBLE - but for the reading interface and LibTiff internally they are stored ALLWAYS as floating point SINGLE precision. + but for the reading interface and LibTiff internally they are stored ALWAYS as floating point SINGLE precision. Double precision custom rational tags are not supported by LibTiff. For the GPS tags in WGS84 a higher accuracy / precision is needed. @@ -1269,7 +5998,7 @@ raw2tiff: avoid divide by 0. fixes #151 / http://bugzilla.maptools.org/show_bug.cgi?id=2839 - first memcmp() lines before computing corellation + first memcmp() lines before computing correlation and always avoid divide by 0 anyway 2020-02-09 Even Rouault @@ -1294,7 +6023,7 @@ tiffcrop.c:4027:20: runtime error: left shift of 190 by 24 places cannot be represented in type 'int' C treats (byte << 24) as an int expression. - casting explicitely to unsigned type uint32 avoids the problem. + casting explicitly to unsigned type uint32 avoids the problem. the same issue has been fixed elsewhere with a24213691616e7cd35aa3e2805493de80c7e4fcf @@ -1523,7 +6252,7 @@ 2019-08-25 Even Rouault - JPEG: avoid use of unintialized memory on corrupted files. + JPEG: avoid use of uninitialized memory on corrupted files. Follow-up of cf3ce6fab894414a336546f62adc57f02590a22c Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16602 Credit to OSS Fuzz @@ -1587,7 +6316,7 @@ signed), which was especially easily triggered on 32-bit builds (with recent enough compilers that assume that signed multiplication cannot overflow, since this is undefined behaviour by the C standard). The original issue which lead to - this fix was trigged from tif_fax3.c + this fix was triggered from tif_fax3.c There were also unsafe (implementation defied), and broken in practice on 64bit builds, ways of checking that a uint64 fits of a (signed) tmsize_t by doing @@ -1660,7 +6389,7 @@ - Discussion in https://gitlab.com/libtiff/libtiff/merge_requests/39 - http://bugzilla.maptools.org/show_bug.cgi?id=2540 - Comments and indention adapted. + Comments and indentation adapted. Preparation to rebase onto master @@ -1680,7 +6409,7 @@ [00:02:58] -- CMAKE_HOST_SYSTEM_PROCESSOR set to AMD64 [00:02:58] -- HOST_FILLORDER set to FILLORDER_MSB2LSB - Ther reason is that we match the "amd64.*" lowercase string whereas + The reason is that we match the "amd64.*" lowercase string whereas CMAKE_HOST_SYSTEM_PROCESSOR is set to AMD64 uppercase. 2019-07-09 Even Rouault @@ -1690,13 +6419,13 @@ 2019-07-09 Even Rouault Merge branch 'fix_chromium_925269' into 'master' - OJPEG: avoid use of unintialized memory on corrupted files + OJPEG: avoid use of uninitialized memory on corrupted files See merge request libtiff/libtiff!86 2019-07-05 Even Rouault - OJPEG: avoid use of unintialized memory on corrupted files. + OJPEG: avoid use of uninitialized memory on corrupted files. Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=925269 Patch from Lei Zhang with little adaptations. @@ -1849,12 +6578,12 @@ arrays are only loaded when first accessed. This can speed-up the opening of files stored on the network when just metadata retrieval is needed. This mode has been used for years by the GDAL library when compiled with - its embeded libtiff copy. + its embedded libtiff copy. To avoid potential out-of-tree code (typically codecs) that would use the td_stripbytecount and td_stripoffset array inconditionnaly assuming they have been loaded, those have been suffixed with _p (for protected). The - use of the new functions mentionned below is then recommended. + use of the new functions mentioned below is then recommended. Another addition of this commit is the capability of loading only the values of the offset/bytecount of the strile of interest instead of the @@ -1870,7 +6599,7 @@ if a strile is present or not without decompressing the data, or updating an existing sparse file. They will also be used to enable a future enhancement where client code can entirely - skip bytecount loading in some situtations + skip bytecount loading in some situations A new test/defer_strile_loading.c test has been added to test the above capabilities. @@ -2141,8 +6870,8 @@ Also the values were not properly calculated. It should be 255-x, 15-x, 3-x for bps 8, 4, 2. - But anyway it is easyer to invert all bits as 255-x = ~x, etc. - (substracting from a binary number composed of all 1 is like inverting + But anyway it is easier to invert all bits as 255-x = ~x, etc. + (subtracting from a binary number composed of all 1 is like inverting the bits) 2019-02-11 Thomas Bernard @@ -2670,7 +7399,7 @@ Merge branch 'zstd' - Add warning about COMPRESSION_ZSTD not being officialy registered. + Add warning about COMPRESSION_ZSTD not being officially registered. 2018-02-14 Even Rouault @@ -2900,7 +7629,7 @@ result, we end up writing past the end of the buffer. There are also some related issues that this also fixes. For example, - TIFFGetField can return uninitalized pointer values, and the logic to + TIFFGetField can return uninitialized pointer values, and the logic to detect a N=3 vs N=1 transfer function seemed rather strange. It is also strange that we declare the transfer functions to be of type @@ -3315,7 +8044,7 @@ scans and not interleavedin a single one, needs to allocate memory (or backing store) for the whole strip/tile. See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf - This limitation may be overriden by setting the + This limitation may be overridden by setting the LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, or recompiling libtiff with a custom value of TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro. @@ -3598,7 +8327,7 @@ * libtiff/tif_jpeg.c: only run JPEGFixupTagsSubsampling() if the YCbCrSubsampling tag is not explicitly present. This helps a bit to reduce - the I/O amount when te tag is present (especially on cloud hosted files). + the I/O amount when the tag is present (especially on cloud hosted files). 2017-01-14 Even Rouault @@ -3839,7 +8568,7 @@ 2016-12-03 Even Rouault * libtiff/tif_dirread.c: modify ChopUpSingleUncompressedStrip() to - instanciate compute ntrips as TIFFhowmany_32(td->td_imagelength, rowsperstrip), + instantiate compute nstrips as TIFFhowmany_32(td->td_imagelength, rowsperstrip), instead of a logic based on the total size of data. Which is faulty is the total size of data is not sufficient to fill the whole image, and thus results in reading outside of the StripByCounts/StripOffsets arrays when @@ -3863,7 +8592,7 @@ 2016-12-02 Even Rouault - * tools/tiffcp.c: avoid uint32 underflow in cpDecodedStrips that + * tools/tiffcp.c: avoid uint32 underflow in cpDecodedStrips that can cause various issues, such as buffer overflows in the library. Reported by Agostino Sarubbo. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2598 @@ -4305,7 +9034,7 @@ * libtiff/tif_write.c: TIFFWriteEncodedStrip() and TIFFWriteEncodedTile() should return -1 in case of failure of tif_encodestrip() as documented * libtiff/tif_dumpmode.c: DumpModeEncode() should return 0 in case of - failure so that the above mentionned functions detect the error. + failure so that the above mentioned functions detect the error. 2015-12-06 Even Rouault @@ -4328,7 +9057,7 @@ 2015-11-22 Even Rouault * libtiff/*.c: fix typos in comments (patch by Kurt Schwehr) - + 2015-11-22 Even Rouault * libtiff/*.c: fix MSVC warnings related to cast shortening and @@ -4896,7 +9625,7 @@ 2014-12-27 Even Rouault * libtiff/tif_dir.c: in TIFFDefaultDirectory(), reset any already existing - extented tags installed by user code through the extender mechaninm before + extended tags installed by user code through the extender mechanism before calling the extender callback (GDAL #5054) 2014-12-26 Bob Friesenhahn @@ -4999,14 +9728,14 @@ cpStripToTile() (called from writeBufferToContigTiles). Note that the resulting TIFF file would be scrambled even if tiffcp wouldn't crash, since the output file would contain - RGB data intepreted as subsampled YCbCr values. + RGB data interpreted as subsampled YCbCr values. This patch fixes the problem by forcing RGB space on the output TIF if the input is JPEG-encoded and output is *not* JPEG-encoded. Author: Tomasz Buchert 2014-12-21 Even Rouault - Fix various crasher bugs on fuzzed images. + Fix various crash bugs on fuzzed images. * libtiff/tif_dir.c: TIFFSetField(): refuse to set negative values for TIFFTAG_XRESOLUTION and TIFFTAG_YRESOLUTION that cause asserts when writing the directory @@ -5343,7 +10072,7 @@ * libtiff 4.0.2 released. - * tools/tif2pdf.c, tools/tifdump.c: avoid unitialized variable + * tools/tif2pdf.c, tools/tifdump.c: avoid uninitialized variable warnings with clang. 2012-06-15 Tom Lane @@ -6990,7 +11719,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic Added support for a TIFF_PTRDIFF_T type to use when doing pointer arithmetic. Added support for a TIFF_SSIZE_T in order to return memory sizes but still allow returning -1 for errors. - * libtiff/tiffconf.vc.h: Add porting type defintions for WIN32. + * libtiff/tiffconf.vc.h: Add porting type definitions for WIN32. 2007-06-25 Bob Friesenhahn @@ -7125,7 +11854,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic * libtiff/tif_config.wince.h: Added configuration header for WinCE. * libtiff/tiffconf.wince.h: Ported old configuration header for WinCE. * libtiff/tif_wince.c: Added WinCE-specific implementation of some - functons from tif_win32.c. + functions from tif_win32.c. * libtiff/tif_win32.c: Disabled some functions already reimplemented in tif_wince.c. * libtiff/tiffiop.h, port/lfind.c: Added conditional include of some standard header files for Windows CE build. @@ -7369,7 +12098,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic * libtiff/tif_jpeg.c: strip size related bugfix in encode raw - * libtiff/tif_strip.c: temporarilly added two new versions of + * libtiff/tif_strip.c: temporarily added two new versions of TIFFScanlineSize - TIFFNewScanlineSize: proposed new version, after all related issues and side-effects are sorted out @@ -7429,7 +12158,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic 2006-03-16 Andrey Kiselev - * libtiff/tiffiop.h: Added decalration for + * libtiff/tiffiop.h: Added declaration for _TIFFSetDefaultCompressionState(). * libtiff/{tif_jpeg.c, tif_fax3.c, tif_zip.c, tif_pixarlog.c, @@ -7759,7 +12488,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic http://bugzilla.remotesensing.org/show_bug.cgi?id=1003 - * libtiff/tif_dirinfo.c: Correctly yse bsearch() and lfind() + * libtiff/tif_dirinfo.c: Correctly use bsearch() and lfind() functions as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1008 @@ -7804,7 +12533,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic http://bugzilla.remotesensing.org/show_bug.cgi?id=977 - * tools/tiffsplit.c: Copy fax related fields over splitted parts + * tools/tiffsplit.c: Copy fax related fields over split parts as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=983 @@ -7986,12 +12715,12 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic 2005-06-07 Andrey Kiselev * contrib/addtiffo/tif_ovrcache.c: Properly extract tile/strip size; - use pixel sized shift in contigous case. + use pixel sized shift in contiguous case. 2005-06-06 Andrey Kiselev * contrib/addtiffo/{tif_overview.c, tif_ovrcache.c, tif_ovrcache.h}: - Make overviews working for contiguos images. + Make overviews working for contiguous images. 2005-06-03 Andrey Kiselev @@ -8421,7 +13150,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic http://bugzilla.remotesensing.org/show_bug.cgi?id=697 - * libtiff/tif_config.in.vc: Removed unneded definitions for + * libtiff/tif_config.in.vc: Removed unneeded definitions for read/open/close/lseek functions to fix the http://bugzilla.remotesensing.org/show_bug.cgi?id=680 @@ -9280,7 +14009,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic * man/tiff2pdf.1: Few improvements in page layout. * Makefile.in, /man/Makefile.in, /html/man/tiff2pdf.1.html: - Added support fpr tiff2pdf manual page. + Added support for tiff2pdf manual page. 2003-11-26 Ross Finlayson @@ -9289,7 +14018,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic 2003-11-26 Andrey Kiselev * Makefile.in, /tools/{Makefile.in, makefile.vc}: - Added support fpr tiff2pdf utility. + Added support for tiff2pdf utility. 2003-11-25 Ross Finlayson @@ -9332,7 +14061,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic 2003-11-17 Andrey Kiselev * contrib/pds/{tif_pdsdirread.c, tif_pdsdirwrite.c}: Use - TIFFDataWidth() function insted of tiffDataWidth array. + TIFFDataWidth() function instead of tiffDataWidth array. 2003-11-16 Andrey Kiselev @@ -10119,7 +14848,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic TIFFDataType sizes instead of working with tiffDataWidth array directly. Should prevent out-of-borders bugs in case of unknown or broken data types. EstimateStripByteCounts routine modified, so it - won't work when tags with uknown sizes founded. + won't work when tags with unknown sizes founded. Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=109 2002-03-13 Andrey Kiselev @@ -10321,7 +15050,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic * libtiff/tif_getimage.c: relax handling of contig case where there are extra samples that are supposed to be ignored. This - should now work for 8bit greyscale or palletted images. + should now work for 8bit greyscale or paletted images. http://bugzilla.remotesensing.org/show_bug.cgi?id=75 @@ -10551,7 +15280,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic 2001-02-16 Frank Warmerdam * libtiff/libtiff.def: Brent Roman submitted new version adding - serveral missing entry points. + several missing entry points. * libtiff/tif_dirinfo.c: don't declare tiffFieldInfo static on VMS. Some sort of weird VMS thing. @@ -10961,7 +15690,7 @@ Tue Nov 30 14:41:43 1999 Frank Warmerdam *** 3.5 Tue Nov 30 14:15:32 EST 1999 Mike Welles - * Added zip creation to relase makefile target + * Added zip creation to release makefile target * Added html for TIFFWriteTile.3t man page. diff --git a/3rdparty/libtiff/README.md b/3rdparty/libtiff/README.md new file mode 100644 index 0000000000..0d83ba24d9 --- /dev/null +++ b/3rdparty/libtiff/README.md @@ -0,0 +1,69 @@ +TIFF Software Distribution +-------------------------- +This file is just a placeholder; the entire documentation is now located +as reStructuredText in the doc directory. To view the documentation +as HTML, visit https://libtiff.gitlab.io/libtiff/ or +http://www.simplesystems.org/libtiff/ or within the release package +in the doc/html-prebuilt directory. The manual pages are +located at doc/man-prebuilt. + +The release package can be downloaded at + +http://download.osgeo.org/libtiff/ + +If you can't hack either of these options then basically what you +want to do is: + + % ./configure + % make + % su + # make install + +More information, email contacts, and mailing list information can be +found online at http://www.simplesystems.org/libtiff/ + +Source code repository +---------------------- + +[GitLab](https://gitlab.com/libtiff/libtiff) + +Bug database +------------ + +[GitLab issues](https://gitlab.com/libtiff/libtiff/issues) + +Previously, the project used +[Bugzilla](http://bugzilla.maptools.org/buglist.cgi?product=libtiff). This +is no longer in use, and all remaining issues have been migrated to GitLab. + +Use and Copyright +----------------- +Silicon Graphics has seen fit to allow us to give this work away. It +is free. There is no support or guarantee of any sort as to its +operations, correctness, or whatever. If you do anything useful with +all or parts of it you need to honor the copyright notices. I would +also be interested in knowing about it and, hopefully, be acknowledged. + +The legal way of saying that is: + +Copyright (c) 1988-1997 Sam Leffler +Copyright (c) 1991-1997 Silicon Graphics, Inc. + +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, provided +that (i) the above copyright notices and this permission notice appear in +all copies of the software and related documentation, and (ii) the names of +Sam Leffler and Silicon Graphics may not be used in any advertising or +publicity relating to the software without the specific, prior written +permission of Sam Leffler and Silicon Graphics. + +THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. diff --git a/3rdparty/libtiff/libport.h b/3rdparty/libtiff/libport.h deleted file mode 100644 index 9f2dace144..0000000000 --- a/3rdparty/libtiff/libport.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2009 Frank Warmerdam - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _LIBPORT_ -#define _LIBPORT_ - -#if defined(HAVE_CONFIG_H) -# include -#endif - -int getopt(int argc, char * const argv[], const char *optstring); -extern char *optarg; -extern int opterr; -extern int optind; -extern int optopt; - -int strcasecmp(const char *s1, const char *s2); - -#ifndef HAVE_GETOPT -# define HAVE_GETOPT 1 -#endif - -#if !defined(HAVE_STRTOL) -long strtol(const char *nptr, char **endptr, int base); -#endif -#if !defined(HAVE_STRTOLL) -long long strtoll(const char *nptr, char **endptr, int base); -#endif -#if !defined(HAVE_STRTOUL) -unsigned long strtoul(const char *nptr, char **endptr, int base); -#endif -#if !defined(HAVE_STRTOULL) -unsigned long long strtoull(const char *nptr, char **endptr, int base); -#endif - -#if 0 -void * -lfind(const void *key, const void *base, size_t *nmemb, size_t size, - int(*compar)(const void *, const void *)); -#endif - -#if !defined(HAVE_SNPRINTF) -#undef vsnprintf -#define vsnprintf _TIFF_vsnprintf_f - -#undef snprintf -#define snprintf _TIFF_snprintf_f -int snprintf(char* str, size_t size, const char* format, ...); -#endif - -#endif /* ndef _LIBPORT_ */ diff --git a/3rdparty/libtiff/snprintf.c b/3rdparty/libtiff/snprintf.c deleted file mode 100644 index 3542ab759b..0000000000 --- a/3rdparty/libtiff/snprintf.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Workaround for lack of snprintf(3) in Visual Studio. See - * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010/8712996#8712996 - * It's a trivial wrapper around the builtin _vsnprintf_s and - * _vscprintf functions. - */ - -#ifdef _MSC_VER - -#include -#include -#include "libport.h" - -int _TIFF_vsnprintf_f(char* str, size_t size, const char* format, va_list ap) -{ - int count = -1; - - if (size != 0) -#if _MSC_VER <= 1310 - count = _vsnprintf(str, size, format, ap); -#else - count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); -#endif - if (count == -1) - count = _vscprintf(format, ap); - - return count; -} - -int _TIFF_snprintf_f(char* str, size_t size, const char* format, ...) -{ - int count; - va_list ap; - - va_start(ap, format); - count = vsnprintf(str, size, format, ap); - va_end(ap); - - return count; -} - -#endif // _MSC_VER diff --git a/3rdparty/libtiff/t4.h b/3rdparty/libtiff/t4.h index fb0951a16f..f933d4a336 100644 --- a/3rdparty/libtiff/t4.h +++ b/3rdparty/libtiff/t4.h @@ -23,26 +23,27 @@ */ #ifndef _T4_ -#define _T4_ +#define _T4_ /* * CCITT T.4 1D Huffman runlength codes and * related definitions. Given the small sizes * of these tables it does not seem * worthwhile to make code & length 8 bits. */ -typedef struct tableentry { - unsigned short length; /* bit length of g3 code */ - unsigned short code; /* g3 code */ - short runlen; /* run length in bits */ +typedef struct tableentry +{ + unsigned short length; /* bit length of g3 code */ + unsigned short code; /* g3 code */ + short runlen; /* run length in bits */ } tableentry; -#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */ +#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */ /* status values returned instead of a run length */ -#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */ -#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */ -#define G3CODE_EOF -3 /* end of input data */ -#define G3CODE_INCOMP -4 /* incomplete run code */ +#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */ +#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */ +#define G3CODE_EOF -3 /* end of input data */ +#define G3CODE_INCOMP -4 /* incomplete run code */ /* * Note that these tables are ordered such that the @@ -54,237 +55,230 @@ typedef struct tableentry { */ #ifdef G3CODES const tableentry TIFFFaxWhiteCodes[] = { - { 8, 0x35, 0 }, /* 0011 0101 */ - { 6, 0x7, 1 }, /* 0001 11 */ - { 4, 0x7, 2 }, /* 0111 */ - { 4, 0x8, 3 }, /* 1000 */ - { 4, 0xB, 4 }, /* 1011 */ - { 4, 0xC, 5 }, /* 1100 */ - { 4, 0xE, 6 }, /* 1110 */ - { 4, 0xF, 7 }, /* 1111 */ - { 5, 0x13, 8 }, /* 1001 1 */ - { 5, 0x14, 9 }, /* 1010 0 */ - { 5, 0x7, 10 }, /* 0011 1 */ - { 5, 0x8, 11 }, /* 0100 0 */ - { 6, 0x8, 12 }, /* 0010 00 */ - { 6, 0x3, 13 }, /* 0000 11 */ - { 6, 0x34, 14 }, /* 1101 00 */ - { 6, 0x35, 15 }, /* 1101 01 */ - { 6, 0x2A, 16 }, /* 1010 10 */ - { 6, 0x2B, 17 }, /* 1010 11 */ - { 7, 0x27, 18 }, /* 0100 111 */ - { 7, 0xC, 19 }, /* 0001 100 */ - { 7, 0x8, 20 }, /* 0001 000 */ - { 7, 0x17, 21 }, /* 0010 111 */ - { 7, 0x3, 22 }, /* 0000 011 */ - { 7, 0x4, 23 }, /* 0000 100 */ - { 7, 0x28, 24 }, /* 0101 000 */ - { 7, 0x2B, 25 }, /* 0101 011 */ - { 7, 0x13, 26 }, /* 0010 011 */ - { 7, 0x24, 27 }, /* 0100 100 */ - { 7, 0x18, 28 }, /* 0011 000 */ - { 8, 0x2, 29 }, /* 0000 0010 */ - { 8, 0x3, 30 }, /* 0000 0011 */ - { 8, 0x1A, 31 }, /* 0001 1010 */ - { 8, 0x1B, 32 }, /* 0001 1011 */ - { 8, 0x12, 33 }, /* 0001 0010 */ - { 8, 0x13, 34 }, /* 0001 0011 */ - { 8, 0x14, 35 }, /* 0001 0100 */ - { 8, 0x15, 36 }, /* 0001 0101 */ - { 8, 0x16, 37 }, /* 0001 0110 */ - { 8, 0x17, 38 }, /* 0001 0111 */ - { 8, 0x28, 39 }, /* 0010 1000 */ - { 8, 0x29, 40 }, /* 0010 1001 */ - { 8, 0x2A, 41 }, /* 0010 1010 */ - { 8, 0x2B, 42 }, /* 0010 1011 */ - { 8, 0x2C, 43 }, /* 0010 1100 */ - { 8, 0x2D, 44 }, /* 0010 1101 */ - { 8, 0x4, 45 }, /* 0000 0100 */ - { 8, 0x5, 46 }, /* 0000 0101 */ - { 8, 0xA, 47 }, /* 0000 1010 */ - { 8, 0xB, 48 }, /* 0000 1011 */ - { 8, 0x52, 49 }, /* 0101 0010 */ - { 8, 0x53, 50 }, /* 0101 0011 */ - { 8, 0x54, 51 }, /* 0101 0100 */ - { 8, 0x55, 52 }, /* 0101 0101 */ - { 8, 0x24, 53 }, /* 0010 0100 */ - { 8, 0x25, 54 }, /* 0010 0101 */ - { 8, 0x58, 55 }, /* 0101 1000 */ - { 8, 0x59, 56 }, /* 0101 1001 */ - { 8, 0x5A, 57 }, /* 0101 1010 */ - { 8, 0x5B, 58 }, /* 0101 1011 */ - { 8, 0x4A, 59 }, /* 0100 1010 */ - { 8, 0x4B, 60 }, /* 0100 1011 */ - { 8, 0x32, 61 }, /* 0011 0010 */ - { 8, 0x33, 62 }, /* 0011 0011 */ - { 8, 0x34, 63 }, /* 0011 0100 */ - { 5, 0x1B, 64 }, /* 1101 1 */ - { 5, 0x12, 128 }, /* 1001 0 */ - { 6, 0x17, 192 }, /* 0101 11 */ - { 7, 0x37, 256 }, /* 0110 111 */ - { 8, 0x36, 320 }, /* 0011 0110 */ - { 8, 0x37, 384 }, /* 0011 0111 */ - { 8, 0x64, 448 }, /* 0110 0100 */ - { 8, 0x65, 512 }, /* 0110 0101 */ - { 8, 0x68, 576 }, /* 0110 1000 */ - { 8, 0x67, 640 }, /* 0110 0111 */ - { 9, 0xCC, 704 }, /* 0110 0110 0 */ - { 9, 0xCD, 768 }, /* 0110 0110 1 */ - { 9, 0xD2, 832 }, /* 0110 1001 0 */ - { 9, 0xD3, 896 }, /* 0110 1001 1 */ - { 9, 0xD4, 960 }, /* 0110 1010 0 */ - { 9, 0xD5, 1024 }, /* 0110 1010 1 */ - { 9, 0xD6, 1088 }, /* 0110 1011 0 */ - { 9, 0xD7, 1152 }, /* 0110 1011 1 */ - { 9, 0xD8, 1216 }, /* 0110 1100 0 */ - { 9, 0xD9, 1280 }, /* 0110 1100 1 */ - { 9, 0xDA, 1344 }, /* 0110 1101 0 */ - { 9, 0xDB, 1408 }, /* 0110 1101 1 */ - { 9, 0x98, 1472 }, /* 0100 1100 0 */ - { 9, 0x99, 1536 }, /* 0100 1100 1 */ - { 9, 0x9A, 1600 }, /* 0100 1101 0 */ - { 6, 0x18, 1664 }, /* 0110 00 */ - { 9, 0x9B, 1728 }, /* 0100 1101 1 */ - { 11, 0x8, 1792 }, /* 0000 0001 000 */ - { 11, 0xC, 1856 }, /* 0000 0001 100 */ - { 11, 0xD, 1920 }, /* 0000 0001 101 */ - { 12, 0x12, 1984 }, /* 0000 0001 0010 */ - { 12, 0x13, 2048 }, /* 0000 0001 0011 */ - { 12, 0x14, 2112 }, /* 0000 0001 0100 */ - { 12, 0x15, 2176 }, /* 0000 0001 0101 */ - { 12, 0x16, 2240 }, /* 0000 0001 0110 */ - { 12, 0x17, 2304 }, /* 0000 0001 0111 */ - { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ - { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ - { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ - { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ - { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ - { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ - { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ - { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ - { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */ + {8, 0x35, 0}, /* 0011 0101 */ + {6, 0x7, 1}, /* 0001 11 */ + {4, 0x7, 2}, /* 0111 */ + {4, 0x8, 3}, /* 1000 */ + {4, 0xB, 4}, /* 1011 */ + {4, 0xC, 5}, /* 1100 */ + {4, 0xE, 6}, /* 1110 */ + {4, 0xF, 7}, /* 1111 */ + {5, 0x13, 8}, /* 1001 1 */ + {5, 0x14, 9}, /* 1010 0 */ + {5, 0x7, 10}, /* 0011 1 */ + {5, 0x8, 11}, /* 0100 0 */ + {6, 0x8, 12}, /* 0010 00 */ + {6, 0x3, 13}, /* 0000 11 */ + {6, 0x34, 14}, /* 1101 00 */ + {6, 0x35, 15}, /* 1101 01 */ + {6, 0x2A, 16}, /* 1010 10 */ + {6, 0x2B, 17}, /* 1010 11 */ + {7, 0x27, 18}, /* 0100 111 */ + {7, 0xC, 19}, /* 0001 100 */ + {7, 0x8, 20}, /* 0001 000 */ + {7, 0x17, 21}, /* 0010 111 */ + {7, 0x3, 22}, /* 0000 011 */ + {7, 0x4, 23}, /* 0000 100 */ + {7, 0x28, 24}, /* 0101 000 */ + {7, 0x2B, 25}, /* 0101 011 */ + {7, 0x13, 26}, /* 0010 011 */ + {7, 0x24, 27}, /* 0100 100 */ + {7, 0x18, 28}, /* 0011 000 */ + {8, 0x2, 29}, /* 0000 0010 */ + {8, 0x3, 30}, /* 0000 0011 */ + {8, 0x1A, 31}, /* 0001 1010 */ + {8, 0x1B, 32}, /* 0001 1011 */ + {8, 0x12, 33}, /* 0001 0010 */ + {8, 0x13, 34}, /* 0001 0011 */ + {8, 0x14, 35}, /* 0001 0100 */ + {8, 0x15, 36}, /* 0001 0101 */ + {8, 0x16, 37}, /* 0001 0110 */ + {8, 0x17, 38}, /* 0001 0111 */ + {8, 0x28, 39}, /* 0010 1000 */ + {8, 0x29, 40}, /* 0010 1001 */ + {8, 0x2A, 41}, /* 0010 1010 */ + {8, 0x2B, 42}, /* 0010 1011 */ + {8, 0x2C, 43}, /* 0010 1100 */ + {8, 0x2D, 44}, /* 0010 1101 */ + {8, 0x4, 45}, /* 0000 0100 */ + {8, 0x5, 46}, /* 0000 0101 */ + {8, 0xA, 47}, /* 0000 1010 */ + {8, 0xB, 48}, /* 0000 1011 */ + {8, 0x52, 49}, /* 0101 0010 */ + {8, 0x53, 50}, /* 0101 0011 */ + {8, 0x54, 51}, /* 0101 0100 */ + {8, 0x55, 52}, /* 0101 0101 */ + {8, 0x24, 53}, /* 0010 0100 */ + {8, 0x25, 54}, /* 0010 0101 */ + {8, 0x58, 55}, /* 0101 1000 */ + {8, 0x59, 56}, /* 0101 1001 */ + {8, 0x5A, 57}, /* 0101 1010 */ + {8, 0x5B, 58}, /* 0101 1011 */ + {8, 0x4A, 59}, /* 0100 1010 */ + {8, 0x4B, 60}, /* 0100 1011 */ + {8, 0x32, 61}, /* 0011 0010 */ + {8, 0x33, 62}, /* 0011 0011 */ + {8, 0x34, 63}, /* 0011 0100 */ + {5, 0x1B, 64}, /* 1101 1 */ + {5, 0x12, 128}, /* 1001 0 */ + {6, 0x17, 192}, /* 0101 11 */ + {7, 0x37, 256}, /* 0110 111 */ + {8, 0x36, 320}, /* 0011 0110 */ + {8, 0x37, 384}, /* 0011 0111 */ + {8, 0x64, 448}, /* 0110 0100 */ + {8, 0x65, 512}, /* 0110 0101 */ + {8, 0x68, 576}, /* 0110 1000 */ + {8, 0x67, 640}, /* 0110 0111 */ + {9, 0xCC, 704}, /* 0110 0110 0 */ + {9, 0xCD, 768}, /* 0110 0110 1 */ + {9, 0xD2, 832}, /* 0110 1001 0 */ + {9, 0xD3, 896}, /* 0110 1001 1 */ + {9, 0xD4, 960}, /* 0110 1010 0 */ + {9, 0xD5, 1024}, /* 0110 1010 1 */ + {9, 0xD6, 1088}, /* 0110 1011 0 */ + {9, 0xD7, 1152}, /* 0110 1011 1 */ + {9, 0xD8, 1216}, /* 0110 1100 0 */ + {9, 0xD9, 1280}, /* 0110 1100 1 */ + {9, 0xDA, 1344}, /* 0110 1101 0 */ + {9, 0xDB, 1408}, /* 0110 1101 1 */ + {9, 0x98, 1472}, /* 0100 1100 0 */ + {9, 0x99, 1536}, /* 0100 1100 1 */ + {9, 0x9A, 1600}, /* 0100 1101 0 */ + {6, 0x18, 1664}, /* 0110 00 */ + {9, 0x9B, 1728}, /* 0100 1101 1 */ + {11, 0x8, 1792}, /* 0000 0001 000 */ + {11, 0xC, 1856}, /* 0000 0001 100 */ + {11, 0xD, 1920}, /* 0000 0001 101 */ + {12, 0x12, 1984}, /* 0000 0001 0010 */ + {12, 0x13, 2048}, /* 0000 0001 0011 */ + {12, 0x14, 2112}, /* 0000 0001 0100 */ + {12, 0x15, 2176}, /* 0000 0001 0101 */ + {12, 0x16, 2240}, /* 0000 0001 0110 */ + {12, 0x17, 2304}, /* 0000 0001 0111 */ + {12, 0x1C, 2368}, /* 0000 0001 1100 */ + {12, 0x1D, 2432}, /* 0000 0001 1101 */ + {12, 0x1E, 2496}, /* 0000 0001 1110 */ + {12, 0x1F, 2560}, /* 0000 0001 1111 */ + {12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */ + {9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */ + {10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */ + {11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */ + {12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */ }; const tableentry TIFFFaxBlackCodes[] = { - { 10, 0x37, 0 }, /* 0000 1101 11 */ - { 3, 0x2, 1 }, /* 010 */ - { 2, 0x3, 2 }, /* 11 */ - { 2, 0x2, 3 }, /* 10 */ - { 3, 0x3, 4 }, /* 011 */ - { 4, 0x3, 5 }, /* 0011 */ - { 4, 0x2, 6 }, /* 0010 */ - { 5, 0x3, 7 }, /* 0001 1 */ - { 6, 0x5, 8 }, /* 0001 01 */ - { 6, 0x4, 9 }, /* 0001 00 */ - { 7, 0x4, 10 }, /* 0000 100 */ - { 7, 0x5, 11 }, /* 0000 101 */ - { 7, 0x7, 12 }, /* 0000 111 */ - { 8, 0x4, 13 }, /* 0000 0100 */ - { 8, 0x7, 14 }, /* 0000 0111 */ - { 9, 0x18, 15 }, /* 0000 1100 0 */ - { 10, 0x17, 16 }, /* 0000 0101 11 */ - { 10, 0x18, 17 }, /* 0000 0110 00 */ - { 10, 0x8, 18 }, /* 0000 0010 00 */ - { 11, 0x67, 19 }, /* 0000 1100 111 */ - { 11, 0x68, 20 }, /* 0000 1101 000 */ - { 11, 0x6C, 21 }, /* 0000 1101 100 */ - { 11, 0x37, 22 }, /* 0000 0110 111 */ - { 11, 0x28, 23 }, /* 0000 0101 000 */ - { 11, 0x17, 24 }, /* 0000 0010 111 */ - { 11, 0x18, 25 }, /* 0000 0011 000 */ - { 12, 0xCA, 26 }, /* 0000 1100 1010 */ - { 12, 0xCB, 27 }, /* 0000 1100 1011 */ - { 12, 0xCC, 28 }, /* 0000 1100 1100 */ - { 12, 0xCD, 29 }, /* 0000 1100 1101 */ - { 12, 0x68, 30 }, /* 0000 0110 1000 */ - { 12, 0x69, 31 }, /* 0000 0110 1001 */ - { 12, 0x6A, 32 }, /* 0000 0110 1010 */ - { 12, 0x6B, 33 }, /* 0000 0110 1011 */ - { 12, 0xD2, 34 }, /* 0000 1101 0010 */ - { 12, 0xD3, 35 }, /* 0000 1101 0011 */ - { 12, 0xD4, 36 }, /* 0000 1101 0100 */ - { 12, 0xD5, 37 }, /* 0000 1101 0101 */ - { 12, 0xD6, 38 }, /* 0000 1101 0110 */ - { 12, 0xD7, 39 }, /* 0000 1101 0111 */ - { 12, 0x6C, 40 }, /* 0000 0110 1100 */ - { 12, 0x6D, 41 }, /* 0000 0110 1101 */ - { 12, 0xDA, 42 }, /* 0000 1101 1010 */ - { 12, 0xDB, 43 }, /* 0000 1101 1011 */ - { 12, 0x54, 44 }, /* 0000 0101 0100 */ - { 12, 0x55, 45 }, /* 0000 0101 0101 */ - { 12, 0x56, 46 }, /* 0000 0101 0110 */ - { 12, 0x57, 47 }, /* 0000 0101 0111 */ - { 12, 0x64, 48 }, /* 0000 0110 0100 */ - { 12, 0x65, 49 }, /* 0000 0110 0101 */ - { 12, 0x52, 50 }, /* 0000 0101 0010 */ - { 12, 0x53, 51 }, /* 0000 0101 0011 */ - { 12, 0x24, 52 }, /* 0000 0010 0100 */ - { 12, 0x37, 53 }, /* 0000 0011 0111 */ - { 12, 0x38, 54 }, /* 0000 0011 1000 */ - { 12, 0x27, 55 }, /* 0000 0010 0111 */ - { 12, 0x28, 56 }, /* 0000 0010 1000 */ - { 12, 0x58, 57 }, /* 0000 0101 1000 */ - { 12, 0x59, 58 }, /* 0000 0101 1001 */ - { 12, 0x2B, 59 }, /* 0000 0010 1011 */ - { 12, 0x2C, 60 }, /* 0000 0010 1100 */ - { 12, 0x5A, 61 }, /* 0000 0101 1010 */ - { 12, 0x66, 62 }, /* 0000 0110 0110 */ - { 12, 0x67, 63 }, /* 0000 0110 0111 */ - { 10, 0xF, 64 }, /* 0000 0011 11 */ - { 12, 0xC8, 128 }, /* 0000 1100 1000 */ - { 12, 0xC9, 192 }, /* 0000 1100 1001 */ - { 12, 0x5B, 256 }, /* 0000 0101 1011 */ - { 12, 0x33, 320 }, /* 0000 0011 0011 */ - { 12, 0x34, 384 }, /* 0000 0011 0100 */ - { 12, 0x35, 448 }, /* 0000 0011 0101 */ - { 13, 0x6C, 512 }, /* 0000 0011 0110 0 */ - { 13, 0x6D, 576 }, /* 0000 0011 0110 1 */ - { 13, 0x4A, 640 }, /* 0000 0010 0101 0 */ - { 13, 0x4B, 704 }, /* 0000 0010 0101 1 */ - { 13, 0x4C, 768 }, /* 0000 0010 0110 0 */ - { 13, 0x4D, 832 }, /* 0000 0010 0110 1 */ - { 13, 0x72, 896 }, /* 0000 0011 1001 0 */ - { 13, 0x73, 960 }, /* 0000 0011 1001 1 */ - { 13, 0x74, 1024 }, /* 0000 0011 1010 0 */ - { 13, 0x75, 1088 }, /* 0000 0011 1010 1 */ - { 13, 0x76, 1152 }, /* 0000 0011 1011 0 */ - { 13, 0x77, 1216 }, /* 0000 0011 1011 1 */ - { 13, 0x52, 1280 }, /* 0000 0010 1001 0 */ - { 13, 0x53, 1344 }, /* 0000 0010 1001 1 */ - { 13, 0x54, 1408 }, /* 0000 0010 1010 0 */ - { 13, 0x55, 1472 }, /* 0000 0010 1010 1 */ - { 13, 0x5A, 1536 }, /* 0000 0010 1101 0 */ - { 13, 0x5B, 1600 }, /* 0000 0010 1101 1 */ - { 13, 0x64, 1664 }, /* 0000 0011 0010 0 */ - { 13, 0x65, 1728 }, /* 0000 0011 0010 1 */ - { 11, 0x8, 1792 }, /* 0000 0001 000 */ - { 11, 0xC, 1856 }, /* 0000 0001 100 */ - { 11, 0xD, 1920 }, /* 0000 0001 101 */ - { 12, 0x12, 1984 }, /* 0000 0001 0010 */ - { 12, 0x13, 2048 }, /* 0000 0001 0011 */ - { 12, 0x14, 2112 }, /* 0000 0001 0100 */ - { 12, 0x15, 2176 }, /* 0000 0001 0101 */ - { 12, 0x16, 2240 }, /* 0000 0001 0110 */ - { 12, 0x17, 2304 }, /* 0000 0001 0111 */ - { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ - { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ - { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ - { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ - { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ - { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ - { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ - { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ - { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */ + {10, 0x37, 0}, /* 0000 1101 11 */ + {3, 0x2, 1}, /* 010 */ + {2, 0x3, 2}, /* 11 */ + {2, 0x2, 3}, /* 10 */ + {3, 0x3, 4}, /* 011 */ + {4, 0x3, 5}, /* 0011 */ + {4, 0x2, 6}, /* 0010 */ + {5, 0x3, 7}, /* 0001 1 */ + {6, 0x5, 8}, /* 0001 01 */ + {6, 0x4, 9}, /* 0001 00 */ + {7, 0x4, 10}, /* 0000 100 */ + {7, 0x5, 11}, /* 0000 101 */ + {7, 0x7, 12}, /* 0000 111 */ + {8, 0x4, 13}, /* 0000 0100 */ + {8, 0x7, 14}, /* 0000 0111 */ + {9, 0x18, 15}, /* 0000 1100 0 */ + {10, 0x17, 16}, /* 0000 0101 11 */ + {10, 0x18, 17}, /* 0000 0110 00 */ + {10, 0x8, 18}, /* 0000 0010 00 */ + {11, 0x67, 19}, /* 0000 1100 111 */ + {11, 0x68, 20}, /* 0000 1101 000 */ + {11, 0x6C, 21}, /* 0000 1101 100 */ + {11, 0x37, 22}, /* 0000 0110 111 */ + {11, 0x28, 23}, /* 0000 0101 000 */ + {11, 0x17, 24}, /* 0000 0010 111 */ + {11, 0x18, 25}, /* 0000 0011 000 */ + {12, 0xCA, 26}, /* 0000 1100 1010 */ + {12, 0xCB, 27}, /* 0000 1100 1011 */ + {12, 0xCC, 28}, /* 0000 1100 1100 */ + {12, 0xCD, 29}, /* 0000 1100 1101 */ + {12, 0x68, 30}, /* 0000 0110 1000 */ + {12, 0x69, 31}, /* 0000 0110 1001 */ + {12, 0x6A, 32}, /* 0000 0110 1010 */ + {12, 0x6B, 33}, /* 0000 0110 1011 */ + {12, 0xD2, 34}, /* 0000 1101 0010 */ + {12, 0xD3, 35}, /* 0000 1101 0011 */ + {12, 0xD4, 36}, /* 0000 1101 0100 */ + {12, 0xD5, 37}, /* 0000 1101 0101 */ + {12, 0xD6, 38}, /* 0000 1101 0110 */ + {12, 0xD7, 39}, /* 0000 1101 0111 */ + {12, 0x6C, 40}, /* 0000 0110 1100 */ + {12, 0x6D, 41}, /* 0000 0110 1101 */ + {12, 0xDA, 42}, /* 0000 1101 1010 */ + {12, 0xDB, 43}, /* 0000 1101 1011 */ + {12, 0x54, 44}, /* 0000 0101 0100 */ + {12, 0x55, 45}, /* 0000 0101 0101 */ + {12, 0x56, 46}, /* 0000 0101 0110 */ + {12, 0x57, 47}, /* 0000 0101 0111 */ + {12, 0x64, 48}, /* 0000 0110 0100 */ + {12, 0x65, 49}, /* 0000 0110 0101 */ + {12, 0x52, 50}, /* 0000 0101 0010 */ + {12, 0x53, 51}, /* 0000 0101 0011 */ + {12, 0x24, 52}, /* 0000 0010 0100 */ + {12, 0x37, 53}, /* 0000 0011 0111 */ + {12, 0x38, 54}, /* 0000 0011 1000 */ + {12, 0x27, 55}, /* 0000 0010 0111 */ + {12, 0x28, 56}, /* 0000 0010 1000 */ + {12, 0x58, 57}, /* 0000 0101 1000 */ + {12, 0x59, 58}, /* 0000 0101 1001 */ + {12, 0x2B, 59}, /* 0000 0010 1011 */ + {12, 0x2C, 60}, /* 0000 0010 1100 */ + {12, 0x5A, 61}, /* 0000 0101 1010 */ + {12, 0x66, 62}, /* 0000 0110 0110 */ + {12, 0x67, 63}, /* 0000 0110 0111 */ + {10, 0xF, 64}, /* 0000 0011 11 */ + {12, 0xC8, 128}, /* 0000 1100 1000 */ + {12, 0xC9, 192}, /* 0000 1100 1001 */ + {12, 0x5B, 256}, /* 0000 0101 1011 */ + {12, 0x33, 320}, /* 0000 0011 0011 */ + {12, 0x34, 384}, /* 0000 0011 0100 */ + {12, 0x35, 448}, /* 0000 0011 0101 */ + {13, 0x6C, 512}, /* 0000 0011 0110 0 */ + {13, 0x6D, 576}, /* 0000 0011 0110 1 */ + {13, 0x4A, 640}, /* 0000 0010 0101 0 */ + {13, 0x4B, 704}, /* 0000 0010 0101 1 */ + {13, 0x4C, 768}, /* 0000 0010 0110 0 */ + {13, 0x4D, 832}, /* 0000 0010 0110 1 */ + {13, 0x72, 896}, /* 0000 0011 1001 0 */ + {13, 0x73, 960}, /* 0000 0011 1001 1 */ + {13, 0x74, 1024}, /* 0000 0011 1010 0 */ + {13, 0x75, 1088}, /* 0000 0011 1010 1 */ + {13, 0x76, 1152}, /* 0000 0011 1011 0 */ + {13, 0x77, 1216}, /* 0000 0011 1011 1 */ + {13, 0x52, 1280}, /* 0000 0010 1001 0 */ + {13, 0x53, 1344}, /* 0000 0010 1001 1 */ + {13, 0x54, 1408}, /* 0000 0010 1010 0 */ + {13, 0x55, 1472}, /* 0000 0010 1010 1 */ + {13, 0x5A, 1536}, /* 0000 0010 1101 0 */ + {13, 0x5B, 1600}, /* 0000 0010 1101 1 */ + {13, 0x64, 1664}, /* 0000 0011 0010 0 */ + {13, 0x65, 1728}, /* 0000 0011 0010 1 */ + {11, 0x8, 1792}, /* 0000 0001 000 */ + {11, 0xC, 1856}, /* 0000 0001 100 */ + {11, 0xD, 1920}, /* 0000 0001 101 */ + {12, 0x12, 1984}, /* 0000 0001 0010 */ + {12, 0x13, 2048}, /* 0000 0001 0011 */ + {12, 0x14, 2112}, /* 0000 0001 0100 */ + {12, 0x15, 2176}, /* 0000 0001 0101 */ + {12, 0x16, 2240}, /* 0000 0001 0110 */ + {12, 0x17, 2304}, /* 0000 0001 0111 */ + {12, 0x1C, 2368}, /* 0000 0001 1100 */ + {12, 0x1D, 2432}, /* 0000 0001 1101 */ + {12, 0x1E, 2496}, /* 0000 0001 1110 */ + {12, 0x1F, 2560}, /* 0000 0001 1111 */ + {12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */ + {9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */ + {10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */ + {11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */ + {12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */ }; #else extern const tableentry TIFFFaxWhiteCodes[]; extern const tableentry TIFFFaxBlackCodes[]; #endif #endif /* _T4_ */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_aux.c b/3rdparty/libtiff/tif_aux.c index c9f190545e..49855bb0b2 100644 --- a/3rdparty/libtiff/tif_aux.c +++ b/3rdparty/libtiff/tif_aux.c @@ -2,23 +2,23 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -27,173 +27,180 @@ * * Auxiliary Support Routines. */ -#include "tiffiop.h" #include "tif_predict.h" -#include +#include "tiffiop.h" #include +#include -uint32 -_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where) +uint32_t _TIFFMultiply32(TIFF *tif, uint32_t first, uint32_t second, + const char *where) { - if (second && first > TIFF_UINT32_MAX / second) { - TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where); - return 0; - } - - return first * second; -} - -uint64 -_TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where) -{ - if (second && first > TIFF_UINT64_MAX / second) { - TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where); - return 0; - } - - return first * second; -} - -tmsize_t -_TIFFMultiplySSize(TIFF* tif, tmsize_t first, tmsize_t second, const char* where) -{ - if( first <= 0 || second <= 0 ) + if (second && first > UINT32_MAX / second) { - if( tif != NULL && where != NULL ) + TIFFErrorExtR(tif, where, "Integer overflow in %s", where); + return 0; + } + + return first * second; +} + +uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second, + const char *where) +{ + if (second && first > UINT64_MAX / second) + { + TIFFErrorExtR(tif, where, "Integer overflow in %s", where); + return 0; + } + + return first * second; +} + +tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second, + const char *where) +{ + if (first <= 0 || second <= 0) + { + if (tif != NULL && where != NULL) { - TIFFErrorExt(tif->tif_clientdata, where, - "Invalid argument to _TIFFMultiplySSize() in %s", where); + TIFFErrorExtR(tif, where, + "Invalid argument to _TIFFMultiplySSize() in %s", + where); } return 0; } - if( first > TIFF_TMSIZE_T_MAX / second ) + if (first > TIFF_TMSIZE_T_MAX / second) { - if( tif != NULL && where != NULL ) + if (tif != NULL && where != NULL) { - TIFFErrorExt(tif->tif_clientdata, where, - "Integer overflow in %s", where); + TIFFErrorExtR(tif, where, "Integer overflow in %s", where); } return 0; } return first * second; } -tmsize_t _TIFFCastUInt64ToSSize(TIFF* tif, uint64 val, const char* module) +tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module) { - if( val > (uint64)TIFF_TMSIZE_T_MAX ) + if (val > (uint64_t)TIFF_TMSIZE_T_MAX) { - if( tif != NULL && module != NULL ) + if (tif != NULL && module != NULL) { - TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + TIFFErrorExtR(tif, module, "Integer overflow"); } return 0; } return (tmsize_t)val; } -void* -_TIFFCheckRealloc(TIFF* tif, void* buffer, - tmsize_t nmemb, tmsize_t elem_size, const char* what) +void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb, + tmsize_t elem_size, const char *what) { - void* cp = NULL; - tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL); - /* - * Check for integer overflow. - */ - if (count != 0) - { - cp = _TIFFrealloc(buffer, count); - } + void *cp = NULL; + tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL); + /* + * Check for integer overflow. + */ + if (count != 0) + { + cp = _TIFFreallocExt(tif, buffer, count); + } - if (cp == NULL) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Failed to allocate memory for %s " - "(%ld elements of %ld bytes each)", - what,(long) nmemb, (long) elem_size); - } + if (cp == NULL) + { + TIFFErrorExtR(tif, tif->tif_name, + "Failed to allocate memory for %s " + "(%" TIFF_SSIZE_FORMAT " elements of %" TIFF_SSIZE_FORMAT + " bytes each)", + what, nmemb, elem_size); + } - return cp; + return cp; } -void* -_TIFFCheckMalloc(TIFF* tif, tmsize_t nmemb, tmsize_t elem_size, const char* what) +void *_TIFFCheckMalloc(TIFF *tif, tmsize_t nmemb, tmsize_t elem_size, + const char *what) { - return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what); + return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what); } -static int -TIFFDefaultTransferFunction(TIFFDirectory* td) +static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td) { - uint16 **tf = td->td_transferfunction; - tmsize_t i, n, nbytes; + uint16_t **tf = td->td_transferfunction; + tmsize_t i, n, nbytes; - tf[0] = tf[1] = tf[2] = 0; - if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2) - return 0; + tf[0] = tf[1] = tf[2] = 0; + if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2) + return 0; - n = ((tmsize_t)1)<td_bitspersample; - nbytes = n * sizeof (uint16); - tf[0] = (uint16 *)_TIFFmalloc(nbytes); - if (tf[0] == NULL) - return 0; - tf[0][0] = 0; - for (i = 1; i < n; i++) { - double t = (double)i/((double) n-1.); - tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5); - } + n = ((tmsize_t)1) << td->td_bitspersample; + nbytes = n * sizeof(uint16_t); + tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes); + if (tf[0] == NULL) + return 0; + tf[0][0] = 0; + for (i = 1; i < n; i++) + { + double t = (double)i / ((double)n - 1.); + tf[0][i] = (uint16_t)floor(65535. * pow(t, 2.2) + .5); + } - if (td->td_samplesperpixel - td->td_extrasamples > 1) { - tf[1] = (uint16 *)_TIFFmalloc(nbytes); - if(tf[1] == NULL) - goto bad; - _TIFFmemcpy(tf[1], tf[0], nbytes); - tf[2] = (uint16 *)_TIFFmalloc(nbytes); - if (tf[2] == NULL) - goto bad; - _TIFFmemcpy(tf[2], tf[0], nbytes); - } - return 1; + if (td->td_samplesperpixel - td->td_extrasamples > 1) + { + tf[1] = (uint16_t *)_TIFFmallocExt(tif, nbytes); + if (tf[1] == NULL) + goto bad; + _TIFFmemcpy(tf[1], tf[0], nbytes); + tf[2] = (uint16_t *)_TIFFmallocExt(tif, nbytes); + if (tf[2] == NULL) + goto bad; + _TIFFmemcpy(tf[2], tf[0], nbytes); + } + return 1; bad: - if (tf[0]) - _TIFFfree(tf[0]); - if (tf[1]) - _TIFFfree(tf[1]); - if (tf[2]) - _TIFFfree(tf[2]); - tf[0] = tf[1] = tf[2] = 0; - return 0; + if (tf[0]) + _TIFFfreeExt(tif, tf[0]); + if (tf[1]) + _TIFFfreeExt(tif, tf[1]); + if (tf[2]) + _TIFFfreeExt(tif, tf[2]); + tf[0] = tf[1] = tf[2] = 0; + return 0; } -static int -TIFFDefaultRefBlackWhite(TIFFDirectory* td) +static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td) { - int i; + int i; - td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float)); - if (td->td_refblackwhite == NULL) - return 0; - if (td->td_photometric == PHOTOMETRIC_YCBCR) { - /* - * YCbCr (Class Y) images must have the ReferenceBlackWhite - * tag set. Fix the broken images, which lacks that tag. - */ - td->td_refblackwhite[0] = 0.0F; - td->td_refblackwhite[1] = td->td_refblackwhite[3] = - td->td_refblackwhite[5] = 255.0F; - td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F; - } else { - /* - * Assume RGB (Class R) - */ - for (i = 0; i < 3; i++) { - td->td_refblackwhite[2*i+0] = 0; - td->td_refblackwhite[2*i+1] = - (float)((1L<td_bitspersample)-1L); - } - } - return 1; + td->td_refblackwhite = (float *)_TIFFmallocExt(tif, 6 * sizeof(float)); + if (td->td_refblackwhite == NULL) + return 0; + if (td->td_photometric == PHOTOMETRIC_YCBCR) + { + /* + * YCbCr (Class Y) images must have the ReferenceBlackWhite + * tag set. Fix the broken images, which lacks that tag. + */ + td->td_refblackwhite[0] = 0.0F; + td->td_refblackwhite[1] = td->td_refblackwhite[3] = + td->td_refblackwhite[5] = 255.0F; + td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F; + } + else + { + /* + * Assume RGB (Class R) + */ + for (i = 0; i < 3; i++) + { + td->td_refblackwhite[2 * i + 0] = 0; + td->td_refblackwhite[2 * i + 1] = + (float)((1L << td->td_bitspersample) - 1L); + } + } + return 1; } /* @@ -204,216 +211,248 @@ TIFFDefaultRefBlackWhite(TIFFDirectory* td) * explicit values so that defaults exist only one * place in the library -- in TIFFDefaultDirectory. */ -int -TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap) +int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap) { - TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; - if (TIFFVGetField(tif, tag, ap)) - return (1); - switch (tag) { - case TIFFTAG_SUBFILETYPE: - *va_arg(ap, uint32 *) = td->td_subfiletype; - return (1); - case TIFFTAG_BITSPERSAMPLE: - *va_arg(ap, uint16 *) = td->td_bitspersample; - return (1); - case TIFFTAG_THRESHHOLDING: - *va_arg(ap, uint16 *) = td->td_threshholding; - return (1); - case TIFFTAG_FILLORDER: - *va_arg(ap, uint16 *) = td->td_fillorder; - return (1); - case TIFFTAG_ORIENTATION: - *va_arg(ap, uint16 *) = td->td_orientation; - return (1); - case TIFFTAG_SAMPLESPERPIXEL: - *va_arg(ap, uint16 *) = td->td_samplesperpixel; - return (1); - case TIFFTAG_ROWSPERSTRIP: - *va_arg(ap, uint32 *) = td->td_rowsperstrip; - return (1); - case TIFFTAG_MINSAMPLEVALUE: - *va_arg(ap, uint16 *) = td->td_minsamplevalue; - return (1); - case TIFFTAG_MAXSAMPLEVALUE: - *va_arg(ap, uint16 *) = td->td_maxsamplevalue; - return (1); - case TIFFTAG_PLANARCONFIG: - *va_arg(ap, uint16 *) = td->td_planarconfig; - return (1); - case TIFFTAG_RESOLUTIONUNIT: - *va_arg(ap, uint16 *) = td->td_resolutionunit; - return (1); - case TIFFTAG_PREDICTOR: + if (TIFFVGetField(tif, tag, ap)) + return (1); + switch (tag) { - TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data; - if( sp == NULL ) + case TIFFTAG_SUBFILETYPE: + *va_arg(ap, uint32_t *) = td->td_subfiletype; + return (1); + case TIFFTAG_BITSPERSAMPLE: + *va_arg(ap, uint16_t *) = td->td_bitspersample; + return (1); + case TIFFTAG_THRESHHOLDING: + *va_arg(ap, uint16_t *) = td->td_threshholding; + return (1); + case TIFFTAG_FILLORDER: + *va_arg(ap, uint16_t *) = td->td_fillorder; + return (1); + case TIFFTAG_ORIENTATION: + *va_arg(ap, uint16_t *) = td->td_orientation; + return (1); + case TIFFTAG_SAMPLESPERPIXEL: + *va_arg(ap, uint16_t *) = td->td_samplesperpixel; + return (1); + case TIFFTAG_ROWSPERSTRIP: + *va_arg(ap, uint32_t *) = td->td_rowsperstrip; + return (1); + case TIFFTAG_MINSAMPLEVALUE: + *va_arg(ap, uint16_t *) = td->td_minsamplevalue; + return (1); + case TIFFTAG_MAXSAMPLEVALUE: { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Cannot get \"Predictor\" tag as plugin is not configured"); - *va_arg(ap, uint16*) = 0; - return 0; + uint16_t maxsamplevalue; + /* td_bitspersample=1 is always set in TIFFDefaultDirectory(). + * Therefore, td_maxsamplevalue has to be re-calculated in + * TIFFGetFieldDefaulted(). */ + if (td->td_bitspersample > 0) + { + /* This shift operation into a uint16_t limits the value to + * 65535 even if td_bitspersamle is > 16 */ + if (td->td_bitspersample <= 16) + { + maxsamplevalue = (1 << td->td_bitspersample) - + 1; /* 2**(BitsPerSample) - 1 */ + } + else + { + maxsamplevalue = 65535; + } + } + else + { + maxsamplevalue = 0; + } + *va_arg(ap, uint16_t *) = maxsamplevalue; + return (1); } - *va_arg(ap, uint16*) = (uint16) sp->predictor; - return 1; + case TIFFTAG_PLANARCONFIG: + *va_arg(ap, uint16_t *) = td->td_planarconfig; + return (1); + case TIFFTAG_RESOLUTIONUNIT: + *va_arg(ap, uint16_t *) = td->td_resolutionunit; + return (1); + case TIFFTAG_PREDICTOR: + { + TIFFPredictorState *sp = (TIFFPredictorState *)tif->tif_data; + if (sp == NULL) + { + TIFFErrorExtR( + tif, tif->tif_name, + "Cannot get \"Predictor\" tag as plugin is not configured"); + *va_arg(ap, uint16_t *) = 0; + return 0; + } + *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor; + return 1; + } + case TIFFTAG_DOTRANGE: + *va_arg(ap, uint16_t *) = 0; + *va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1; + return (1); + case TIFFTAG_INKSET: + *va_arg(ap, uint16_t *) = INKSET_CMYK; + return 1; + case TIFFTAG_NUMBEROFINKS: + *va_arg(ap, uint16_t *) = 4; + return (1); + case TIFFTAG_EXTRASAMPLES: + *va_arg(ap, uint16_t *) = td->td_extrasamples; + *va_arg(ap, const uint16_t **) = td->td_sampleinfo; + return (1); + case TIFFTAG_MATTEING: + *va_arg(ap, uint16_t *) = + (td->td_extrasamples == 1 && + td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + return (1); + case TIFFTAG_TILEDEPTH: + *va_arg(ap, uint32_t *) = td->td_tiledepth; + return (1); + case TIFFTAG_DATATYPE: + *va_arg(ap, uint16_t *) = td->td_sampleformat - 1; + return (1); + case TIFFTAG_SAMPLEFORMAT: + *va_arg(ap, uint16_t *) = td->td_sampleformat; + return (1); + case TIFFTAG_IMAGEDEPTH: + *va_arg(ap, uint32_t *) = td->td_imagedepth; + return (1); + case TIFFTAG_YCBCRCOEFFICIENTS: + { + /* defaults are from CCIR Recommendation 601-1 */ + static const float ycbcrcoeffs[] = {0.299f, 0.587f, 0.114f}; + *va_arg(ap, const float **) = ycbcrcoeffs; + return 1; + } + case TIFFTAG_YCBCRSUBSAMPLING: + *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0]; + *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1]; + return (1); + case TIFFTAG_YCBCRPOSITIONING: + *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning; + return (1); + case TIFFTAG_WHITEPOINT: + { + /* TIFF 6.0 specification tells that it is no default + value for the WhitePoint, but AdobePhotoshop TIFF + Technical Note tells that it should be CIE D50. */ + static const float whitepoint[] = { + D50_X0 / (D50_X0 + D50_Y0 + D50_Z0), + D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0)}; + *va_arg(ap, const float **) = whitepoint; + return 1; + } + case TIFFTAG_TRANSFERFUNCTION: + if (!td->td_transferfunction[0] && + !TIFFDefaultTransferFunction(tif, td)) + { + TIFFErrorExtR(tif, tif->tif_name, + "No space for \"TransferFunction\" tag"); + return (0); + } + *va_arg(ap, const uint16_t **) = td->td_transferfunction[0]; + if (td->td_samplesperpixel - td->td_extrasamples > 1) + { + *va_arg(ap, const uint16_t **) = td->td_transferfunction[1]; + *va_arg(ap, const uint16_t **) = td->td_transferfunction[2]; + } + return (1); + case TIFFTAG_REFERENCEBLACKWHITE: + if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(tif, td)) + return (0); + *va_arg(ap, const float **) = td->td_refblackwhite; + return (1); } - case TIFFTAG_DOTRANGE: - *va_arg(ap, uint16 *) = 0; - *va_arg(ap, uint16 *) = (1<td_bitspersample)-1; - return (1); - case TIFFTAG_INKSET: - *va_arg(ap, uint16 *) = INKSET_CMYK; - return 1; - case TIFFTAG_NUMBEROFINKS: - *va_arg(ap, uint16 *) = 4; - return (1); - case TIFFTAG_EXTRASAMPLES: - *va_arg(ap, uint16 *) = td->td_extrasamples; - *va_arg(ap, const uint16 **) = td->td_sampleinfo; - return (1); - case TIFFTAG_MATTEING: - *va_arg(ap, uint16 *) = - (td->td_extrasamples == 1 && - td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); - return (1); - case TIFFTAG_TILEDEPTH: - *va_arg(ap, uint32 *) = td->td_tiledepth; - return (1); - case TIFFTAG_DATATYPE: - *va_arg(ap, uint16 *) = td->td_sampleformat-1; - return (1); - case TIFFTAG_SAMPLEFORMAT: - *va_arg(ap, uint16 *) = td->td_sampleformat; - return(1); - case TIFFTAG_IMAGEDEPTH: - *va_arg(ap, uint32 *) = td->td_imagedepth; - return (1); - case TIFFTAG_YCBCRCOEFFICIENTS: - { - /* defaults are from CCIR Recommendation 601-1 */ - static const float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f }; - *va_arg(ap, const float **) = ycbcrcoeffs; - return 1; - } - case TIFFTAG_YCBCRSUBSAMPLING: - *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0]; - *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1]; - return (1); - case TIFFTAG_YCBCRPOSITIONING: - *va_arg(ap, uint16 *) = td->td_ycbcrpositioning; - return (1); - case TIFFTAG_WHITEPOINT: - { - /* TIFF 6.0 specification tells that it is no default - value for the WhitePoint, but AdobePhotoshop TIFF - Technical Note tells that it should be CIE D50. */ - static const float whitepoint[] = { - D50_X0 / (D50_X0 + D50_Y0 + D50_Z0), - D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0) - }; - *va_arg(ap, const float **) = whitepoint; - return 1; - } - case TIFFTAG_TRANSFERFUNCTION: - if (!td->td_transferfunction[0] && - !TIFFDefaultTransferFunction(td)) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag"); - return (0); - } - *va_arg(ap, const uint16 **) = td->td_transferfunction[0]; - if (td->td_samplesperpixel - td->td_extrasamples > 1) { - *va_arg(ap, const uint16 **) = td->td_transferfunction[1]; - *va_arg(ap, const uint16 **) = td->td_transferfunction[2]; - } - return (1); - case TIFFTAG_REFERENCEBLACKWHITE: - if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td)) - return (0); - *va_arg(ap, const float **) = td->td_refblackwhite; - return (1); - } - return 0; + return 0; } /* * Like TIFFGetField, but return any default * value if the tag is not present in the directory. */ -int -TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...) +int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...) { - int ok; - va_list ap; + int ok; + va_list ap; - va_start(ap, tag); - ok = TIFFVGetFieldDefaulted(tif, tag, ap); - va_end(ap); - return (ok); + va_start(ap, tag); + ok = TIFFVGetFieldDefaulted(tif, tag, ap); + va_end(ap); + return (ok); } -struct _Int64Parts { - int32 low, high; +struct _Int64Parts +{ + int32_t low, high; }; -typedef union { - struct _Int64Parts part; - int64 value; +typedef union +{ + struct _Int64Parts part; + int64_t value; } _Int64; -float -_TIFFUInt64ToFloat(uint64 ui64) +float _TIFFUInt64ToFloat(uint64_t ui64) { - _Int64 i; + _Int64 i; - i.value = ui64; - if (i.part.high >= 0) { - return (float)i.value; - } else { - long double df; - df = (long double)i.value; - df += 18446744073709551616.0; /* adding 2**64 */ - return (float)df; - } + i.value = ui64; + if (i.part.high >= 0) + { + return (float)i.value; + } + else + { + long double df; + df = (long double)i.value; + df += 18446744073709551616.0; /* adding 2**64 */ + return (float)df; + } } -double -_TIFFUInt64ToDouble(uint64 ui64) +double _TIFFUInt64ToDouble(uint64_t ui64) { - _Int64 i; + _Int64 i; - i.value = ui64; - if (i.part.high >= 0) { - return (double)i.value; - } else { - long double df; - df = (long double)i.value; - df += 18446744073709551616.0; /* adding 2**64 */ - return (double)df; - } + i.value = ui64; + if (i.part.high >= 0) + { + return (double)i.value; + } + else + { + long double df; + df = (long double)i.value; + df += 18446744073709551616.0; /* adding 2**64 */ + return (double)df; + } } -float _TIFFClampDoubleToFloat( double val ) +float _TIFFClampDoubleToFloat(double val) { - if( val > FLT_MAX ) + if (val > FLT_MAX) return FLT_MAX; - if( val < -FLT_MAX ) + if (val < -FLT_MAX) return -FLT_MAX; return (float)val; } -int _TIFFSeekOK(TIFF* tif, toff_t off) +uint32_t _TIFFClampDoubleToUInt32(double val) +{ + if (val < 0) + return 0; + if (val > 0xFFFFFFFFU || val != val) + return 0xFFFFFFFFU; + return (uint32_t)val; +} + +int _TIFFSeekOK(TIFF *tif, toff_t off) { /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */ /* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */ - return off <= (~(uint64)0)/2 && TIFFSeekFile(tif,off,SEEK_SET)==off; + return off <= (~(uint64_t)0) / 2 && TIFFSeekFile(tif, off, SEEK_SET) == off; } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_close.c b/3rdparty/libtiff/tif_close.c index e4228df9c9..907d7f139b 100644 --- a/3rdparty/libtiff/tif_close.c +++ b/3rdparty/libtiff/tif_close.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -37,70 +37,98 @@ * completely freed, so you should save opened file handle and pointer * to the close procedure in external variables before calling * _TIFFCleanup(), if you will need these ones to close the file. - * + * * @param tif A TIFF pointer. */ -void -TIFFCleanup(TIFF* tif) +void TIFFCleanup(TIFF *tif) { - /* - * Flush buffered data and directory (if dirty). - */ - if (tif->tif_mode != O_RDONLY) - TIFFFlush(tif); - (*tif->tif_cleanup)(tif); - TIFFFreeDirectory(tif); + /* + * Flush buffered data and directory (if dirty). + */ + if (tif->tif_mode != O_RDONLY) + TIFFFlush(tif); + (*tif->tif_cleanup)(tif); + TIFFFreeDirectory(tif); - if (tif->tif_dirlist) - _TIFFfree(tif->tif_dirlist); + _TIFFCleanupIFDOffsetAndNumberMaps(tif); - /* - * Clean up client info links. - */ - while( tif->tif_clientinfo ) - { - TIFFClientInfoLink *psLink = tif->tif_clientinfo; + /* + * Clean up client info links. + */ + while (tif->tif_clientinfo) + { + TIFFClientInfoLink *psLink = tif->tif_clientinfo; - tif->tif_clientinfo = psLink->next; - _TIFFfree( psLink->name ); - _TIFFfree( psLink ); - } + tif->tif_clientinfo = psLink->next; + _TIFFfreeExt(tif, psLink->name); + _TIFFfreeExt(tif, psLink); + } - if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER)) - _TIFFfree(tif->tif_rawdata); - if (isMapped(tif)) - TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size); + if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER)) + _TIFFfreeExt(tif, tif->tif_rawdata); + if (isMapped(tif)) + TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size); - /* - * Clean up custom fields. - */ - if (tif->tif_fields && tif->tif_nfields > 0) { - uint32 i; + /* + * Clean up custom fields. + */ + if (tif->tif_fields && tif->tif_nfields > 0) + { + uint32_t i; - for (i = 0; i < tif->tif_nfields; i++) { - TIFFField *fld = tif->tif_fields[i]; - if (fld->field_bit == FIELD_CUSTOM && - strncmp("Tag ", fld->field_name, 4) == 0) { - _TIFFfree(fld->field_name); - _TIFFfree(fld); - } - } - - _TIFFfree(tif->tif_fields); - } - - if (tif->tif_nfieldscompat > 0) { - uint32 i; - - for (i = 0; i < tif->tif_nfieldscompat; i++) { - if (tif->tif_fieldscompat[i].allocated_size) - _TIFFfree(tif->tif_fieldscompat[i].fields); + for (i = 0; i < tif->tif_nfields; i++) + { + TIFFField *fld = tif->tif_fields[i]; + if (fld->field_name != NULL) + { + if (fld->field_bit == FIELD_CUSTOM && + /* caution: tif_fields[i] must not be the beginning of a + * fields-array. Otherwise the following tags are also freed + * with the first free(). + */ + TIFFFieldIsAnonymous(fld)) + { + _TIFFfreeExt(tif, fld->field_name); + _TIFFfreeExt(tif, fld); } - _TIFFfree(tif->tif_fieldscompat); + } } - _TIFFfree(tif); + _TIFFfreeExt(tif, tif->tif_fields); + } + + if (tif->tif_nfieldscompat > 0) + { + uint32_t i; + + for (i = 0; i < tif->tif_nfieldscompat; i++) + { + if (tif->tif_fieldscompat[i].allocated_size) + _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields); + } + _TIFFfreeExt(tif, tif->tif_fieldscompat); + } + + _TIFFfreeExt(NULL, tif); +} + +/************************************************************************/ +/* _TIFFCleanupIFDOffsetAndNumberMaps() */ +/************************************************************************/ + +void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif) +{ + if (tif->tif_map_dir_offset_to_number) + { + TIFFHashSetDestroy(tif->tif_map_dir_offset_to_number); + tif->tif_map_dir_offset_to_number = NULL; + } + if (tif->tif_map_dir_number_to_offset) + { + TIFFHashSetDestroy(tif->tif_map_dir_number_to_offset); + tif->tif_map_dir_number_to_offset = NULL; + } } /************************************************************************/ @@ -113,26 +141,18 @@ TIFFCleanup(TIFF* tif) * TIFFClose closes a file that was previously opened with TIFFOpen(). * Any buffered data are flushed to the file, including the contents of * the current directory (if modified); and all resources are reclaimed. - * + * * @param tif A TIFF pointer. */ -void -TIFFClose(TIFF* tif) +void TIFFClose(TIFF *tif) { - TIFFCloseProc closeproc = tif->tif_closeproc; - thandle_t fd = tif->tif_clientdata; + if (tif != NULL) + { + TIFFCloseProc closeproc = tif->tif_closeproc; + thandle_t fd = tif->tif_clientdata; - TIFFCleanup(tif); - (void) (*closeproc)(fd); + TIFFCleanup(tif); + (void)(*closeproc)(fd); + } } - -/* vim: set ts=8 sts=8 sw=8 noet: */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_codec.c b/3rdparty/libtiff/tif_codec.c index b6c04f01d7..d499b63a58 100644 --- a/3rdparty/libtiff/tif_codec.c +++ b/3rdparty/libtiff/tif_codec.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,7 +29,7 @@ */ #include "tiffiop.h" -static int NotConfigured(TIFF*, int); +static int NotConfigured(TIFF *, int); #ifndef LZW_SUPPORT #define TIFFInitLZW NotConfigured @@ -67,6 +67,9 @@ static int NotConfigured(TIFF*, int); #ifndef LOGLUV_SUPPORT #define TIFFInitSGILog NotConfigured #endif +#ifndef LERC_SUPPORT +#define TIFFInitLERC NotConfigured +#endif #ifndef LZMA_SUPPORT #define TIFFInitLZMA NotConfigured #endif @@ -80,58 +83,53 @@ static int NotConfigured(TIFF*, int); /* * Compression schemes statically built into the library. */ -#ifdef VMS const TIFFCodec _TIFFBuiltinCODECS[] = { -#else -TIFFCodec _TIFFBuiltinCODECS[] = { -#endif - { "None", COMPRESSION_NONE, TIFFInitDumpMode }, - { "LZW", COMPRESSION_LZW, TIFFInitLZW }, - { "PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits }, - { "ThunderScan", COMPRESSION_THUNDERSCAN,TIFFInitThunderScan }, - { "NeXT", COMPRESSION_NEXT, TIFFInitNeXT }, - { "JPEG", COMPRESSION_JPEG, TIFFInitJPEG }, - { "Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG }, - { "CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE }, - { "CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW }, - { "CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3 }, - { "CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4 }, - { "ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG }, - { "Deflate", COMPRESSION_DEFLATE, TIFFInitZIP }, - { "AdobeDeflate", COMPRESSION_ADOBE_DEFLATE , TIFFInitZIP }, - { "PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog }, - { "SGILog", COMPRESSION_SGILOG, TIFFInitSGILog }, - { "SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog }, - { "LZMA", COMPRESSION_LZMA, TIFFInitLZMA }, - { "ZSTD", COMPRESSION_ZSTD, TIFFInitZSTD }, - { "WEBP", COMPRESSION_WEBP, TIFFInitWebP }, - { NULL, 0, NULL } -}; + {"None", COMPRESSION_NONE, TIFFInitDumpMode}, + {"LZW", COMPRESSION_LZW, TIFFInitLZW}, + {"PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits}, + {"ThunderScan", COMPRESSION_THUNDERSCAN, TIFFInitThunderScan}, + {"NeXT", COMPRESSION_NEXT, TIFFInitNeXT}, + {"JPEG", COMPRESSION_JPEG, TIFFInitJPEG}, + {"Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG}, + {"CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE}, + {"CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW}, + {"CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3}, + {"CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4}, + {"ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG}, + {"Deflate", COMPRESSION_DEFLATE, TIFFInitZIP}, + {"AdobeDeflate", COMPRESSION_ADOBE_DEFLATE, TIFFInitZIP}, + {"PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog}, + {"SGILog", COMPRESSION_SGILOG, TIFFInitSGILog}, + {"SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog}, + {"LZMA", COMPRESSION_LZMA, TIFFInitLZMA}, + {"ZSTD", COMPRESSION_ZSTD, TIFFInitZSTD}, + {"WEBP", COMPRESSION_WEBP, TIFFInitWebP}, + {"LERC", COMPRESSION_LERC, TIFFInitLERC}, + {NULL, 0, NULL}}; -static int -_notConfigured(TIFF* tif) +static int _notConfigured(TIFF *tif) { - const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); - char compression_code[20]; - - sprintf(compression_code, "%d",tif->tif_dir.td_compression ); - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%s compression support is not configured", - c ? c->name : compression_code ); - return (0); + const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); + char compression_code[20]; + + snprintf(compression_code, sizeof(compression_code), "%" PRIu16, + tif->tif_dir.td_compression); + TIFFErrorExtR(tif, tif->tif_name, + "%s compression support is not configured", + c ? c->name : compression_code); + return (0); } -static int -NotConfigured(TIFF* tif, int scheme) +static int NotConfigured(TIFF *tif, int scheme) { - (void) scheme; + (void)scheme; - tif->tif_fixuptags = _notConfigured; - tif->tif_decodestatus = FALSE; - tif->tif_setupdecode = _notConfigured; - tif->tif_encodestatus = FALSE; - tif->tif_setupencode = _notConfigured; - return (1); + tif->tif_fixuptags = _notConfigured; + tif->tif_decodestatus = FALSE; + tif->tif_setupdecode = _notConfigured; + tif->tif_encodestatus = FALSE; + tif->tif_setupencode = _notConfigured; + return (1); } /************************************************************************/ @@ -145,27 +143,21 @@ NotConfigured(TIFF* tif, int scheme) * 0 will be returned. */ -int -TIFFIsCODECConfigured(uint16 scheme) +int TIFFIsCODECConfigured(uint16_t scheme) { - const TIFFCodec* codec = TIFFFindCODEC(scheme); + const TIFFCodec *codec = TIFFFindCODEC(scheme); - if(codec == NULL) { - return 0; - } - if(codec->init == NULL) { - return 0; - } - if(codec->init != NotConfigured){ - return 1; - } - return 0; + if (codec == NULL) + { + return 0; + } + if (codec->init == NULL) + { + return 0; + } + if (codec->init != NotConfigured) + { + return 1; + } + return 0; } - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_color.c b/3rdparty/libtiff/tif_color.c index 8fae40ea4b..2d7dcac6fe 100644 --- a/3rdparty/libtiff/tif_color.c +++ b/3rdparty/libtiff/tif_color.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -40,173 +40,191 @@ /* * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ. */ -void -TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b, - float *X, float *Y, float *Z) +void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, + float *X, float *Y, float *Z) { - float L = (float)l * 100.0F / 255.0F; - float cby, tmp; - - if( L < 8.856F ) { - *Y = (L * cielab->Y0) / 903.292F; - cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F; - } else { - cby = (L + 16.0F) / 116.0F; - *Y = cielab->Y0 * cby * cby * cby; - } - - tmp = (float)a / 500.0F + cby; - if( tmp < 0.2069F ) - *X = cielab->X0 * (tmp - 0.13793F) / 7.787F; - else - *X = cielab->X0 * tmp * tmp * tmp; - - tmp = cby - (float)b / 200.0F; - if( tmp < 0.2069F ) - *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F; - else - *Z = cielab->Z0 * tmp * tmp * tmp; + TIFFCIELab16ToXYZ(cielab, l * 257, a * 256, b * 256, X, Y, Z); } -#define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5))) +/* + * For CIELab encoded in 16 bits, L is an unsigned integer range [0,65535]. + * The a* and b* components are signed integers range [-32768,32767]. The 16 + * bit chrominance values are encoded as 256 times the 1976 CIE a* and b* + * values + */ +void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, + int32_t b, float *X, float *Y, float *Z) +{ + float L = (float)l * 100.0F / 65535.0F; + float cby, tmp; + + if (L < 8.856F) + { + *Y = (L * cielab->Y0) / 903.292F; + cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F; + } + else + { + cby = (L + 16.0F) / 116.0F; + *Y = cielab->Y0 * cby * cby * cby; + } + + tmp = (float)a / 256.0F / 500.0F + cby; + if (tmp < 0.2069F) + *X = cielab->X0 * (tmp - 0.13793F) / 7.787F; + else + *X = cielab->X0 * tmp * tmp * tmp; + + tmp = cby - (float)b / 256.0F / 200.0F; + if (tmp < 0.2069F) + *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F; + else + *Z = cielab->Z0 * tmp * tmp * tmp; +} + +#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5) : ((R)-0.5))) /* * Convert color value from the XYZ space to RGB. */ -void -TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, - uint32 *r, uint32 *g, uint32 *b) +void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, + uint32_t *r, uint32_t *g, uint32_t *b) { - int i; - float Yr, Yg, Yb; - float *matrix = &cielab->display.d_mat[0][0]; + int i; + float Yr, Yg, Yb; + float *matrix = &cielab->display.d_mat[0][0]; - /* Multiply through the matrix to get luminosity values. */ - Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z; - Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z; - Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z; + /* Multiply through the matrix to get luminosity values. */ + Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z; + Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z; + Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z; - /* Clip input */ - Yr = TIFFmax(Yr, cielab->display.d_Y0R); - Yg = TIFFmax(Yg, cielab->display.d_Y0G); - Yb = TIFFmax(Yb, cielab->display.d_Y0B); + /* Clip input */ + Yr = TIFFmax(Yr, cielab->display.d_Y0R); + Yg = TIFFmax(Yg, cielab->display.d_Y0G); + Yb = TIFFmax(Yb, cielab->display.d_Y0B); - /* Avoid overflow in case of wrong input values */ - Yr = TIFFmin(Yr, cielab->display.d_YCR); - Yg = TIFFmin(Yg, cielab->display.d_YCG); - Yb = TIFFmin(Yb, cielab->display.d_YCB); + /* Avoid overflow in case of wrong input values */ + Yr = TIFFmin(Yr, cielab->display.d_YCR); + Yg = TIFFmin(Yg, cielab->display.d_YCG); + Yb = TIFFmin(Yb, cielab->display.d_YCB); - /* Turn luminosity to colour value. */ - i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep); - i = TIFFmin(cielab->range, i); - *r = RINT(cielab->Yr2r[i]); + /* Turn luminosity to colour value. */ + i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep); + i = TIFFmin(cielab->range, i); + *r = RINT(cielab->Yr2r[i]); - i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep); - i = TIFFmin(cielab->range, i); - *g = RINT(cielab->Yg2g[i]); + i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep); + i = TIFFmin(cielab->range, i); + *g = RINT(cielab->Yg2g[i]); - i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep); - i = TIFFmin(cielab->range, i); - *b = RINT(cielab->Yb2b[i]); + i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep); + i = TIFFmin(cielab->range, i); + *b = RINT(cielab->Yb2b[i]); - /* Clip output. */ - *r = TIFFmin(*r, cielab->display.d_Vrwr); - *g = TIFFmin(*g, cielab->display.d_Vrwg); - *b = TIFFmin(*b, cielab->display.d_Vrwb); + /* Clip output. */ + *r = TIFFmin(*r, cielab->display.d_Vrwr); + *g = TIFFmin(*g, cielab->display.d_Vrwg); + *b = TIFFmin(*b, cielab->display.d_Vrwb); } #undef RINT -/* +/* * Allocate conversion state structures and make look_up tables for * the Yr,Yb,Yg <=> r,g,b conversions. */ -int -TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, - const TIFFDisplay *display, float *refWhite) +int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, + float *refWhite) { - int i; - double dfGamma; + int i; + double dfGamma; - cielab->range = CIELABTORGB_TABLE_RANGE; + cielab->range = CIELABTORGB_TABLE_RANGE; - _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay)); + _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay)); - /* Red */ - dfGamma = 1.0 / cielab->display.d_gammaR ; - cielab->rstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for(i = 0; i <= cielab->range; i++) { - cielab->Yr2r[i] = cielab->display.d_Vrwr - * ((float)pow((double)i / cielab->range, dfGamma)); - } + /* Red */ + dfGamma = 1.0 / cielab->display.d_gammaR; + cielab->rstep = + (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + for (i = 0; i <= cielab->range; i++) + { + cielab->Yr2r[i] = cielab->display.d_Vrwr * + ((float)pow((double)i / cielab->range, dfGamma)); + } - /* Green */ - dfGamma = 1.0 / cielab->display.d_gammaG ; - cielab->gstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for(i = 0; i <= cielab->range; i++) { - cielab->Yg2g[i] = cielab->display.d_Vrwg - * ((float)pow((double)i / cielab->range, dfGamma)); - } + /* Green */ + dfGamma = 1.0 / cielab->display.d_gammaG; + cielab->gstep = + (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + for (i = 0; i <= cielab->range; i++) + { + cielab->Yg2g[i] = cielab->display.d_Vrwg * + ((float)pow((double)i / cielab->range, dfGamma)); + } - /* Blue */ - dfGamma = 1.0 / cielab->display.d_gammaB ; - cielab->bstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for(i = 0; i <= cielab->range; i++) { - cielab->Yb2b[i] = cielab->display.d_Vrwb - * ((float)pow((double)i / cielab->range, dfGamma)); - } + /* Blue */ + dfGamma = 1.0 / cielab->display.d_gammaB; + cielab->bstep = + (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + for (i = 0; i <= cielab->range; i++) + { + cielab->Yb2b[i] = cielab->display.d_Vrwb * + ((float)pow((double)i / cielab->range, dfGamma)); + } - /* Init reference white point */ - cielab->X0 = refWhite[0]; - cielab->Y0 = refWhite[1]; - cielab->Z0 = refWhite[2]; + /* Init reference white point */ + cielab->X0 = refWhite[0]; + cielab->Y0 = refWhite[1]; + cielab->Z0 = refWhite[2]; - return 0; + return 0; } -/* +/* * Convert color value from the YCbCr space to RGB. * The colorspace conversion algorithm comes from the IJG v5a code; * see below for more information on how it works. */ -#define SHIFT 16 -#define FIX(x) ((int32)((x) * (1L<(max)?(max):(f)) -#define HICLAMP(f,max) ((f)>(max)?(max):(f)) +#define SHIFT 16 +#define FIX(x) ((int32_t)((x) * (1L << SHIFT) + 0.5)) +#define ONE_HALF ((int32_t)(1 << (SHIFT - 1))) +#define Code2V(c, RB, RW, CR) \ + ((((c) - (int32_t)(RB)) * (float)(CR)) / \ + (float)(((RW) - (RB) != 0) ? ((RW) - (RB)) : 1)) +/* !((f)>=(min)) written that way to deal with NaN */ +#define CLAMP(f, min, max) \ + ((!((f) >= (min))) ? (min) : (f) > (max) ? (max) : (f)) +#define HICLAMP(f, max) ((f) > (max) ? (max) : (f)) -void -TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr, - uint32 *r, uint32 *g, uint32 *b) +void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr, + uint32_t *r, uint32_t *g, uint32_t *b) { - int32 i; + int32_t i; - /* XXX: Only 8-bit YCbCr input supported for now */ - Y = HICLAMP(Y, 255); - Cb = CLAMP(Cb, 0, 255); - Cr = CLAMP(Cr, 0, 255); + /* XXX: Only 8-bit YCbCr input supported for now */ + Y = HICLAMP(Y, 255); + Cb = CLAMP(Cb, 0, 255); + Cr = CLAMP(Cr, 0, 255); - i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]; - *r = CLAMP(i, 0, 255); - i = ycbcr->Y_tab[Y] - + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT); - *g = CLAMP(i, 0, 255); - i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]; - *b = CLAMP(i, 0, 255); + i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]; + *r = CLAMP(i, 0, 255); + i = ycbcr->Y_tab[Y] + + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT); + *g = CLAMP(i, 0, 255); + i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]; + *b = CLAMP(i, 0, 255); } /* Clamp function for sanitization purposes. Normally clamping should not */ /* occur for well behaved chroma and refBlackWhite coefficients */ static float CLAMPw(float v, float vmin, float vmax) { - if( v < vmin ) + if (v < vmin) { /* printf("%f clamped to %f\n", v, vmin); */ return vmin; } - if( v > vmax ) + if (v > vmax) { /* printf("%f clamped to %f\n", v, vmax); */ return vmax; @@ -230,78 +248,75 @@ static float CLAMPw(float v, float vmin, float vmax) * pre-calculating possible values indexed by Cb and Cr (this code * assumes conversion is being done for 8-bit samples). */ -int -TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite) +int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite) { - TIFFRGBValue* clamptab; + TIFFRGBValue *clamptab; int i; - -#define LumaRed luma[0] -#define LumaGreen luma[1] -#define LumaBlue luma[2] - clamptab = (TIFFRGBValue*)( - (uint8*) ycbcr+TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))); - _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */ +#define LumaRed luma[0] +#define LumaGreen luma[1] +#define LumaBlue luma[2] + + clamptab = + (TIFFRGBValue *)((uint8_t *)ycbcr + + TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long))); + _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */ ycbcr->clamptab = (clamptab += 256); for (i = 0; i < 256; i++) - clamptab[i] = (TIFFRGBValue) i; - _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */ - ycbcr->Cr_r_tab = (int*) (clamptab + 3*256); + clamptab[i] = (TIFFRGBValue)i; + _TIFFmemset(clamptab + 256, 255, 2 * 256); /* v > 255 => 255 */ + ycbcr->Cr_r_tab = (int *)(clamptab + 3 * 256); ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256; - ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256); + ycbcr->Cr_g_tab = (int32_t *)(ycbcr->Cb_b_tab + 256); ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256; ycbcr->Y_tab = ycbcr->Cb_g_tab + 256; - { float f1 = 2-2*LumaRed; int32 D1 = FIX(CLAMP(f1,0.0F,2.0F)); - float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(CLAMP(f2,0.0F,2.0F)); - float f3 = 2-2*LumaBlue; int32 D3 = FIX(CLAMP(f3,0.0F,2.0F)); - float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(CLAMP(f4,0.0F,2.0F)); - int x; + { + float f1 = 2 - 2 * LumaRed; + int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F)); + float f2 = LumaRed * f1 / LumaGreen; + int32_t D2 = -FIX(CLAMP(f2, 0.0F, 2.0F)); + float f3 = 2 - 2 * LumaBlue; + int32_t D3 = FIX(CLAMP(f3, 0.0F, 2.0F)); + float f4 = LumaBlue * f3 / LumaGreen; + int32_t D4 = -FIX(CLAMP(f4, 0.0F, 2.0F)); + int x; #undef LumaBlue #undef LumaGreen #undef LumaRed - - /* - * i is the actual input pixel value in the range 0..255 - * Cb and Cr values are in the range -128..127 (actually - * they are in a range defined by the ReferenceBlackWhite - * tag) so there is some range shifting to do here when - * constructing tables indexed by the raw pixel data. - */ - for (i = 0, x = -128; i < 256; i++, x++) { - int32 Cr = (int32)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F, - refBlackWhite[5] - 128.0F, 127), - -128.0F * 32, 128.0F * 32); - int32 Cb = (int32)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F, - refBlackWhite[3] - 128.0F, 127), - -128.0F * 32, 128.0F * 32); - ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT); - ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT); - ycbcr->Cr_g_tab[i] = D2*Cr; - ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF; - ycbcr->Y_tab[i] = - (int32)CLAMPw(Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255), - -128.0F * 32, 128.0F * 32); - } + /* + * i is the actual input pixel value in the range 0..255 + * Cb and Cr values are in the range -128..127 (actually + * they are in a range defined by the ReferenceBlackWhite + * tag) so there is some range shifting to do here when + * constructing tables indexed by the raw pixel data. + */ + for (i = 0, x = -128; i < 256; i++, x++) + { + int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F, + refBlackWhite[5] - 128.0F, 127), + -128.0F * 32, 128.0F * 32); + int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F, + refBlackWhite[3] - 128.0F, 127), + -128.0F * 32, 128.0F * 32); + + ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT); + ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT); + ycbcr->Cr_g_tab[i] = D2 * Cr; + ycbcr->Cb_g_tab[i] = D4 * Cb + ONE_HALF; + ycbcr->Y_tab[i] = (int32_t)CLAMPw( + Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255), + -128.0F * 32, 128.0F * 32); + } } return 0; } -#undef HICLAMP -#undef CLAMP -#undef Code2V -#undef SHIFT -#undef ONE_HALF -#undef FIX - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ +#undef HICLAMP +#undef CLAMP +#undef Code2V +#undef SHIFT +#undef ONE_HALF +#undef FIX diff --git a/3rdparty/libtiff/tif_compress.c b/3rdparty/libtiff/tif_compress.c index 915478f500..c6e17d3e11 100644 --- a/3rdparty/libtiff/tif_compress.c +++ b/3rdparty/libtiff/tif_compress.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,145 +29,152 @@ */ #include "tiffiop.h" -static int -TIFFNoEncode(TIFF* tif, const char* method) +static int TIFFNoEncode(TIFF *tif, const char *method) { - const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); - if (c) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%s %s encoding is not implemented", - c->name, method); - } else { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Compression scheme %u %s encoding is not implemented", - tif->tif_dir.td_compression, method); - } - return (-1); + if (c) + { + TIFFErrorExtR(tif, tif->tif_name, "%s %s encoding is not implemented", + c->name, method); + } + else + { + TIFFErrorExtR(tif, tif->tif_name, + "Compression scheme %" PRIu16 + " %s encoding is not implemented", + tif->tif_dir.td_compression, method); + } + return (-1); } -int -_TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoEncode(tif, "scanline")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoEncode(tif, "scanline")); } -int -_TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoEncode(tif, "strip")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoEncode(tif, "strip")); } -int -_TIFFNoTileEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +int _TIFFNoTileEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoEncode(tif, "tile")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoEncode(tif, "tile")); } -static int -TIFFNoDecode(TIFF* tif, const char* method) +static int TIFFNoDecode(TIFF *tif, const char *method) { - const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); - if (c) - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%s %s decoding is not implemented", - c->name, method); - else - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Compression scheme %u %s decoding is not implemented", - tif->tif_dir.td_compression, method); - return (0); + if (c) + TIFFErrorExtR(tif, tif->tif_name, "%s %s decoding is not implemented", + c->name, method); + else + TIFFErrorExtR(tif, tif->tif_name, + "Compression scheme %" PRIu16 + " %s decoding is not implemented", + tif->tif_dir.td_compression, method); + return (0); } -static int -_TIFFNoFixupTags(TIFF* tif) +static int _TIFFNoFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } -int -_TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoDecode(tif, "scanline")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoDecode(tif, "scanline")); } -int -_TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoDecode(tif, "strip")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoDecode(tif, "strip")); } -int -_TIFFNoTileDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +int _TIFFNoTileDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoDecode(tif, "tile")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoDecode(tif, "tile")); } -int -_TIFFNoSeek(TIFF* tif, uint32 off) +int _TIFFNoSeek(TIFF *tif, uint32_t off) { - (void) off; - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Compression algorithm does not support random access"); - return (0); + (void)off; + TIFFErrorExtR(tif, tif->tif_name, + "Compression algorithm does not support random access"); + return (0); } -int -_TIFFNoPreCode(TIFF* tif, uint16 s) +int _TIFFNoPreCode(TIFF *tif, uint16_t s) { - (void) tif; (void) s; - return (1); + (void)tif; + (void)s; + return (1); } -static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); } -static void _TIFFvoid(TIFF* tif) { (void) tif; } - -void -_TIFFSetDefaultCompressionState(TIFF* tif) +static int _TIFFtrue(TIFF *tif) { - tif->tif_fixuptags = _TIFFNoFixupTags; - tif->tif_decodestatus = TRUE; - tif->tif_setupdecode = _TIFFtrue; - tif->tif_predecode = _TIFFNoPreCode; - tif->tif_decoderow = _TIFFNoRowDecode; - tif->tif_decodestrip = _TIFFNoStripDecode; - tif->tif_decodetile = _TIFFNoTileDecode; - tif->tif_encodestatus = TRUE; - tif->tif_setupencode = _TIFFtrue; - tif->tif_preencode = _TIFFNoPreCode; - tif->tif_postencode = _TIFFtrue; - tif->tif_encoderow = _TIFFNoRowEncode; - tif->tif_encodestrip = _TIFFNoStripEncode; - tif->tif_encodetile = _TIFFNoTileEncode; - tif->tif_close = _TIFFvoid; - tif->tif_seek = _TIFFNoSeek; - tif->tif_cleanup = _TIFFvoid; - tif->tif_defstripsize = _TIFFDefaultStripSize; - tif->tif_deftilesize = _TIFFDefaultTileSize; - tif->tif_flags &= ~(TIFF_NOBITREV|TIFF_NOREADRAW); + (void)tif; + return (1); +} +static void _TIFFvoid(TIFF *tif) { (void)tif; } + +void _TIFFSetDefaultCompressionState(TIFF *tif) +{ + tif->tif_fixuptags = _TIFFNoFixupTags; + tif->tif_decodestatus = TRUE; + tif->tif_setupdecode = _TIFFtrue; + tif->tif_predecode = _TIFFNoPreCode; + tif->tif_decoderow = _TIFFNoRowDecode; + tif->tif_decodestrip = _TIFFNoStripDecode; + tif->tif_decodetile = _TIFFNoTileDecode; + tif->tif_encodestatus = TRUE; + tif->tif_setupencode = _TIFFtrue; + tif->tif_preencode = _TIFFNoPreCode; + tif->tif_postencode = _TIFFtrue; + tif->tif_encoderow = _TIFFNoRowEncode; + tif->tif_encodestrip = _TIFFNoStripEncode; + tif->tif_encodetile = _TIFFNoTileEncode; + tif->tif_close = _TIFFvoid; + tif->tif_seek = _TIFFNoSeek; + tif->tif_cleanup = _TIFFvoid; + tif->tif_defstripsize = _TIFFDefaultStripSize; + tif->tif_deftilesize = _TIFFDefaultTileSize; + tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW); } -int -TIFFSetCompressionScheme(TIFF* tif, int scheme) +int TIFFSetCompressionScheme(TIFF *tif, int scheme) { - const TIFFCodec *c = TIFFFindCODEC((uint16) scheme); + const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme); - _TIFFSetDefaultCompressionState(tif); - /* - * Don't treat an unknown compression scheme as an error. - * This permits applications to open files with data that - * the library does not have builtin support for, but which - * may still be meaningful. - */ - return (c ? (*c->init)(tif, scheme) : 1); + _TIFFSetDefaultCompressionState(tif); + /* + * Don't treat an unknown compression scheme as an error. + * This permits applications to open files with data that + * the library does not have builtin support for, but which + * may still be meaningful. + */ + return (c ? (*c->init)(tif, scheme) : 1); } /* @@ -175,64 +182,68 @@ TIFFSetCompressionScheme(TIFF* tif, int scheme) * schemes can also override the builtin versions provided * by this library. */ -typedef struct _codec { - struct _codec* next; - TIFFCodec* info; +typedef struct _codec +{ + struct _codec *next; + TIFFCodec *info; } codec_t; -static codec_t* registeredCODECS = NULL; +static codec_t *registeredCODECS = NULL; -const TIFFCodec* -TIFFFindCODEC(uint16 scheme) +const TIFFCodec *TIFFFindCODEC(uint16_t scheme) { - const TIFFCodec* c; - codec_t* cd; + const TIFFCodec *c; + codec_t *cd; - for (cd = registeredCODECS; cd; cd = cd->next) - if (cd->info->scheme == scheme) - return ((const TIFFCodec*) cd->info); - for (c = _TIFFBuiltinCODECS; c->name; c++) - if (c->scheme == scheme) - return (c); - return ((const TIFFCodec*) 0); + for (cd = registeredCODECS; cd; cd = cd->next) + if (cd->info->scheme == scheme) + return ((const TIFFCodec *)cd->info); + for (c = _TIFFBuiltinCODECS; c->name; c++) + if (c->scheme == scheme) + return (c); + return ((const TIFFCodec *)0); } -TIFFCodec* -TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init) +TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name, + TIFFInitMethod init) { - codec_t* cd = (codec_t*) - _TIFFmalloc((tmsize_t)(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1)); + codec_t *cd = (codec_t *)_TIFFmallocExt( + NULL, + (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1)); - if (cd != NULL) { - cd->info = (TIFFCodec*) ((uint8*) cd + sizeof (codec_t)); - cd->info->name = (char*) - ((uint8*) cd->info + sizeof (TIFFCodec)); - strcpy(cd->info->name, name); - cd->info->scheme = scheme; - cd->info->init = init; - cd->next = registeredCODECS; - registeredCODECS = cd; - } else { - TIFFErrorExt(0, "TIFFRegisterCODEC", - "No space to register compression scheme %s", name); - return NULL; - } - return (cd->info); + if (cd != NULL) + { + cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t)); + cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec)); + strcpy(cd->info->name, name); + cd->info->scheme = scheme; + cd->info->init = init; + cd->next = registeredCODECS; + registeredCODECS = cd; + } + else + { + TIFFErrorExt(0, "TIFFRegisterCODEC", + "No space to register compression scheme %s", name); + return NULL; + } + return (cd->info); } -void -TIFFUnRegisterCODEC(TIFFCodec* c) +void TIFFUnRegisterCODEC(TIFFCodec *c) { - codec_t* cd; - codec_t** pcd; + codec_t *cd; + codec_t **pcd; - for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next) - if (cd->info == c) { - *pcd = cd->next; - _TIFFfree(cd); - return; - } - TIFFErrorExt(0, "TIFFUnRegisterCODEC", - "Cannot remove compression scheme %s; not registered", c->name); + for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next) + if (cd->info == c) + { + *pcd = cd->next; + _TIFFfreeExt(NULL, cd); + return; + } + TIFFErrorExt(0, "TIFFUnRegisterCODEC", + "Cannot remove compression scheme %s; not registered", + c->name); } /************************************************************************/ @@ -242,61 +253,58 @@ TIFFUnRegisterCODEC(TIFFCodec* c) /** * Get list of configured codecs, both built-in and registered by user. * Caller is responsible to free this structure. - * + * * @return returns array of TIFFCodec records (the last record should be NULL) * or NULL if function failed. */ -TIFFCodec* -TIFFGetConfiguredCODECs() +TIFFCodec *TIFFGetConfiguredCODECs() { - int i = 1; - codec_t *cd; - const TIFFCodec* c; - TIFFCodec* codecs = NULL; - TIFFCodec* new_codecs; + int i = 1; + codec_t *cd; + const TIFFCodec *c; + TIFFCodec *codecs = NULL; + TIFFCodec *new_codecs; - for (cd = registeredCODECS; cd; cd = cd->next) { - new_codecs = (TIFFCodec *) - _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); - if (!new_codecs) { - _TIFFfree (codecs); - return NULL; - } - codecs = new_codecs; - _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec)); - i++; - } - for (c = _TIFFBuiltinCODECS; c->name; c++) { - if (TIFFIsCODECConfigured(c->scheme)) { - new_codecs = (TIFFCodec *) - _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); - if (!new_codecs) { - _TIFFfree (codecs); - return NULL; - } - codecs = new_codecs; - _TIFFmemcpy(codecs + i - 1, (const void*)c, sizeof(TIFFCodec)); - i++; - } - } + for (cd = registeredCODECS; cd; cd = cd->next) + { + new_codecs = + (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); + if (!new_codecs) + { + _TIFFfreeExt(NULL, codecs); + return NULL; + } + codecs = new_codecs; + _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec)); + i++; + } + for (c = _TIFFBuiltinCODECS; c->name; c++) + { + if (TIFFIsCODECConfigured(c->scheme)) + { + new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs, + i * sizeof(TIFFCodec)); + if (!new_codecs) + { + _TIFFfreeExt(NULL, codecs); + return NULL; + } + codecs = new_codecs; + _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec)); + i++; + } + } - new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); - if (!new_codecs) { - _TIFFfree (codecs); - return NULL; - } - codecs = new_codecs; - _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); + new_codecs = + (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); + if (!new_codecs) + { + _TIFFfreeExt(NULL, codecs); + return NULL; + } + codecs = new_codecs; + _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); - return codecs; + return codecs; } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_config.h.cmake.in b/3rdparty/libtiff/tif_config.h.cmake.in index 2414460338..62a4c7305a 100644 --- a/3rdparty/libtiff/tif_config.h.cmake.in +++ b/3rdparty/libtiff/tif_config.h.cmake.in @@ -1,6 +1,14 @@ +/* clang-format off */ +/* clang-format disabled because CMake scripts are very sensitive to the + * formatting of this file. configure_file variables of type "@VAR@" are + * modified by clang-format and won't be substituted. + */ + /* libtiff/tif_config.h.cmake.in. Not generated, but originated from autoheader. */ /* This file must be kept up-to-date with needed substitutions from libtiff/tif_config.h.in. */ +#include "tiffconf.h" + /* Support CCITT Group 3 & 4 algorithms */ #cmakedefine CCITT_SUPPORT 1 @@ -20,84 +28,33 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ASSERT_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_DLFCN_H 1 +/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't. */ +#cmakedefine HAVE_DECL_OPTARG 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_FCNTL_H 1 +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#cmakedefine HAVE_FSEEKO 1 + /* Define to 1 if you have the `getopt' function. */ #cmakedefine HAVE_GETOPT 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GLUT_GLUT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GL_GLUT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GL_GLU_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GL_GL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_IO_H 1 /* Define to 1 if you have the `jbg_newlen' function. */ #cmakedefine HAVE_JBG_NEWLEN 1 -/* Define to 1 if you have the `lfind' function. */ -#cmakedefine HAVE_LFIND 1 - /* Define to 1 if you have the `mmap' function. */ #cmakedefine HAVE_MMAP 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENGL_GLU_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENGL_GL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SEARCH_H 1 - /* Define to 1 if you have the `setmode' function. */ #cmakedefine HAVE_SETMODE 1 -/* Define to 1 if you have the `snprintf' function. */ -#cmakedefine HAVE_SNPRINTF 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#cmakedefine HAVE_STRCASECMP 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRINGS_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRING_H 1 - -/* Define to 1 if you have the `strtol' function. */ -#cmakedefine HAVE_STRTOL 1 - -/* Define to 1 if you have the `strtoll' function. */ -#cmakedefine HAVE_STRTOLL 1 - -/* Define to 1 if you have the `strtoul' function. */ -#cmakedefine HAVE_STRTOUL 1 - -/* Define to 1 if you have the `strtoull' function. */ -#cmakedefine HAVE_STRTOULL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TIME_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_TYPES_H 1 @@ -105,20 +62,17 @@ #cmakedefine HAVE_UNISTD_H 1 /* 8/12 bit libjpeg dual mode enabled */ -#cmakedefine JPEG_DUAL_MODE_8_12 1 +#cmakedefine JPEG_DUAL_MODE_8_12 1 1 + +/* Support LERC compression */ +#cmakedefine LERC_SUPPORT 1 /* 12bit libjpeg primary include file with path */ -#define LIBJPEG_12_PATH @LIBJPEG_12_PATH@ +#define LIBJPEG_12_PATH "@LIBJPEG_12_PATH@" /* Support LZMA2 compression */ #cmakedefine LZMA_SUPPORT 1 -/* Support ZSTD compression */ -#cmakedefine ZSTD_SUPPORT 1 - -/* Support WEBP compression */ -#cmakedefine WEBP_SUPPORT 1 - /* Name of package */ #define PACKAGE "@PACKAGE_NAME@" @@ -128,80 +82,30 @@ /* Define to the full name of this package. */ #define PACKAGE_NAME "@PACKAGE_NAME@" -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "@PACKAGE_STRING@" - /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "@PACKAGE_TARNAME@" /* Define to the home page for this package. */ #define PACKAGE_URL "@PACKAGE_URL@" -/* Define to the version of this package. */ -#define PACKAGE_VERSION "@PACKAGE_VERSION@" - -/* The size of `signed int', as computed by sizeof. */ -#define SIZEOF_SIGNED_INT @SIZEOF_SIGNED_INT@ - -/* The size of `signed long', as computed by sizeof. */ -#define SIZEOF_SIGNED_LONG @SIZEOF_SIGNED_LONG@ - -/* The size of `signed long long', as computed by sizeof. */ -#define SIZEOF_SIGNED_LONG_LONG @SIZEOF_SIGNED_LONG_LONG@ - -/* The size of `unsigned char *', as computed by sizeof. */ -#define SIZEOF_UNSIGNED_CHAR_P @SIZEOF_UNSIGNED_CHAR_P@ - -/* The size of `unsigned int', as computed by sizeof. */ -#define SIZEOF_UNSIGNED_INT @SIZEOF_UNSIGNED_INT@ - -/* The size of `unsigned long', as computed by sizeof. */ -#define SIZEOF_UNSIGNED_LONG @SIZEOF_UNSIGNED_LONG@ - -/* The size of `unsigned long long', as computed by sizeof. */ -#define SIZEOF_UNSIGNED_LONG_LONG @SIZEOF_UNSIGNED_LONG_LONG@ - -/* The size of `unsigned short', as computed by sizeof. */ -#define SIZEOF_UNSIGNED_SHORT @SIZEOF_UNSIGNED_SHORT@ +/* Size of size_t */ +#define SIZEOF_SIZE_T @SIZEOF_SIZE_T@ /* Default size of the strip in bytes (when strip chopping enabled) */ -#define STRIP_SIZE_DEFAULT @STRIP_SIZE_DEFAULT@ +#cmakedefine STRIP_SIZE_DEFAULT @STRIP_SIZE_DEFAULT@ -/* Signed 32-bit type formatter */ -#define TIFF_INT32_FORMAT "@TIFF_INT32_FORMAT@" - -/* Signed 64-bit type formatter */ -#define TIFF_INT64_FORMAT "@TIFF_INT64_FORMAT@" - -/* Pointer difference type formatter */ -#define TIFF_PTRDIFF_FORMAT "@TIFF_PTRDIFF_FORMAT@" - -/* Unsigned size type formatter */ -#define TIFF_SIZE_FORMAT "@TIFF_SIZE_FORMAT@" - -/* Signed size type formatter */ -#define TIFF_SSIZE_FORMAT "@TIFF_SSIZE_FORMAT@" - -/* Unsigned 32-bit type formatter */ -#define TIFF_UINT32_FORMAT "@TIFF_UINT32_FORMAT@" - -/* Unsigned 64-bit type formatter */ -#define TIFF_UINT64_FORMAT "@TIFF_UINT64_FORMAT@" - -/* Unsigned 8-bit type */ -#define TIFF_UINT8_T @TIFF_UINT8_T@ - -/* Define to 1 if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Define to 1 if your declares `struct tm'. */ -#cmakedefine TM_IN_SYS_TIME 1 +/** Maximum number of TIFF IFDs that libtiff can iterate through in a file. */ +#define TIFF_MAX_DIR_COUNT @TIFF_MAX_DIR_COUNT@ /* define to use win32 IO system */ #cmakedefine USE_WIN32_FILEIO 1 -/* Version number of package */ -#define VERSION "@PACKAGE_VERSION@" +/* Support WEBP compression */ +#cmakedefine WEBP_SUPPORT 1 + +/* Support ZSTD compression */ +#cmakedefine ZSTD_SUPPORT 1 + /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ @@ -215,17 +119,21 @@ # endif #endif -/* Number of bits in a file offset, on hosts where this is settable. */ -#define _FILE_OFFSET_BITS @FILE_OFFSET_BITS@ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#define inline @INLINE_KEYWORD@ +#if !defined(__MINGW32__) +# define TIFF_SIZE_FORMAT "zu" +#endif +#if SIZEOF_SIZE_T == 8 +# define TIFF_SSIZE_FORMAT PRId64 +# if defined(__MINGW32__) +# define TIFF_SIZE_FORMAT PRIu64 +# endif +#elif SIZEOF_SIZE_T == 4 +# define TIFF_SSIZE_FORMAT PRId32 +# if defined(__MINGW32__) +# define TIFF_SIZE_FORMAT PRIu32 +# endif +#else +# error "Unsupported size_t size; please submit a bug report" #endif -/* Define to `long int' if does not define. */ -#undef off_t - -/* Define to `unsigned int' if does not define. */ -#undef size_t +/* clang-format on */ diff --git a/3rdparty/libtiff/tif_dir.c b/3rdparty/libtiff/tif_dir.c index 347b7115cb..8500621837 100644 --- a/3rdparty/libtiff/tif_dir.c +++ b/3rdparty/libtiff/tif_dir.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,760 +29,1078 @@ * (and also some miscellaneous stuff) */ #include "tiffiop.h" -#include /*--: for Rational2Double */ +#include /*--: for Rational2Double */ +#include /* * These are used in the backwards compatibility code... */ -#define DATATYPE_VOID 0 /* !untyped data */ -#define DATATYPE_INT 1 /* !signed integer data */ -#define DATATYPE_UINT 2 /* !unsigned integer data */ -#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ +#define DATATYPE_VOID 0 /* !untyped data */ +#define DATATYPE_INT 1 /* !signed integer data */ +#define DATATYPE_UINT 2 /* !unsigned integer data */ +#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ -static void -setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) +static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb, + size_t elem_size) { - if (*vpp) { - _TIFFfree(*vpp); - *vpp = 0; - } - if (vp) { - tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL); - if (bytes) - *vpp = (void*) _TIFFmalloc(bytes); - if (*vpp) - _TIFFmemcpy(*vpp, vp, bytes); - } + if (*vpp) + { + _TIFFfreeExt(tif, *vpp); + *vpp = 0; + } + if (vp) + { + tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL); + if (bytes) + *vpp = (void *)_TIFFmallocExt(tif, bytes); + if (*vpp) + _TIFFmemcpy(*vpp, vp, bytes); + } } -void _TIFFsetByteArray(void** vpp, void* vp, uint32 n) - { setByteArray(vpp, vp, n, 1); } -void _TIFFsetString(char** cpp, char* cp) - { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); } -static void _TIFFsetNString(char** cpp, char* cp, uint32 n) - { setByteArray((void**) cpp, (void*) cp, n, 1); } -void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n) - { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); } -void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n) - { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); } -static void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n) - { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); } -void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n) - { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); } -void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n) - { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); } - -static void -setDoubleArrayOneValue(double** vpp, double value, size_t nmemb) +void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n) { - if (*vpp) - _TIFFfree(*vpp); - *vpp = _TIFFmalloc(nmemb*sizeof(double)); - if (*vpp) - { - while (nmemb--) - ((double*)*vpp)[nmemb] = value; - } + setByteArray(NULL, vpp, vp, n, 1); +} +void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n) +{ + setByteArray(tif, vpp, vp, n, 1); +} + +static void _TIFFsetNString(TIFF *tif, char **cpp, const char *cp, uint32_t n) +{ + setByteArray(tif, (void **)cpp, cp, n, 1); +} + +void _TIFFsetShortArray(uint16_t **wpp, const uint16_t *wp, uint32_t n) +{ + setByteArray(NULL, (void **)wpp, wp, n, sizeof(uint16_t)); +} +void _TIFFsetShortArrayExt(TIFF *tif, uint16_t **wpp, const uint16_t *wp, + uint32_t n) +{ + setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t)); +} + +void _TIFFsetLongArray(uint32_t **lpp, const uint32_t *lp, uint32_t n) +{ + setByteArray(NULL, (void **)lpp, lp, n, sizeof(uint32_t)); +} +void _TIFFsetLongArrayExt(TIFF *tif, uint32_t **lpp, const uint32_t *lp, + uint32_t n) +{ + setByteArray(tif, (void **)lpp, lp, n, sizeof(uint32_t)); +} + +static void _TIFFsetLong8Array(TIFF *tif, uint64_t **lpp, const uint64_t *lp, + uint32_t n) +{ + setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t)); +} + +void _TIFFsetFloatArray(float **fpp, const float *fp, uint32_t n) +{ + setByteArray(NULL, (void **)fpp, fp, n, sizeof(float)); +} +void _TIFFsetFloatArrayExt(TIFF *tif, float **fpp, const float *fp, uint32_t n) +{ + setByteArray(tif, (void **)fpp, fp, n, sizeof(float)); +} + +void _TIFFsetDoubleArray(double **dpp, const double *dp, uint32_t n) +{ + setByteArray(NULL, (void **)dpp, dp, n, sizeof(double)); +} +void _TIFFsetDoubleArrayExt(TIFF *tif, double **dpp, const double *dp, + uint32_t n) +{ + setByteArray(tif, (void **)dpp, dp, n, sizeof(double)); +} + +static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value, + size_t nmemb) +{ + if (*vpp) + _TIFFfreeExt(tif, *vpp); + *vpp = _TIFFmallocExt(tif, nmemb * sizeof(double)); + if (*vpp) + { + while (nmemb--) + ((double *)*vpp)[nmemb] = value; + } } /* * Install extra samples information. */ -static int -setExtraSamples(TIFF* tif, va_list ap, uint32* v) +static int setExtraSamples(TIFF *tif, va_list ap, uint32_t *v) { /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */ -#define EXTRASAMPLE_COREL_UNASSALPHA 999 +#define EXTRASAMPLE_COREL_UNASSALPHA 999 - uint16* va; - uint32 i; - TIFFDirectory* td = &tif->tif_dir; - static const char module[] = "setExtraSamples"; + uint16_t *va; + uint32_t i; + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "setExtraSamples"; - *v = (uint16) va_arg(ap, uint16_vap); - if ((uint16) *v > td->td_samplesperpixel) - return 0; - va = va_arg(ap, uint16*); - if (*v > 0 && va == NULL) /* typically missing param */ - return 0; - for (i = 0; i < *v; i++) { - if (va[i] > EXTRASAMPLE_UNASSALPHA) { - /* - * XXX: Corel Draw is known to produce incorrect - * ExtraSamples tags which must be patched here if we - * want to be able to open some of the damaged TIFF - * files: - */ - if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA) - va[i] = EXTRASAMPLE_UNASSALPHA; - else - return 0; - } - } - - if ( td->td_transferfunction[0] != NULL && (td->td_samplesperpixel - *v > 1) && - !(td->td_samplesperpixel - td->td_extrasamples > 1)) + *v = (uint16_t)va_arg(ap, uint16_vap); + if ((uint16_t)*v > td->td_samplesperpixel) + return 0; + va = va_arg(ap, uint16_t *); + if (*v > 0 && va == NULL) /* typically missing param */ + return 0; + for (i = 0; i < *v; i++) + { + if (va[i] > EXTRASAMPLE_UNASSALPHA) { - TIFFWarningExt(tif->tif_clientdata,module, - "ExtraSamples tag value is changing, " - "but TransferFunction was read with a different value. Canceling it"); - TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION); - _TIFFfree(td->td_transferfunction[0]); - td->td_transferfunction[0] = NULL; + /* + * XXX: Corel Draw is known to produce incorrect + * ExtraSamples tags which must be patched here if we + * want to be able to open some of the damaged TIFF + * files: + */ + if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA) + va[i] = EXTRASAMPLE_UNASSALPHA; + else + return 0; } + } - td->td_extrasamples = (uint16) *v; - _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples); - return 1; + if (td->td_transferfunction[0] != NULL && + (td->td_samplesperpixel - *v > 1) && + !(td->td_samplesperpixel - td->td_extrasamples > 1)) + { + TIFFWarningExtR(tif, module, + "ExtraSamples tag value is changing, " + "but TransferFunction was read with a different value. " + "Canceling it"); + TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION); + _TIFFfreeExt(tif, td->td_transferfunction[0]); + td->td_transferfunction[0] = NULL; + } + + td->td_extrasamples = (uint16_t)*v; + _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples); + return 1; #undef EXTRASAMPLE_COREL_UNASSALPHA } /* - * Confirm we have "samplesperpixel" ink names separated by \0. Returns + * Count ink names separated by \0. Returns * zero if the ink names are not as expected. */ -static uint32 -checkInkNamesString(TIFF* tif, uint32 slen, const char* s) +static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s) { - TIFFDirectory* td = &tif->tif_dir; - uint16 i = td->td_samplesperpixel; + uint16_t i = 0; - if (slen > 0) { - const char* ep = s+slen; - const char* cp = s; - for (; i > 0; i--) { - for (; cp < ep && *cp != '\0'; cp++) {} - if (cp >= ep) - goto bad; - cp++; /* skip \0 */ - } - return ((uint32)(cp-s)); - } + if (slen > 0) + { + const char *ep = s + slen; + const char *cp = s; + do + { + for (; cp < ep && *cp != '\0'; cp++) + { + } + if (cp >= ep) + goto bad; + cp++; /* skip \0 */ + i++; + } while (cp < ep); + return (i); + } bad: - TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", - "%s: Invalid InkNames value; expecting %d names, found %d", - tif->tif_name, - td->td_samplesperpixel, - td->td_samplesperpixel-i); - return (0); -} - -static int -_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) -{ - static const char module[] = "_TIFFVSetField"; - - TIFFDirectory* td = &tif->tif_dir; - int status = 1; - uint32 v32, i, v; - double dblval; - char* s; - const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); - uint32 standard_tag = tag; - if( fip == NULL ) /* cannot happen since OkToChangeTag() already checks it */ - return 0; - /* - * We want to force the custom code to be used for custom - * fields even if the tag happens to match a well known - * one - important for reinterpreted handling of standard - * tag values in custom directories (i.e. EXIF) - */ - if (fip->field_bit == FIELD_CUSTOM) { - standard_tag = 0; - } - - switch (standard_tag) { - case TIFFTAG_SUBFILETYPE: - td->td_subfiletype = (uint32) va_arg(ap, uint32); - break; - case TIFFTAG_IMAGEWIDTH: - td->td_imagewidth = (uint32) va_arg(ap, uint32); - break; - case TIFFTAG_IMAGELENGTH: - td->td_imagelength = (uint32) va_arg(ap, uint32); - break; - case TIFFTAG_BITSPERSAMPLE: - td->td_bitspersample = (uint16) va_arg(ap, uint16_vap); - /* - * If the data require post-decoding processing to byte-swap - * samples, set it up here. Note that since tags are required - * to be ordered, compression code can override this behavior - * in the setup method if it wants to roll the post decoding - * work in with its normal work. - */ - if (tif->tif_flags & TIFF_SWAB) { - if (td->td_bitspersample == 8) - tif->tif_postdecode = _TIFFNoPostDecode; - else if (td->td_bitspersample == 16) - tif->tif_postdecode = _TIFFSwab16BitData; - else if (td->td_bitspersample == 24) - tif->tif_postdecode = _TIFFSwab24BitData; - else if (td->td_bitspersample == 32) - tif->tif_postdecode = _TIFFSwab32BitData; - else if (td->td_bitspersample == 64) - tif->tif_postdecode = _TIFFSwab64BitData; - else if (td->td_bitspersample == 128) /* two 64's */ - tif->tif_postdecode = _TIFFSwab64BitData; - } - break; - case TIFFTAG_COMPRESSION: - v = (uint16) va_arg(ap, uint16_vap); - /* - * If we're changing the compression scheme, the notify the - * previous module so that it can cleanup any state it's - * setup. - */ - if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { - if ((uint32)td->td_compression == v) - break; - (*tif->tif_cleanup)(tif); - tif->tif_flags &= ~TIFF_CODERSETUP; - } - /* - * Setup new compression routine state. - */ - if( (status = TIFFSetCompressionScheme(tif, v)) != 0 ) - td->td_compression = (uint16) v; - else - status = 0; - break; - case TIFFTAG_PHOTOMETRIC: - td->td_photometric = (uint16) va_arg(ap, uint16_vap); - break; - case TIFFTAG_THRESHHOLDING: - td->td_threshholding = (uint16) va_arg(ap, uint16_vap); - break; - case TIFFTAG_FILLORDER: - v = (uint16) va_arg(ap, uint16_vap); - if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) - goto badvalue; - td->td_fillorder = (uint16) v; - break; - case TIFFTAG_ORIENTATION: - v = (uint16) va_arg(ap, uint16_vap); - if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) - goto badvalue; - else - td->td_orientation = (uint16) v; - break; - case TIFFTAG_SAMPLESPERPIXEL: - v = (uint16) va_arg(ap, uint16_vap); - if (v == 0) - goto badvalue; - if( v != td->td_samplesperpixel ) - { - /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */ - if( td->td_sminsamplevalue != NULL ) - { - TIFFWarningExt(tif->tif_clientdata,module, - "SamplesPerPixel tag value is changing, " - "but SMinSampleValue tag was read with a different value. Canceling it"); - TIFFClrFieldBit(tif,FIELD_SMINSAMPLEVALUE); - _TIFFfree(td->td_sminsamplevalue); - td->td_sminsamplevalue = NULL; - } - if( td->td_smaxsamplevalue != NULL ) - { - TIFFWarningExt(tif->tif_clientdata,module, - "SamplesPerPixel tag value is changing, " - "but SMaxSampleValue tag was read with a different value. Canceling it"); - TIFFClrFieldBit(tif,FIELD_SMAXSAMPLEVALUE); - _TIFFfree(td->td_smaxsamplevalue); - td->td_smaxsamplevalue = NULL; - } - /* Test if 3 transfer functions instead of just one are now needed - See http://bugzilla.maptools.org/show_bug.cgi?id=2820 */ - if( td->td_transferfunction[0] != NULL && (v - td->td_extrasamples > 1) && - !(td->td_samplesperpixel - td->td_extrasamples > 1)) - { - TIFFWarningExt(tif->tif_clientdata,module, - "SamplesPerPixel tag value is changing, " - "but TransferFunction was read with a different value. Canceling it"); - TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION); - _TIFFfree(td->td_transferfunction[0]); - td->td_transferfunction[0] = NULL; - } - } - td->td_samplesperpixel = (uint16) v; - break; - case TIFFTAG_ROWSPERSTRIP: - v32 = (uint32) va_arg(ap, uint32); - if (v32 == 0) - goto badvalue32; - td->td_rowsperstrip = v32; - if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { - td->td_tilelength = v32; - td->td_tilewidth = td->td_imagewidth; - } - break; - case TIFFTAG_MINSAMPLEVALUE: - td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap); - break; - case TIFFTAG_MAXSAMPLEVALUE: - td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap); - break; - case TIFFTAG_SMINSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - _TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel); - else - setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel); - break; - case TIFFTAG_SMAXSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - _TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel); - else - setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel); - break; - case TIFFTAG_XRESOLUTION: - dblval = va_arg(ap, double); - if( dblval < 0 ) - goto badvaluedouble; - td->td_xresolution = _TIFFClampDoubleToFloat( dblval ); - break; - case TIFFTAG_YRESOLUTION: - dblval = va_arg(ap, double); - if( dblval < 0 ) - goto badvaluedouble; - td->td_yresolution = _TIFFClampDoubleToFloat( dblval ); - break; - case TIFFTAG_PLANARCONFIG: - v = (uint16) va_arg(ap, uint16_vap); - if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) - goto badvalue; - td->td_planarconfig = (uint16) v; - break; - case TIFFTAG_XPOSITION: - td->td_xposition = _TIFFClampDoubleToFloat( va_arg(ap, double) ); - break; - case TIFFTAG_YPOSITION: - td->td_yposition = _TIFFClampDoubleToFloat( va_arg(ap, double) ); - break; - case TIFFTAG_RESOLUTIONUNIT: - v = (uint16) va_arg(ap, uint16_vap); - if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) - goto badvalue; - td->td_resolutionunit = (uint16) v; - break; - case TIFFTAG_PAGENUMBER: - td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap); - td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap); - break; - case TIFFTAG_HALFTONEHINTS: - td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap); - td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap); - break; - case TIFFTAG_COLORMAP: - v32 = (uint32)(1L<td_bitspersample); - _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32); - _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32); - _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32); - break; - case TIFFTAG_EXTRASAMPLES: - if (!setExtraSamples(tif, ap, &v)) - goto badvalue; - break; - case TIFFTAG_MATTEING: - td->td_extrasamples = (((uint16) va_arg(ap, uint16_vap)) != 0); - if (td->td_extrasamples) { - uint16 sv = EXTRASAMPLE_ASSOCALPHA; - _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1); - } - break; - case TIFFTAG_TILEWIDTH: - v32 = (uint32) va_arg(ap, uint32); - if (v32 % 16) { - if (tif->tif_mode != O_RDONLY) - goto badvalue32; - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "Nonstandard tile width %u, convert file", v32); - } - td->td_tilewidth = v32; - tif->tif_flags |= TIFF_ISTILED; - break; - case TIFFTAG_TILELENGTH: - v32 = (uint32) va_arg(ap, uint32); - if (v32 % 16) { - if (tif->tif_mode != O_RDONLY) - goto badvalue32; - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "Nonstandard tile length %u, convert file", v32); - } - td->td_tilelength = v32; - tif->tif_flags |= TIFF_ISTILED; - break; - case TIFFTAG_TILEDEPTH: - v32 = (uint32) va_arg(ap, uint32); - if (v32 == 0) - goto badvalue32; - td->td_tiledepth = v32; - break; - case TIFFTAG_DATATYPE: - v = (uint16) va_arg(ap, uint16_vap); - switch (v) { - case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; - case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; - case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break; - case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break; - default: goto badvalue; - } - td->td_sampleformat = (uint16) v; - break; - case TIFFTAG_SAMPLEFORMAT: - v = (uint16) va_arg(ap, uint16_vap); - if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) - goto badvalue; - td->td_sampleformat = (uint16) v; - - /* Try to fix up the SWAB function for complex data. */ - if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT - && td->td_bitspersample == 32 - && tif->tif_postdecode == _TIFFSwab32BitData ) - tif->tif_postdecode = _TIFFSwab16BitData; - else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT - || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) - && td->td_bitspersample == 64 - && tif->tif_postdecode == _TIFFSwab64BitData ) - tif->tif_postdecode = _TIFFSwab32BitData; - break; - case TIFFTAG_IMAGEDEPTH: - td->td_imagedepth = (uint32) va_arg(ap, uint32); - break; - case TIFFTAG_SUBIFD: - if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { - td->td_nsubifd = (uint16) va_arg(ap, uint16_vap); - _TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*), - (uint32) td->td_nsubifd); - } else { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Sorry, cannot nest SubIFDs", - tif->tif_name); - status = 0; - } - break; - case TIFFTAG_YCBCRPOSITIONING: - td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap); - break; - case TIFFTAG_YCBCRSUBSAMPLING: - td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap); - td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap); - break; - case TIFFTAG_TRANSFERFUNCTION: - v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; - for (i = 0; i < v; i++) - _TIFFsetShortArray(&td->td_transferfunction[i], - va_arg(ap, uint16*), 1U<td_bitspersample); - break; - case TIFFTAG_REFERENCEBLACKWHITE: - /* XXX should check for null range */ - _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6); - break; - case TIFFTAG_INKNAMES: - v = (uint16) va_arg(ap, uint16_vap); - s = va_arg(ap, char*); - v = checkInkNamesString(tif, v, s); - status = v > 0; - if( v > 0 ) { - _TIFFsetNString(&td->td_inknames, s, v); - td->td_inknameslen = v; - } - break; - case TIFFTAG_PERSAMPLE: - v = (uint16) va_arg(ap, uint16_vap); - if( v == PERSAMPLE_MULTI ) - tif->tif_flags |= TIFF_PERSAMPLE; - else - tif->tif_flags &= ~TIFF_PERSAMPLE; - break; - default: { - TIFFTagValue *tv; - int tv_size, iCustom; - - /* - * This can happen if multiple images are open with different - * codecs which have private tags. The global tag information - * table may then have tags that are valid for one file but not - * the other. If the client tries to set a tag that is not valid - * for the image's codec then we'll arrive here. This - * happens, for example, when tiffcp is used to convert between - * compression schemes and codec-specific tags are blindly copied. - */ - if(fip->field_bit != FIELD_CUSTOM) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Invalid %stag \"%s\" (not supported by codec)", - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", - fip->field_name); - status = 0; - break; - } - - /* - * Find the existing entry for this custom value. - */ - tv = NULL; - for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) { - if (td->td_customValues[iCustom].info->field_tag == tag) { - tv = td->td_customValues + iCustom; - if (tv->value != NULL) { - _TIFFfree(tv->value); - tv->value = NULL; - } - break; - } - } - - /* - * Grow the custom list if the entry was not found. - */ - if(tv == NULL) { - TIFFTagValue *new_customValues; - - td->td_customValueCount++; - new_customValues = (TIFFTagValue *) - _TIFFrealloc(td->td_customValues, - sizeof(TIFFTagValue) * td->td_customValueCount); - if (!new_customValues) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Failed to allocate space for list of custom values", - tif->tif_name); - status = 0; - goto end; - } - - td->td_customValues = new_customValues; - - tv = td->td_customValues + (td->td_customValueCount - 1); - tv->info = fip; - tv->value = NULL; - tv->count = 0; - } - - /* - * Set custom value ... save a copy of the custom tag value. - */ - tv_size = _TIFFDataSize(fip->field_type); - /*--: Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ - if (fip->field_type == TIFF_RATIONAL || fip->field_type == TIFF_SRATIONAL) { - tv_size = _TIFFSetGetFieldSize(fip->set_field_type); - } - if (tv_size == 0) { - status = 0; - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Bad field type %d for \"%s\"", - tif->tif_name, fip->field_type, - fip->field_name); - goto end; - } - - if (fip->field_type == TIFF_ASCII) - { - uint32 ma; - char* mb; - if (fip->field_passcount) - { - assert(fip->field_writecount==TIFF_VARIABLE2); - ma=(uint32)va_arg(ap,uint32); - mb=(char*)va_arg(ap,char*); - } - else - { - mb=(char*)va_arg(ap,char*); - ma=(uint32)(strlen(mb)+1); - } - tv->count=ma; - setByteArray(&tv->value,mb,ma,1); - } - else - { - if (fip->field_passcount) { - if (fip->field_writecount == TIFF_VARIABLE2) - tv->count = (uint32) va_arg(ap, uint32); - else - tv->count = (int) va_arg(ap, int); - } else if (fip->field_writecount == TIFF_VARIABLE - || fip->field_writecount == TIFF_VARIABLE2) - tv->count = 1; - else if (fip->field_writecount == TIFF_SPP) - tv->count = td->td_samplesperpixel; - else - tv->count = fip->field_writecount; - - if (tv->count == 0) { - status = 0; - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Null count for \"%s\" (type " - "%d, writecount %d, passcount %d)", - tif->tif_name, - fip->field_name, - fip->field_type, - fip->field_writecount, - fip->field_passcount); - goto end; - } - - tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, - "custom tag binary object"); - if (!tv->value) { - status = 0; - goto end; - } - - if (fip->field_tag == TIFFTAG_DOTRANGE - && strcmp(fip->field_name,"DotRange") == 0) { - /* TODO: This is an evil exception and should not have been - handled this way ... likely best if we move it into - the directory structure with an explicit field in - libtiff 4.1 and assign it a FIELD_ value */ - uint16 v2[2]; - v2[0] = (uint16)va_arg(ap, int); - v2[1] = (uint16)va_arg(ap, int); - _TIFFmemcpy(tv->value, &v2, 4); - } - - else if (fip->field_passcount - || fip->field_writecount == TIFF_VARIABLE - || fip->field_writecount == TIFF_VARIABLE2 - || fip->field_writecount == TIFF_SPP - || tv->count > 1) { - /*--: Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */ - _TIFFmemcpy(tv->value, va_arg(ap, void *), - tv->count * tv_size); - } else { - char *val = (char *)tv->value; - assert( tv->count == 1 ); - - switch (fip->field_type) { - case TIFF_BYTE: - case TIFF_UNDEFINED: - { - uint8 v2 = (uint8)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SBYTE: - { - int8 v2 = (int8)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SHORT: - { - uint16 v2 = (uint16)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SSHORT: - { - int16 v2 = (int16)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_LONG: - case TIFF_IFD: - { - uint32 v2 = va_arg(ap, uint32); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SLONG: - { - int32 v2 = va_arg(ap, int32); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_LONG8: - case TIFF_IFD8: - { - uint64 v2 = va_arg(ap, uint64); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SLONG8: - { - int64 v2 = va_arg(ap, int64); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - /*-- Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */ - { - if (tv_size == 8) { - double v2 = va_arg(ap, double); - _TIFFmemcpy(val, &v2, tv_size); - } else { - /*-- default should be tv_size == 4 */ - float v3 = (float)va_arg(ap, double); - _TIFFmemcpy(val, &v3, tv_size); - /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */ - if (tv_size != 4) { - TIFFErrorExt(0,"TIFFLib: _TIFFVSetField()", "Rational2Double: .set_field_type in not 4 but %d", tv_size); - } - } - } - break; - case TIFF_FLOAT: - { - float v2 = _TIFFClampDoubleToFloat(va_arg(ap, double)); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_DOUBLE: - { - double v2 = va_arg(ap, double); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - default: - _TIFFmemset(val, 0, tv_size); - status = 0; - break; - } - } - } - } - } - if (status) { - const TIFFField* fip2=TIFFFieldWithTag(tif,tag); - if (fip2) - TIFFSetFieldBit(tif, fip2->field_bit); - tif->tif_flags |= TIFF_DIRTYDIRECT; - } - -end: - va_end(ap); - return (status); -badvalue: - { - const TIFFField* fip2=TIFFFieldWithTag(tif,tag); - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Bad value %u for \"%s\" tag", - tif->tif_name, v, - fip2 ? fip2->field_name : "Unknown"); - va_end(ap); - } - return (0); -badvalue32: - { - const TIFFField* fip2=TIFFFieldWithTag(tif,tag); - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Bad value %u for \"%s\" tag", - tif->tif_name, v32, - fip2 ? fip2->field_name : "Unknown"); - va_end(ap); - } - return (0); -badvaluedouble: - { - const TIFFField* fip2=TIFFFieldWithTag(tif,tag); - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Bad value %f for \"%s\" tag", - tif->tif_name, dblval, - fip2 ? fip2->field_name : "Unknown"); - va_end(ap); - } + TIFFErrorExtR(tif, "TIFFSetField", + "%s: Invalid InkNames value; no NUL at given buffer end " + "location %" PRIu32 ", after %" PRIu16 " ink", + tif->tif_name, slen, i); return (0); } +static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) +{ + static const char module[] = "_TIFFVSetField"; + + TIFFDirectory *td = &tif->tif_dir; + int status = 1; + uint32_t v32, v; + double dblval; + char *s; + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + uint32_t standard_tag = tag; + if (fip == NULL) /* cannot happen since OkToChangeTag() already checks it */ + return 0; + /* + * We want to force the custom code to be used for custom + * fields even if the tag happens to match a well known + * one - important for reinterpreted handling of standard + * tag values in custom directories (i.e. EXIF) + */ + if (fip->field_bit == FIELD_CUSTOM) + { + standard_tag = 0; + } + + switch (standard_tag) + { + case TIFFTAG_SUBFILETYPE: + td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_IMAGEWIDTH: + td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_IMAGELENGTH: + td->td_imagelength = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_BITSPERSAMPLE: + td->td_bitspersample = (uint16_t)va_arg(ap, uint16_vap); + /* + * If the data require post-decoding processing to byte-swap + * samples, set it up here. Note that since tags are required + * to be ordered, compression code can override this behavior + * in the setup method if it wants to roll the post decoding + * work in with its normal work. + */ + if (tif->tif_flags & TIFF_SWAB) + { + if (td->td_bitspersample == 8) + tif->tif_postdecode = _TIFFNoPostDecode; + else if (td->td_bitspersample == 16) + tif->tif_postdecode = _TIFFSwab16BitData; + else if (td->td_bitspersample == 24) + tif->tif_postdecode = _TIFFSwab24BitData; + else if (td->td_bitspersample == 32) + tif->tif_postdecode = _TIFFSwab32BitData; + else if (td->td_bitspersample == 64) + tif->tif_postdecode = _TIFFSwab64BitData; + else if (td->td_bitspersample == 128) /* two 64's */ + tif->tif_postdecode = _TIFFSwab64BitData; + } + break; + case TIFFTAG_COMPRESSION: + v = (uint16_t)va_arg(ap, uint16_vap); + /* + * If we're changing the compression scheme, notify the + * previous module so that it can cleanup any state it's + * setup. + */ + if (TIFFFieldSet(tif, FIELD_COMPRESSION)) + { + if ((uint32_t)td->td_compression == v) + break; + (*tif->tif_cleanup)(tif); + tif->tif_flags &= ~TIFF_CODERSETUP; + } + /* + * Setup new compression routine state. + */ + if ((status = TIFFSetCompressionScheme(tif, v)) != 0) + td->td_compression = (uint16_t)v; + else + status = 0; + break; + case TIFFTAG_PHOTOMETRIC: + td->td_photometric = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_THRESHHOLDING: + td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_FILLORDER: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) + goto badvalue; + td->td_fillorder = (uint16_t)v; + break; + case TIFFTAG_ORIENTATION: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) + goto badvalue; + else + td->td_orientation = (uint16_t)v; + break; + case TIFFTAG_SAMPLESPERPIXEL: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v == 0) + goto badvalue; + if (v != td->td_samplesperpixel) + { + /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */ + if (td->td_sminsamplevalue != NULL) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag value is changing, " + "but SMinSampleValue tag was read with a " + "different value. Canceling it"); + TIFFClrFieldBit(tif, FIELD_SMINSAMPLEVALUE); + _TIFFfreeExt(tif, td->td_sminsamplevalue); + td->td_sminsamplevalue = NULL; + } + if (td->td_smaxsamplevalue != NULL) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag value is changing, " + "but SMaxSampleValue tag was read with a " + "different value. Canceling it"); + TIFFClrFieldBit(tif, FIELD_SMAXSAMPLEVALUE); + _TIFFfreeExt(tif, td->td_smaxsamplevalue); + td->td_smaxsamplevalue = NULL; + } + /* Test if 3 transfer functions instead of just one are now + needed See http://bugzilla.maptools.org/show_bug.cgi?id=2820 + */ + if (td->td_transferfunction[0] != NULL && + (v - td->td_extrasamples > 1) && + !(td->td_samplesperpixel - td->td_extrasamples > 1)) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag value is changing, " + "but TransferFunction was read with a " + "different value. Canceling it"); + TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION); + _TIFFfreeExt(tif, td->td_transferfunction[0]); + td->td_transferfunction[0] = NULL; + } + } + td->td_samplesperpixel = (uint16_t)v; + break; + case TIFFTAG_ROWSPERSTRIP: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 == 0) + goto badvalue32; + td->td_rowsperstrip = v32; + if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) + { + td->td_tilelength = v32; + td->td_tilewidth = td->td_imagewidth; + } + break; + case TIFFTAG_MINSAMPLEVALUE: + td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_MAXSAMPLEVALUE: + td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_SMINSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue, + va_arg(ap, double *), + td->td_samplesperpixel); + else + setDoubleArrayOneValue(tif, &td->td_sminsamplevalue, + va_arg(ap, double), + td->td_samplesperpixel); + break; + case TIFFTAG_SMAXSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue, + va_arg(ap, double *), + td->td_samplesperpixel); + else + setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue, + va_arg(ap, double), + td->td_samplesperpixel); + break; + case TIFFTAG_XRESOLUTION: + dblval = va_arg(ap, double); + if (dblval != dblval || dblval < 0) + goto badvaluedouble; + td->td_xresolution = _TIFFClampDoubleToFloat(dblval); + break; + case TIFFTAG_YRESOLUTION: + dblval = va_arg(ap, double); + if (dblval != dblval || dblval < 0) + goto badvaluedouble; + td->td_yresolution = _TIFFClampDoubleToFloat(dblval); + break; + case TIFFTAG_PLANARCONFIG: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) + goto badvalue; + td->td_planarconfig = (uint16_t)v; + break; + case TIFFTAG_XPOSITION: + td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double)); + break; + case TIFFTAG_YPOSITION: + td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double)); + break; + case TIFFTAG_RESOLUTIONUNIT: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) + goto badvalue; + td->td_resolutionunit = (uint16_t)v; + break; + case TIFFTAG_PAGENUMBER: + td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap); + td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_HALFTONEHINTS: + td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap); + td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_COLORMAP: + v32 = (uint32_t)(1L << td->td_bitspersample); + _TIFFsetShortArrayExt(tif, &td->td_colormap[0], + va_arg(ap, uint16_t *), v32); + _TIFFsetShortArrayExt(tif, &td->td_colormap[1], + va_arg(ap, uint16_t *), v32); + _TIFFsetShortArrayExt(tif, &td->td_colormap[2], + va_arg(ap, uint16_t *), v32); + break; + case TIFFTAG_EXTRASAMPLES: + if (!setExtraSamples(tif, ap, &v)) + goto badvalue; + break; + case TIFFTAG_MATTEING: + td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0); + if (td->td_extrasamples) + { + uint16_t sv = EXTRASAMPLE_ASSOCALPHA; + _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1); + } + break; + case TIFFTAG_TILEWIDTH: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 % 16) + { + if (tif->tif_mode != O_RDONLY) + goto badvalue32; + TIFFWarningExtR( + tif, tif->tif_name, + "Nonstandard tile width %" PRIu32 ", convert file", v32); + } + td->td_tilewidth = v32; + tif->tif_flags |= TIFF_ISTILED; + break; + case TIFFTAG_TILELENGTH: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 % 16) + { + if (tif->tif_mode != O_RDONLY) + goto badvalue32; + TIFFWarningExtR( + tif, tif->tif_name, + "Nonstandard tile length %" PRIu32 ", convert file", v32); + } + td->td_tilelength = v32; + tif->tif_flags |= TIFF_ISTILED; + break; + case TIFFTAG_TILEDEPTH: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 == 0) + goto badvalue32; + td->td_tiledepth = v32; + break; + case TIFFTAG_DATATYPE: + v = (uint16_t)va_arg(ap, uint16_vap); + switch (v) + { + case DATATYPE_VOID: + v = SAMPLEFORMAT_VOID; + break; + case DATATYPE_INT: + v = SAMPLEFORMAT_INT; + break; + case DATATYPE_UINT: + v = SAMPLEFORMAT_UINT; + break; + case DATATYPE_IEEEFP: + v = SAMPLEFORMAT_IEEEFP; + break; + default: + goto badvalue; + } + td->td_sampleformat = (uint16_t)v; + break; + case TIFFTAG_SAMPLEFORMAT: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) + goto badvalue; + td->td_sampleformat = (uint16_t)v; + + /* Try to fix up the SWAB function for complex data. */ + if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT && + td->td_bitspersample == 32 && + tif->tif_postdecode == _TIFFSwab32BitData) + tif->tif_postdecode = _TIFFSwab16BitData; + else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT || + td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) && + td->td_bitspersample == 64 && + tif->tif_postdecode == _TIFFSwab64BitData) + tif->tif_postdecode = _TIFFSwab32BitData; + break; + case TIFFTAG_IMAGEDEPTH: + td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_SUBIFD: + if ((tif->tif_flags & TIFF_INSUBIFD) == 0) + { + td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap); + _TIFFsetLong8Array(tif, &td->td_subifd, + (uint64_t *)va_arg(ap, uint64_t *), + (uint32_t)td->td_nsubifd); + } + else + { + TIFFErrorExtR(tif, module, "%s: Sorry, cannot nest SubIFDs", + tif->tif_name); + status = 0; + } + break; + case TIFFTAG_YCBCRPOSITIONING: + td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_YCBCRSUBSAMPLING: + td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap); + td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_TRANSFERFUNCTION: + { + uint32_t i; + v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; + for (i = 0; i < v; i++) + _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i], + va_arg(ap, uint16_t *), + 1U << td->td_bitspersample); + break; + } + case TIFFTAG_REFERENCEBLACKWHITE: + /* XXX should check for null range */ + _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite, + va_arg(ap, float *), 6); + break; + case TIFFTAG_INKNAMES: + { + v = (uint16_t)va_arg(ap, uint16_vap); + s = va_arg(ap, char *); + uint16_t ninksinstring; + ninksinstring = countInkNamesString(tif, v, s); + status = ninksinstring > 0; + if (ninksinstring > 0) + { + _TIFFsetNString(tif, &td->td_inknames, s, v); + td->td_inknameslen = v; + /* Set NumberOfInks to the value ninksinstring */ + if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) + { + if (td->td_numberofinks != ninksinstring) + { + TIFFErrorExtR( + tif, module, + "Warning %s; Tag %s:\n Value %" PRIu16 + " of NumberOfInks is different from the number of " + "inks %" PRIu16 + ".\n -> NumberOfInks value adapted to %" PRIu16 "", + tif->tif_name, fip->field_name, td->td_numberofinks, + ninksinstring, ninksinstring); + td->td_numberofinks = ninksinstring; + } + } + else + { + td->td_numberofinks = ninksinstring; + TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS); + } + if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + { + if (td->td_numberofinks != td->td_samplesperpixel) + { + TIFFErrorExtR(tif, module, + "Warning %s; Tag %s:\n Value %" PRIu16 + " of NumberOfInks is different from the " + "SamplesPerPixel value %" PRIu16 "", + tif->tif_name, fip->field_name, + td->td_numberofinks, + td->td_samplesperpixel); + } + } + } + } + break; + case TIFFTAG_NUMBEROFINKS: + v = (uint16_t)va_arg(ap, uint16_vap); + /* If InkNames already set also NumberOfInks is set accordingly and + * should be equal */ + if (TIFFFieldSet(tif, FIELD_INKNAMES)) + { + if (v != td->td_numberofinks) + { + TIFFErrorExtR( + tif, module, + "Error %s; Tag %s:\n It is not possible to set the " + "value %" PRIu32 + " for NumberOfInks\n which is different from the " + "number of inks in the InkNames tag (%" PRIu16 ")", + tif->tif_name, fip->field_name, v, td->td_numberofinks); + /* Do not set / overwrite number of inks already set by + * InkNames case accordingly. */ + status = 0; + } + } + else + { + td->td_numberofinks = (uint16_t)v; + if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + { + if (td->td_numberofinks != td->td_samplesperpixel) + { + TIFFErrorExtR(tif, module, + "Warning %s; Tag %s:\n Value %" PRIu32 + " of NumberOfInks is different from the " + "SamplesPerPixel value %" PRIu16 "", + tif->tif_name, fip->field_name, v, + td->td_samplesperpixel); + } + } + } + break; + case TIFFTAG_PERSAMPLE: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v == PERSAMPLE_MULTI) + tif->tif_flags |= TIFF_PERSAMPLE; + else + tif->tif_flags &= ~TIFF_PERSAMPLE; + break; + default: + { + TIFFTagValue *tv; + int tv_size, iCustom; + + /* + * This can happen if multiple images are open with different + * codecs which have private tags. The global tag information + * table may then have tags that are valid for one file but not + * the other. If the client tries to set a tag that is not valid + * for the image's codec then we'll arrive here. This + * happens, for example, when tiffcp is used to convert between + * compression schemes and codec-specific tags are blindly copied. + * + * This also happens when a FIELD_IGNORE tag is written. + */ + if (fip->field_bit == FIELD_IGNORE) + { + TIFFErrorExtR( + tif, module, + "%s: Ignored %stag \"%s\" (not supported by libtiff)", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", + fip->field_name); + status = 0; + break; + } + if (fip->field_bit != FIELD_CUSTOM) + { + TIFFErrorExtR( + tif, module, + "%s: Invalid %stag \"%s\" (not supported by codec)", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", + fip->field_name); + status = 0; + break; + } + + /* + * Find the existing entry for this custom value. + */ + tv = NULL; + for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) + { + if (td->td_customValues[iCustom].info->field_tag == tag) + { + tv = td->td_customValues + iCustom; + if (tv->value != NULL) + { + _TIFFfreeExt(tif, tv->value); + tv->value = NULL; + } + break; + } + } + + /* + * Grow the custom list if the entry was not found. + */ + if (tv == NULL) + { + TIFFTagValue *new_customValues; + + td->td_customValueCount++; + new_customValues = (TIFFTagValue *)_TIFFreallocExt( + tif, td->td_customValues, + sizeof(TIFFTagValue) * td->td_customValueCount); + if (!new_customValues) + { + TIFFErrorExtR(tif, module, + "%s: Failed to allocate space for list of " + "custom values", + tif->tif_name); + status = 0; + goto end; + } + + td->td_customValues = new_customValues; + + tv = td->td_customValues + (td->td_customValueCount - 1); + tv->info = fip; + tv->value = NULL; + tv->count = 0; + } + + /* + * Set custom value ... save a copy of the custom tag value. + */ + /*--: Rational2Double: For Rationals evaluate "set_field_type" to + * determine internal storage size. */ + tv_size = TIFFFieldSetGetSize(fip); + if (tv_size == 0) + { + status = 0; + TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"", + tif->tif_name, fip->field_type, fip->field_name); + goto end; + } + + if (fip->field_type == TIFF_ASCII) + { + uint32_t ma; + const char *mb; + if (fip->field_passcount) + { + assert(fip->field_writecount == TIFF_VARIABLE2); + ma = (uint32_t)va_arg(ap, uint32_t); + mb = (const char *)va_arg(ap, const char *); + } + else + { + mb = (const char *)va_arg(ap, const char *); + size_t len = strlen(mb) + 1; + if (len >= 0x80000000U) + { + status = 0; + TIFFErrorExtR(tif, module, + "%s: Too long string value for \"%s\". " + "Maximum supported is 2147483647 bytes", + tif->tif_name, fip->field_name); + goto end; + } + ma = (uint32_t)len; + } + tv->count = ma; + setByteArray(tif, &tv->value, mb, ma, 1); + } + else + { + if (fip->field_passcount) + { + if (fip->field_writecount == TIFF_VARIABLE2) + tv->count = (uint32_t)va_arg(ap, uint32_t); + else + tv->count = (int)va_arg(ap, int); + } + else if (fip->field_writecount == TIFF_VARIABLE || + fip->field_writecount == TIFF_VARIABLE2) + tv->count = 1; + else if (fip->field_writecount == TIFF_SPP) + tv->count = td->td_samplesperpixel; + else + tv->count = fip->field_writecount; + + if (tv->count == 0) + { + status = 0; + TIFFErrorExtR(tif, module, + "%s: Null count for \"%s\" (type " + "%d, writecount %d, passcount %d)", + tif->tif_name, fip->field_name, + fip->field_type, fip->field_writecount, + fip->field_passcount); + goto end; + } + + tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, + "custom tag binary object"); + if (!tv->value) + { + status = 0; + goto end; + } + + if (fip->field_tag == TIFFTAG_DOTRANGE && + strcmp(fip->field_name, "DotRange") == 0) + { + /* TODO: This is an evil exception and should not have been + handled this way ... likely best if we move it into + the directory structure with an explicit field in + libtiff 4.1 and assign it a FIELD_ value */ + uint16_t v2[2]; + v2[0] = (uint16_t)va_arg(ap, int); + v2[1] = (uint16_t)va_arg(ap, int); + _TIFFmemcpy(tv->value, &v2, 4); + } + + else if (fip->field_passcount || + fip->field_writecount == TIFF_VARIABLE || + fip->field_writecount == TIFF_VARIABLE2 || + fip->field_writecount == TIFF_SPP || tv->count > 1) + { + /*--: Rational2Double: For Rationals tv_size is set above to + * 4 or 8 according to fip->set_field_type! */ + _TIFFmemcpy(tv->value, va_arg(ap, void *), + tv->count * tv_size); + /* Test here for too big values for LONG8, SLONG8 in + * ClassicTIFF and delete custom field from custom list */ + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (tv->info->field_type == TIFF_LONG8) + { + uint64_t *pui64 = (uint64_t *)tv->value; + for (int i = 0; i < tv->count; i++) + { + if (pui64[i] > 0xffffffffu) + { + TIFFErrorExtR( + tif, module, + "%s: Bad LONG8 value %" PRIu64 + " at %d. array position for \"%s\" tag " + "%d in ClassicTIFF. Tag won't be " + "written to file", + tif->tif_name, pui64[i], i, + fip->field_name, tag); + goto badvalueifd8long8; + } + } + } + else if (tv->info->field_type == TIFF_SLONG8) + { + int64_t *pi64 = (int64_t *)tv->value; + for (int i = 0; i < tv->count; i++) + { + if (pi64[i] > 2147483647 || + pi64[i] < (-2147483647 - 1)) + { + TIFFErrorExtR( + tif, module, + "%s: Bad SLONG8 value %" PRIi64 + " at %d. array position for \"%s\" tag " + "%d in ClassicTIFF. Tag won't be " + "written to file", + tif->tif_name, pi64[i], i, + fip->field_name, tag); + goto badvalueifd8long8; + } + } + } + } + } + else + { + char *val = (char *)tv->value; + assert(tv->count == 1); + + switch (fip->field_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + { + uint8_t v2 = (uint8_t)va_arg(ap, int); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_SBYTE: + { + int8_t v2 = (int8_t)va_arg(ap, int); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_SHORT: + { + uint16_t v2 = (uint16_t)va_arg(ap, int); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_SSHORT: + { + int16_t v2 = (int16_t)va_arg(ap, int); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_LONG: + case TIFF_IFD: + { + uint32_t v2 = va_arg(ap, uint32_t); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_SLONG: + { + int32_t v2 = va_arg(ap, int32_t); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_LONG8: + case TIFF_IFD8: + { + uint64_t v2 = va_arg(ap, uint64_t); + _TIFFmemcpy(val, &v2, tv_size); + /* Test here for too big values for ClassicTIFF and + * delete custom field from custom list */ + if (!(tif->tif_flags & TIFF_BIGTIFF) && + (v2 > 0xffffffffu)) + { + TIFFErrorExtR( + tif, module, + "%s: Bad LONG8 or IFD8 value %" PRIu64 + " for \"%s\" tag %d in ClassicTIFF. Tag " + "won't be written to file", + tif->tif_name, v2, fip->field_name, tag); + goto badvalueifd8long8; + } + } + break; + case TIFF_SLONG8: + { + int64_t v2 = va_arg(ap, int64_t); + _TIFFmemcpy(val, &v2, tv_size); + /* Test here for too big values for ClassicTIFF and + * delete custom field from custom list */ + if (!(tif->tif_flags & TIFF_BIGTIFF) && + ((v2 > 2147483647) || (v2 < (-2147483647 - 1)))) + { + TIFFErrorExtR( + tif, module, + "%s: Bad SLONG8 value %" PRIi64 + " for \"%s\" tag %d in ClassicTIFF. Tag " + "won't be written to file", + tif->tif_name, v2, fip->field_name, tag); + goto badvalueifd8long8; + } + } + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + /*-- Rational2Double: For Rationals tv_size is set + * above to 4 or 8 according to fip->set_field_type! + */ + { + if (tv_size == 8) + { + double v2 = va_arg(ap, double); + _TIFFmemcpy(val, &v2, tv_size); + } + else + { + /*-- default should be tv_size == 4 */ + float v3 = (float)va_arg(ap, double); + _TIFFmemcpy(val, &v3, tv_size); + /*-- ToDo: After Testing, this should be + * removed and tv_size==4 should be set as + * default. */ + if (tv_size != 4) + { + TIFFErrorExtR( + tif, module, + "Rational2Double: .set_field_type " + "in not 4 but %d", + tv_size); + } + } + } + break; + case TIFF_FLOAT: + { + float v2 = + _TIFFClampDoubleToFloat(va_arg(ap, double)); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_DOUBLE: + { + double v2 = va_arg(ap, double); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + default: + _TIFFmemset(val, 0, tv_size); + status = 0; + break; + } + } + } + } + } + if (status) + { + const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); + if (fip2) + TIFFSetFieldBit(tif, fip2->field_bit); + tif->tif_flags |= TIFF_DIRTYDIRECT; + } + +end: + va_end(ap); + return (status); +badvalue: +{ + const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); + TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag", + tif->tif_name, v, fip2 ? fip2->field_name : "Unknown"); + va_end(ap); +} + return (0); +badvalue32: +{ + const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); + TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag", + tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown"); + va_end(ap); +} + return (0); +badvaluedouble: +{ + const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); + TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name, + dblval, fip2 ? fip2->field_name : "Unknown"); + va_end(ap); +} + return (0); +badvalueifd8long8: +{ + /* Error message issued already above. */ + TIFFTagValue *tv2 = NULL; + int iCustom2, iC2; + /* Find the existing entry for this custom value. */ + for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++) + { + if (td->td_customValues[iCustom2].info->field_tag == tag) + { + tv2 = td->td_customValues + (iCustom2); + break; + } + } + if (tv2 != NULL) + { + /* Remove custom field from custom list */ + if (tv2->value != NULL) + { + _TIFFfreeExt(tif, tv2->value); + tv2->value = NULL; + } + /* Shorten list and close gap in customValues list. + * Re-allocation of td_customValues not necessary here. */ + td->td_customValueCount--; + for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++) + { + td->td_customValues[iC2] = td->td_customValues[iC2 + 1]; + } + } + else + { + assert(0); + } + va_end(ap); +} + return (0); +} /*-- _TIFFVSetField() --*/ + /* * Return 1/0 according to whether or not * it is permissible to set the tag's value. @@ -792,29 +1110,30 @@ badvaluedouble: * has commenced, unless its value has no effect * on the format of the data that is written. */ -static int -OkToChangeTag(TIFF* tif, uint32 tag) +static int OkToChangeTag(TIFF *tif, uint32_t tag) { - const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); - if (!fip) { /* unknown tag */ - TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u", - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); - return (0); - } - if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && - !fip->field_oktochange) { - /* - * Consult info table to see if tag can be changed - * after we've started writing. We only allow changes - * to those tags that don't/shouldn't affect the - * compression and/or format of the data. - */ - TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", - "%s: Cannot modify tag \"%s\" while writing", - tif->tif_name, fip->field_name); - return (0); - } - return (1); + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + if (!fip) + { /* unknown tag */ + TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32, + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); + return (0); + } + if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && + !fip->field_oktochange) + { + /* + * Consult info table to see if tag can be changed + * after we've started writing. We only allow changes + * to those tags that don't/shouldn't affect the + * compression and/or format of the data. + */ + TIFFErrorExtR(tif, "TIFFSetField", + "%s: Cannot modify tag \"%s\" while writing", + tif->tif_name, fip->field_name); + return (0); + } + return (1); } /* @@ -824,54 +1143,54 @@ OkToChangeTag(TIFF* tif, uint32 tag) * when/if the directory structure is * updated. */ -int -TIFFSetField(TIFF* tif, uint32 tag, ...) +int TIFFSetField(TIFF *tif, uint32_t tag, ...) { - va_list ap; - int status; + va_list ap; + int status; - va_start(ap, tag); - status = TIFFVSetField(tif, tag, ap); - va_end(ap); - return (status); + va_start(ap, tag); + status = TIFFVSetField(tif, tag, ap); + va_end(ap); + return (status); } /* * Clear the contents of the field in the internal structure. */ -int -TIFFUnsetField(TIFF* tif, uint32 tag) +int TIFFUnsetField(TIFF *tif, uint32_t tag) { - const TIFFField *fip = TIFFFieldWithTag(tif, tag); - TIFFDirectory* td = &tif->tif_dir; + const TIFFField *fip = TIFFFieldWithTag(tif, tag); + TIFFDirectory *td = &tif->tif_dir; - if( !fip ) + if (!fip) return 0; - if( fip->field_bit != FIELD_CUSTOM ) + if (fip->field_bit != FIELD_CUSTOM) TIFFClrFieldBit(tif, fip->field_bit); else { TIFFTagValue *tv = NULL; int i; - for (i = 0; i < td->td_customValueCount; i++) { - + for (i = 0; i < td->td_customValueCount; i++) + { + tv = td->td_customValues + i; - if( tv->info->field_tag == tag ) + if (tv->info->field_tag == tag) break; } - if( i < td->td_customValueCount ) + if (i < td->td_customValueCount) { - _TIFFfree(tv->value); - for( ; i < td->td_customValueCount-1; i++) { - td->td_customValues[i] = td->td_customValues[i+1]; + _TIFFfreeExt(tif, tv->value); + for (; i < td->td_customValueCount - 1; i++) + { + td->td_customValues[i] = td->td_customValues[i + 1]; } td->td_customValueCount--; } } - + tif->tif_flags |= TIFF_DIRTYDIRECT; return (1); @@ -883,399 +1202,392 @@ TIFFUnsetField(TIFF* tif, uint32 tag) * for building higher-level interfaces on * top of the library. */ -int -TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) +int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) { - return OkToChangeTag(tif, tag) ? - (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0; + return OkToChangeTag(tif, tag) + ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) + : 0; } -static int -_TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) +static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) { - TIFFDirectory* td = &tif->tif_dir; - int ret_val = 1; - uint32 standard_tag = tag; - const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); - if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */ - return 0; + TIFFDirectory *td = &tif->tif_dir; + int ret_val = 1; + uint32_t standard_tag = tag; + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + if (fip == NULL) /* cannot happen since TIFFGetField() already checks it */ + return 0; - /* - * We want to force the custom code to be used for custom - * fields even if the tag happens to match a well known - * one - important for reinterpreted handling of standard - * tag values in custom directories (i.e. EXIF) - */ - if (fip->field_bit == FIELD_CUSTOM) { - standard_tag = 0; - } - - if( standard_tag == TIFFTAG_NUMBEROFINKS ) + /* + * We want to force the custom code to be used for custom + * fields even if the tag happens to match a well known + * one - important for reinterpreted handling of standard + * tag values in custom directories (i.e. EXIF) + */ + if (fip->field_bit == FIELD_CUSTOM) + { + standard_tag = 0; + } + + switch (standard_tag) + { + case TIFFTAG_SUBFILETYPE: + *va_arg(ap, uint32_t *) = td->td_subfiletype; + break; + case TIFFTAG_IMAGEWIDTH: + *va_arg(ap, uint32_t *) = td->td_imagewidth; + break; + case TIFFTAG_IMAGELENGTH: + *va_arg(ap, uint32_t *) = td->td_imagelength; + break; + case TIFFTAG_BITSPERSAMPLE: + *va_arg(ap, uint16_t *) = td->td_bitspersample; + break; + case TIFFTAG_COMPRESSION: + *va_arg(ap, uint16_t *) = td->td_compression; + break; + case TIFFTAG_PHOTOMETRIC: + *va_arg(ap, uint16_t *) = td->td_photometric; + break; + case TIFFTAG_THRESHHOLDING: + *va_arg(ap, uint16_t *) = td->td_threshholding; + break; + case TIFFTAG_FILLORDER: + *va_arg(ap, uint16_t *) = td->td_fillorder; + break; + case TIFFTAG_ORIENTATION: + *va_arg(ap, uint16_t *) = td->td_orientation; + break; + case TIFFTAG_SAMPLESPERPIXEL: + *va_arg(ap, uint16_t *) = td->td_samplesperpixel; + break; + case TIFFTAG_ROWSPERSTRIP: + *va_arg(ap, uint32_t *) = td->td_rowsperstrip; + break; + case TIFFTAG_MINSAMPLEVALUE: + *va_arg(ap, uint16_t *) = td->td_minsamplevalue; + break; + case TIFFTAG_MAXSAMPLEVALUE: + *va_arg(ap, uint16_t *) = td->td_maxsamplevalue; + break; + case TIFFTAG_SMINSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + *va_arg(ap, double **) = td->td_sminsamplevalue; + else + { + /* libtiff historically treats this as a single value. */ + uint16_t i; + double v = td->td_sminsamplevalue[0]; + for (i = 1; i < td->td_samplesperpixel; ++i) + if (td->td_sminsamplevalue[i] < v) + v = td->td_sminsamplevalue[i]; + *va_arg(ap, double *) = v; + } + break; + case TIFFTAG_SMAXSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + *va_arg(ap, double **) = td->td_smaxsamplevalue; + else + { + /* libtiff historically treats this as a single value. */ + uint16_t i; + double v = td->td_smaxsamplevalue[0]; + for (i = 1; i < td->td_samplesperpixel; ++i) + if (td->td_smaxsamplevalue[i] > v) + v = td->td_smaxsamplevalue[i]; + *va_arg(ap, double *) = v; + } + break; + case TIFFTAG_XRESOLUTION: + *va_arg(ap, float *) = td->td_xresolution; + break; + case TIFFTAG_YRESOLUTION: + *va_arg(ap, float *) = td->td_yresolution; + break; + case TIFFTAG_PLANARCONFIG: + *va_arg(ap, uint16_t *) = td->td_planarconfig; + break; + case TIFFTAG_XPOSITION: + *va_arg(ap, float *) = td->td_xposition; + break; + case TIFFTAG_YPOSITION: + *va_arg(ap, float *) = td->td_yposition; + break; + case TIFFTAG_RESOLUTIONUNIT: + *va_arg(ap, uint16_t *) = td->td_resolutionunit; + break; + case TIFFTAG_PAGENUMBER: + *va_arg(ap, uint16_t *) = td->td_pagenumber[0]; + *va_arg(ap, uint16_t *) = td->td_pagenumber[1]; + break; + case TIFFTAG_HALFTONEHINTS: + *va_arg(ap, uint16_t *) = td->td_halftonehints[0]; + *va_arg(ap, uint16_t *) = td->td_halftonehints[1]; + break; + case TIFFTAG_COLORMAP: + *va_arg(ap, const uint16_t **) = td->td_colormap[0]; + *va_arg(ap, const uint16_t **) = td->td_colormap[1]; + *va_arg(ap, const uint16_t **) = td->td_colormap[2]; + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: + _TIFFFillStriles(tif); + *va_arg(ap, const uint64_t **) = td->td_stripoffset_p; + if (td->td_stripoffset_p == NULL) + ret_val = 0; + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: + _TIFFFillStriles(tif); + *va_arg(ap, const uint64_t **) = td->td_stripbytecount_p; + if (td->td_stripbytecount_p == NULL) + ret_val = 0; + break; + case TIFFTAG_MATTEING: + *va_arg(ap, uint16_t *) = + (td->td_extrasamples == 1 && + td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + break; + case TIFFTAG_EXTRASAMPLES: + *va_arg(ap, uint16_t *) = td->td_extrasamples; + *va_arg(ap, const uint16_t **) = td->td_sampleinfo; + break; + case TIFFTAG_TILEWIDTH: + *va_arg(ap, uint32_t *) = td->td_tilewidth; + break; + case TIFFTAG_TILELENGTH: + *va_arg(ap, uint32_t *) = td->td_tilelength; + break; + case TIFFTAG_TILEDEPTH: + *va_arg(ap, uint32_t *) = td->td_tiledepth; + break; + case TIFFTAG_DATATYPE: + switch (td->td_sampleformat) + { + case SAMPLEFORMAT_UINT: + *va_arg(ap, uint16_t *) = DATATYPE_UINT; + break; + case SAMPLEFORMAT_INT: + *va_arg(ap, uint16_t *) = DATATYPE_INT; + break; + case SAMPLEFORMAT_IEEEFP: + *va_arg(ap, uint16_t *) = DATATYPE_IEEEFP; + break; + case SAMPLEFORMAT_VOID: + *va_arg(ap, uint16_t *) = DATATYPE_VOID; + break; + } + break; + case TIFFTAG_SAMPLEFORMAT: + *va_arg(ap, uint16_t *) = td->td_sampleformat; + break; + case TIFFTAG_IMAGEDEPTH: + *va_arg(ap, uint32_t *) = td->td_imagedepth; + break; + case TIFFTAG_SUBIFD: + *va_arg(ap, uint16_t *) = td->td_nsubifd; + *va_arg(ap, const uint64_t **) = td->td_subifd; + break; + case TIFFTAG_YCBCRPOSITIONING: + *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning; + break; + case TIFFTAG_YCBCRSUBSAMPLING: + *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0]; + *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1]; + break; + case TIFFTAG_TRANSFERFUNCTION: + *va_arg(ap, const uint16_t **) = td->td_transferfunction[0]; + if (td->td_samplesperpixel - td->td_extrasamples > 1) + { + *va_arg(ap, const uint16_t **) = td->td_transferfunction[1]; + *va_arg(ap, const uint16_t **) = td->td_transferfunction[2]; + } + else + { + *va_arg(ap, const uint16_t **) = NULL; + *va_arg(ap, const uint16_t **) = NULL; + } + break; + case TIFFTAG_REFERENCEBLACKWHITE: + *va_arg(ap, const float **) = td->td_refblackwhite; + break; + case TIFFTAG_INKNAMES: + *va_arg(ap, const char **) = td->td_inknames; + break; + case TIFFTAG_NUMBEROFINKS: + *va_arg(ap, uint16_t *) = td->td_numberofinks; + break; + default: { int i; - for (i = 0; i < td->td_customValueCount; i++) { - uint16 val; - TIFFTagValue *tv = td->td_customValues + i; - if (tv->info->field_tag != standard_tag) - continue; - if( tv->value == NULL ) - return 0; - val = *(uint16 *)tv->value; - /* Truncate to SamplesPerPixel, since the */ - /* setting code for INKNAMES assume that there are SamplesPerPixel */ - /* inknames. */ - /* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */ - if( val > td->td_samplesperpixel ) - { - TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField", - "Truncating NumberOfInks from %u to %u", - val, td->td_samplesperpixel); - val = td->td_samplesperpixel; - } - *va_arg(ap, uint16*) = val; - return 1; + + /* + * This can happen if multiple images are open + * with different codecs which have private + * tags. The global tag information table may + * then have tags that are valid for one file + * but not the other. If the client tries to + * get a tag that is not valid for the image's + * codec then we'll arrive here. + */ + if (fip->field_bit != FIELD_CUSTOM) + { + TIFFErrorExtR(tif, "_TIFFVGetField", + "%s: Invalid %stag \"%s\" " + "(not supported by codec)", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", + fip->field_name); + ret_val = 0; + break; + } + + /* + * Do we have a custom value? + */ + ret_val = 0; + for (i = 0; i < td->td_customValueCount; i++) + { + TIFFTagValue *tv = td->td_customValues + i; + + if (tv->info->field_tag != tag) + continue; + + if (fip->field_passcount) + { + if (fip->field_readcount == TIFF_VARIABLE2) + *va_arg(ap, uint32_t *) = (uint32_t)tv->count; + else /* Assume TIFF_VARIABLE */ + *va_arg(ap, uint16_t *) = (uint16_t)tv->count; + *va_arg(ap, const void **) = tv->value; + ret_val = 1; + } + else if (fip->field_tag == TIFFTAG_DOTRANGE && + strcmp(fip->field_name, "DotRange") == 0) + { + /* TODO: This is an evil exception and should not have been + handled this way ... likely best if we move it into + the directory structure with an explicit field in + libtiff 4.1 and assign it a FIELD_ value */ + *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[0]; + *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[1]; + ret_val = 1; + } + else + { + if (fip->field_type == TIFF_ASCII || + fip->field_readcount == TIFF_VARIABLE || + fip->field_readcount == TIFF_VARIABLE2 || + fip->field_readcount == TIFF_SPP || tv->count > 1) + { + *va_arg(ap, void **) = tv->value; + ret_val = 1; + } + else + { + char *val = (char *)tv->value; + assert(tv->count == 1); + switch (fip->field_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + *va_arg(ap, uint8_t *) = *(uint8_t *)val; + ret_val = 1; + break; + case TIFF_SBYTE: + *va_arg(ap, int8_t *) = *(int8_t *)val; + ret_val = 1; + break; + case TIFF_SHORT: + *va_arg(ap, uint16_t *) = *(uint16_t *)val; + ret_val = 1; + break; + case TIFF_SSHORT: + *va_arg(ap, int16_t *) = *(int16_t *)val; + ret_val = 1; + break; + case TIFF_LONG: + case TIFF_IFD: + *va_arg(ap, uint32_t *) = *(uint32_t *)val; + ret_val = 1; + break; + case TIFF_SLONG: + *va_arg(ap, int32_t *) = *(int32_t *)val; + ret_val = 1; + break; + case TIFF_LONG8: + case TIFF_IFD8: + *va_arg(ap, uint64_t *) = *(uint64_t *)val; + ret_val = 1; + break; + case TIFF_SLONG8: + *va_arg(ap, int64_t *) = *(int64_t *)val; + ret_val = 1; + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + { + /*-- Rational2Double: For Rationals evaluate + * "set_field_type" to determine internal + * storage size and return value size. */ + int tv_size = TIFFFieldSetGetSize(fip); + if (tv_size == 8) + { + *va_arg(ap, double *) = *(double *)val; + ret_val = 1; + } + else + { + /*-- default should be tv_size == 4 */ + *va_arg(ap, float *) = *(float *)val; + ret_val = 1; + /*-- ToDo: After Testing, this should be + * removed and tv_size==4 should be set as + * default. */ + if (tv_size != 4) + { + TIFFErrorExtR( + tif, "_TIFFVGetField", + "Rational2Double: .set_field_type " + "in not 4 but %d", + tv_size); + } + } + } + break; + case TIFF_FLOAT: + *va_arg(ap, float *) = *(float *)val; + ret_val = 1; + break; + case TIFF_DOUBLE: + *va_arg(ap, double *) = *(double *)val; + ret_val = 1; + break; + default: + ret_val = 0; + break; + } + } + } + break; } - return 0; } - - switch (standard_tag) { - case TIFFTAG_SUBFILETYPE: - *va_arg(ap, uint32*) = td->td_subfiletype; - break; - case TIFFTAG_IMAGEWIDTH: - *va_arg(ap, uint32*) = td->td_imagewidth; - break; - case TIFFTAG_IMAGELENGTH: - *va_arg(ap, uint32*) = td->td_imagelength; - break; - case TIFFTAG_BITSPERSAMPLE: - *va_arg(ap, uint16*) = td->td_bitspersample; - break; - case TIFFTAG_COMPRESSION: - *va_arg(ap, uint16*) = td->td_compression; - break; - case TIFFTAG_PHOTOMETRIC: - *va_arg(ap, uint16*) = td->td_photometric; - break; - case TIFFTAG_THRESHHOLDING: - *va_arg(ap, uint16*) = td->td_threshholding; - break; - case TIFFTAG_FILLORDER: - *va_arg(ap, uint16*) = td->td_fillorder; - break; - case TIFFTAG_ORIENTATION: - *va_arg(ap, uint16*) = td->td_orientation; - break; - case TIFFTAG_SAMPLESPERPIXEL: - *va_arg(ap, uint16*) = td->td_samplesperpixel; - break; - case TIFFTAG_ROWSPERSTRIP: - *va_arg(ap, uint32*) = td->td_rowsperstrip; - break; - case TIFFTAG_MINSAMPLEVALUE: - *va_arg(ap, uint16*) = td->td_minsamplevalue; - break; - case TIFFTAG_MAXSAMPLEVALUE: - *va_arg(ap, uint16*) = td->td_maxsamplevalue; - break; - case TIFFTAG_SMINSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - *va_arg(ap, double**) = td->td_sminsamplevalue; - else - { - /* libtiff historically treats this as a single value. */ - uint16 i; - double v = td->td_sminsamplevalue[0]; - for (i=1; i < td->td_samplesperpixel; ++i) - if( td->td_sminsamplevalue[i] < v ) - v = td->td_sminsamplevalue[i]; - *va_arg(ap, double*) = v; - } - break; - case TIFFTAG_SMAXSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - *va_arg(ap, double**) = td->td_smaxsamplevalue; - else - { - /* libtiff historically treats this as a single value. */ - uint16 i; - double v = td->td_smaxsamplevalue[0]; - for (i=1; i < td->td_samplesperpixel; ++i) - if( td->td_smaxsamplevalue[i] > v ) - v = td->td_smaxsamplevalue[i]; - *va_arg(ap, double*) = v; - } - break; - case TIFFTAG_XRESOLUTION: - *va_arg(ap, float*) = td->td_xresolution; - break; - case TIFFTAG_YRESOLUTION: - *va_arg(ap, float*) = td->td_yresolution; - break; - case TIFFTAG_PLANARCONFIG: - *va_arg(ap, uint16*) = td->td_planarconfig; - break; - case TIFFTAG_XPOSITION: - *va_arg(ap, float*) = td->td_xposition; - break; - case TIFFTAG_YPOSITION: - *va_arg(ap, float*) = td->td_yposition; - break; - case TIFFTAG_RESOLUTIONUNIT: - *va_arg(ap, uint16*) = td->td_resolutionunit; - break; - case TIFFTAG_PAGENUMBER: - *va_arg(ap, uint16*) = td->td_pagenumber[0]; - *va_arg(ap, uint16*) = td->td_pagenumber[1]; - break; - case TIFFTAG_HALFTONEHINTS: - *va_arg(ap, uint16*) = td->td_halftonehints[0]; - *va_arg(ap, uint16*) = td->td_halftonehints[1]; - break; - case TIFFTAG_COLORMAP: - *va_arg(ap, const uint16**) = td->td_colormap[0]; - *va_arg(ap, const uint16**) = td->td_colormap[1]; - *va_arg(ap, const uint16**) = td->td_colormap[2]; - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_TILEOFFSETS: - _TIFFFillStriles( tif ); - *va_arg(ap, const uint64**) = td->td_stripoffset_p; - break; - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEBYTECOUNTS: - _TIFFFillStriles( tif ); - *va_arg(ap, const uint64**) = td->td_stripbytecount_p; - break; - case TIFFTAG_MATTEING: - *va_arg(ap, uint16*) = - (td->td_extrasamples == 1 && - td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); - break; - case TIFFTAG_EXTRASAMPLES: - *va_arg(ap, uint16*) = td->td_extrasamples; - *va_arg(ap, const uint16**) = td->td_sampleinfo; - break; - case TIFFTAG_TILEWIDTH: - *va_arg(ap, uint32*) = td->td_tilewidth; - break; - case TIFFTAG_TILELENGTH: - *va_arg(ap, uint32*) = td->td_tilelength; - break; - case TIFFTAG_TILEDEPTH: - *va_arg(ap, uint32*) = td->td_tiledepth; - break; - case TIFFTAG_DATATYPE: - switch (td->td_sampleformat) { - case SAMPLEFORMAT_UINT: - *va_arg(ap, uint16*) = DATATYPE_UINT; - break; - case SAMPLEFORMAT_INT: - *va_arg(ap, uint16*) = DATATYPE_INT; - break; - case SAMPLEFORMAT_IEEEFP: - *va_arg(ap, uint16*) = DATATYPE_IEEEFP; - break; - case SAMPLEFORMAT_VOID: - *va_arg(ap, uint16*) = DATATYPE_VOID; - break; - } - break; - case TIFFTAG_SAMPLEFORMAT: - *va_arg(ap, uint16*) = td->td_sampleformat; - break; - case TIFFTAG_IMAGEDEPTH: - *va_arg(ap, uint32*) = td->td_imagedepth; - break; - case TIFFTAG_SUBIFD: - *va_arg(ap, uint16*) = td->td_nsubifd; - *va_arg(ap, const uint64**) = td->td_subifd; - break; - case TIFFTAG_YCBCRPOSITIONING: - *va_arg(ap, uint16*) = td->td_ycbcrpositioning; - break; - case TIFFTAG_YCBCRSUBSAMPLING: - *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0]; - *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1]; - break; - case TIFFTAG_TRANSFERFUNCTION: - *va_arg(ap, const uint16**) = td->td_transferfunction[0]; - if (td->td_samplesperpixel - td->td_extrasamples > 1) { - *va_arg(ap, const uint16**) = td->td_transferfunction[1]; - *va_arg(ap, const uint16**) = td->td_transferfunction[2]; - } else { - *va_arg(ap, const uint16**) = NULL; - *va_arg(ap, const uint16**) = NULL; - } - break; - case TIFFTAG_REFERENCEBLACKWHITE: - *va_arg(ap, const float**) = td->td_refblackwhite; - break; - case TIFFTAG_INKNAMES: - *va_arg(ap, const char**) = td->td_inknames; - break; - default: - { - int i; - - /* - * This can happen if multiple images are open - * with different codecs which have private - * tags. The global tag information table may - * then have tags that are valid for one file - * but not the other. If the client tries to - * get a tag that is not valid for the image's - * codec then we'll arrive here. - */ - if( fip->field_bit != FIELD_CUSTOM ) - { - TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField", - "%s: Invalid %stag \"%s\" " - "(not supported by codec)", - tif->tif_name, - isPseudoTag(tag) ? "pseudo-" : "", - fip->field_name); - ret_val = 0; - break; - } - - /* - * Do we have a custom value? - */ - ret_val = 0; - for (i = 0; i < td->td_customValueCount; i++) { - TIFFTagValue *tv = td->td_customValues + i; - - if (tv->info->field_tag != tag) - continue; - - if (fip->field_passcount) { - if (fip->field_readcount == TIFF_VARIABLE2) - *va_arg(ap, uint32*) = (uint32)tv->count; - else /* Assume TIFF_VARIABLE */ - *va_arg(ap, uint16*) = (uint16)tv->count; - *va_arg(ap, const void **) = tv->value; - ret_val = 1; - } else if (fip->field_tag == TIFFTAG_DOTRANGE - && strcmp(fip->field_name,"DotRange") == 0) { - /* TODO: This is an evil exception and should not have been - handled this way ... likely best if we move it into - the directory structure with an explicit field in - libtiff 4.1 and assign it a FIELD_ value */ - *va_arg(ap, uint16*) = ((uint16 *)tv->value)[0]; - *va_arg(ap, uint16*) = ((uint16 *)tv->value)[1]; - ret_val = 1; - } else { - if (fip->field_type == TIFF_ASCII - || fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2 - || fip->field_readcount == TIFF_SPP - || tv->count > 1) { - *va_arg(ap, void **) = tv->value; - ret_val = 1; - } else { - char *val = (char *)tv->value; - assert( tv->count == 1 ); - switch (fip->field_type) { - case TIFF_BYTE: - case TIFF_UNDEFINED: - *va_arg(ap, uint8*) = - *(uint8 *)val; - ret_val = 1; - break; - case TIFF_SBYTE: - *va_arg(ap, int8*) = - *(int8 *)val; - ret_val = 1; - break; - case TIFF_SHORT: - *va_arg(ap, uint16*) = - *(uint16 *)val; - ret_val = 1; - break; - case TIFF_SSHORT: - *va_arg(ap, int16*) = - *(int16 *)val; - ret_val = 1; - break; - case TIFF_LONG: - case TIFF_IFD: - *va_arg(ap, uint32*) = - *(uint32 *)val; - ret_val = 1; - break; - case TIFF_SLONG: - *va_arg(ap, int32*) = - *(int32 *)val; - ret_val = 1; - break; - case TIFF_LONG8: - case TIFF_IFD8: - *va_arg(ap, uint64*) = - *(uint64 *)val; - ret_val = 1; - break; - case TIFF_SLONG8: - *va_arg(ap, int64*) = - *(int64 *)val; - ret_val = 1; - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - { - /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size and return value size. */ - int tv_size = _TIFFSetGetFieldSize(fip->set_field_type); - if (tv_size == 8) { - *va_arg(ap, double*) = *(double *)val; - ret_val = 1; - } else { - /*-- default should be tv_size == 4 */ - *va_arg(ap, float*) = *(float *)val; - ret_val = 1; - /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */ - if (tv_size != 4) { - TIFFErrorExt(0,"TIFFLib: _TIFFVGetField()", "Rational2Double: .set_field_type in not 4 but %d", tv_size); - } - } - } - break; - case TIFF_FLOAT: - *va_arg(ap, float*) = - *(float *)val; - ret_val = 1; - break; - case TIFF_DOUBLE: - *va_arg(ap, double*) = - *(double *)val; - ret_val = 1; - break; - default: - ret_val = 0; - break; - } - } - } - break; - } - } - } - return(ret_val); + } + return (ret_val); } /* * Return the value of a field in the * internal directory structure. */ -int -TIFFGetField(TIFF* tif, uint32 tag, ...) +int TIFFGetField(TIFF *tif, uint32_t tag, ...) { - int status; - va_list ap; + int status; + va_list ap; - va_start(ap, tag); - status = TIFFVGetField(tif, tag, ap); - va_end(ap); - return (status); + va_start(ap, tag); + status = TIFFVGetField(tif, tag, ap); + va_end(ap); + return (status); } /* @@ -1284,74 +1596,75 @@ TIFFGetField(TIFF* tif, uint32 tag, ...) * for building higher-level interfaces on * top of the library. */ -int -TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) +int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) { - const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); - return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? - (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0); + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) + ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) + : 0); } -#define CleanupField(member) { \ - if (td->member) { \ - _TIFFfree(td->member); \ - td->member = 0; \ - } \ -} +#define CleanupField(member) \ + { \ + if (td->member) \ + { \ + _TIFFfreeExt(tif, td->member); \ + td->member = 0; \ + } \ + } /* * Release storage associated with a directory. */ -void -TIFFFreeDirectory(TIFF* tif) +void TIFFFreeDirectory(TIFF *tif) { - TIFFDirectory *td = &tif->tif_dir; - int i; + TIFFDirectory *td = &tif->tif_dir; + int i; - _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS); - CleanupField(td_sminsamplevalue); - CleanupField(td_smaxsamplevalue); - CleanupField(td_colormap[0]); - CleanupField(td_colormap[1]); - CleanupField(td_colormap[2]); - CleanupField(td_sampleinfo); - CleanupField(td_subifd); - CleanupField(td_inknames); - CleanupField(td_refblackwhite); - CleanupField(td_transferfunction[0]); - CleanupField(td_transferfunction[1]); - CleanupField(td_transferfunction[2]); - CleanupField(td_stripoffset_p); - CleanupField(td_stripbytecount_p); - td->td_stripoffsetbyteallocsize = 0; - TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); - TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); + _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset)); + CleanupField(td_sminsamplevalue); + CleanupField(td_smaxsamplevalue); + CleanupField(td_colormap[0]); + CleanupField(td_colormap[1]); + CleanupField(td_colormap[2]); + CleanupField(td_sampleinfo); + CleanupField(td_subifd); + CleanupField(td_inknames); + CleanupField(td_refblackwhite); + CleanupField(td_transferfunction[0]); + CleanupField(td_transferfunction[1]); + CleanupField(td_transferfunction[2]); + CleanupField(td_stripoffset_p); + CleanupField(td_stripbytecount_p); + td->td_stripoffsetbyteallocsize = 0; + TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); + TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); - /* Cleanup custom tag values */ - for( i = 0; i < td->td_customValueCount; i++ ) { - if (td->td_customValues[i].value) - _TIFFfree(td->td_customValues[i].value); - } + /* Cleanup custom tag values */ + for (i = 0; i < td->td_customValueCount; i++) + { + if (td->td_customValues[i].value) + _TIFFfreeExt(tif, td->td_customValues[i].value); + } - td->td_customValueCount = 0; - CleanupField(td_customValues); + td->td_customValueCount = 0; + CleanupField(td_customValues); - _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); - _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); } #undef CleanupField /* * Client Tag extension support (from Niles Ritter). */ -static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL; +static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL; -TIFFExtendProc -TIFFSetTagExtender(TIFFExtendProc extender) +TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender) { - TIFFExtendProc prev = _TIFFextender; - _TIFFextender = extender; - return (prev); + TIFFExtendProc prev = _TIFFextender; + _TIFFextender = extender; + return (prev); } /* @@ -1361,333 +1674,433 @@ TIFFSetTagExtender(TIFFExtendProc extender) * The newly created directory will not exist on the file till * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called. */ -int -TIFFCreateDirectory(TIFF* tif) +int TIFFCreateDirectory(TIFF *tif) { - TIFFDefaultDirectory(tif); - tif->tif_diroff = 0; - tif->tif_nextdiroff = 0; - tif->tif_curoff = 0; - tif->tif_row = (uint32) -1; - tif->tif_curstrip = (uint32) -1; + TIFFDefaultDirectory(tif); + tif->tif_diroff = 0; + tif->tif_nextdiroff = 0; + tif->tif_curoff = 0; + tif->tif_row = (uint32_t)-1; + tif->tif_curstrip = (uint32_t)-1; - return 0; + return 0; } -int -TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray) +int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray) { - TIFFDefaultDirectory(tif); + TIFFDefaultDirectory(tif); - /* - * Reset the field definitions to match the application provided list. - * Hopefully TIFFDefaultDirectory() won't have done anything irreversable - * based on it's assumption this is an image directory. - */ - _TIFFSetupFields(tif, infoarray); + /* + * Reset the field definitions to match the application provided list. + * Hopefully TIFFDefaultDirectory() won't have done anything irreversible + * based on it's assumption this is an image directory. + */ + _TIFFSetupFields(tif, infoarray); - tif->tif_diroff = 0; - tif->tif_nextdiroff = 0; - tif->tif_curoff = 0; - tif->tif_row = (uint32) -1; - tif->tif_curstrip = (uint32) -1; + tif->tif_diroff = 0; + tif->tif_nextdiroff = 0; + tif->tif_curoff = 0; + tif->tif_row = (uint32_t)-1; + tif->tif_curstrip = (uint32_t)-1; + /* invalidate directory index */ + tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; + /* invalidate IFD loop lists */ + _TIFFCleanupIFDOffsetAndNumberMaps(tif); + /* To be able to return from SubIFD or custom-IFD to main-IFD */ + tif->tif_setdirectory_force_absolute = TRUE; - return 0; + return 0; } -int -TIFFCreateEXIFDirectory(TIFF* tif) +int TIFFCreateEXIFDirectory(TIFF *tif) { - const TIFFFieldArray* exifFieldArray; - exifFieldArray = _TIFFGetExifFields(); - return TIFFCreateCustomDirectory(tif, exifFieldArray); + const TIFFFieldArray *exifFieldArray; + exifFieldArray = _TIFFGetExifFields(); + return TIFFCreateCustomDirectory(tif, exifFieldArray); } /* - * Creates the EXIF GPS custom directory + * Creates the EXIF GPS custom directory */ -int -TIFFCreateGPSDirectory(TIFF* tif) +int TIFFCreateGPSDirectory(TIFF *tif) { - const TIFFFieldArray* gpsFieldArray; - gpsFieldArray = _TIFFGetGpsFields(); - return TIFFCreateCustomDirectory(tif, gpsFieldArray); + const TIFFFieldArray *gpsFieldArray; + gpsFieldArray = _TIFFGetGpsFields(); + return TIFFCreateCustomDirectory(tif, gpsFieldArray); } /* * Setup a default directory structure. */ -int -TIFFDefaultDirectory(TIFF* tif) +int TIFFDefaultDirectory(TIFF *tif) { - register TIFFDirectory* td = &tif->tif_dir; - const TIFFFieldArray* tiffFieldArray; + register TIFFDirectory *td = &tif->tif_dir; + const TIFFFieldArray *tiffFieldArray; - tiffFieldArray = _TIFFGetFields(); - _TIFFSetupFields(tif, tiffFieldArray); + tiffFieldArray = _TIFFGetFields(); + _TIFFSetupFields(tif, tiffFieldArray); - _TIFFmemset(td, 0, sizeof (*td)); - td->td_fillorder = FILLORDER_MSB2LSB; - td->td_bitspersample = 1; - td->td_threshholding = THRESHHOLD_BILEVEL; - td->td_orientation = ORIENTATION_TOPLEFT; - td->td_samplesperpixel = 1; - td->td_rowsperstrip = (uint32) -1; - td->td_tilewidth = 0; - td->td_tilelength = 0; - td->td_tiledepth = 1; + _TIFFmemset(td, 0, sizeof(*td)); + td->td_fillorder = FILLORDER_MSB2LSB; + td->td_bitspersample = 1; + td->td_threshholding = THRESHHOLD_BILEVEL; + td->td_orientation = ORIENTATION_TOPLEFT; + td->td_samplesperpixel = 1; + td->td_rowsperstrip = (uint32_t)-1; + td->td_tilewidth = 0; + td->td_tilelength = 0; + td->td_tiledepth = 1; #ifdef STRIPBYTECOUNTSORTED_UNUSED - td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ + td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ #endif - td->td_resolutionunit = RESUNIT_INCH; - td->td_sampleformat = SAMPLEFORMAT_UINT; - td->td_imagedepth = 1; - td->td_ycbcrsubsampling[0] = 2; - td->td_ycbcrsubsampling[1] = 2; - td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; - tif->tif_postdecode = _TIFFNoPostDecode; - tif->tif_foundfield = NULL; - tif->tif_tagmethods.vsetfield = _TIFFVSetField; - tif->tif_tagmethods.vgetfield = _TIFFVGetField; - tif->tif_tagmethods.printdir = NULL; - /* - * Give client code a chance to install their own - * tag extensions & methods, prior to compression overloads, - * but do some prior cleanup first. (http://trac.osgeo.org/gdal/ticket/5054) - */ - if (tif->tif_nfieldscompat > 0) { - uint32 i; + td->td_resolutionunit = RESUNIT_INCH; + td->td_sampleformat = SAMPLEFORMAT_UINT; + td->td_imagedepth = 1; + td->td_ycbcrsubsampling[0] = 2; + td->td_ycbcrsubsampling[1] = 2; + td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; + tif->tif_postdecode = _TIFFNoPostDecode; + tif->tif_foundfield = NULL; + tif->tif_tagmethods.vsetfield = _TIFFVSetField; + tif->tif_tagmethods.vgetfield = _TIFFVGetField; + tif->tif_tagmethods.printdir = NULL; + /* additional default values */ + td->td_planarconfig = PLANARCONFIG_CONTIG; + td->td_compression = COMPRESSION_NONE; + td->td_subfiletype = 0; + td->td_minsamplevalue = 0; + /* td_bitspersample=1 is always set in TIFFDefaultDirectory(). + * Therefore, td_maxsamplevalue has to be re-calculated in + * TIFFGetFieldDefaulted(). */ + td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */ + td->td_extrasamples = 0; + td->td_sampleinfo = NULL; - for (i = 0; i < tif->tif_nfieldscompat; i++) { - if (tif->tif_fieldscompat[i].allocated_size) - _TIFFfree(tif->tif_fieldscompat[i].fields); - } - _TIFFfree(tif->tif_fieldscompat); - tif->tif_nfieldscompat = 0; - tif->tif_fieldscompat = NULL; - } - if (_TIFFextender) - (*_TIFFextender)(tif); - (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); - /* - * NB: The directory is marked dirty as a result of setting - * up the default compression scheme. However, this really - * isn't correct -- we want TIFF_DIRTYDIRECT to be set only - * if the user does something. We could just do the setup - * by hand, but it seems better to use the normal mechanism - * (i.e. TIFFSetField). - */ - tif->tif_flags &= ~TIFF_DIRTYDIRECT; + /* + * Give client code a chance to install their own + * tag extensions & methods, prior to compression overloads, + * but do some prior cleanup first. + * (http://trac.osgeo.org/gdal/ticket/5054) + */ + if (tif->tif_nfieldscompat > 0) + { + uint32_t i; - /* - * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 - * we clear the ISTILED flag when setting up a new directory. - * Should we also be clearing stuff like INSUBIFD? - */ - tif->tif_flags &= ~TIFF_ISTILED; + for (i = 0; i < tif->tif_nfieldscompat; i++) + { + if (tif->tif_fieldscompat[i].allocated_size) + _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields); + } + _TIFFfreeExt(tif, tif->tif_fieldscompat); + tif->tif_nfieldscompat = 0; + tif->tif_fieldscompat = NULL; + } + if (_TIFFextender) + (*_TIFFextender)(tif); + (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + /* + * NB: The directory is marked dirty as a result of setting + * up the default compression scheme. However, this really + * isn't correct -- we want TIFF_DIRTYDIRECT to be set only + * if the user does something. We could just do the setup + * by hand, but it seems better to use the normal mechanism + * (i.e. TIFFSetField). + */ + tif->tif_flags &= ~TIFF_DIRTYDIRECT; - return (1); + /* + * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 + * we clear the ISTILED flag when setting up a new directory. + * Should we also be clearing stuff like INSUBIFD? + */ + tif->tif_flags &= ~TIFF_ISTILED; + + return (1); } -static int -TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off) +static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, + tdir_t *nextdirnum) { - static const char module[] = "TIFFAdvanceDirectory"; - if (isMapped(tif)) - { - uint64 poff=*nextdir; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - tmsize_t poffa,poffb,poffc,poffd; - uint16 dircount; - uint32 nextdir32; - poffa=(tmsize_t)poff; - poffb=poffa+sizeof(uint16); - if (((uint64)poffa!=poff)||(poffbtif->tif_size)) - { - TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count"); - *nextdir=0; - return(0); - } - _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(&dircount); - poffc=poffb+dircount*12; - poffd=poffc+sizeof(uint32); - if ((poffctif->tif_size)) - { - TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link"); - return(0); - } - if (off!=NULL) - *off=(uint64)poffc; - _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nextdir32); - *nextdir=nextdir32; - } - else - { - tmsize_t poffa,poffb,poffc,poffd; - uint64 dircount64; - uint16 dircount16; - poffa=(tmsize_t)poff; - poffb=poffa+sizeof(uint64); - if (((uint64)poffa!=poff)||(poffbtif->tif_size)) - { - TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count"); - return(0); - } - _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>0xFFFF) - { - TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed"); - return(0); - } - dircount16=(uint16)dircount64; - poffc=poffb+dircount16*20; - poffd=poffc+sizeof(uint64); - if ((poffctif->tif_size)) - { - TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link"); - return(0); - } - if (off!=NULL) - *off=(uint64)poffc; - _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(nextdir); - } - return(1); - } - else - { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint16 dircount; - uint32 nextdir32; - if (!SeekOK(tif, *nextdir) || - !ReadOK(tif, &dircount, sizeof (uint16))) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - if (off != NULL) - *off = TIFFSeekFile(tif, - dircount*12, SEEK_CUR); - else - (void) TIFFSeekFile(tif, - dircount*12, SEEK_CUR); - if (!ReadOK(tif, &nextdir32, sizeof (uint32))) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir32); - *nextdir=nextdir32; - } - else - { - uint64 dircount64; - uint16 dircount16; - if (!SeekOK(tif, *nextdir) || - !ReadOK(tif, &dircount64, sizeof (uint64))) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>0xFFFF) - { - TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count"); - return(0); - } - dircount16 = (uint16)dircount64; - if (off != NULL) - *off = TIFFSeekFile(tif, - dircount16*20, SEEK_CUR); - else - (void) TIFFSeekFile(tif, - dircount16*20, SEEK_CUR); - if (!ReadOK(tif, nextdir, sizeof (uint64))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Error fetching directory link", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(nextdir); - } - return (1); - } + static const char module[] = "TIFFAdvanceDirectory"; + + /* Add this directory to the directory list, if not already in. */ + if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) + { + TIFFErrorExtR(tif, module, + "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64 + ") might cause an IFD loop", + *nextdirnum, *nextdiroff, *nextdiroff); + *nextdiroff = 0; + *nextdirnum = 0; + return (0); + } + + if (isMapped(tif)) + { + uint64_t poff = *nextdiroff; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + tmsize_t poffa, poffb, poffc, poffd; + uint16_t dircount; + uint32_t nextdir32; + poffa = (tmsize_t)poff; + poffb = poffa + sizeof(uint16_t); + if (((uint64_t)poffa != poff) || (poffb < poffa) || + (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + *nextdiroff = 0; + return (0); + } + _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + poffc = poffb + dircount * 12; + poffd = poffc + sizeof(uint32_t); + if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) || + (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (off != NULL) + *off = (uint64_t)poffc; + _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + *nextdiroff = nextdir32; + } + else + { + tmsize_t poffa, poffb, poffc, poffd; + uint64_t dircount64; + uint16_t dircount16; + if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t)) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + poffa = (tmsize_t)poff; + poffb = poffa + sizeof(uint64_t); + if (poffb > tif->tif_size) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 0xFFFF) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed"); + return (0); + } + dircount16 = (uint16_t)dircount64; + if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) - + (tmsize_t)sizeof(uint64_t)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + poffc = poffb + dircount16 * 20; + poffd = poffc + sizeof(uint64_t); + if (poffd > tif->tif_size) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (off != NULL) + *off = (uint64_t)poffc; + _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + else + { + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint16_t dircount; + uint32_t nextdir32; + if (!SeekOK(tif, *nextdiroff) || + !ReadOK(tif, &dircount, sizeof(uint16_t))) + { + TIFFErrorExtR(tif, module, "%s: Error fetching directory count", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + if (off != NULL) + *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR); + else + (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR); + if (!ReadOK(tif, &nextdir32, sizeof(uint32_t))) + { + TIFFErrorExtR(tif, module, "%s: Error fetching directory link", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + *nextdiroff = nextdir32; + } + else + { + uint64_t dircount64; + uint16_t dircount16; + if (!SeekOK(tif, *nextdiroff) || + !ReadOK(tif, &dircount64, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, "%s: Error fetching directory count", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 0xFFFF) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + dircount16 = (uint16_t)dircount64; + if (off != NULL) + *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR); + else + (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR); + if (!ReadOK(tif, nextdiroff, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, "%s: Error fetching directory link", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + if (*nextdiroff != 0) + { + (*nextdirnum)++; + /* Check next directory for IFD looping and if so, set it as last + * directory. */ + if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) + { + TIFFWarningExtR( + tif, module, + "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64 + ") might be an IFD loop. Treating directory %d as " + "last directory", + *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1); + *nextdiroff = 0; + (*nextdirnum)--; + } + } + return (1); } /* * Count the number of directories in a file. */ -uint16 -TIFFNumberOfDirectories(TIFF* tif) +tdir_t TIFFNumberOfDirectories(TIFF *tif) { - static const char module[] = "TIFFNumberOfDirectories"; - uint64 nextdir; - uint16 n; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - nextdir = tif->tif_header.classic.tiff_diroff; - else - nextdir = tif->tif_header.big.tiff_diroff; - n = 0; - while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) - { - if (n != 65535) { - ++n; - } - else - { - TIFFErrorExt(tif->tif_clientdata, module, - "Directory count exceeded 65535 limit," - " giving up on counting."); - return (65535); - } - } - return (n); + uint64_t nextdiroff; + tdir_t nextdirnum; + tdir_t n; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + nextdiroff = tif->tif_header.classic.tiff_diroff; + else + nextdiroff = tif->tif_header.big.tiff_diroff; + nextdirnum = 0; + n = 0; + while (nextdiroff != 0 && + TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum)) + { + ++n; + } + return (n); } /* * Set the n-th directory as the current directory. * NB: Directories are numbered starting at 0. */ -int -TIFFSetDirectory(TIFF* tif, uint16 dirn) +int TIFFSetDirectory(TIFF *tif, tdir_t dirn) { - uint64 nextdir; - uint16 n; + uint64_t nextdiroff; + tdir_t nextdirnum = 0; + tdir_t n; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - nextdir = tif->tif_header.classic.tiff_diroff; - else - nextdir = tif->tif_header.big.tiff_diroff; - for (n = dirn; n > 0 && nextdir != 0; n--) - if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) - return (0); - tif->tif_nextdiroff = nextdir; - /* - * Set curdir to the actual directory index. The - * -1 is because TIFFReadDirectory will increment - * tif_curdir after successfully reading the directory. - */ - tif->tif_curdir = (dirn - n) - 1; - /* - * Reset tif_dirnumber counter and start new list of seen directories. - * We need this to prevent IFD loops. - */ - tif->tif_dirnumber = 0; - return (TIFFReadDirectory(tif)); + if (tif->tif_setdirectory_force_absolute) + { + /* tif_setdirectory_force_absolute=1 will force parsing the main IFD + * chain from the beginning, thus IFD directory list needs to be cleared + * from possible SubIFD offsets. + */ + _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */ + } + + /* Even faster path, if offset is available within IFD loop hash list. */ + if (!tif->tif_setdirectory_force_absolute && + _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff)) + { + /* Set parameters for following TIFFReadDirectory() below. */ + tif->tif_nextdiroff = nextdiroff; + tif->tif_curdir = dirn; + /* Reset to relative stepping */ + tif->tif_setdirectory_force_absolute = FALSE; + } + else + { + + /* Fast path when we just advance relative to the current directory: + * start at the current dir offset and continue to seek from there. + * Check special cases when relative is not allowed: + * - jump back from SubIFD or custom directory + * - right after TIFFWriteDirectory() jump back to that directory + * using TIFFSetDirectory() */ + const int relative = (dirn >= tif->tif_curdir) && + (tif->tif_diroff != 0) && + !tif->tif_setdirectory_force_absolute; + + if (relative) + { + nextdiroff = tif->tif_diroff; + dirn -= tif->tif_curdir; + nextdirnum = tif->tif_curdir; + } + else if (!(tif->tif_flags & TIFF_BIGTIFF)) + nextdiroff = tif->tif_header.classic.tiff_diroff; + else + nextdiroff = tif->tif_header.big.tiff_diroff; + + /* Reset to relative stepping */ + tif->tif_setdirectory_force_absolute = FALSE; + + for (n = dirn; n > 0 && nextdiroff != 0; n--) + if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum)) + return (0); + /* If the n-th directory could not be reached (does not exist), + * return here without touching anything further. */ + if (nextdiroff == 0 || n > 0) + return (0); + + tif->tif_nextdiroff = nextdiroff; + + /* Set curdir to the actual directory index. */ + if (relative) + tif->tif_curdir += dirn - n; + else + tif->tif_curdir = dirn - n; + } + + /* The -1 decrement is because TIFFReadDirectory will increment + * tif_curdir after successfully reading the directory. */ + if (tif->tif_curdir == 0) + tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; + else + tif->tif_curdir--; + return (TIFFReadDirectory(tif)); } /* @@ -1696,140 +2109,200 @@ TIFFSetDirectory(TIFF* tif, uint16 dirn) * is used mainly to access directories linked with * the SubIFD tag (e.g. thumbnail images). */ -int -TIFFSetSubDirectory(TIFF* tif, uint64 diroff) +int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff) { - tif->tif_nextdiroff = diroff; - /* - * Reset tif_dirnumber counter and start new list of seen directories. - * We need this to prevent IFD loops. - */ - tif->tif_dirnumber = 0; - return (TIFFReadDirectory(tif)); + /* Match nextdiroff and curdir for consistent IFD-loop checking. + * Only with TIFFSetSubDirectory() the IFD list can be corrupted with + * invalid offsets within the main IFD tree. In the case of several subIFDs + * of a main image, there are two possibilities that are not even mutually + * exclusive. a.) The subIFD tag contains an array with all offsets of the + * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters. + * (refer to + * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.) + */ + int retval; + uint32_t curdir = 0; + int8_t probablySubIFD = 0; + if (diroff == 0) + { + /* Special case to invalidate the tif_lastdiroff member. */ + tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; + } + else + { + if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir)) + { + /* Non-existing offsets might point to a SubIFD or invalid IFD.*/ + probablySubIFD = 1; + } + /* -1 because TIFFReadDirectory() will increment tif_curdir. */ + tif->tif_curdir = + curdir == 0 ? TIFF_NON_EXISTENT_DIR_NUMBER : curdir - 1; + } + + tif->tif_nextdiroff = diroff; + retval = TIFFReadDirectory(tif); + /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it + * back, but leave it for diroff==0. */ + if (!retval && diroff != 0) + { + if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER) + tif->tif_curdir = 0; + else + tif->tif_curdir++; + } + if (retval && probablySubIFD) + { + /* Reset IFD list to start new one for SubIFD chain and also start + * SubIFD chain with tif_curdir=0. */ + _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */ + tif->tif_curdir = 0; /* first directory of new chain */ + /* add this offset to new IFD list */ + _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff); + /* To be able to return from SubIFD or custom-IFD to main-IFD */ + tif->tif_setdirectory_force_absolute = TRUE; + } + return (retval); } /* * Return file offset of the current directory. */ -uint64 -TIFFCurrentDirOffset(TIFF* tif) -{ - return (tif->tif_diroff); -} +uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); } /* * Return an indication of whether or not we are * at the last directory in the file. */ -int -TIFFLastDirectory(TIFF* tif) -{ - return (tif->tif_nextdiroff == 0); -} +int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); } /* * Unlink the specified directory from the directory chain. + * Note: First directory starts with number dirn=1. + * This is different to TIFFSetDirectory() where the first directory starts with + * zero. */ -int -TIFFUnlinkDirectory(TIFF* tif, uint16 dirn) +int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn) { - static const char module[] = "TIFFUnlinkDirectory"; - uint64 nextdir; - uint64 off; - uint16 n; + static const char module[] = "TIFFUnlinkDirectory"; + uint64_t nextdir; + tdir_t nextdirnum; + uint64_t off; + tdir_t n; - if (tif->tif_mode == O_RDONLY) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not unlink directory in read-only file"); - return (0); - } - /* - * Go to the directory before the one we want - * to unlink and nab the offset of the link - * field we'll need to patch. - */ - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - nextdir = tif->tif_header.classic.tiff_diroff; - off = 4; - } - else - { - nextdir = tif->tif_header.big.tiff_diroff; - off = 8; - } - for (n = dirn-1; n > 0; n--) { - if (nextdir == 0) { - TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn); - return (0); - } - if (!TIFFAdvanceDirectory(tif, &nextdir, &off)) - return (0); - } - /* - * Advance to the directory to be unlinked and fetch - * the offset of the directory that follows. - */ - if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) - return (0); - /* - * Go back and patch the link field of the preceding - * directory to point to the offset of the directory - * that follows. - */ - (void) TIFFSeekFile(tif, off, SEEK_SET); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32 nextdir32; - nextdir32=(uint32)nextdir; - assert((uint64)nextdir32==nextdir); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir32); - if (!WriteOK(tif, &nextdir32, sizeof (uint32))) { - TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link"); - return (0); - } - } - else - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&nextdir); - if (!WriteOK(tif, &nextdir, sizeof (uint64))) { - TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link"); - return (0); - } - } - /* - * Leave directory state setup safely. We don't have - * facilities for doing inserting and removing directories, - * so it's safest to just invalidate everything. This - * means that the caller can only append to the directory - * chain. - */ - (*tif->tif_cleanup)(tif); - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { - _TIFFfree(tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawcc = 0; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = 0; - } - tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE); - TIFFFreeDirectory(tif); - TIFFDefaultDirectory(tif); - tif->tif_diroff = 0; /* force link on next write */ - tif->tif_nextdiroff = 0; /* next write must be at end */ - tif->tif_curoff = 0; - tif->tif_row = (uint32) -1; - tif->tif_curstrip = (uint32) -1; - return (1); + if (tif->tif_mode == O_RDONLY) + { + TIFFErrorExtR(tif, module, + "Can not unlink directory in read-only file"); + return (0); + } + if (dirn == 0) + { + TIFFErrorExtR(tif, module, + "For TIFFUnlinkDirectory() first directory starts with " + "number 1 and not 0"); + return (0); + } + /* + * Go to the directory before the one we want + * to unlink and nab the offset of the link + * field we'll need to patch. + */ + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + nextdir = tif->tif_header.classic.tiff_diroff; + off = 4; + } + else + { + nextdir = tif->tif_header.big.tiff_diroff; + off = 8; + } + nextdirnum = 0; /* First directory is dirn=0 */ + + for (n = dirn - 1; n > 0; n--) + { + if (nextdir == 0) + { + TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn); + return (0); + } + if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum)) + return (0); + } + /* + * Advance to the directory to be unlinked and fetch + * the offset of the directory that follows. + */ + if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum)) + return (0); + /* + * Go back and patch the link field of the preceding + * directory to point to the offset of the directory + * that follows. + */ + (void)TIFFSeekFile(tif, off, SEEK_SET); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t nextdir32; + nextdir32 = (uint32_t)nextdir; + assert((uint64_t)nextdir32 == nextdir); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + if (!WriteOK(tif, &nextdir32, sizeof(uint32_t))) + { + TIFFErrorExtR(tif, module, "Error writing directory link"); + return (0); + } + } + else + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextdir); + if (!WriteOK(tif, &nextdir, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, "Error writing directory link"); + return (0); + } + } + + /* For dirn=1 (first directory) also update the libtiff internal + * base offset variables. */ + if (dirn == 1) + { + if (!(tif->tif_flags & TIFF_BIGTIFF)) + tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir; + else + tif->tif_header.big.tiff_diroff = nextdir; + } + + /* + * Leave directory state setup safely. We don't have + * facilities for doing inserting and removing directories, + * so it's safest to just invalidate everything. This + * means that the caller can only append to the directory + * chain. + */ + (*tif->tif_cleanup)(tif); + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawcc = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + } + tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE | + TIFF_BUF4WRITE); + TIFFFreeDirectory(tif); + TIFFDefaultDirectory(tif); + tif->tif_diroff = 0; /* force link on next write */ + tif->tif_nextdiroff = 0; /* next write must be at end */ + tif->tif_lastdiroff = 0; /* will be updated on next link */ + tif->tif_curoff = 0; + tif->tif_row = (uint32_t)-1; + tif->tif_curstrip = (uint32_t)-1; + tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; + _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */ + return (1); } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_dir.h b/3rdparty/libtiff/tif_dir.h index f608dd713b..9eaf22f8e6 100644 --- a/3rdparty/libtiff/tif_dir.h +++ b/3rdparty/libtiff/tif_dir.h @@ -2,28 +2,28 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _TIFFDIR_ -#define _TIFFDIR_ +#define _TIFFDIR_ #include "tiff.h" #include "tiffio.h" @@ -32,10 +32,11 @@ * ``Library-private'' Directory-related Definitions. */ -typedef struct { - const TIFFField *info; - int count; - void *value; +typedef struct +{ + const TIFFField *info; + int count; + void *value; } TIFFTagValue; /* @@ -49,79 +50,91 @@ typedef struct { * BigTIFF, then it is placed in the offset field to save space. If so, * it is left-justified in the offset field. */ -typedef struct { - uint16 tdir_tag; /* see below */ - uint16 tdir_type; /* data type; see below */ - uint64 tdir_count; /* number of items; length in spec */ - union { - uint16 toff_short; - uint32 toff_long; - uint64 toff_long8; - } tdir_offset; /* either offset or the data itself if fits */ - uint8 tdir_ignore; /* flag status to ignore tag when parsing tags in tif_dirread.c */ +typedef struct +{ + uint16_t tdir_tag; /* see below */ + uint16_t tdir_type; /* data type; see below */ + uint64_t tdir_count; /* number of items; length in spec */ + union + { + uint16_t toff_short; + uint32_t toff_long; + uint64_t toff_long8; + } tdir_offset; /* either offset or the data itself if fits */ + uint8_t tdir_ignore; /* flag status to ignore tag when parsing tags in + tif_dirread.c */ } TIFFDirEntry; /* * Internal format of a TIFF directory entry. */ -typedef struct { -#define FIELD_SETLONGS 4 - /* bit vector of fields that are set */ - unsigned long td_fieldsset[FIELD_SETLONGS]; +typedef struct +{ +#define FIELDSET_ITEMS 4 + /* bit vector of fields that are set */ + uint32_t td_fieldsset[FIELDSET_ITEMS]; - uint32 td_imagewidth, td_imagelength, td_imagedepth; - uint32 td_tilewidth, td_tilelength, td_tiledepth; - uint32 td_subfiletype; - uint16 td_bitspersample; - uint16 td_sampleformat; - uint16 td_compression; - uint16 td_photometric; - uint16 td_threshholding; - uint16 td_fillorder; - uint16 td_orientation; - uint16 td_samplesperpixel; - uint32 td_rowsperstrip; - uint16 td_minsamplevalue, td_maxsamplevalue; - double* td_sminsamplevalue; - double* td_smaxsamplevalue; - float td_xresolution, td_yresolution; - uint16 td_resolutionunit; - uint16 td_planarconfig; - float td_xposition, td_yposition; - uint16 td_pagenumber[2]; - uint16* td_colormap[3]; - uint16 td_halftonehints[2]; - uint16 td_extrasamples; - uint16* td_sampleinfo; - /* even though the name is misleading, td_stripsperimage is the number - * of striles (=strips or tiles) per plane, and td_nstrips the total - * number of striles */ - uint32 td_stripsperimage; - uint32 td_nstrips; /* size of offset & bytecount arrays */ - uint64* td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */ - uint64* td_stripbytecount_p; /* should be accessed with TIFFGetStrileByteCount */ - uint32 td_stripoffsetbyteallocsize; /* number of elements currently allocated for td_stripoffset/td_stripbytecount. Only used if TIFF_LAZYSTRILELOAD is set */ + uint32_t td_imagewidth, td_imagelength, td_imagedepth; + uint32_t td_tilewidth, td_tilelength, td_tiledepth; + uint32_t td_subfiletype; + uint16_t td_bitspersample; + uint16_t td_sampleformat; + uint16_t td_compression; + uint16_t td_photometric; + uint16_t td_threshholding; + uint16_t td_fillorder; + uint16_t td_orientation; + uint16_t td_samplesperpixel; + uint32_t td_rowsperstrip; + uint16_t td_minsamplevalue, td_maxsamplevalue; + double *td_sminsamplevalue; + double *td_smaxsamplevalue; + float td_xresolution, td_yresolution; + uint16_t td_resolutionunit; + uint16_t td_planarconfig; + float td_xposition, td_yposition; + uint16_t td_pagenumber[2]; + uint16_t *td_colormap[3]; + uint16_t td_halftonehints[2]; + uint16_t td_extrasamples; + uint16_t *td_sampleinfo; + /* even though the name is misleading, td_stripsperimage is the number + * of striles (=strips or tiles) per plane, and td_nstrips the total + * number of striles */ + uint32_t td_stripsperimage; + uint32_t td_nstrips; /* size of offset & bytecount arrays */ + uint64_t + *td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */ + uint64_t *td_stripbytecount_p; /* should be accessed with + TIFFGetStrileByteCount */ + uint32_t + td_stripoffsetbyteallocsize; /* number of elements currently allocated + for td_stripoffset/td_stripbytecount. + Only used if TIFF_LAZYSTRILELOAD is set + */ #ifdef STRIPBYTECOUNTSORTED_UNUSED - int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */ + int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */ #endif - TIFFDirEntry td_stripoffset_entry; /* for deferred loading */ - TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */ - uint16 td_nsubifd; - uint64* td_subifd; - /* YCbCr parameters */ - uint16 td_ycbcrsubsampling[2]; - uint16 td_ycbcrpositioning; - /* Colorimetry parameters */ - uint16* td_transferfunction[3]; - float* td_refblackwhite; - /* CMYK parameters */ - int td_inknameslen; - char* td_inknames; + TIFFDirEntry td_stripoffset_entry; /* for deferred loading */ + TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */ + uint16_t td_nsubifd; + uint64_t *td_subifd; + /* YCbCr parameters */ + uint16_t td_ycbcrsubsampling[2]; + uint16_t td_ycbcrpositioning; + /* Colorimetry parameters */ + uint16_t *td_transferfunction[3]; + float *td_refblackwhite; + /* CMYK parameters */ + int td_inknameslen; + char *td_inknames; + uint16_t td_numberofinks; /* number of inks in InkNames string */ - int td_customValueCount; - TIFFTagValue *td_customValues; + int td_customValueCount; + TIFFTagValue *td_customValues; - unsigned char td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */ + unsigned char + td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */ } TIFFDirectory; /* @@ -135,49 +148,49 @@ typedef struct { * Note that a bit *is* allocated for ignored tags; this is understood by the * directory reading logic which uses this fact to avoid special-case handling */ -#define FIELD_IGNORE 0 +#define FIELD_IGNORE 0 /* multi-item fields */ -#define FIELD_IMAGEDIMENSIONS 1 -#define FIELD_TILEDIMENSIONS 2 -#define FIELD_RESOLUTION 3 -#define FIELD_POSITION 4 +#define FIELD_IMAGEDIMENSIONS 1 +#define FIELD_TILEDIMENSIONS 2 +#define FIELD_RESOLUTION 3 +#define FIELD_POSITION 4 /* single-item fields */ -#define FIELD_SUBFILETYPE 5 -#define FIELD_BITSPERSAMPLE 6 -#define FIELD_COMPRESSION 7 -#define FIELD_PHOTOMETRIC 8 -#define FIELD_THRESHHOLDING 9 -#define FIELD_FILLORDER 10 -#define FIELD_ORIENTATION 15 -#define FIELD_SAMPLESPERPIXEL 16 -#define FIELD_ROWSPERSTRIP 17 -#define FIELD_MINSAMPLEVALUE 18 -#define FIELD_MAXSAMPLEVALUE 19 -#define FIELD_PLANARCONFIG 20 -#define FIELD_RESOLUTIONUNIT 22 -#define FIELD_PAGENUMBER 23 -#define FIELD_STRIPBYTECOUNTS 24 -#define FIELD_STRIPOFFSETS 25 -#define FIELD_COLORMAP 26 -#define FIELD_EXTRASAMPLES 31 -#define FIELD_SAMPLEFORMAT 32 -#define FIELD_SMINSAMPLEVALUE 33 -#define FIELD_SMAXSAMPLEVALUE 34 -#define FIELD_IMAGEDEPTH 35 -#define FIELD_TILEDEPTH 36 -#define FIELD_HALFTONEHINTS 37 -#define FIELD_YCBCRSUBSAMPLING 39 -#define FIELD_YCBCRPOSITIONING 40 -#define FIELD_REFBLACKWHITE 41 -#define FIELD_TRANSFERFUNCTION 44 -#define FIELD_INKNAMES 46 -#define FIELD_SUBIFD 49 +#define FIELD_SUBFILETYPE 5 +#define FIELD_BITSPERSAMPLE 6 +#define FIELD_COMPRESSION 7 +#define FIELD_PHOTOMETRIC 8 +#define FIELD_THRESHHOLDING 9 +#define FIELD_FILLORDER 10 +#define FIELD_ORIENTATION 15 +#define FIELD_SAMPLESPERPIXEL 16 +#define FIELD_ROWSPERSTRIP 17 +#define FIELD_MINSAMPLEVALUE 18 +#define FIELD_MAXSAMPLEVALUE 19 +#define FIELD_PLANARCONFIG 20 +#define FIELD_RESOLUTIONUNIT 22 +#define FIELD_PAGENUMBER 23 +#define FIELD_STRIPBYTECOUNTS 24 +#define FIELD_STRIPOFFSETS 25 +#define FIELD_COLORMAP 26 +#define FIELD_EXTRASAMPLES 31 +#define FIELD_SAMPLEFORMAT 32 +#define FIELD_SMINSAMPLEVALUE 33 +#define FIELD_SMAXSAMPLEVALUE 34 +#define FIELD_IMAGEDEPTH 35 +#define FIELD_TILEDEPTH 36 +#define FIELD_HALFTONEHINTS 37 +#define FIELD_YCBCRSUBSAMPLING 39 +#define FIELD_YCBCRPOSITIONING 40 +#define FIELD_REFBLACKWHITE 41 +#define FIELD_TRANSFERFUNCTION 44 +#define FIELD_INKNAMES 46 +#define FIELD_SUBIFD 49 +#define FIELD_NUMBEROFINKS 50 /* FIELD_CUSTOM (see tiffio.h) 65 */ /* end of support for well-known tags; codec-private tags follow */ -#define FIELD_CODEC 66 /* base of codec-private tags */ - +#define FIELD_CODEC 66 /* base of codec-private tags */ /* * Pseudo-tags don't normally need field bits since they are not written to an @@ -187,131 +200,141 @@ typedef struct { * or ``unset'' then it can do using internal state flags without polluting * the field bit space defined for real tags. */ -#define FIELD_PSEUDO 0 +#define FIELD_PSEUDO 0 -#define FIELD_LAST (32*FIELD_SETLONGS-1) +#define FIELD_LAST (32 * FIELDSET_ITEMS - 1) -#define BITn(n) (((unsigned long)1L)<<((n)&0x1f)) -#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n)/32]) -#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field)) -#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field)) -#define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field)) +#define BITn(n) (((uint32_t)1L) << ((n)&0x1f)) +#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n) / 32]) +#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field)) +#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field)) +#define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field)) -#define FieldSet(fields, f) (fields[(f)/32] & BITn(f)) -#define ResetFieldBit(fields, f) (fields[(f)/32] &= ~BITn(f)) +#define FieldSet(fields, f) (fields[(f) / 32] & BITn(f)) +#define ResetFieldBit(fields, f) (fields[(f) / 32] &= ~BITn(f)) -typedef enum { - TIFF_SETGET_UNDEFINED = 0, - TIFF_SETGET_ASCII = 1, - TIFF_SETGET_UINT8 = 2, - TIFF_SETGET_SINT8 = 3, - TIFF_SETGET_UINT16 = 4, - TIFF_SETGET_SINT16 = 5, - TIFF_SETGET_UINT32 = 6, - TIFF_SETGET_SINT32 = 7, - TIFF_SETGET_UINT64 = 8, - TIFF_SETGET_SINT64 = 9, - TIFF_SETGET_FLOAT = 10, - TIFF_SETGET_DOUBLE = 11, - TIFF_SETGET_IFD8 = 12, - TIFF_SETGET_INT = 13, - TIFF_SETGET_UINT16_PAIR = 14, - TIFF_SETGET_C0_ASCII = 15, - TIFF_SETGET_C0_UINT8 = 16, - TIFF_SETGET_C0_SINT8 = 17, - TIFF_SETGET_C0_UINT16 = 18, - TIFF_SETGET_C0_SINT16 = 19, - TIFF_SETGET_C0_UINT32 = 20, - TIFF_SETGET_C0_SINT32 = 21, - TIFF_SETGET_C0_UINT64 = 22, - TIFF_SETGET_C0_SINT64 = 23, - TIFF_SETGET_C0_FLOAT = 24, - TIFF_SETGET_C0_DOUBLE = 25, - TIFF_SETGET_C0_IFD8 = 26, - TIFF_SETGET_C16_ASCII = 27, - TIFF_SETGET_C16_UINT8 = 28, - TIFF_SETGET_C16_SINT8 = 29, - TIFF_SETGET_C16_UINT16 = 30, - TIFF_SETGET_C16_SINT16 = 31, - TIFF_SETGET_C16_UINT32 = 32, - TIFF_SETGET_C16_SINT32 = 33, - TIFF_SETGET_C16_UINT64 = 34, - TIFF_SETGET_C16_SINT64 = 35, - TIFF_SETGET_C16_FLOAT = 36, - TIFF_SETGET_C16_DOUBLE = 37, - TIFF_SETGET_C16_IFD8 = 38, - TIFF_SETGET_C32_ASCII = 39, - TIFF_SETGET_C32_UINT8 = 40, - TIFF_SETGET_C32_SINT8 = 41, - TIFF_SETGET_C32_UINT16 = 42, - TIFF_SETGET_C32_SINT16 = 43, - TIFF_SETGET_C32_UINT32 = 44, - TIFF_SETGET_C32_SINT32 = 45, - TIFF_SETGET_C32_UINT64 = 46, - TIFF_SETGET_C32_SINT64 = 47, - TIFF_SETGET_C32_FLOAT = 48, - TIFF_SETGET_C32_DOUBLE = 49, - TIFF_SETGET_C32_IFD8 = 50, - TIFF_SETGET_OTHER = 51 +typedef enum +{ + TIFF_SETGET_UNDEFINED = 0, + TIFF_SETGET_ASCII = 1, + TIFF_SETGET_UINT8 = 2, + TIFF_SETGET_SINT8 = 3, + TIFF_SETGET_UINT16 = 4, + TIFF_SETGET_SINT16 = 5, + TIFF_SETGET_UINT32 = 6, + TIFF_SETGET_SINT32 = 7, + TIFF_SETGET_UINT64 = 8, + TIFF_SETGET_SINT64 = 9, + TIFF_SETGET_FLOAT = 10, + TIFF_SETGET_DOUBLE = 11, + TIFF_SETGET_IFD8 = 12, + TIFF_SETGET_INT = 13, + TIFF_SETGET_UINT16_PAIR = 14, + TIFF_SETGET_C0_ASCII = 15, + TIFF_SETGET_C0_UINT8 = 16, + TIFF_SETGET_C0_SINT8 = 17, + TIFF_SETGET_C0_UINT16 = 18, + TIFF_SETGET_C0_SINT16 = 19, + TIFF_SETGET_C0_UINT32 = 20, + TIFF_SETGET_C0_SINT32 = 21, + TIFF_SETGET_C0_UINT64 = 22, + TIFF_SETGET_C0_SINT64 = 23, + TIFF_SETGET_C0_FLOAT = 24, + TIFF_SETGET_C0_DOUBLE = 25, + TIFF_SETGET_C0_IFD8 = 26, + TIFF_SETGET_C16_ASCII = 27, + TIFF_SETGET_C16_UINT8 = 28, + TIFF_SETGET_C16_SINT8 = 29, + TIFF_SETGET_C16_UINT16 = 30, + TIFF_SETGET_C16_SINT16 = 31, + TIFF_SETGET_C16_UINT32 = 32, + TIFF_SETGET_C16_SINT32 = 33, + TIFF_SETGET_C16_UINT64 = 34, + TIFF_SETGET_C16_SINT64 = 35, + TIFF_SETGET_C16_FLOAT = 36, + TIFF_SETGET_C16_DOUBLE = 37, + TIFF_SETGET_C16_IFD8 = 38, + TIFF_SETGET_C32_ASCII = 39, + TIFF_SETGET_C32_UINT8 = 40, + TIFF_SETGET_C32_SINT8 = 41, + TIFF_SETGET_C32_UINT16 = 42, + TIFF_SETGET_C32_SINT16 = 43, + TIFF_SETGET_C32_UINT32 = 44, + TIFF_SETGET_C32_SINT32 = 45, + TIFF_SETGET_C32_UINT64 = 46, + TIFF_SETGET_C32_SINT64 = 47, + TIFF_SETGET_C32_FLOAT = 48, + TIFF_SETGET_C32_DOUBLE = 49, + TIFF_SETGET_C32_IFD8 = 50, + TIFF_SETGET_OTHER = 51 } TIFFSetGetFieldType; #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -extern const TIFFFieldArray* _TIFFGetFields(void); -extern const TIFFFieldArray* _TIFFGetExifFields(void); -extern const TIFFFieldArray* _TIFFGetGpsFields(void); -extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray); -extern void _TIFFPrintFieldInfo(TIFF*, FILE*); + extern const TIFFFieldArray *_TIFFGetFields(void); + extern const TIFFFieldArray *_TIFFGetExifFields(void); + extern const TIFFFieldArray *_TIFFGetGpsFields(void); + extern void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *infoarray); + extern void _TIFFPrintFieldInfo(TIFF *, FILE *); -extern int _TIFFFillStriles(TIFF*); + extern int _TIFFFillStriles(TIFF *); -typedef enum { - tfiatImage, - tfiatExif, - tfiatGps, /* EXIF-GPS fields array type */ - tfiatOther -} TIFFFieldArrayType; + typedef enum + { + tfiatImage, + tfiatExif, + tfiatGps, /* EXIF-GPS fields array type */ + tfiatOther + } TIFFFieldArrayType; -struct _TIFFFieldArray { - TIFFFieldArrayType type; /* array type, will be used to determine if IFD is image and such */ - uint32 allocated_size; /* 0 if array is constant, other if modified by future definition extension support */ - uint32 count; /* number of elements in fields array */ - TIFFField* fields; /* actual field info */ -}; + struct _TIFFFieldArray + { + TIFFFieldArrayType type; /* array type, will be used to determine if IFD + is image and such */ + uint32_t allocated_size; /* 0 if array is constant, other if modified by + future definition extension support */ + uint32_t count; /* number of elements in fields array */ + TIFFField *fields; /* actual field info */ + }; -struct _TIFFField { - uint32 field_tag; /* field's tag */ - short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ - short field_writecount; /* write count/TIFF_VARIABLE */ - TIFFDataType field_type; /* type of associated data */ - uint32 reserved; /* reserved for future extension */ - TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */ - TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */ - unsigned short field_bit; /* bit in fieldsset bit vector */ - unsigned char field_oktochange; /* if true, can change while writing */ - unsigned char field_passcount; /* if true, pass dir count on set */ - char* field_name; /* ASCII name */ - TIFFFieldArray* field_subfields; /* if field points to child ifds, child ifd field definition array */ -}; + struct _TIFFField + { + uint32_t field_tag; /* field's tag */ + short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ + short field_writecount; /* write count/TIFF_VARIABLE */ + TIFFDataType field_type; /* type of associated data */ + uint32_t + field_anonymous; /* if true, this is a unknown / anonymous tag */ + TIFFSetGetFieldType + set_field_type; /* type to be passed to TIFFSetField */ + TIFFSetGetFieldType + get_field_type; /* type to be passed to TIFFGetField */ + unsigned short field_bit; /* bit in fieldsset bit vector */ + unsigned char field_oktochange; /* if true, can change while writing */ + unsigned char field_passcount; /* if true, pass dir count on set */ + char *field_name; /* ASCII name */ + TIFFFieldArray *field_subfields; /* if field points to child ifds, child + ifd field definition array */ + }; -extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32); -extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType); -extern TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType); -extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag); + extern int _TIFFMergeFields(TIFF *, const TIFFField[], uint32_t); + extern const TIFFField *_TIFFFindOrRegisterField(TIFF *, uint32_t, + TIFFDataType); + extern TIFFField *_TIFFCreateAnonField(TIFF *, uint32_t, TIFFDataType); + extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag); + extern int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, + uint64_t diroff); + extern int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, + tdir_t *dirn); + extern int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn, + uint64_t *diroff); + extern int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif, + uint64_t diroff); #if defined(__cplusplus) } #endif #endif /* _TIFFDIR_ */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_dirinfo.c b/3rdparty/libtiff/tif_dirinfo.c index 7217042c25..0e705e81e3 100644 --- a/3rdparty/libtiff/tif_dirinfo.c +++ b/3rdparty/libtiff/tif_dirinfo.c @@ -42,860 +42,954 @@ /* const object should be initialized */ #ifdef _MSC_VER -#pragma warning( push ) -#pragma warning( disable : 4132 ) +#pragma warning(push) +#pragma warning(disable : 4132) #endif static const TIFFFieldArray tiffFieldArray; static const TIFFFieldArray exifFieldArray; static const TIFFFieldArray gpsFieldArray; #ifdef _MSC_VER -#pragma warning( pop ) +#pragma warning(pop) #endif /*--: Rational2Double: -- - * The Rational2Double upgraded libtiff functionality allows the definition and achievement of true double-precision accuracy - * for TIFF tags of RATIONAL type and field_bit=FIELD_CUSTOM using the set_field_type = TIFF_SETGET_DOUBLE. + * The Rational2Double upgraded libtiff functionality allows the definition and + * achievement of true double-precision accuracy for TIFF tags of RATIONAL type + * and field_bit=FIELD_CUSTOM using the set_field_type = TIFF_SETGET_DOUBLE. * Unfortunately, that changes the old implemented interface for TIFFGetField(). - * In order to keep the old TIFFGetField() interface behavior those tags have to be redefined with set_field_type = TIFF_SETGET_FLOAT! + * In order to keep the old TIFFGetField() interface behavior those tags have to + * be redefined with set_field_type = TIFF_SETGET_FLOAT! * * Rational custom arrays are already defined as _Cxx_FLOAT, thus can stay. * */ -static const TIFFField -tiffFields[] = { - { TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL }, - { TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "OldSubfileType", NULL }, - { TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL }, - { TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL }, - { TIFFTAG_BITSPERSAMPLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL }, - { TIFFTAG_COMPRESSION, -1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL }, - { TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL }, - { TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL }, - { TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellWidth", NULL }, - { TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellLength", NULL }, - { TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL }, - { TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL }, - { TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL }, - { TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL }, - { TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL }, - { TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL }, - { TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL }, - { TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL }, - { TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL }, - { TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL }, - { TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL }, - { TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL }, - { TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL }, - { TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL }, - { TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL }, - { TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL }, - { TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL }, - { TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL }, - { TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL }, - { TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL }, - { TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL }, - { TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL }, - { TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL }, - { TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL }, - { TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL }, - { TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL }, - { TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL }, - { TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL }, - { TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL }, - { TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL }, - { TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL }, - { TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL }, - { TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL }, - { TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL }, - { TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL }, - { TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL }, - { TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL }, - { TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL }, - { TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray*) &tiffFieldArray }, - { TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL }, - { TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL }, - { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NumberOfInks", NULL }, - { TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL }, - { TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL }, - { TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL }, - { TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL }, - { TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL }, - { TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL }, - { TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL }, - { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, - { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, - { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL }, - { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL }, - { TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL }, - { TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL }, - { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL }, - { TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "XMLPacket", NULL }, - /* begin SGI tags */ - { TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL }, - { TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL }, - { TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL }, - { TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL }, - /* end SGI tags */ - /* begin Pixar tags */ - { TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL }, - { TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL }, - { TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL }, - { TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL }, - { TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL }, - { TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL }, - { TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL }, - { TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFARepeatPatternDim", NULL }, - { TIFFTAG_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPattern" , NULL}, - { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL }, - /* end Pixar tags */ - { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL }, - { TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL }, - /*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff. - * However, for IFD-like tags, libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with - * a special handling procedure in order to write either a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files - * or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */ - { TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray*) &exifFieldArray }, - { TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL }, - { TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray*) &gpsFieldArray }, - { TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL }, - { TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL }, - { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL }, - { TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL }, - { TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL }, - { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL }, - /* begin DNG tags */ - { TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL }, - { TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGBackwardVersion", NULL }, - { TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL }, - { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL }, - { TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPlaneColor", NULL }, - { TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFALayout", NULL }, - { TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "LinearizationTable", NULL }, - { TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BlackLevelRepeatDim", NULL }, - { TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevel", NULL }, - { TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaH", NULL }, - { TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL }, - { TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL }, - { TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL }, - { TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL }, - { TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL }, - { TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL }, - { TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL }, - { TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix2", NULL }, - { TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration1", NULL }, - { TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration2", NULL }, - { TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix1", NULL }, - { TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix2", NULL }, - { TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL }, - { TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL }, - { TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL }, - { TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL }, - { TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL }, - { TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL }, - { TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL }, - { TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL }, - { TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL }, - { TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL }, - { TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL }, - { TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL }, - { TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL }, - { TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL }, - { TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL }, - { TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL }, - { TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant2", NULL }, - { TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "RawDataUniqueID", NULL }, - { TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL }, - { TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "OriginalRawFileData", NULL }, - { TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ActiveArea", NULL }, - { TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "MaskedAreas", NULL }, - { TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotICCProfile", NULL }, - { TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotPreProfileMatrix", NULL }, - { TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentICCProfile", NULL }, - { TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentPreProfileMatrix", NULL }, - { TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL}, - /* end DNG tags */ - /* begin TIFF/FX tags */ - { TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "Indexed", NULL }, - { TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GlobalParametersIFD", NULL }, - { TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ProfileType", NULL }, - { TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "FaxProfile", NULL }, - { TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CodingMethods", NULL }, - { TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "VersionYear", NULL }, - { TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ModeNumber", NULL }, - { TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Decode", NULL }, - { TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ImageBaseColor", NULL }, - { TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "T82Options", NULL }, - { TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "StripRowCounts", NULL }, - { TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ImageLayer", NULL }, - /* end TIFF/FX tags */ - /* begin pseudo tags */ +/* clang-format off */ /* for better readability of tag comments */ +static const TIFFField tiffFields[] = { + {TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL}, + {TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "OldSubfileType", NULL}, + {TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL}, + {TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL}, + {TIFFTAG_BITSPERSAMPLE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL}, + {TIFFTAG_COMPRESSION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL}, + {TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL}, + {TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL}, + {TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellWidth", NULL}, + {TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellLength", NULL}, + {TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL}, + {TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL}, + {TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL}, + {TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL}, + {TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL}, + {TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL}, + {TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL}, + {TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL}, + {TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL}, + {TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL}, + {TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL}, + {TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL}, + {TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL}, + {TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL}, + {TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL}, + {TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL}, + {TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL}, + {TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL}, + {TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL}, + {TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL}, + {TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL}, + {TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL}, + {TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL}, + {TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL}, + {TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL}, + {TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL}, + {TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL}, + {TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL}, + {TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL}, + {TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL}, + {TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL}, + {TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL}, + {TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL}, + {TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL}, + {TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL}, + {TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL}, + {TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL}, + {TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL}, + {TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray *)&tiffFieldArray}, + {TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL}, + {TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL}, + {TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_NUMBEROFINKS, 1, 0, "NumberOfInks", NULL}, + {TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL}, + {TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL}, + {TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL}, + {TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL}, + {TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL}, + {TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL}, + {TIFFTAG_CLIPPATH, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL}, + {TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL}, + {TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL}, + {TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL}, + {TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL}, + {TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL}, + {TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL}, + {TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "XMLPacket", NULL}, + /* begin SGI tags */ + {TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL}, + {TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL}, + {TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL}, + {TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL}, + /* end SGI tags */ + /* begin Pixar tags */ + {TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL}, + {TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL}, + {TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL}, + {TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL}, + {TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL}, + {TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL}, + {TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL}, + {TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL}, + /* end Pixar tags */ + {TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "RichTIFFIPTC", NULL}, + {TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Photoshop", NULL}, + /*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff. However, for IFD-like tags, + * libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with a special handling procedure in order to write either + * a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */ + {TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray}, + {TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ICC Profile", NULL}, + {TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray}, + {TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL}, + {TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL}, + {TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL}, + {TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL}, + {TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL}, + {TIFFTAG_IMAGESOURCEDATA, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Adobe Photoshop Document Data Block", NULL}, + {TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL}, + /* begin DNG tags */ + {TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DNGVersion", NULL}, + {TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DNGBackwardVersion", NULL}, + {TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL}, + {TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL}, + {TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPlaneColor", NULL}, + {TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CFALayout", NULL}, + {TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LinearizationTable", NULL}, + {TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BlackLevelRepeatDim", NULL}, + {TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevel", NULL}, + {TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaH", NULL}, + {TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaV", NULL}, + {TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "WhiteLevel", NULL}, + {TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultScale", NULL}, + {TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BestQualityScale", NULL}, + {TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultCropOrigin", NULL}, + {TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultCropSize", NULL}, + {TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix1", NULL}, + {TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix2", NULL}, + {TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration1", NULL}, + {TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration2", NULL}, + {TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix1", NULL}, + {TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix2", NULL}, + {TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AnalogBalance", NULL}, + {TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotNeutral", NULL}, + {TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AsShotWhiteXY", NULL}, + {TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineExposure", NULL}, + {TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineNoise", NULL}, + {TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineSharpness", NULL}, + {TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BayerGreenSplit", NULL}, + {TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LinearResponseLimit", NULL}, + {TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL}, + {TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensInfo", NULL}, + {TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ChromaBlurRadius", NULL}, + {TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AntiAliasStrength", NULL}, + {TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShadowScale", NULL}, + {TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DNGPrivateData", NULL}, + {TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MakerNoteSafety", NULL}, + {TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant1", NULL}, + {TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant2", NULL}, + {TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawDataUniqueID", NULL}, + {TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL}, + {TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileData", NULL}, + {TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ActiveArea", NULL}, + {TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MaskedAreas", NULL}, + {TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotICCProfile", NULL}, + {TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotPreProfileMatrix", NULL}, + {TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentICCProfile", NULL}, + {TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentPreProfileMatrix", NULL}, + {TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL}, +#if 0 + /* TODO: revert above #if 0 for TIFF 4.6.0 */ + + /* begin DNG 1.2.0.0 tags */ + {TIFFTAG_COLORIMETRICREFERENCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorimetricReference", NULL}, + {TIFFTAG_CAMERACALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibrationSignature", NULL}, + {TIFFTAG_PROFILECALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileCalibrationSignature", NULL}, + {TIFFTAG_EXTRACAMERAPROFILES, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ExtraCameraProfiles", NULL}, + {TIFFTAG_ASSHOTPROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotProfileName", NULL}, + {TIFFTAG_NOISEREDUCTIONAPPLIED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NoiseReductionApplied", NULL}, + {TIFFTAG_PROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileName", NULL}, + {TIFFTAG_PROFILEHUESATMAPDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapDims", NULL}, + {TIFFTAG_PROFILEHUESATMAPDATA1, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData1", NULL}, + {TIFFTAG_PROFILEHUESATMAPDATA2, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData2", NULL}, + {TIFFTAG_PROFILETONECURVE, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileToneCurve", NULL}, + {TIFFTAG_PROFILEEMBEDPOLICY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileEmbedPolicy", NULL}, + {TIFFTAG_PROFILECOPYRIGHT, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileCopyright", NULL}, + {TIFFTAG_FORWARDMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix1", NULL}, + {TIFFTAG_FORWARDMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix2", NULL}, + {TIFFTAG_PREVIEWAPPLICATIONNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewApplicationName", NULL}, + {TIFFTAG_PREVIEWAPPLICATIONVERSION, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewApplicationVersion", NULL}, + {TIFFTAG_PREVIEWSETTINGSNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewSettingsName", NULL}, + {TIFFTAG_PREVIEWSETTINGSDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewSettingsDigest", NULL}, + {TIFFTAG_PREVIEWCOLORSPACE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewColorSpace", NULL}, + {TIFFTAG_PREVIEWDATETIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewDateTime", NULL}, + {TIFFTAG_RAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawImageDigest", NULL}, + {TIFFTAG_ORIGINALRAWFILEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalRawFileDigest", NULL}, + {TIFFTAG_SUBTILEBLOCKSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubTileBlockSize", NULL}, + {TIFFTAG_ROWINTERLEAVEFACTOR, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RowInterleaveFactor", NULL}, + {TIFFTAG_PROFILELOOKTABLEDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileLookTableDims", NULL}, + {TIFFTAG_PROFILELOOKTABLEDATA, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileLookTableData", NULL}, + /* begin DNG 1.3.0.0 tags */ + {TIFFTAG_OPCODELIST1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList1", NULL}, + {TIFFTAG_OPCODELIST2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList2", NULL}, + {TIFFTAG_OPCODELIST3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList3", NULL}, + {TIFFTAG_NOISEPROFILE, -1, -1, TIFF_DOUBLE, 0, TIFF_SETGET_C16_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "NoiseProfile", NULL}, + /* begin DNG 1.4.0.0 tags */ + {TIFFTAG_DEFAULTUSERCROP, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultUserCrop", NULL}, + {TIFFTAG_DEFAULTBLACKRENDER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultBlackRender", NULL}, + {TIFFTAG_BASELINEEXPOSUREOFFSET, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineExposureOffset", NULL}, + {TIFFTAG_PROFILELOOKTABLEENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileLookTableEncoding", NULL}, + {TIFFTAG_PROFILEHUESATMAPENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapEncoding", NULL}, + {TIFFTAG_ORIGINALDEFAULTFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalDefaultFinalSize", NULL}, + {TIFFTAG_ORIGINALBESTQUALITYFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalBestQualityFinalSize", NULL}, + {TIFFTAG_ORIGINALDEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalDefaultCropSize", NULL}, /* could also be rational */ + {TIFFTAG_NEWRAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NewRawImageDigest", NULL}, + {TIFFTAG_RAWTOPREVIEWGAIN, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawToPreviewGain", NULL}, + /* begin DNG 1.5.0.0 tags */ + {TIFFTAG_DEPTHFORMAT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthFormat", NULL}, + {TIFFTAG_DEPTHNEAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthNear", NULL}, + {TIFFTAG_DEPTHFAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthFar", NULL}, + {TIFFTAG_DEPTHUNITS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthUnits", NULL}, + {TIFFTAG_DEPTHMEASURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthMeasureType", NULL}, + {TIFFTAG_ENHANCEPARAMS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EnhanceParams", NULL}, + /* begin DNG 1.6.0.0 tags */ + {TIFFTAG_PROFILEGAINTABLEMAP, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileGainTableMap", NULL}, + {TIFFTAG_SEMANTICNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SemanticName", NULL}, + {TIFFTAG_SEMANTICINSTANCEID, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SemanticInstanceID", NULL}, + {TIFFTAG_MASKSUBAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaskSubArea", NULL}, + {TIFFTAG_RGBTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "RGBTables", NULL}, + {TIFFTAG_CALIBRATIONILLUMINANT3, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant3", NULL}, + {TIFFTAG_COLORMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix3", NULL}, + {TIFFTAG_CAMERACALIBRATION3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration3", NULL}, + {TIFFTAG_REDUCTIONMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix3", NULL}, + {TIFFTAG_PROFILEHUESATMAPDATA3, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData3", NULL}, + {TIFFTAG_FORWARDMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix3", NULL}, + {TIFFTAG_ILLUMINANTDATA1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData1", NULL}, + {TIFFTAG_ILLUMINANTDATA2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData2", NULL}, + {TIFFTAG_ILLUMINANTDATA3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData3", NULL}, + /* end DNG tags */ + /* begin TIFF/EP tags */ + {TIFFTAG_EP_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CFARepeatPatternDim", NULL}, + {TIFFTAG_EP_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP CFAPattern", NULL}, + /* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII. + * LibTiff defines it as ASCII and converts RATIONAL to an ASCII string. */ + {TIFFTAG_EP_BATTERYLEVEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP BatteryLevel", NULL}, + {TIFFTAG_EP_INTERLACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP Interlace", NULL}, + /* TIFFTAG_EP_IPTC_NAA and TIFFTAG_RICHTIFFIPTC share the same tag number (33723) + * LibTIFF type is UNDEFINED or BYTE, but often times incorrectly specified as LONG, because TIFF/EP (ISO/DIS 12234-2) specifies type LONG or ASCII. */ + {TIFFTAG_EP_TIMEZONEOFFSET, -1, -1, TIFF_SSHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP TimeZoneOffset", NULL}, + {TIFFTAG_EP_SELFTIMERMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SelfTimerMode", NULL}, + {TIFFTAG_EP_FLASHENERGY, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FlashEnergy", NULL}, + {TIFFTAG_EP_SPATIALFREQUENCYRESPONSE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SpatialFrequencyResponse", NULL}, + {TIFFTAG_EP_NOISE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP Noise", NULL}, + {TIFFTAG_EP_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneXResolution", NULL}, + {TIFFTAG_EP_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneYResolution", NULL}, + {TIFFTAG_EP_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneResolutionUnit", NULL}, + {TIFFTAG_EP_IMAGENUMBER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ImageNumber", NULL}, /* or SHORT */ + {TIFFTAG_EP_SECURITYCLASSIFICATION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SecurityClassification", NULL}, + {TIFFTAG_EP_IMAGEHISTORY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ImageHistory", NULL}, + {TIFFTAG_EP_EXPOSUREINDEX, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureIndex", NULL}, + {TIFFTAG_EP_STANDARDID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP StandardId", NULL}, + {TIFFTAG_EP_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SensingMethod", NULL}, + /* TIFF/EP tags equivalent to EXIF tags, sometimes defined differently. */ + {TIFFTAG_EP_EXPOSURETIME, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureTime", NULL}, /*N=1 or 2 */ + {TIFFTAG_EP_FNUMBER, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FNumber", NULL}, + {TIFFTAG_EP_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ExposureProgram", NULL}, + {TIFFTAG_EP_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SpectralSensitivity", NULL}, + {TIFFTAG_EP_ISOSPEEDRATINGS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ISOSpeedRatings", NULL}, + {TIFFTAG_EP_OECF, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP OptoelectricConversionFactor", NULL}, + {TIFFTAG_EP_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP DateTimeOriginal", NULL}, + {TIFFTAG_EP_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CompressedBitsPerPixel", NULL}, + {TIFFTAG_EP_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ShutterSpeedValue", NULL}, + {TIFFTAG_EP_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ApertureValue", NULL}, + {TIFFTAG_EP_BRIGHTNESSVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP BrightnessValue", NULL}, + {TIFFTAG_EP_EXPOSUREBIASVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureBiasValue", NULL}, /*N=1 or 2 */ + {TIFFTAG_EP_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP MaxApertureValue", NULL}, + {TIFFTAG_EP_SUBJECTDISTANCE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SubjectDistance", NULL}, + {TIFFTAG_EP_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP MeteringMode", NULL}, + {TIFFTAG_EP_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP LightSource", NULL}, + {TIFFTAG_EP_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP Flash", NULL}, + {TIFFTAG_EP_FOCALLENGTH, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FocalLength", NULL}, + {TIFFTAG_EP_SUBJECTLOCATION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SubjectLocation", NULL}, + /* end TIFF/EP tags */ +#endif + /* begin TIFF/FX tags */ + {TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Indexed", NULL}, + {TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GlobalParametersIFD", NULL}, + {TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileType", NULL}, + {TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FaxProfile", NULL}, + {TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CodingMethods", NULL}, + {TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "VersionYear", NULL}, + {TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ModeNumber", NULL}, + {TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Decode", NULL}, + {TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ImageBaseColor", NULL}, + {TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "T82Options", NULL}, + {TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "StripRowCounts", NULL}, + {TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageLayer", NULL}, + /* end TIFF/FX tags */ + /* begin pseudo tags */ }; /* * EXIF tags (Version 2.31, July 2016 plus version 2.32 May 2019) */ -static const TIFFField -exifFields[] = { - { EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL }, - { EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL }, - { EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL }, - { EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL }, - { EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL }, - { EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL }, - { EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL }, - { EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", NULL }, - { EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", NULL }, - { EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL }, - { EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL }, - { EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL }, - { EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL }, - { EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL }, - { EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL }, - { EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL }, - { EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL }, - { EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL }, - { EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL }, - { EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL }, - { EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL }, - { EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL }, - { EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL }, - { EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL }, - { EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL }, - /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance! - * However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values, - * which are not treated within LibTiff!! */ - { EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL }, - { EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL }, - { EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL }, - { EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL }, - { EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL }, - { EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL }, - { EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL }, - { EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL }, - { EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL }, - { EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL }, - { EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL }, - { EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Temperature", NULL }, - { EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Humidity", NULL }, - { EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Pressure", NULL }, - { EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL }, - { EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Acceleration", NULL }, - { EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL }, - { EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL }, - { EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL }, - { EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL }, - { EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL }, - { EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL }, - { EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL }, - { EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL }, - { EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL }, - { EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL }, - { EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL }, - { EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL }, - { EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL }, - { EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL }, - { EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL }, - { EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL }, - { EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL }, - { EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL }, - { EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL }, - { EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL }, - { EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL }, - { EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL }, - { EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL }, - { EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL }, - { EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL }, - { EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL }, - { EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL }, - { EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL }, - { EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL }, - { EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL }, - { EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL }, - { EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL }, - { EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL }, - { EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensMake", NULL }, - { EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensModel", NULL }, - { EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL }, - { EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Gamma", NULL }, - { EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL }, - { EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SourceImageNumberOfCompositeImage", NULL }, - { EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SourceExposureTimesOfCompositeImage", NULL } -}; +static const TIFFField exifFields[] = { + {EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL}, + {EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL}, + {EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL}, + {EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL}, + /* After EXIF 2.2.1 ISOSpeedRatings is named PhotographicSensitivity. In addition, while "Count=Any", only 1 count should be used. */ + {EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL}, + {EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL}, + {EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL}, + {EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", NULL}, + {EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", NULL}, + {EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL}, + {EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL}, + {EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL}, + {EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL}, + {EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL}, + {EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL}, + {EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL}, + {EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL}, + {EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL}, + {EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL}, + {EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL}, + {EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL}, + {EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL}, + {EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL}, + {EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL}, + {EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL}, + /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance! + * However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values, + * which are not treated within LibTiff!! */ + {EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL}, + {EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL}, + {EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL}, + {EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL}, + {EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL}, + {EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL}, + {EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL}, + {EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL}, + {EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL}, + {EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL}, + {EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL}, + {EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Temperature", NULL}, + {EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Humidity", NULL}, + {EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Pressure", NULL}, + {EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL}, + {EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Acceleration", NULL}, + {EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL}, + {EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL}, + {EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL}, + {EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL}, + {EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL}, + {EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL}, + {EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL}, + {EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL}, + {EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL}, + {EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL}, + {EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL}, + {EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL}, + {EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL}, + {EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL}, + {EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL}, + {EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL}, + {EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL}, + {EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL}, + {EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL}, + {EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL}, + {EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL}, + {EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL}, + {EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL}, + {EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL}, + {EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL}, + {EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL}, + {EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL}, + {EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL}, + {EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL}, + {EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL}, + {EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL}, + {EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL}, + {EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL}, + {EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensMake", NULL}, + {EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensModel", NULL}, + {EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL}, + {EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Gamma", NULL}, + {EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL}, + {EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SourceImageNumberOfCompositeImage", NULL}, + {EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, + "SourceExposureTimesOfCompositeImage", NULL}}; /* - * EXIF-GPS tags (Version 2.31, July 2016; nothing changed for version 2.32 May 2019) + * EXIF-GPS tags (Version 2.31, July 2016; nothing changed for version 2.32 May + * 2019) */ -static TIFFField -gpsFields[] = { - /* For the GPS tag definitions in gpsFields[] the standard definition for Rationals is TIFF_SETGET_DOUBLE and TIFF_SETGET_C0_FLOAT. - *-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values can now be written and also read in double precision! - * In order to achieve double precision for GPS tags: - * Standard definitions for GPSTAG is kept to TIFF_SETGET_DOUBLE - * and TIFF_SETGET_C0_FLOAT is changed to TIFF_SETGET_C0_DOUBLE. - */ - { GPSTAG_VERSIONID , 4, 4, TIFF_BYTE , 0, TIFF_SETGET_C0_UINT8 , TIFF_SETGET_UINT8 , FIELD_CUSTOM , 1, 0, "VersionID", NULL }, - { GPSTAG_LATITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "LatitudeRef", NULL }, - { GPSTAG_LATITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Latitude", NULL }, - { GPSTAG_LONGITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "LongitudeRef", NULL }, - { GPSTAG_LONGITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Longitude", NULL }, - { GPSTAG_ALTITUDEREF , 1, 1, TIFF_BYTE , 0, TIFF_SETGET_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "AltitudeRef", NULL }, - { GPSTAG_ALTITUDE , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Altitude", NULL }, - { GPSTAG_TIMESTAMP , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "TimeStamp", NULL }, - { GPSTAG_SATELLITES , -1, -1, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Satellites", NULL }, - { GPSTAG_STATUS , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Status", NULL }, - { GPSTAG_MEASUREMODE , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "MeasureMode", NULL }, - { GPSTAG_DOP , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DOP", NULL }, - { GPSTAG_SPEEDREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "SpeedRef", NULL }, - { GPSTAG_SPEED , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Speed", NULL }, - { GPSTAG_TRACKREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "TrackRef", NULL }, - { GPSTAG_TRACK , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Track", NULL }, - { GPSTAG_IMGDIRECTIONREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "ImgDirectionRef", NULL }, - { GPSTAG_IMGDIRECTION , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "ImgDirection", NULL }, - { GPSTAG_MAPDATUM , -1, -1, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "MapDatum", NULL }, - { GPSTAG_DESTLATITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLatitudeRef", NULL }, - { GPSTAG_DESTLATITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLatitude", NULL }, - { GPSTAG_DESTLONGITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLongitudeRef", NULL }, - { GPSTAG_DESTLONGITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLongitude", NULL }, - { GPSTAG_DESTBEARINGREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestBearingRef", NULL }, - { GPSTAG_DESTBEARING , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestBearing", NULL }, - { GPSTAG_DESTDISTANCEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestDistanceRef", NULL }, - { GPSTAG_DESTDISTANCE , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestDistance", NULL }, - { GPSTAG_PROCESSINGMETHOD , -1, -1, TIFF_UNDEFINED , 0, TIFF_SETGET_C16_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 1, "ProcessingMethod", NULL }, - { GPSTAG_AREAINFORMATION , -1, -1, TIFF_UNDEFINED , 0, TIFF_SETGET_C16_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 1, "AreaInformation", NULL }, - { GPSTAG_DATESTAMP , 11, 11, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DateStamp", NULL }, - { GPSTAG_DIFFERENTIAL , 1, 1, TIFF_SHORT , 0, TIFF_SETGET_UINT16 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Differential", NULL }, - { GPSTAG_GPSHPOSITIONINGERROR , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "HorizontalPositioningError", NULL } -}; +static const TIFFField gpsFields[] = { + /* For the GPS tag definitions in gpsFields[] the standard definition for Rationals is TIFF_SETGET_DOUBLE and TIFF_SETGET_C0_FLOAT. + *-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values can now be written and also read in double precision! + * In order to achieve double precision for GPS tags: Standard definitions for GPSTAG is kept to TIFF_SETGET_DOUBLE + * and TIFF_SETGET_C0_FLOAT is changed to TIFF_SETGET_C0_DOUBLE. + */ + {GPSTAG_VERSIONID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "VersionID", NULL}, + {GPSTAG_LATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LatitudeRef", NULL}, + {GPSTAG_LATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Latitude", NULL}, + {GPSTAG_LONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LongitudeRef", NULL}, + {GPSTAG_LONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Longitude", NULL}, + {GPSTAG_ALTITUDEREF, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AltitudeRef", NULL}, + {GPSTAG_ALTITUDE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Altitude", NULL}, + {GPSTAG_TIMESTAMP, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TimeStamp", NULL}, + {GPSTAG_SATELLITES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Satellites", NULL}, + {GPSTAG_STATUS, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Status", NULL}, + {GPSTAG_MEASUREMODE, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeasureMode", NULL}, + {GPSTAG_DOP, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DOP", NULL}, + {GPSTAG_SPEEDREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpeedRef", NULL}, + {GPSTAG_SPEED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Speed", NULL}, + {GPSTAG_TRACKREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TrackRef", NULL}, + {GPSTAG_TRACK, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Track", NULL}, + {GPSTAG_IMGDIRECTIONREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirectionRef", NULL}, + {GPSTAG_IMGDIRECTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirection", NULL}, + {GPSTAG_MAPDATUM, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MapDatum", NULL}, + {GPSTAG_DESTLATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitudeRef", NULL}, + {GPSTAG_DESTLATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitude", NULL}, + {GPSTAG_DESTLONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitudeRef", NULL}, + {GPSTAG_DESTLONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitude", NULL}, + {GPSTAG_DESTBEARINGREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearingRef", NULL}, + {GPSTAG_DESTBEARING, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearing", NULL}, + {GPSTAG_DESTDISTANCEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistanceRef", NULL}, + {GPSTAG_DESTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistance", NULL}, + {GPSTAG_PROCESSINGMETHOD, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProcessingMethod", NULL}, + {GPSTAG_AREAINFORMATION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AreaInformation", NULL}, + {GPSTAG_DATESTAMP, 11, 11, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateStamp", NULL}, + {GPSTAG_DIFFERENTIAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Differential", NULL}, + {GPSTAG_GPSHPOSITIONINGERROR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HorizontalPositioningError", NULL}}; +/* clang-format on */ /* was off for better readability of tag comments */ -static const TIFFFieldArray -tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField*) tiffFields }; -static const TIFFFieldArray -exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField*) exifFields }; -static const TIFFFieldArray -gpsFieldArray = { tfiatGps, 0, TIFFArrayCount(gpsFields), (TIFFField*) gpsFields }; +static const TIFFFieldArray tiffFieldArray = { + tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField *)tiffFields}; +static const TIFFFieldArray exifFieldArray = { + tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField *)exifFields}; +static const TIFFFieldArray gpsFieldArray = { + tfiatGps, 0, TIFFArrayCount(gpsFields), (TIFFField *)gpsFields}; /* * We have our own local lfind() equivalent to avoid subtle differences - * in types passed to lfind() on different systems. + * in types passed to lfind() on different systems. */ -static void * -td_lfind(const void *key, const void *base, size_t *nmemb, size_t size, - int(*compar)(const void *, const void *)) +static void *td_lfind(const void *key, const void *base, size_t *nmemb, + size_t size, int (*compar)(const void *, const void *)) { char *element, *end; end = (char *)base + *nmemb * size; for (element = (char *)base; element < end; element += size) - if (!compar(key, element)) /* key found */ + if (!compar(key, element)) /* key found */ return element; return NULL; } -const TIFFFieldArray* -_TIFFGetFields(void) +const TIFFFieldArray *_TIFFGetFields(void) { return (&tiffFieldArray); } + +const TIFFFieldArray *_TIFFGetExifFields(void) { return (&exifFieldArray); } + +const TIFFFieldArray *_TIFFGetGpsFields(void) { return (&gpsFieldArray); } + +void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *fieldarray) { - return(&tiffFieldArray); -} + if (tif->tif_fields && tif->tif_nfields > 0) + { + uint32_t i; -const TIFFFieldArray* -_TIFFGetExifFields(void) -{ - return(&exifFieldArray); -} - -const TIFFFieldArray* -_TIFFGetGpsFields(void) -{ - return(&gpsFieldArray); -} - -void -_TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray) -{ - if (tif->tif_fields && tif->tif_nfields > 0) { - uint32 i; - - for (i = 0; i < tif->tif_nfields; i++) { - TIFFField *fld = tif->tif_fields[i]; - if (fld->field_bit == FIELD_CUSTOM && - strncmp("Tag ", fld->field_name, 4) == 0) { - _TIFFfree(fld->field_name); - _TIFFfree(fld); - } - } - - _TIFFfree(tif->tif_fields); - tif->tif_fields = NULL; - tif->tif_nfields = 0; - } - if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) { - TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFields", - "Setting up field info failed"); - } -} - -static int -tagCompare(const void* a, const void* b) -{ - const TIFFField* ta = *(const TIFFField**) a; - const TIFFField* tb = *(const TIFFField**) b; - /* NB: be careful of return values for 16-bit platforms */ - if (ta->field_tag != tb->field_tag) - return (int)ta->field_tag - (int)tb->field_tag; - else - return (ta->field_type == TIFF_ANY) ? - 0 : ((int)tb->field_type - (int)ta->field_type); -} - -static int -tagNameCompare(const void* a, const void* b) -{ - const TIFFField* ta = *(const TIFFField**) a; - const TIFFField* tb = *(const TIFFField**) b; - int ret = strcmp(ta->field_name, tb->field_name); - - if (ret) - return ret; - else - return (ta->field_type == TIFF_ANY) ? - 0 : ((int)tb->field_type - (int)ta->field_type); -} - -int -_TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n) -{ - static const char module[] = "_TIFFMergeFields"; - static const char reason[] = "for fields array"; - /* TIFFField** tp; */ - uint32 i; - - tif->tif_foundfield = NULL; - - if (tif->tif_fields && tif->tif_nfields > 0) { - tif->tif_fields = (TIFFField**) - _TIFFCheckRealloc(tif, tif->tif_fields, - (tif->tif_nfields + n), - sizeof(TIFFField *), reason); - } else { - tif->tif_fields = (TIFFField **) - _TIFFCheckMalloc(tif, n, sizeof(TIFFField *), - reason); - } - if (!tif->tif_fields) { - TIFFErrorExt(tif->tif_clientdata, module, - "Failed to allocate fields array"); - return 0; - } - - /* tp = tif->tif_fields + tif->tif_nfields; */ - for (i = 0; i < n; i++) { - const TIFFField *fip = - TIFFFindField(tif, info[i].field_tag, TIFF_ANY); - - /* only add definitions that aren't already present */ - if (!fip) { - tif->tif_fields[tif->tif_nfields] = (TIFFField *) (info+i); - tif->tif_nfields++; + for (i = 0; i < tif->tif_nfields; i++) + { + TIFFField *fld = tif->tif_fields[i]; + if (fld->field_name != NULL) + { + if (fld->field_bit == FIELD_CUSTOM && TIFFFieldIsAnonymous(fld)) + { + _TIFFfreeExt(tif, fld->field_name); + /* caution: tif_fields[i] must not be the beginning of a + * fields-array. Otherwise the following tags are also freed + * with the first free(). + */ + _TIFFfreeExt(tif, fld); } - } + } + } - /* Sort the field info by tag number */ - qsort(tif->tif_fields, tif->tif_nfields, - sizeof(TIFFField *), tagCompare); - - return n; + _TIFFfreeExt(tif, tif->tif_fields); + tif->tif_fields = NULL; + tif->tif_nfields = 0; + } + if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) + { + TIFFErrorExtR(tif, "_TIFFSetupFields", "Setting up field info failed"); + } } -void -_TIFFPrintFieldInfo(TIFF* tif, FILE* fd) +static int tagCompare(const void *a, const void *b) { - uint32 i; + const TIFFField *ta = *(const TIFFField **)a; + const TIFFField *tb = *(const TIFFField **)b; + /* NB: be careful of return values for 16-bit platforms */ + if (ta->field_tag != tb->field_tag) + return (int)ta->field_tag - (int)tb->field_tag; + else + return (ta->field_type == TIFF_ANY) + ? 0 + : ((int)tb->field_type - (int)ta->field_type); +} - fprintf(fd, "%s: \n", tif->tif_name); - for (i = 0; i < tif->tif_nfields; i++) { - const TIFFField* fip = tif->tif_fields[i]; - fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n" - , (int)i - , (unsigned long) fip->field_tag - , fip->field_readcount, fip->field_writecount - , fip->field_type - , fip->field_bit - , fip->field_oktochange ? "TRUE" : "FALSE" - , fip->field_passcount ? "TRUE" : "FALSE" - , fip->field_name - ); - } +static int tagNameCompare(const void *a, const void *b) +{ + const TIFFField *ta = *(const TIFFField **)a; + const TIFFField *tb = *(const TIFFField **)b; + int ret = strcmp(ta->field_name, tb->field_name); + + if (ret) + return ret; + else + return (ta->field_type == TIFF_ANY) + ? 0 + : ((int)tb->field_type - (int)ta->field_type); +} + +int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n) +{ + static const char module[] = "_TIFFMergeFields"; + static const char reason[] = "for fields array"; + /* TIFFField** tp; */ + uint32_t i; + + tif->tif_foundfield = NULL; + + if (tif->tif_fields && tif->tif_nfields > 0) + { + tif->tif_fields = (TIFFField **)_TIFFCheckRealloc( + tif, tif->tif_fields, (tif->tif_nfields + n), sizeof(TIFFField *), + reason); + } + else + { + tif->tif_fields = + (TIFFField **)_TIFFCheckMalloc(tif, n, sizeof(TIFFField *), reason); + } + if (!tif->tif_fields) + { + TIFFErrorExtR(tif, module, "Failed to allocate fields array"); + return 0; + } + + /* tp = tif->tif_fields + tif->tif_nfields; */ + for (i = 0; i < n; i++) + { + const TIFFField *fip = TIFFFindField(tif, info[i].field_tag, TIFF_ANY); + + /* only add definitions that aren't already present */ + if (!fip) + { + tif->tif_fields[tif->tif_nfields] = (TIFFField *)(info + i); + tif->tif_nfields++; + } + } + + /* Sort the field info by tag number */ + qsort(tif->tif_fields, tif->tif_nfields, sizeof(TIFFField *), tagCompare); + + return n; +} + +void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd) +{ + uint32_t i; + + fprintf(fd, "%s: \n", tif->tif_name); + for (i = 0; i < tif->tif_nfields; i++) + { + const TIFFField *fip = tif->tif_fields[i]; + fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n", + (int)i, (unsigned long)fip->field_tag, fip->field_readcount, + fip->field_writecount, fip->field_type, fip->field_bit, + fip->field_oktochange ? "TRUE" : "FALSE", + fip->field_passcount ? "TRUE" : "FALSE", fip->field_name); + } } /* - * Return size of TIFFDataType in bytes + * Return size of TIFFDataType within TIFF-file in bytes */ -int -TIFFDataWidth(TIFFDataType type) +int TIFFDataWidth(TIFFDataType type) { - switch(type) - { - case 0: /* nothing */ - case TIFF_BYTE: - case TIFF_ASCII: - case TIFF_SBYTE: - case TIFF_UNDEFINED: - return 1; - case TIFF_SHORT: - case TIFF_SSHORT: - return 2; - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_FLOAT: - case TIFF_IFD: - return 4; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_DOUBLE: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_IFD8: - return 8; - default: - return 0; /* will return 0 for unknown types */ - } + switch (type) + { + case 0: /* nothing */ + case TIFF_BYTE: + case TIFF_ASCII: + case TIFF_SBYTE: + case TIFF_UNDEFINED: + return 1; + case TIFF_SHORT: + case TIFF_SSHORT: + return 2; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + case TIFF_IFD: + return 4; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_DOUBLE: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_IFD8: + return 8; + default: + return 0; /* will return 0 for unknown types */ + } } /* - * Return size of TIFFDataType in bytes. - * - * XXX: We need a separate function to determine the space needed - * to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8, - * but we use 4-byte float to represent rationals. + * Return internal storage size of TIFFSetGetFieldType in bytes. + * TIFFSetField() and TIFFGetField() have to provide the parameter accordingly. + * Replaces internal functions _TIFFDataSize() and _TIFFSetGetFieldSize() + * with now extern available function TIFFFieldSetGetSize(). */ -int -_TIFFDataSize(TIFFDataType type) +int TIFFFieldSetGetSize(const TIFFField *fip) { - switch (type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_ASCII: - case TIFF_UNDEFINED: - return 1; - case TIFF_SHORT: - case TIFF_SSHORT: - return 2; - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_FLOAT: - case TIFF_IFD: - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - return 4; - case TIFF_DOUBLE: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_IFD8: - return 8; - default: - return 0; - } -} + /* + * TIFFSetField() and TIFFGetField() must provide the parameter accordingly + * to the definition of "set_field_type" of the tag definition in + * dir_info.c. This function returns the data size for that purpose. + * + * Furthermore, this data size is also used for the internal storage, + * even for TIFF_RATIONAL values for FIELD_CUSTOM, which are stored + * internally as 4-byte float, but some of them should be stored internally + * as 8-byte double, depending on the "set_field_type" _FLOAT_ or _DOUBLE_. + */ + if (fip == NULL) + return 0; + + switch (fip->set_field_type) + { + case TIFF_SETGET_UNDEFINED: + case TIFF_SETGET_ASCII: + case TIFF_SETGET_C0_ASCII: + case TIFF_SETGET_C16_ASCII: + case TIFF_SETGET_C32_ASCII: + case TIFF_SETGET_OTHER: + return 1; + case TIFF_SETGET_UINT8: + case TIFF_SETGET_SINT8: + case TIFF_SETGET_C0_UINT8: + case TIFF_SETGET_C0_SINT8: + case TIFF_SETGET_C16_UINT8: + case TIFF_SETGET_C16_SINT8: + case TIFF_SETGET_C32_UINT8: + case TIFF_SETGET_C32_SINT8: + return 1; + case TIFF_SETGET_UINT16: + case TIFF_SETGET_SINT16: + case TIFF_SETGET_C0_UINT16: + case TIFF_SETGET_C0_SINT16: + case TIFF_SETGET_C16_UINT16: + case TIFF_SETGET_C16_SINT16: + case TIFF_SETGET_C32_UINT16: + case TIFF_SETGET_C32_SINT16: + return 2; + case TIFF_SETGET_INT: + case TIFF_SETGET_UINT32: + case TIFF_SETGET_SINT32: + case TIFF_SETGET_FLOAT: + case TIFF_SETGET_UINT16_PAIR: + case TIFF_SETGET_C0_UINT32: + case TIFF_SETGET_C0_SINT32: + case TIFF_SETGET_C0_FLOAT: + case TIFF_SETGET_C16_UINT32: + case TIFF_SETGET_C16_SINT32: + case TIFF_SETGET_C16_FLOAT: + case TIFF_SETGET_C32_UINT32: + case TIFF_SETGET_C32_SINT32: + case TIFF_SETGET_C32_FLOAT: + return 4; + case TIFF_SETGET_UINT64: + case TIFF_SETGET_SINT64: + case TIFF_SETGET_DOUBLE: + case TIFF_SETGET_IFD8: + case TIFF_SETGET_C0_UINT64: + case TIFF_SETGET_C0_SINT64: + case TIFF_SETGET_C0_DOUBLE: + case TIFF_SETGET_C0_IFD8: + case TIFF_SETGET_C16_UINT64: + case TIFF_SETGET_C16_SINT64: + case TIFF_SETGET_C16_DOUBLE: + case TIFF_SETGET_C16_IFD8: + case TIFF_SETGET_C32_UINT64: + case TIFF_SETGET_C32_SINT64: + case TIFF_SETGET_C32_DOUBLE: + case TIFF_SETGET_C32_IFD8: + return 8; + default: + return 0; + } +} /*-- TIFFFieldSetGetSize() --- */ /* - * Rational2Double: - * Return size of TIFFSetGetFieldType in bytes. - * - * XXX: TIFF_RATIONAL values for FIELD_CUSTOM are stored internally as 4-byte float. - * However, some of them should be stored internally as 8-byte double. - * This is now managed by the SetGetField of the tag-definition! + * Return size of count parameter of TIFFSetField() and TIFFGetField() + * and also if it is required: 0=none, 2=uint16_t, 4=uint32_t */ -int -_TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype) +int TIFFFieldSetGetCountSize(const TIFFField *fip) { - switch (setgettype) - { - case TIFF_SETGET_UNDEFINED: - case TIFF_SETGET_ASCII: - case TIFF_SETGET_C0_ASCII: - case TIFF_SETGET_C16_ASCII: - case TIFF_SETGET_C32_ASCII: - case TIFF_SETGET_OTHER: - return 0; - case TIFF_SETGET_UINT8: - case TIFF_SETGET_SINT8: - case TIFF_SETGET_C0_UINT8: - case TIFF_SETGET_C0_SINT8: - case TIFF_SETGET_C16_UINT8: - case TIFF_SETGET_C16_SINT8: - case TIFF_SETGET_C32_UINT8: - case TIFF_SETGET_C32_SINT8: - return 1; - case TIFF_SETGET_UINT16: - case TIFF_SETGET_SINT16: - case TIFF_SETGET_C0_UINT16: - case TIFF_SETGET_C0_SINT16: - case TIFF_SETGET_C16_UINT16: - case TIFF_SETGET_C16_SINT16: - case TIFF_SETGET_C32_UINT16: - case TIFF_SETGET_C32_SINT16: - return 2; - case TIFF_SETGET_INT: - case TIFF_SETGET_UINT32: - case TIFF_SETGET_SINT32: - case TIFF_SETGET_FLOAT: - case TIFF_SETGET_UINT16_PAIR: - case TIFF_SETGET_C0_UINT32: - case TIFF_SETGET_C0_SINT32: - case TIFF_SETGET_C0_FLOAT: - case TIFF_SETGET_C16_UINT32: - case TIFF_SETGET_C16_SINT32: - case TIFF_SETGET_C16_FLOAT: - case TIFF_SETGET_C32_UINT32: - case TIFF_SETGET_C32_SINT32: - case TIFF_SETGET_C32_FLOAT: - return 4; - case TIFF_SETGET_UINT64: - case TIFF_SETGET_SINT64: - case TIFF_SETGET_DOUBLE: - case TIFF_SETGET_IFD8: - case TIFF_SETGET_C0_UINT64: - case TIFF_SETGET_C0_SINT64: - case TIFF_SETGET_C0_DOUBLE: - case TIFF_SETGET_C0_IFD8: - case TIFF_SETGET_C16_UINT64: - case TIFF_SETGET_C16_SINT64: - case TIFF_SETGET_C16_DOUBLE: - case TIFF_SETGET_C16_IFD8: - case TIFF_SETGET_C32_UINT64: - case TIFF_SETGET_C32_SINT64: - case TIFF_SETGET_C32_DOUBLE: - case TIFF_SETGET_C32_IFD8: - return 8; - default: - return 0; - } -} /*-- _TIFFSetGetFieldSize --- */ + if (fip == NULL) + return 0; + switch (fip->set_field_type) + { + case TIFF_SETGET_C16_ASCII: + case TIFF_SETGET_C16_UINT8: + case TIFF_SETGET_C16_SINT8: + case TIFF_SETGET_C16_UINT16: + case TIFF_SETGET_C16_SINT16: + case TIFF_SETGET_C16_UINT32: + case TIFF_SETGET_C16_SINT32: + case TIFF_SETGET_C16_FLOAT: + case TIFF_SETGET_C16_UINT64: + case TIFF_SETGET_C16_SINT64: + case TIFF_SETGET_C16_DOUBLE: + case TIFF_SETGET_C16_IFD8: + return 2; + case TIFF_SETGET_C32_ASCII: + case TIFF_SETGET_C32_UINT8: + case TIFF_SETGET_C32_SINT8: + case TIFF_SETGET_C32_UINT16: + case TIFF_SETGET_C32_SINT16: + case TIFF_SETGET_C32_UINT32: + case TIFF_SETGET_C32_SINT32: + case TIFF_SETGET_C32_FLOAT: + case TIFF_SETGET_C32_UINT64: + case TIFF_SETGET_C32_SINT64: + case TIFF_SETGET_C32_DOUBLE: + case TIFF_SETGET_C32_IFD8: + return 4; + default: + return 0; + } +} /*-- TIFFFieldSetGetCountSize() --- */ -const TIFFField* -TIFFFindField(TIFF* tif, uint32 tag, TIFFDataType dt) +const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt) { - TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; - TIFFField* pkey = &key; - const TIFFField **ret; - if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag && - (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) - return tif->tif_foundfield; + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField *pkey = &key; + const TIFFField **ret; + if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag && + (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) + return tif->tif_foundfield; - /* If we are invoked with no field information, then just return. */ - if (!tif->tif_fields) - return NULL; + /* If we are invoked with no field information, then just return. */ + if (!tif->tif_fields) + return NULL; - /* NB: use sorted search (e.g. binary search) */ + /* NB: use sorted search (e.g. binary search) */ - key.field_tag = tag; - key.field_type = dt; + key.field_tag = tag; + key.field_type = dt; - ret = (const TIFFField **) bsearch(&pkey, tif->tif_fields, - tif->tif_nfields, - sizeof(TIFFField *), tagCompare); - return tif->tif_foundfield = (ret ? *ret : NULL); + ret = (const TIFFField **)bsearch(&pkey, tif->tif_fields, tif->tif_nfields, + sizeof(TIFFField *), tagCompare); + return tif->tif_foundfield = (ret ? *ret : NULL); } -static const TIFFField* -_TIFFFindFieldByName(TIFF* tif, const char *field_name, TIFFDataType dt) +static const TIFFField *_TIFFFindFieldByName(TIFF *tif, const char *field_name, + TIFFDataType dt) { - TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; - TIFFField* pkey = &key; - const TIFFField **ret; - if (tif->tif_foundfield - && streq(tif->tif_foundfield->field_name, field_name) - && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) - return (tif->tif_foundfield); + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField *pkey = &key; + const TIFFField **ret; + if (tif->tif_foundfield && + streq(tif->tif_foundfield->field_name, field_name) && + (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) + return (tif->tif_foundfield); - /* If we are invoked with no field information, then just return. */ - if (!tif->tif_fields) - return NULL; + /* If we are invoked with no field information, then just return. */ + if (!tif->tif_fields) + return NULL; - /* NB: use linear search since list is sorted by key#, not name */ + /* NB: use linear search since list is sorted by key#, not name */ - key.field_name = (char *)field_name; - key.field_type = dt; + key.field_name = (char *)field_name; + key.field_type = dt; - ret = (const TIFFField **) - td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields, - sizeof(TIFFField *), tagNameCompare); + ret = + (const TIFFField **)td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields, + sizeof(TIFFField *), tagNameCompare); - return tif->tif_foundfield = (ret ? *ret : NULL); + return tif->tif_foundfield = (ret ? *ret : NULL); } -const TIFFField* -TIFFFieldWithTag(TIFF* tif, uint32 tag) +const TIFFField *TIFFFieldWithTag(TIFF *tif, uint32_t tag) { - const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); - if (!fip) { - TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag", - "Internal error, unknown tag 0x%x", - (unsigned int) tag); - } - return (fip); + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + if (!fip) + { + TIFFWarningExtR(tif, "TIFFFieldWithTag", "Warning, unknown tag 0x%x", + (unsigned int)tag); + } + return (fip); } -const TIFFField* -TIFFFieldWithName(TIFF* tif, const char *field_name) +const TIFFField *TIFFFieldWithName(TIFF *tif, const char *field_name) { - const TIFFField* fip = - _TIFFFindFieldByName(tif, field_name, TIFF_ANY); - if (!fip) { - TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName", - "Internal error, unknown tag %s", field_name); - } - return (fip); + const TIFFField *fip = _TIFFFindFieldByName(tif, field_name, TIFF_ANY); + if (!fip) + { + TIFFWarningExtR(tif, "TIFFFieldWithName", "Warning, unknown tag %s", + field_name); + } + return (fip); } -uint32 -TIFFFieldTag(const TIFFField* fip) +uint32_t TIFFFieldTag(const TIFFField *fip) { return fip->field_tag; } + +const char *TIFFFieldName(const TIFFField *fip) { return fip->field_name; } + +TIFFDataType TIFFFieldDataType(const TIFFField *fip) { return fip->field_type; } + +int TIFFFieldPassCount(const TIFFField *fip) { return fip->field_passcount; } + +int TIFFFieldReadCount(const TIFFField *fip) { return fip->field_readcount; } + +int TIFFFieldWriteCount(const TIFFField *fip) { return fip->field_writecount; } + +int TIFFFieldIsAnonymous(const TIFFField *fip) { return fip->field_anonymous; } + +const TIFFField *_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, + TIFFDataType dt) + { - return fip->field_tag; + const TIFFField *fld; + + fld = TIFFFindField(tif, tag, dt); + if (fld == NULL) + { + fld = _TIFFCreateAnonField(tif, tag, dt); + if (!_TIFFMergeFields(tif, fld, 1)) + return NULL; + } + + return fld; } -const char * -TIFFFieldName(const TIFFField* fip) +TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag, + TIFFDataType field_type) { - return fip->field_name; -} + TIFFField *fld; + (void)tif; -TIFFDataType -TIFFFieldDataType(const TIFFField* fip) -{ - return fip->field_type; -} + fld = (TIFFField *)_TIFFmallocExt(tif, sizeof(TIFFField)); + if (fld == NULL) + return NULL; + _TIFFmemset(fld, 0, sizeof(TIFFField)); -int -TIFFFieldPassCount(const TIFFField* fip) -{ - return fip->field_passcount; -} + fld->field_tag = tag; + fld->field_readcount = TIFF_VARIABLE2; + fld->field_writecount = TIFF_VARIABLE2; + fld->field_type = field_type; + fld->field_anonymous = + 1; /* indicate that this is an anonymous / unknown tag */ + switch (field_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + fld->set_field_type = TIFF_SETGET_C32_UINT8; + fld->get_field_type = TIFF_SETGET_C32_UINT8; + break; + case TIFF_ASCII: + fld->set_field_type = TIFF_SETGET_C32_ASCII; + fld->get_field_type = TIFF_SETGET_C32_ASCII; + break; + case TIFF_SHORT: + fld->set_field_type = TIFF_SETGET_C32_UINT16; + fld->get_field_type = TIFF_SETGET_C32_UINT16; + break; + case TIFF_LONG: + fld->set_field_type = TIFF_SETGET_C32_UINT32; + fld->get_field_type = TIFF_SETGET_C32_UINT32; + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + fld->set_field_type = TIFF_SETGET_C32_FLOAT; + fld->get_field_type = TIFF_SETGET_C32_FLOAT; + break; + case TIFF_SBYTE: + fld->set_field_type = TIFF_SETGET_C32_SINT8; + fld->get_field_type = TIFF_SETGET_C32_SINT8; + break; + case TIFF_SSHORT: + fld->set_field_type = TIFF_SETGET_C32_SINT16; + fld->get_field_type = TIFF_SETGET_C32_SINT16; + break; + case TIFF_SLONG: + fld->set_field_type = TIFF_SETGET_C32_SINT32; + fld->get_field_type = TIFF_SETGET_C32_SINT32; + break; + case TIFF_DOUBLE: + fld->set_field_type = TIFF_SETGET_C32_DOUBLE; + fld->get_field_type = TIFF_SETGET_C32_DOUBLE; + break; + case TIFF_IFD: + case TIFF_IFD8: + fld->set_field_type = TIFF_SETGET_C32_IFD8; + fld->get_field_type = TIFF_SETGET_C32_IFD8; + break; + case TIFF_LONG8: + fld->set_field_type = TIFF_SETGET_C32_UINT64; + fld->get_field_type = TIFF_SETGET_C32_UINT64; + break; + case TIFF_SLONG8: + fld->set_field_type = TIFF_SETGET_C32_SINT64; + fld->get_field_type = TIFF_SETGET_C32_SINT64; + break; + default: + fld->set_field_type = TIFF_SETGET_UNDEFINED; + fld->get_field_type = TIFF_SETGET_UNDEFINED; + break; + } + fld->field_bit = FIELD_CUSTOM; + fld->field_oktochange = TRUE; + fld->field_passcount = TRUE; + fld->field_name = (char *)_TIFFmallocExt(tif, 32); + if (fld->field_name == NULL) + { + _TIFFfreeExt(tif, fld); + return NULL; + } + fld->field_subfields = NULL; -int -TIFFFieldReadCount(const TIFFField* fip) -{ - return fip->field_readcount; -} + /* + * note that this name is a special sign to TIFFClose() and + * _TIFFSetupFields() to free the field + * Update: + * This special sign is replaced by fld->field_anonymous flag. + */ + (void)snprintf(fld->field_name, 32, "Tag %d", (int)tag); -int -TIFFFieldWriteCount(const TIFFField* fip) -{ - return fip->field_writecount; -} - -const TIFFField* -_TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt) - -{ - const TIFFField *fld; - - fld = TIFFFindField(tif, tag, dt); - if (fld == NULL) { - fld = _TIFFCreateAnonField(tif, tag, dt); - if (!_TIFFMergeFields(tif, fld, 1)) - return NULL; - } - - return fld; -} - -TIFFField* -_TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type) -{ - TIFFField *fld; - (void) tif; - - fld = (TIFFField *) _TIFFmalloc(sizeof (TIFFField)); - if (fld == NULL) - return NULL; - _TIFFmemset(fld, 0, sizeof(TIFFField)); - - fld->field_tag = tag; - fld->field_readcount = TIFF_VARIABLE2; - fld->field_writecount = TIFF_VARIABLE2; - fld->field_type = field_type; - fld->reserved = 0; - switch (field_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - fld->set_field_type = TIFF_SETGET_C32_UINT8; - fld->get_field_type = TIFF_SETGET_C32_UINT8; - break; - case TIFF_ASCII: - fld->set_field_type = TIFF_SETGET_C32_ASCII; - fld->get_field_type = TIFF_SETGET_C32_ASCII; - break; - case TIFF_SHORT: - fld->set_field_type = TIFF_SETGET_C32_UINT16; - fld->get_field_type = TIFF_SETGET_C32_UINT16; - break; - case TIFF_LONG: - fld->set_field_type = TIFF_SETGET_C32_UINT32; - fld->get_field_type = TIFF_SETGET_C32_UINT32; - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - fld->set_field_type = TIFF_SETGET_C32_FLOAT; - fld->get_field_type = TIFF_SETGET_C32_FLOAT; - break; - case TIFF_SBYTE: - fld->set_field_type = TIFF_SETGET_C32_SINT8; - fld->get_field_type = TIFF_SETGET_C32_SINT8; - break; - case TIFF_SSHORT: - fld->set_field_type = TIFF_SETGET_C32_SINT16; - fld->get_field_type = TIFF_SETGET_C32_SINT16; - break; - case TIFF_SLONG: - fld->set_field_type = TIFF_SETGET_C32_SINT32; - fld->get_field_type = TIFF_SETGET_C32_SINT32; - break; - case TIFF_DOUBLE: - fld->set_field_type = TIFF_SETGET_C32_DOUBLE; - fld->get_field_type = TIFF_SETGET_C32_DOUBLE; - break; - case TIFF_IFD: - case TIFF_IFD8: - fld->set_field_type = TIFF_SETGET_C32_IFD8; - fld->get_field_type = TIFF_SETGET_C32_IFD8; - break; - case TIFF_LONG8: - fld->set_field_type = TIFF_SETGET_C32_UINT64; - fld->get_field_type = TIFF_SETGET_C32_UINT64; - break; - case TIFF_SLONG8: - fld->set_field_type = TIFF_SETGET_C32_SINT64; - fld->get_field_type = TIFF_SETGET_C32_SINT64; - break; - default: - fld->set_field_type = TIFF_SETGET_UNDEFINED; - fld->get_field_type = TIFF_SETGET_UNDEFINED; - break; - } - fld->field_bit = FIELD_CUSTOM; - fld->field_oktochange = TRUE; - fld->field_passcount = TRUE; - fld->field_name = (char *) _TIFFmalloc(32); - if (fld->field_name == NULL) { - _TIFFfree(fld); - return NULL; - } - fld->field_subfields = NULL; - - /* - * note that this name is a special sign to TIFFClose() and - * _TIFFSetupFields() to free the field - */ - (void) snprintf(fld->field_name, 32, "Tag %d", (int) tag); - - return fld; + return fld; } /**************************************************************************** @@ -905,347 +999,353 @@ _TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type) * libtiff versions. ****************************************************************************/ -static TIFFSetGetFieldType -_TIFFSetGetType(TIFFDataType type, short count, unsigned char passcount) +static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count, + unsigned char passcount) { - if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0) - return TIFF_SETGET_ASCII; + if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0) + return TIFF_SETGET_ASCII; - else if (count == 1 && passcount == 0) { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_UINT16; - case TIFF_LONG: - return TIFF_SETGET_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } + else if (count == 1 && passcount == 0) + { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_UINT16; + case TIFF_LONG: + return TIFF_SETGET_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } - else if (count >= 1 && passcount == 0) { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_C0_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_C0_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_C0_UINT16; - case TIFF_LONG: - return TIFF_SETGET_C0_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_C0_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_C0_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_C0_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_C0_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_C0_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_C0_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_C0_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_C0_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } + else if (count >= 1 && passcount == 0) + { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C0_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C0_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C0_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C0_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C0_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C0_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C0_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C0_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C0_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C0_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C0_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C0_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } - else if (count == TIFF_VARIABLE && passcount == 1) { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_C16_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_C16_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_C16_UINT16; - case TIFF_LONG: - return TIFF_SETGET_C16_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_C16_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_C16_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_C16_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_C16_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_C16_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_C16_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_C16_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_C16_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } + else if (count == TIFF_VARIABLE && passcount == 1) + { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C16_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C16_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C16_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C16_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C16_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C16_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C16_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C16_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C16_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C16_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C16_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C16_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } - else if (count == TIFF_VARIABLE2 && passcount == 1) { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_C32_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_C32_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_C32_UINT16; - case TIFF_LONG: - return TIFF_SETGET_C32_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_C32_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_C32_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_C32_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_C32_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_C32_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_C32_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_C32_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_C32_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } + else if (count == TIFF_VARIABLE2 && passcount == 1) + { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C32_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C32_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C32_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C32_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C32_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C32_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C32_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C32_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C32_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C32_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C32_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C32_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } - return TIFF_SETGET_UNDEFINED; + return TIFF_SETGET_UNDEFINED; } -int -TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n) +int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n) { - static const char module[] = "TIFFMergeFieldInfo"; - static const char reason[] = "for fields array"; - TIFFField *tp; - size_t nfields; - uint32 i; + static const char module[] = "TIFFMergeFieldInfo"; + static const char reason[] = "for fields array"; + TIFFField *tp; + size_t nfields; + uint32_t i; - if (tif->tif_nfieldscompat > 0) { - tif->tif_fieldscompat = (TIFFFieldArray *) - _TIFFCheckRealloc(tif, tif->tif_fieldscompat, - tif->tif_nfieldscompat + 1, - sizeof(TIFFFieldArray), reason); - } else { - tif->tif_fieldscompat = (TIFFFieldArray *) - _TIFFCheckMalloc(tif, 1, sizeof(TIFFFieldArray), - reason); - } - if (!tif->tif_fieldscompat) { - TIFFErrorExt(tif->tif_clientdata, module, - "Failed to allocate fields array"); - return -1; - } - nfields = tif->tif_nfieldscompat++; + if (tif->tif_nfieldscompat > 0) + { + tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc( + tif, tif->tif_fieldscompat, tif->tif_nfieldscompat + 1, + sizeof(TIFFFieldArray), reason); + } + else + { + tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc( + tif, 1, sizeof(TIFFFieldArray), reason); + } + if (!tif->tif_fieldscompat) + { + TIFFErrorExtR(tif, module, "Failed to allocate fields array"); + return -1; + } + nfields = tif->tif_nfieldscompat++; - tif->tif_fieldscompat[nfields].type = tfiatOther; - tif->tif_fieldscompat[nfields].allocated_size = n; - tif->tif_fieldscompat[nfields].count = n; - tif->tif_fieldscompat[nfields].fields = - (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField), - reason); - if (!tif->tif_fieldscompat[nfields].fields) { - TIFFErrorExt(tif->tif_clientdata, module, - "Failed to allocate fields array"); - return -1; - } + tif->tif_fieldscompat[nfields].type = tfiatOther; + tif->tif_fieldscompat[nfields].allocated_size = n; + tif->tif_fieldscompat[nfields].count = n; + tif->tif_fieldscompat[nfields].fields = + (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField), reason); + if (!tif->tif_fieldscompat[nfields].fields) + { + TIFFErrorExtR(tif, module, "Failed to allocate fields array"); + return -1; + } - tp = tif->tif_fieldscompat[nfields].fields; - for (i = 0; i < n; i++) { - tp->field_tag = info[i].field_tag; - tp->field_readcount = info[i].field_readcount; - tp->field_writecount = info[i].field_writecount; - tp->field_type = info[i].field_type; - tp->reserved = 0; - tp->set_field_type = - _TIFFSetGetType(info[i].field_type, - info[i].field_readcount, - info[i].field_passcount); - tp->get_field_type = - _TIFFSetGetType(info[i].field_type, - info[i].field_readcount, - info[i].field_passcount); - tp->field_bit = info[i].field_bit; - tp->field_oktochange = info[i].field_oktochange; - tp->field_passcount = info[i].field_passcount; - tp->field_name = info[i].field_name; - tp->field_subfields = NULL; - tp++; - } + tp = tif->tif_fieldscompat[nfields].fields; + for (i = 0; i < n; i++) + { + tp->field_tag = info[i].field_tag; + tp->field_readcount = info[i].field_readcount; + tp->field_writecount = info[i].field_writecount; + tp->field_type = info[i].field_type; + tp->field_anonymous = 0; + tp->set_field_type = + _TIFFSetGetType(info[i].field_type, info[i].field_readcount, + info[i].field_passcount); + tp->get_field_type = + _TIFFSetGetType(info[i].field_type, info[i].field_readcount, + info[i].field_passcount); + tp->field_bit = info[i].field_bit; + tp->field_oktochange = info[i].field_oktochange; + tp->field_passcount = info[i].field_passcount; + if (info[i].field_name == NULL) + { + TIFFErrorExtR(tif, module, + "Field_name of %d.th allocation tag %d is NULL", i, + info[i].field_tag); + return -1; + } + tp->field_name = info[i].field_name; + tp->field_subfields = NULL; + tp++; + } - if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Setting up field info failed"); - return -1; - } + if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) + { + TIFFErrorExtR(tif, module, "Setting up field info failed"); + return -1; + } - return 0; + return 0; } -int -_TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) +int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) { - /* Filter out non-codec specific tags */ - switch (tag) { - /* Shared tags */ - case TIFFTAG_PREDICTOR: - /* JPEG tags */ - case TIFFTAG_JPEGTABLES: - /* OJPEG tags */ - case TIFFTAG_JPEGIFOFFSET: - case TIFFTAG_JPEGIFBYTECOUNT: - case TIFFTAG_JPEGQTABLES: - case TIFFTAG_JPEGDCTABLES: - case TIFFTAG_JPEGACTABLES: - case TIFFTAG_JPEGPROC: - case TIFFTAG_JPEGRESTARTINTERVAL: - /* CCITT* */ - case TIFFTAG_BADFAXLINES: - case TIFFTAG_CLEANFAXDATA: - case TIFFTAG_CONSECUTIVEBADFAXLINES: - case TIFFTAG_GROUP3OPTIONS: - case TIFFTAG_GROUP4OPTIONS: - /* LERC */ - case TIFFTAG_LERC_PARAMETERS: - break; - default: - return 1; - } - /* Check if codec specific tags are allowed for the current - * compression scheme (codec) */ - switch (tif->tif_dir.td_compression) { - case COMPRESSION_LZW: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_PACKBITS: - /* No codec-specific tags */ - break; - case COMPRESSION_THUNDERSCAN: - /* No codec-specific tags */ - break; - case COMPRESSION_NEXT: - /* No codec-specific tags */ - break; - case COMPRESSION_JPEG: - if (tag == TIFFTAG_JPEGTABLES) - return 1; - break; - case COMPRESSION_OJPEG: - switch (tag) { - case TIFFTAG_JPEGIFOFFSET: - case TIFFTAG_JPEGIFBYTECOUNT: - case TIFFTAG_JPEGQTABLES: - case TIFFTAG_JPEGDCTABLES: - case TIFFTAG_JPEGACTABLES: - case TIFFTAG_JPEGPROC: - case TIFFTAG_JPEGRESTARTINTERVAL: - return 1; - } - break; - case COMPRESSION_CCITTRLE: - case COMPRESSION_CCITTRLEW: - case COMPRESSION_CCITTFAX3: - case COMPRESSION_CCITTFAX4: - switch (tag) { - case TIFFTAG_BADFAXLINES: - case TIFFTAG_CLEANFAXDATA: - case TIFFTAG_CONSECUTIVEBADFAXLINES: - return 1; - case TIFFTAG_GROUP3OPTIONS: - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) - return 1; - break; - case TIFFTAG_GROUP4OPTIONS: - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) - return 1; - break; - } - break; - case COMPRESSION_JBIG: - /* No codec-specific tags */ - break; - case COMPRESSION_DEFLATE: - case COMPRESSION_ADOBE_DEFLATE: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_PIXARLOG: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_SGILOG: - case COMPRESSION_SGILOG24: - /* No codec-specific tags */ - break; - case COMPRESSION_LZMA: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_ZSTD: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_LERC: - if (tag == TIFFTAG_LERC_PARAMETERS) - return 1; - break; - } - return 0; + /* Filter out non-codec specific tags */ + switch (tag) + { + /* Shared tags */ + case TIFFTAG_PREDICTOR: + /* JPEG tags */ + case TIFFTAG_JPEGTABLES: + /* OJPEG tags */ + case TIFFTAG_JPEGIFOFFSET: + case TIFFTAG_JPEGIFBYTECOUNT: + case TIFFTAG_JPEGQTABLES: + case TIFFTAG_JPEGDCTABLES: + case TIFFTAG_JPEGACTABLES: + case TIFFTAG_JPEGPROC: + case TIFFTAG_JPEGRESTARTINTERVAL: + /* CCITT* */ + case TIFFTAG_BADFAXLINES: + case TIFFTAG_CLEANFAXDATA: + case TIFFTAG_CONSECUTIVEBADFAXLINES: + case TIFFTAG_GROUP3OPTIONS: + case TIFFTAG_GROUP4OPTIONS: + /* LERC */ + case TIFFTAG_LERC_PARAMETERS: + break; + default: + return 1; + } + if (!TIFFIsCODECConfigured(tif->tif_dir.td_compression)) + { + return 0; + } + /* Check if codec specific tags are allowed for the current + * compression scheme (codec) */ + switch (tif->tif_dir.td_compression) + { + case COMPRESSION_LZW: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_PACKBITS: + /* No codec-specific tags */ + break; + case COMPRESSION_THUNDERSCAN: + /* No codec-specific tags */ + break; + case COMPRESSION_NEXT: + /* No codec-specific tags */ + break; + case COMPRESSION_JPEG: + if (tag == TIFFTAG_JPEGTABLES) + return 1; + break; + case COMPRESSION_OJPEG: + switch (tag) + { + case TIFFTAG_JPEGIFOFFSET: + case TIFFTAG_JPEGIFBYTECOUNT: + case TIFFTAG_JPEGQTABLES: + case TIFFTAG_JPEGDCTABLES: + case TIFFTAG_JPEGACTABLES: + case TIFFTAG_JPEGPROC: + case TIFFTAG_JPEGRESTARTINTERVAL: + return 1; + } + break; + case COMPRESSION_CCITTRLE: + case COMPRESSION_CCITTRLEW: + case COMPRESSION_CCITTFAX3: + case COMPRESSION_CCITTFAX4: + switch (tag) + { + case TIFFTAG_BADFAXLINES: + case TIFFTAG_CLEANFAXDATA: + case TIFFTAG_CONSECUTIVEBADFAXLINES: + return 1; + case TIFFTAG_GROUP3OPTIONS: + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) + return 1; + break; + case TIFFTAG_GROUP4OPTIONS: + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) + return 1; + break; + } + break; + case COMPRESSION_JBIG: + /* No codec-specific tags */ + break; + case COMPRESSION_DEFLATE: + case COMPRESSION_ADOBE_DEFLATE: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_PIXARLOG: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_SGILOG: + case COMPRESSION_SGILOG24: + /* No codec-specific tags */ + break; + case COMPRESSION_LZMA: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_ZSTD: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_LERC: + if (tag == TIFFTAG_LERC_PARAMETERS) + return 1; + break; + } + return 0; } - -/* vim: set ts=8 sts=8 sw=8 noet: */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_dirread.c b/3rdparty/libtiff/tif_dirread.c index 45c1107697..2c49dc6aa0 100644 --- a/3rdparty/libtiff/tif_dirread.c +++ b/3rdparty/libtiff/tif_dirread.c @@ -34,3471 +34,3993 @@ * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup. */ +#include "tiffconf.h" #include "tiffiop.h" #include +#include #include +#include -#define FAILED_FII ((uint32) -1) - -/* - * Largest 64-bit signed integer value. - */ -#define TIFF_INT64_MAX ((int64)(TIFF_UINT64_MAX >> 1)) +#define FAILED_FII ((uint32_t)-1) #ifdef HAVE_IEEEFP -# define TIFFCvtIEEEFloatToNative(tif, n, fp) -# define TIFFCvtIEEEDoubleToNative(tif, n, dp) +#define TIFFCvtIEEEFloatToNative(tif, n, fp) +#define TIFFCvtIEEEDoubleToNative(tif, n, dp) #else -extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*); -extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*); +extern void TIFFCvtIEEEFloatToNative(TIFF *, uint32_t, float *); +extern void TIFFCvtIEEEDoubleToNative(TIFF *, uint32_t, double *); #endif -enum TIFFReadDirEntryErr { - TIFFReadDirEntryErrOk = 0, - TIFFReadDirEntryErrCount = 1, - TIFFReadDirEntryErrType = 2, - TIFFReadDirEntryErrIo = 3, - TIFFReadDirEntryErrRange = 4, - TIFFReadDirEntryErrPsdif = 5, - TIFFReadDirEntryErrSizesan = 6, - TIFFReadDirEntryErrAlloc = 7, +enum TIFFReadDirEntryErr +{ + TIFFReadDirEntryErrOk = 0, + TIFFReadDirEntryErrCount = 1, + TIFFReadDirEntryErrType = 2, + TIFFReadDirEntryErrIo = 3, + TIFFReadDirEntryErrRange = 4, + TIFFReadDirEntryErrPsdif = 5, + TIFFReadDirEntryErrSizesan = 6, + TIFFReadDirEntryErrAlloc = 7, }; -static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count, + uint32_t desttypesize, void **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry, + uint16_t *value); + +static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry, + uint8_t *value); +static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry, + int8_t *value); +static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry, + uint16_t *value); +static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry, + int16_t *value); +static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry, + uint32_t *value); +static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry, + int32_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, + uint64_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, + int64_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry, + double *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry, + double *value); +static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry, + float *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value); #if 0 -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry, + TIFFRational_t *value); #endif +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSbyte(int8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteShort(uint16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSlong8(int64_t value); -static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value); -static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value); -static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); -static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value); -static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value); -static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value); -static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSbyte(int8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSlong8(int64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortShort(uint16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSbyte(int8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSlong8(int64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64 value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Slong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64 value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32 value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset, + tmsize_t size, void *dest); +static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, + const char *module, const char *tagname, + int recover); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value); +static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount); +static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount, + uint16_t tagid); +static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid, + uint32_t *fii); -static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest); -static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover); +static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount); +static void MissingRequired(TIFF *, const char *); +static int CheckDirCount(TIFF *, TIFFDirEntry *, uint32_t); +static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, + TIFFDirEntry **pdir, uint64_t *nextdiroff); +static int TIFFFetchNormalTag(TIFF *, TIFFDirEntry *, int recover); +static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips, + uint64_t **lpp); +static int TIFFFetchSubjectDistance(TIFF *, TIFFDirEntry *); +static void ChopUpSingleUncompressedStrip(TIFF *); +static void TryChopUpUncompressedBigTiff(TIFF *); +static uint64_t TIFFReadUInt64(const uint8_t *value); +static int _TIFFGetMaxColorChannels(uint16_t photometric); -static void TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount); -static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid); -static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii); - -static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount); -static void MissingRequired(TIFF*, const char*); -static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff); -static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32); -static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff); -static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover); -static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp); -static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); -static void ChopUpSingleUncompressedStrip(TIFF*); -static void TryChopUpUncompressedBigTiff(TIFF*); -static uint64 TIFFReadUInt64(const uint8 *value); -static int _TIFFGetMaxColorChannels(uint16 photometric); - -static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount ); +static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount); typedef union _UInt64Aligned_t { - double d; - uint64 l; - uint32 i[2]; - uint16 s[4]; - uint8 c[8]; + double d; + uint64_t l; + uint32_t i[2]; + uint16_t s[4]; + uint8_t c[8]; } UInt64Aligned_t; /* - Unaligned safe copy of a uint64 value from an octet array. + Unaligned safe copy of a uint64_t value from an octet array. */ -static uint64 TIFFReadUInt64(const uint8 *value) +static uint64_t TIFFReadUInt64(const uint8_t *value) { - UInt64Aligned_t result; + UInt64Aligned_t result; - result.c[0]=value[0]; - result.c[1]=value[1]; - result.c[2]=value[2]; - result.c[3]=value[3]; - result.c[4]=value[4]; - result.c[5]=value[5]; - result.c[6]=value[6]; - result.c[7]=value[7]; + result.c[0] = value[0]; + result.c[1] = value[1]; + result.c[2] = value[2]; + result.c[3] = value[3]; + result.c[4] = value[4]; + result.c[5] = value[5]; + result.c[6] = value[6]; + result.c[7] = value[7]; - return result.l; + return result.l; } -static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with field_readcount==1 */ - TIFFReadDirEntryCheckedByte(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteSbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteShort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteSshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteLong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteSlong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeByteLong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeByteSlong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with + field_readcount==1 */ + TIFFReadDirEntryCheckedByte(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteSbyte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteShort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteSshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeByteLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeByteSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } } -static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortSbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - TIFFReadDirEntryCheckedShort(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortSshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortLong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortSlong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeShortLong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeShortSlong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with + field_readcount==1 */ + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteByte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + TIFFReadDirEntryCheckedSbyte(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteShort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteSshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSbyteLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSbyteSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySbyte() --*/ -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLongSbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLongSshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - TIFFReadDirEntryCheckedLong(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLongSlong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeLongLong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeLongSlong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeShortSbyte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + TIFFReadDirEntryCheckedShort(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeShortSshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeShortLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeShortSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeShortLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeShortSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntryShort() --*/ -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLong8Sbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLong8Sshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLong8Slong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); - return(err); - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeLong8Slong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSshortShort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + TIFFReadDirEntryCheckedSshort(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSshortLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSshortSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSshortLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSshortSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySshort() --*/ -static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLongSbyte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLongSshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + TIFFReadDirEntryCheckedLong(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLongSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeLongLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeLongSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntryLong() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSlongLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + TIFFReadDirEntryCheckedSlong(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSlongLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSlongSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySlong() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLong8Sbyte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLong8Sshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLong8Slong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); + return (err); + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeLong8Slong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntryLong8() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSlong8Long8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, value); + return (err); + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySlong8() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); #if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support conversion - * of 64-bit integers into floating point - * values. - */ - *value = _TIFFUInt64ToFloat(m); + /* + * XXX: MSVC 6.0 does not support conversion + * of 64-bit integers into floating point + * values. + */ + *value = _TIFFUInt64ToFloat(m); #else - *value=(float)m; + *value = (float)m; #endif - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_RATIONAL: - { - double m; - err=TIFFReadDirEntryCheckedRational(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SRATIONAL: - { - double m; - err=TIFFReadDirEntryCheckedSrational(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_FLOAT: - TIFFReadDirEntryCheckedFloat(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_DOUBLE: - { - double m; - err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - if ((m > FLT_MAX) || (m < -FLT_MAX)) - return(TIFFReadDirEntryErrRange); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_RATIONAL: + { + double m; + err = TIFFReadDirEntryCheckedRational(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SRATIONAL: + { + double m; + err = TIFFReadDirEntryCheckedSrational(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_FLOAT: + TIFFReadDirEntryCheckedFloat(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_DOUBLE: + { + double m; + err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + if ((m > FLT_MAX) || (m < -FLT_MAX)) + return (TIFFReadDirEntryErrRange); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } } -static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8 m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8 m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16 m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16 m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32 m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64 m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); #if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support conversion - * of 64-bit integers into floating point - * values. - */ - *value = _TIFFUInt64ToDouble(m); + /* + * XXX: MSVC 6.0 does not support conversion + * of 64-bit integers into floating point + * values. + */ + *value = _TIFFUInt64ToDouble(m); #else - *value = (double)m; + *value = (double)m; #endif - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64 m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_RATIONAL: - err=TIFFReadDirEntryCheckedRational(tif,direntry,value); - return(err); - case TIFF_SRATIONAL: - err=TIFFReadDirEntryCheckedSrational(tif,direntry,value); - return(err); - case TIFF_FLOAT: - { - float m; - TIFFReadDirEntryCheckedFloat(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_DOUBLE: - err=TIFFReadDirEntryCheckedDouble(tif,direntry,value); - return(err); - default: - return(TIFFReadDirEntryErrType); - } + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_RATIONAL: + err = TIFFReadDirEntryCheckedRational(tif, direntry, value); + return (err); + case TIFF_SRATIONAL: + err = TIFFReadDirEntryCheckedSrational(tif, direntry, value); + return (err); + case TIFF_FLOAT: + { + float m; + TIFFReadDirEntryCheckedFloat(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_DOUBLE: + err = TIFFReadDirEntryCheckedDouble(tif, direntry, value); + return (err); + default: + return (TIFFReadDirEntryErrType); + } } -static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_IFD: - { - uint32 m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(uint64)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - case TIFF_IFD8: - err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); - return(err); - default: - return(TIFFReadDirEntryErrType); - } + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_IFD: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + case TIFF_IFD8: + err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); + return (err); + default: + return (TIFFReadDirEntryErrType); + } } - #define INITIAL_THRESHOLD (1024 * 1024) #define THRESHOLD_MULTIPLIER 10 -#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD) +#define MAX_THRESHOLD \ + (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \ + INITIAL_THRESHOLD) -static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc( - TIFF* tif, uint64 offset, tmsize_t size, void** pdest) +static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif, + uint64_t offset, + tmsize_t size, + void **pdest) { #if SIZEOF_SIZE_T == 8 - tmsize_t threshold = INITIAL_THRESHOLD; + tmsize_t threshold = INITIAL_THRESHOLD; #endif - tmsize_t already_read = 0; + tmsize_t already_read = 0; - assert( !isMapped(tif) ); + assert(!isMapped(tif)); - if (!SeekOK(tif,offset)) - return(TIFFReadDirEntryErrIo); + if (!SeekOK(tif, offset)) + return (TIFFReadDirEntryErrIo); - /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ - /* so as to avoid allocating too much memory in case the file is too */ - /* short. We could ask for the file size, but this might be */ - /* expensive with some I/O layers (think of reading a gzipped file) */ - /* Restrict to 64 bit processes, so as to avoid reallocs() */ - /* on 32 bit processes where virtual memory is scarce. */ - while( already_read < size ) - { - void* new_dest; - tmsize_t bytes_read; - tmsize_t to_read = size - already_read; + /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ + /* so as to avoid allocating too much memory in case the file is too */ + /* short. We could ask for the file size, but this might be */ + /* expensive with some I/O layers (think of reading a gzipped file) */ + /* Restrict to 64 bit processes, so as to avoid reallocs() */ + /* on 32 bit processes where virtual memory is scarce. */ + while (already_read < size) + { + void *new_dest; + tmsize_t bytes_read; + tmsize_t to_read = size - already_read; #if SIZEOF_SIZE_T == 8 - if( to_read >= threshold && threshold < MAX_THRESHOLD ) - { - to_read = threshold; - threshold *= THRESHOLD_MULTIPLIER; - } + if (to_read >= threshold && threshold < MAX_THRESHOLD) + { + to_read = threshold; + threshold *= THRESHOLD_MULTIPLIER; + } #endif - new_dest = (uint8*) _TIFFrealloc( - *pdest, already_read + to_read); - if( new_dest == NULL ) - { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Failed to allocate memory for %s " - "(%ld elements of %ld bytes each)", - "TIFFReadDirEntryArray", - (long) 1, (long) (already_read + to_read)); - return TIFFReadDirEntryErrAlloc; - } - *pdest = new_dest; + new_dest = + (uint8_t *)_TIFFreallocExt(tif, *pdest, already_read + to_read); + if (new_dest == NULL) + { + TIFFErrorExtR(tif, tif->tif_name, + "Failed to allocate memory for %s " + "(%" TIFF_SSIZE_FORMAT + " elements of %" TIFF_SSIZE_FORMAT " bytes each)", + "TIFFReadDirEntryArray", (tmsize_t)1, + already_read + to_read); + return TIFFReadDirEntryErrAlloc; + } + *pdest = new_dest; - bytes_read = TIFFReadFile(tif, - (char*)*pdest + already_read, to_read); - already_read += bytes_read; - if (bytes_read != to_read) { - return TIFFReadDirEntryErrIo; + bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read); + already_read += bytes_read; + if (bytes_read != to_read) + { + return TIFFReadDirEntryErrIo; + } + } + return TIFFReadDirEntryErrOk; +} + +/* Caution: if raising that value, make sure int32 / uint32 overflows can't + * occur elsewhere */ +#define MAX_SIZE_TAG_DATA 2147483647U + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, + uint32_t *count, uint32_t desttypesize, + void **value, uint64_t maxcount) +{ + int typesize; + uint32_t datasize; + void *data; + uint64_t target_count64; + int original_datasize_clamped; + typesize = TIFFDataWidth(direntry->tdir_type); + + target_count64 = + (direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count; + + if ((target_count64 == 0) || (typesize == 0)) + { + *value = 0; + return (TIFFReadDirEntryErrOk); + } + (void)desttypesize; + + /* We just want to know if the original tag size is more than 4 bytes + * (classic TIFF) or 8 bytes (BigTIFF) + */ + original_datasize_clamped = + ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * + typesize; + + /* + * As a sanity check, make sure we have no more than a 2GB tag array + * in either the current data type or the dest data type. This also + * avoids problems with overflow of tmsize_t on 32bit systems. + */ + if ((uint64_t)(MAX_SIZE_TAG_DATA / typesize) < target_count64) + return (TIFFReadDirEntryErrSizesan); + if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64) + return (TIFFReadDirEntryErrSizesan); + + *count = (uint32_t)target_count64; + datasize = (*count) * typesize; + assert((tmsize_t)datasize > 0); + + if (isMapped(tif) && datasize > (uint64_t)tif->tif_size) + return TIFFReadDirEntryErrIo; + + if (!isMapped(tif) && (((tif->tif_flags & TIFF_BIGTIFF) && datasize > 8) || + (!(tif->tif_flags & TIFF_BIGTIFF) && datasize > 4))) + { + data = NULL; + } + else + { + data = _TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); + if (data == 0) + return (TIFFReadDirEntryErrAlloc); + } + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + /* Only the condition on original_datasize_clamped. The second + * one is implied, but Coverity Scan cannot see it. */ + if (original_datasize_clamped <= 4 && datasize <= 4) + _TIFFmemcpy(data, &direntry->tdir_offset, datasize); + else + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + if (isMapped(tif)) + err = TIFFReadDirEntryData(tif, (uint64_t)offset, + (tmsize_t)datasize, data); + else + err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, + (tmsize_t)datasize, &data); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); } } - return TIFFReadDirEntryErrOk; -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( - TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, - void** value, uint64 maxcount) -{ - int typesize; - uint32 datasize; - void* data; - uint64 target_count64; - int original_datasize_clamped; - typesize=TIFFDataWidth(direntry->tdir_type); - - target_count64 = (direntry->tdir_count > maxcount) ? - maxcount : direntry->tdir_count; - - if ((target_count64==0)||(typesize==0)) - { - *value=0; - return(TIFFReadDirEntryErrOk); - } - (void) desttypesize; - - /* We just want to know if the original tag size is more than 4 bytes - * (classic TIFF) or 8 bytes (BigTIFF) - */ - original_datasize_clamped = - ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * typesize; - - /* - * As a sanity check, make sure we have no more than a 2GB tag array - * in either the current data type or the dest data type. This also - * avoids problems with overflow of tmsize_t on 32bit systems. - */ - if ((uint64)(2147483647/typesize)0); - - if( isMapped(tif) && datasize > (uint64)tif->tif_size ) - return TIFFReadDirEntryErrIo; - - if( !isMapped(tif) && - (((tif->tif_flags&TIFF_BIGTIFF) && datasize > 8) || - (!(tif->tif_flags&TIFF_BIGTIFF) && datasize > 4)) ) - { - data = NULL; - } - else - { - data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); - if (data==0) - return(TIFFReadDirEntryErrAlloc); - } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (original_datasize_clamped<=4) - _TIFFmemcpy(data,&direntry->tdir_offset,datasize); - else - { - enum TIFFReadDirEntryErr err; - uint32 offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - if( isMapped(tif) ) - err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); - else - err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - } - } - else - { - if (original_datasize_clamped<=8) - _TIFFmemcpy(data,&direntry->tdir_offset,datasize); - else - { - enum TIFFReadDirEntryErr err; - uint64 offset = direntry->tdir_offset.toff_long8; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(&offset); - if( isMapped(tif) ) - err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); - else - err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - } - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value) -{ - return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, - desttypesize, value, ~((uint64)0)); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - uint8* data; - switch (direntry->tdir_type) - { - case TIFF_ASCII: - case TIFF_UNDEFINED: - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_ASCII: - case TIFF_UNDEFINED: - case TIFF_BYTE: - *value=(uint8*)origdata; - return(TIFFReadDirEntryErrOk); - case TIFF_SBYTE: - { - int8* m; - uint32 n; - m=(int8*)origdata; - for (n=0; ntdir_type) - { - case TIFF_SHORT: - { - uint16* ma; - uint8* mb; - uint32 n; - ma=(uint16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - err=TIFFReadDirEntryCheckRangeByteShort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - uint8* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - err=TIFFReadDirEntryCheckRangeByteSshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - uint8* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeByteLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - uint8* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeByteSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - uint8* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeByteLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - uint8* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeByteSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - int8* data; - switch (direntry->tdir_type) - { - case TIFF_UNDEFINED: - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_UNDEFINED: - case TIFF_BYTE: - { - uint8* m; - uint32 n; - m=(uint8*)origdata; - for (n=0; ntdir_type) - { - case TIFF_SHORT: - { - uint16* ma; - int8* mb; - uint32 n; - ma=(uint16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - err=TIFFReadDirEntryCheckRangeSbyteShort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - int8* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - err=TIFFReadDirEntryCheckRangeSbyteSshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - int8* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeSbyteLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - int8* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeSbyteSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - int8* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeSbyteLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - int8* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeSbyteSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - uint16* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - *value=(uint16*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort(*value,count); - return(TIFFReadDirEntryErrOk); - case TIFF_SSHORT: - { - int16* m; - uint32 n; - m=(int16*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)m); - err=TIFFReadDirEntryCheckRangeShortSshort(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(uint16*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint16*)_TIFFmalloc(count*2); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - uint16* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeShortLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - uint16* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeShortSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - uint16* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeShortLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - uint16* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeShortSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - int16* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - { - uint16* m; - uint32 n; - m=(uint16*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(m); - err=TIFFReadDirEntryCheckRangeSshortShort(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(int16*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - *value=(int16*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort((uint16*)(*value),count); - return(TIFFReadDirEntryErrOk); - } - data=(int16*)_TIFFmalloc(count*2); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - int16* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeSshortLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - int16* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeSshortSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - int16* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeSshortLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - int16* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeSshortSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - uint32* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - *value=(uint32*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(*value,count); - return(TIFFReadDirEntryErrOk); - case TIFF_SLONG: - { - int32* m; - uint32 n; - m=(int32*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)m); - err=TIFFReadDirEntryCheckRangeLongSlong(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(uint32*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint32*)_TIFFmalloc(count*4); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - uint32* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(uint32)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - uint32* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - err=TIFFReadDirEntryCheckRangeLongSshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - uint32* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeLongLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - uint32* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeLongSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - int32* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - { - uint32* m; - uint32 n; - m=(uint32*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)m); - err=TIFFReadDirEntryCheckRangeSlongLong(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(int32*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - *value=(int32*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32*)(*value),count); - return(TIFFReadDirEntryErrOk); - } - data=(int32*)_TIFFmalloc(count*4); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - int32* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(int32)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - int32* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - *mb++=(int32)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - int32* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeSlongLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int32)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - int32* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - err=TIFFReadDirEntryCheckRangeSlongSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int32)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8ArrayWithLimit( - TIFF* tif, TIFFDirEntry* direntry, uint64** value, uint64 maxcount) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - uint64* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArrayWithLimit(tif,direntry,&count,8,&origdata,maxcount); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG8: - *value=(uint64*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(*value,count); - return(TIFFReadDirEntryErrOk); - case TIFF_SLONG8: - { - int64* m; - uint32 n; - m=(int64*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)m); - err=TIFFReadDirEntryCheckRangeLong8Slong8(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(uint64*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint64*)_TIFFmalloc(count*8); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - uint64* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(uint64)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - uint64* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - err=TIFFReadDirEntryCheckRangeLong8Sshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint64)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - uint64* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(uint64)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - uint64* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - err=TIFFReadDirEntryCheckRangeLong8Slong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint64)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value) -{ - return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, ~((uint64)0)); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - int64* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG8: - { - uint64* m; - uint32 n; - m=(uint64*)origdata; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(m); - err=TIFFReadDirEntryCheckRangeSlong8Long8(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfree(origdata); - return(err); - } - m++; - } - *value=(int64*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - *value=(int64*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64*)(*value),count); - return(TIFFReadDirEntryErrOk); - } - data=(int64*)_TIFFmalloc(count*8); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - int64* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(int64)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - int64* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - *mb++=(int64)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - int64* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(int64)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - int64* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - *mb++=(int64)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - *value=data; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value) -{ - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - float* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - case TIFF_DOUBLE: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_FLOAT: - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32*)origdata,count); - TIFFCvtIEEEDoubleToNative(tif,count,(float*)origdata); - *value=(float*)origdata; - return(TIFFReadDirEntryErrOk); - } - data=(float*)_TIFFmalloc(count*sizeof(float)); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - float* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - float* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - float* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - float* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - float* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); -#if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support - * conversion of 64-bit integers into - * floating point values. - */ - *mb++ = _TIFFUInt64ToFloat(*ma++); -#else - *mb++ = (float)(*ma++); -#endif - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - float* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_RATIONAL: - { - uint32* ma; - uint32 maa; - uint32 mab; - float* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*ma++; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - mab=*ma++; - if (mab==0) - *mb++=0.0; - else - *mb++=(float)maa/(float)mab; - } - } - break; - case TIFF_SRATIONAL: - { - uint32* ma; - int32 maa; - uint32 mab; - float* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*(int32*)ma; - ma++; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - mab=*ma++; - if (mab==0) - *mb++=0.0; - else - *mb++=(float)maa/(float)mab; - } - } - break; - case TIFF_DOUBLE: - { - double* ma; - float* mb; - uint32 n; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64*)origdata,count); - TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); - ma=(double*)origdata; - mb=data; - for (n=0; n FLT_MAX ) - val = FLT_MAX; - else if( val < -FLT_MAX ) - val = -FLT_MAX; - *mb++=(float)val; - } - } - break; - } - _TIFFfree(origdata); - *value=data; - return(TIFFReadDirEntryErrOk); + } + else + { + /* See above comment for the Classic TIFF case */ + if (original_datasize_clamped <= 8 && datasize <= 8) + _TIFFmemcpy(data, &direntry->tdir_offset, datasize); + else + { + enum TIFFReadDirEntryErr err; + uint64_t offset = direntry->tdir_offset.toff_long8; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&offset); + if (isMapped(tif)) + err = TIFFReadDirEntryData(tif, (uint64_t)offset, + (tmsize_t)datasize, data); + else + err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, + (tmsize_t)datasize, &data); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + } + } + *value = data; + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value) +TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count, + uint32_t desttypesize, void **value) { - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - double* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - case TIFF_DOUBLE: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_DOUBLE: - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64*)origdata,count); - TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); - *value=(double*)origdata; - return(TIFFReadDirEntryErrOk); - } - data=(double*)_TIFFmalloc(count*sizeof(double)); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8* ma; - double* mb; - uint32 n; - ma=(uint8*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16* ma; - double* mb; - uint32 n; - ma=(int16*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32* ma; - double* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32* ma; - double* mb; - uint32 n; - ma=(int32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64* ma; - double* mb; - uint32 n; - ma=(uint64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); + return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, desttypesize, + value, ~((uint64_t)0)); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value) +{ + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint8_t *data; + switch (direntry->tdir_type) + { + case TIFF_ASCII: + case TIFF_UNDEFINED: + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_ASCII: + case TIFF_UNDEFINED: + case TIFF_BYTE: + *value = (uint8_t *)origdata; + return (TIFFReadDirEntryErrOk); + case TIFF_SBYTE: + { + int8_t *m; + uint32_t n; + m = (int8_t *)origdata; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeByteSbyte(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (uint8_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + } + data = (uint8_t *)_TIFFmallocExt(tif, count); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + { + uint16_t *ma; + uint8_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + err = TIFFReadDirEntryCheckRangeByteShort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + uint8_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + err = TIFFReadDirEntryCheckRangeByteSshort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + uint8_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + err = TIFFReadDirEntryCheckRangeByteLong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + uint8_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeByteSlong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + uint8_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeByteLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + uint8_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeByteSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value) +{ + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + int8_t *data; + switch (direntry->tdir_type) + { + case TIFF_UNDEFINED: + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_UNDEFINED: + case TIFF_BYTE: + { + uint8_t *m; + uint32_t n; + m = (uint8_t *)origdata; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeSbyteByte(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (int8_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + *value = (int8_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + data = (int8_t *)_TIFFmallocExt(tif, count); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + { + uint16_t *ma; + int8_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + err = TIFFReadDirEntryCheckRangeSbyteShort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + int8_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + err = TIFFReadDirEntryCheckRangeSbyteSshort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + int8_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + err = TIFFReadDirEntryCheckRangeSbyteLong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + int8_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeSbyteSlong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + int8_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeSbyteLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + int8_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeSbyteSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value) +{ + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint16_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + *value = (uint16_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort(*value, count); + return (TIFFReadDirEntryErrOk); + case TIFF_SSHORT: + { + int16_t *m; + uint32_t n; + m = (int16_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)m); + err = TIFFReadDirEntryCheckRangeShortSshort(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (uint16_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + } + data = (uint16_t *)_TIFFmallocExt(tif, count * 2); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + uint16_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (uint16_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + uint16_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeShortSbyte(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + uint16_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + err = TIFFReadDirEntryCheckRangeShortLong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + uint16_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeShortSlong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + uint16_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeShortLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + uint16_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeShortSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value) +{ + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + int16_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + { + uint16_t *m; + uint32_t n; + m = (uint16_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(m); + err = TIFFReadDirEntryCheckRangeSshortShort(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (int16_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + *value = (int16_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort((uint16_t *)(*value), count); + return (TIFFReadDirEntryErrOk); + } + data = (int16_t *)_TIFFmallocExt(tif, count * 2); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + int16_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int16_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + int16_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int16_t)(*ma++); + } + break; + case TIFF_LONG: + { + uint32_t *ma; + int16_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + err = TIFFReadDirEntryCheckRangeSshortLong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int16_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + int16_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeSshortSlong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int16_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + int16_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeSshortLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int16_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + int16_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeSshortSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int16_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value) +{ + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint32_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + *value = (uint32_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(*value, count); + return (TIFFReadDirEntryErrOk); + case TIFF_SLONG: + { + int32_t *m; + uint32_t n; + m = (int32_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)m); + err = TIFFReadDirEntryCheckRangeLongSlong(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (uint32_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + } + data = (uint32_t *)_TIFFmallocExt(tif, count * 4); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + uint32_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (uint32_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + uint32_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeLongSbyte(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint32_t)(*ma++); + } + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + uint32_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (uint32_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + uint32_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + err = TIFFReadDirEntryCheckRangeLongSshort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint32_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + uint32_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeLongLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint32_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + uint32_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeLongSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint32_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value) +{ + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + int32_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + { + uint32_t *m; + uint32_t n; + m = (uint32_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)m); + err = TIFFReadDirEntryCheckRangeSlongLong(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (int32_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + *value = (int32_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)(*value), count); + return (TIFFReadDirEntryErrOk); + } + data = (int32_t *)_TIFFmallocExt(tif, count * 4); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + int32_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int32_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + int32_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int32_t)(*ma++); + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + int32_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (int32_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + int32_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + *mb++ = (int32_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + int32_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeSlongLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int32_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + int32_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeSlongSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int32_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, + uint64_t **value, uint64_t maxcount) +{ + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint64_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArrayWithLimit(tif, direntry, &count, 8, &origdata, + maxcount); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + *value = (uint64_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8(*value, count); + return (TIFFReadDirEntryErrOk); + case TIFF_SLONG8: + { + int64_t *m; + uint32_t n; + m = (int64_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)m); + err = TIFFReadDirEntryCheckRangeLong8Slong8(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (uint64_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + } + data = (uint64_t *)_TIFFmallocExt(tif, count * 8); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + uint64_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (uint64_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + uint64_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeLong8Sbyte(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint64_t)(*ma++); + } + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + uint64_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (uint64_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + uint64_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + err = TIFFReadDirEntryCheckRangeLong8Sshort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint64_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + uint64_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (uint64_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + uint64_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeLong8Slong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint64_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) +{ + return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, + ~((uint64_t)0)); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value) +{ + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + int64_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + { + uint64_t *m; + uint32_t n; + m = (uint64_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(m); + err = TIFFReadDirEntryCheckRangeSlong8Long8(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (int64_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + *value = (int64_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64_t *)(*value), count); + return (TIFFReadDirEntryErrOk); + } + data = (int64_t *)_TIFFmallocExt(tif, count * 8); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + int64_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int64_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + int64_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int64_t)(*ma++); + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + int64_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (int64_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + int64_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + *mb++ = (int64_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + int64_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (int64_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + int64_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + *mb++ = (int64_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + *value = data; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value) +{ + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + float *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + case TIFF_DOUBLE: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_FLOAT: + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)origdata, count); + TIFFCvtIEEEDoubleToNative(tif, count, (float *)origdata); + *value = (float *)origdata; + return (TIFFReadDirEntryErrOk); + } + data = (float *)_TIFFmallocExt(tif, count * sizeof(float)); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + float *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (float)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + float *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (float)(*ma++); + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + float *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + float *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + float *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + float *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + float *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); #if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support - * conversion of 64-bit integers into - * floating point values. - */ - *mb++ = _TIFFUInt64ToDouble(*ma++); + /* + * XXX: MSVC 6.0 does not support + * conversion of 64-bit integers into + * floating point values. + */ + *mb++ = _TIFFUInt64ToFloat(*ma++); #else - *mb++ = (double)(*ma++); + *mb++ = (float)(*ma++); #endif - } - } - break; - case TIFF_SLONG8: - { - int64* ma; - double* mb; - uint32 n; - ma=(int64*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_RATIONAL: - { - uint32* ma; - uint32 maa; - uint32 mab; - double* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*ma++; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - mab=*ma++; - if (mab==0) - *mb++=0.0; - else - *mb++=(double)maa/(double)mab; - } - } - break; - case TIFF_SRATIONAL: - { - uint32* ma; - int32 maa; - uint32 mab; - double* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*(int32*)ma; - ma++; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - mab=*ma++; - if (mab==0) - *mb++=0.0; - else - *mb++=(double)maa/(double)mab; - } - } - break; - case TIFF_FLOAT: - { - float* ma; - double* mb; - uint32 n; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32*)origdata,count); - TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata); - ma=(float*)origdata; - mb=data; - for (n=0; ntif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_RATIONAL: + { + uint32_t *ma; + uint32_t maa; + uint32_t mab; + float *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + maa = *ma++; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + mab = *ma++; + if (mab == 0) + *mb++ = 0.0; + else + *mb++ = (float)maa / (float)mab; + } + } + break; + case TIFF_SRATIONAL: + { + uint32_t *ma; + int32_t maa; + uint32_t mab; + float *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + maa = *(int32_t *)ma; + ma++; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + mab = *ma++; + if (mab == 0) + *mb++ = 0.0; + else + *mb++ = (float)maa / (float)mab; + } + } + break; + case TIFF_DOUBLE: + { + double *ma; + float *mb; + uint32_t n; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64_t *)origdata, count); + TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata); + ma = (double *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + double val = *ma++; + if (val > FLT_MAX) + val = FLT_MAX; + else if (val < -FLT_MAX) + val = -FLT_MAX; + *mb++ = (float)val; + } + } + break; + } + _TIFFfreeExt(tif, origdata); + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value) { - enum TIFFReadDirEntryErr err; - uint32 count; - void* origdata; - uint64* data; - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_LONG8: - case TIFF_IFD: - case TIFF_IFD8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG8: - case TIFF_IFD8: - *value=(uint64*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(*value,count); - return(TIFFReadDirEntryErrOk); - } - data=(uint64*)_TIFFmalloc(count*8); - if (data==0) - { - _TIFFfree(origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_IFD: - { - uint32* ma; - uint64* mb; - uint32 n; - ma=(uint32*)origdata; - mb=data; - for (n=0; ntif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(uint64)(*ma++); - } - } - break; - } - _TIFFfree(origdata); - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + double *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + case TIFF_DOUBLE: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_DOUBLE: + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64_t *)origdata, count); + TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata); + *value = (double *)origdata; + return (TIFFReadDirEntryErrOk); + } + data = (double *)_TIFFmallocExt(tif, count * sizeof(double)); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + double *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (double)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + double *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (double)(*ma++); + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + double *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + double *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + double *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + double *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + double *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); +#if defined(__WIN32__) && (_MSC_VER < 1500) + /* + * XXX: MSVC 6.0 does not support + * conversion of 64-bit integers into + * floating point values. + */ + *mb++ = _TIFFUInt64ToDouble(*ma++); +#else + *mb++ = (double)(*ma++); +#endif + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + double *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_RATIONAL: + { + uint32_t *ma; + uint32_t maa; + uint32_t mab; + double *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + maa = *ma++; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + mab = *ma++; + if (mab == 0) + *mb++ = 0.0; + else + *mb++ = (double)maa / (double)mab; + } + } + break; + case TIFF_SRATIONAL: + { + uint32_t *ma; + int32_t maa; + uint32_t mab; + double *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + maa = *(int32_t *)ma; + ma++; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + mab = *ma++; + if (mab == 0) + *mb++ = 0.0; + else + *mb++ = (double)maa / (double)mab; + } + } + break; + case TIFF_FLOAT: + { + float *ma; + double *mb; + uint32_t n; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)origdata, count); + TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata); + ma = (float *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (double)(*ma++); + } + break; + } + _TIFFfreeExt(tif, origdata); + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) { - enum TIFFReadDirEntryErr err; - uint16* m; - uint16* na; - uint16 nb; - if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel) - return(TIFFReadDirEntryErrCount); - err=TIFFReadDirEntryShortArray(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk || m == NULL) - return(err); - na=m; - nb=tif->tif_dir.td_samplesperpixel; - *value=*na++; - nb--; - while (nb>0) - { - if (*na++!=*value) - { - err=TIFFReadDirEntryErrPsdif; - break; - } - nb--; - } - _TIFFfree(m); - return(err); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint64_t *data; + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_LONG8: + case TIFF_IFD: + case TIFF_IFD8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + case TIFF_IFD8: + *value = (uint64_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8(*value, count); + return (TIFFReadDirEntryErrOk); + } + data = (uint64_t *)_TIFFmallocExt(tif, count * 8); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_IFD: + { + uint32_t *ma; + uint64_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (uint64_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + *value = data; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry, + uint16_t *value) +{ + enum TIFFReadDirEntryErr err; + uint16_t *m; + uint16_t *na; + uint16_t nb; + if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel) + return (TIFFReadDirEntryErrCount); + err = TIFFReadDirEntryShortArray(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk || m == NULL) + return (err); + na = m; + nb = tif->tif_dir.td_samplesperpixel; + *value = *na++; + nb--; + while (nb > 0) + { + if (*na++ != *value) + { + err = TIFFReadDirEntryErrPsdif; + break; + } + nb--; + } + _TIFFfreeExt(tif, m); + return (err); +} + +static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry, + uint8_t *value) +{ + (void)tif; + *value = *(uint8_t *)(&direntry->tdir_offset); +} + +static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry, + int8_t *value) +{ + (void)tif; + *value = *(int8_t *)(&direntry->tdir_offset); +} + +static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry, + uint16_t *value) +{ + *value = direntry->tdir_offset.toff_short; + /* *value=*(uint16_t*)(&direntry->tdir_offset); */ + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(value); +} + +static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry, + int16_t *value) +{ + *value = *(int16_t *)(&direntry->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)value); +} + +static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry, + uint32_t *value) +{ + *value = *(uint32_t *)(&direntry->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(value); +} + +static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry, + int32_t *value) +{ + *value = *(int32_t *)(&direntry->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)value); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) +{ + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, value); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + *value = direntry->tdir_offset.toff_long8; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(value); + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) +{ + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, value); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + *value = *(int64_t *)(&direntry->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)value); + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry, + double *value) +{ + UInt64Aligned_t m; + + assert(sizeof(double) == 8); + assert(sizeof(uint64_t) == 8); + assert(sizeof(uint32_t) == 4); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, m.i); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + m.l = direntry->tdir_offset.toff_long8; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m.i, 2); + /* Not completely sure what we should do when m.i[1]==0, but some */ + /* sanitizers do not like division by 0.0: */ + /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ + if (m.i[0] == 0 || m.i[1] == 0) + *value = 0.0; + else + *value = (double)m.i[0] / (double)m.i[1]; + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry, + double *value) +{ + UInt64Aligned_t m; + assert(sizeof(double) == 8); + assert(sizeof(uint64_t) == 8); + assert(sizeof(int32_t) == 4); + assert(sizeof(uint32_t) == 4); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, m.i); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + m.l = direntry->tdir_offset.toff_long8; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m.i, 2); + /* Not completely sure what we should do when m.i[1]==0, but some */ + /* sanitizers do not like division by 0.0: */ + /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ + if ((int32_t)m.i[0] == 0 || m.i[1] == 0) + *value = 0.0; + else + *value = (double)((int32_t)m.i[0]) / (double)m.i[1]; + return (TIFFReadDirEntryErrOk); } #if 0 -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) -{ - enum TIFFReadDirEntryErr err; - double* m; - double* na; - uint16 nb; - if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel) - return(TIFFReadDirEntryErrCount); - err=TIFFReadDirEntryDoubleArray(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - na=m; - nb=tif->tif_dir.td_samplesperpixel; - *value=*na++; - nb--; - while (nb>0) - { - if (*na++!=*value) - { - err=TIFFReadDirEntryErrPsdif; - break; - } - nb--; - } - _TIFFfree(m); - return(err); -} +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry, + TIFFRational_t *value) +{ /*--: SetGetRATIONAL_directly:_CustomTag: Read rational (and signed rationals) + directly --*/ + UInt64Aligned_t m; + + assert(sizeof(double) == 8); + assert(sizeof(uint64_t) == 8); + assert(sizeof(uint32_t) == 4); + + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + + if (direntry->tdir_type != TIFF_RATIONAL && + direntry->tdir_type != TIFF_SRATIONAL) + return (TIFFReadDirEntryErrType); + + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, m.i); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + { + m.l = direntry->tdir_offset.toff_long8; + } + + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m.i, 2); + + value->uNum = m.i[0]; + value->uDenom = m.i[1]; + return (TIFFReadDirEntryErrOk); +} /*-- TIFFReadDirEntryCheckedRationalDirect() --*/ #endif -static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value) +static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry, + float *value) { - (void) tif; - *value=*(uint8*)(&direntry->tdir_offset); -} - -static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value) -{ - (void) tif; - *value=*(int8*)(&direntry->tdir_offset); -} - -static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) -{ - *value = direntry->tdir_offset.toff_short; - /* *value=*(uint16*)(&direntry->tdir_offset); */ - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(value); -} - -static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value) -{ - *value=*(int16*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)value); -} - -static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value) -{ - *value=*(uint32*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(value); -} - -static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value) -{ - *value=*(int32*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)value); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) -{ - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,value); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - *value = direntry->tdir_offset.toff_long8; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(value); - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value) -{ - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,value); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - *value=*(int64*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)value); - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value) -{ - UInt64Aligned_t m; - - assert(sizeof(double)==8); - assert(sizeof(uint64)==8); - assert(sizeof(uint32)==4); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,m.i); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - m.l = direntry->tdir_offset.toff_long8; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m.i,2); - /* Not completely sure what we should do when m.i[1]==0, but some */ - /* sanitizers do not like division by 0.0: */ - /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ - if (m.i[0]==0 || m.i[1]==0) - *value=0.0; - else - *value=(double)m.i[0]/(double)m.i[1]; - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value) -{ - UInt64Aligned_t m; - assert(sizeof(double)==8); - assert(sizeof(uint64)==8); - assert(sizeof(int32)==4); - assert(sizeof(uint32)==4); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,m.i); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - m.l=direntry->tdir_offset.toff_long8; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m.i,2); - /* Not completely sure what we should do when m.i[1]==0, but some */ - /* sanitizers do not like division by 0.0: */ - /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ - if ((int32)m.i[0]==0 || m.i[1]==0) - *value=0.0; - else - *value=(double)((int32)m.i[0])/(double)m.i[1]; - return(TIFFReadDirEntryErrOk); -} - -static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) -{ - union - { - float f; - uint32 i; - } float_union; - assert(sizeof(float)==4); - assert(sizeof(uint32)==4); - assert(sizeof(float_union)==4); - float_union.i=*(uint32*)(&direntry->tdir_offset); - *value=float_union.f; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)value); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) -{ - assert(sizeof(double)==8); - assert(sizeof(uint64)==8); - assert(sizeof(UInt64Aligned_t)==8); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32 offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,value); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - { - UInt64Aligned_t uint64_union; - uint64_union.l=direntry->tdir_offset.toff_long8; - *value=uint64_union.d; - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)value); - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value) -{ - if (value>0xFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value) -{ - if ((value<0)||(value>0xFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value) -{ - if (value>0xFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value) -{ - if ((value<0)||(value>0xFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value) -{ - if (value>0xFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value) -{ - if ((value<0)||(value>0xFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value) -{ - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value) -{ - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value) -{ - if ((value<-0x80)||(value>0x7F)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value) -{ - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value) -{ - if ((value<-0x80)||(value>0x7F)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value) -{ - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value) -{ - if ((value<-0x80)||(value>0x7F)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value) -{ - if (value>0xFFFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value) -{ - if ((value<0)||(value>0xFFFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value) -{ - if (value>0xFFFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value) -{ - if ((value<0)||(value>0xFFFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value) -{ - if (value>0x7FFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value) -{ - if (value>0x7FFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value) -{ - if ((value<-0x8000)||(value>0x7FFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value) -{ - if (value>0x7FFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value) -{ - if ((value<-0x8000)||(value>0x7FFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); -} - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value) -{ - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + union + { + float f; + uint32_t i; + } float_union; + assert(sizeof(float) == 4); + assert(sizeof(uint32_t) == 4); + assert(sizeof(float_union) == 4); + float_union.i = *(uint32_t *)(&direntry->tdir_offset); + *value = float_union.f; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)value); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongLong8(uint64 value) +TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value) { - if (value > TIFF_UINT32_MAX) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + assert(sizeof(double) == 8); + assert(sizeof(uint64_t) == 8); + assert(sizeof(UInt64Aligned_t) == 8); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, value); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + { + UInt64Aligned_t uint64_union; + uint64_union.l = direntry->tdir_offset.toff_long8; + *value = uint64_union.d; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)value); + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLongSlong8(int64 value) +TIFFReadDirEntryCheckRangeByteSbyte(int8_t value) { - if ((value < 0) || (value > (int64) TIFF_UINT32_MAX)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongLong(uint32 value) +TIFFReadDirEntryCheckRangeByteShort(uint16_t value) { - if (value > 0x7FFFFFFFUL) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0xFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSshort(int16_t value) +{ + if ((value < 0) || (value > 0xFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteLong(uint32_t value) +{ + if (value > 0xFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSlong(int32_t value) +{ + if ((value < 0) || (value > 0xFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteLong8(uint64_t value) +{ + if (value > 0xFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSlong8(int64_t value) +{ + if ((value < 0) || (value > 0xFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value) +{ + if (value > 0x7F) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value) +{ + if (value > 0x7F) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value) +{ + if ((value < -0x80) || (value > 0x7F)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value) +{ + if (value > 0x7F) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value) +{ + if ((value < -0x80) || (value > 0x7F)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value) +{ + if (value > 0x7F) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value) +{ + if ((value < -0x80) || (value > 0x7F)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSbyte(int8_t value) +{ + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSshort(int16_t value) +{ + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortLong(uint32_t value) +{ + if (value > 0xFFFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSlong(int32_t value) +{ + if ((value < 0) || (value > 0xFFFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortLong8(uint64_t value) +{ + if (value > 0xFFFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSlong8(int64_t value) +{ + if ((value < 0) || (value > 0xFFFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortShort(uint16_t value) +{ + if (value > 0x7FFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortLong(uint32_t value) +{ + if (value > 0x7FFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortSlong(int32_t value) +{ + if ((value < -0x8000) || (value > 0x7FFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value) +{ + if (value > 0x7FFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value) +{ + if ((value < -0x8000) || (value > 0x7FFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSbyte(int8_t value) +{ + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSshort(int16_t value) +{ + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSlong(int32_t value) +{ + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongLong8(uint64_t value) +{ + if (value > UINT32_MAX) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSlong8(int64_t value) +{ + if ((value < 0) || (value > (int64_t)UINT32_MAX)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongLong(uint32_t value) +{ + if (value > 0x7FFFFFFFUL) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } /* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */ static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongLong8(uint64 value) +TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value) { - if (value > 0x7FFFFFFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7FFFFFFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } /* Check that the 8-byte signed value can fit in a 4-byte signed range */ static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlongSlong8(int64 value) +TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value) { - if ((value < 0-((int64) 0x7FFFFFFF+1)) || (value > 0x7FFFFFFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < 0 - ((int64_t)0x7FFFFFFF + 1)) || (value > 0x7FFFFFFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value) +TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value) { - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Sshort(int16 value) +TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value) { - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Slong(int32 value) +TIFFReadDirEntryCheckRangeLong8Slong(int32_t value) { - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeLong8Slong8(int64 value) +TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value) { - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value) +TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value) { - if (value > TIFF_INT64_MAX) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > INT64_MAX) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr -TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest) +static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset, + tmsize_t size, void *dest) { - assert(size>0); - if (!isMapped(tif)) { - if (!SeekOK(tif,offset)) - return(TIFFReadDirEntryErrIo); - if (!ReadOK(tif,dest,size)) - return(TIFFReadDirEntryErrIo); - } else { - size_t ma,mb; - ma=(size_t)offset; - if( (uint64)ma!=offset || - ma > (~(size_t)0) - (size_t)size ) - { - return TIFFReadDirEntryErrIo; - } - mb=ma+size; - if (mb > (uint64)tif->tif_size) - return(TIFFReadDirEntryErrIo); - _TIFFmemcpy(dest,tif->tif_base+ma,size); - } - return(TIFFReadDirEntryErrOk); + assert(size > 0); + if (!isMapped(tif)) + { + if (!SeekOK(tif, offset)) + return (TIFFReadDirEntryErrIo); + if (!ReadOK(tif, dest, size)) + return (TIFFReadDirEntryErrIo); + } + else + { + size_t ma, mb; + ma = (size_t)offset; + if ((uint64_t)ma != offset || ma > (~(size_t)0) - (size_t)size) + { + return TIFFReadDirEntryErrIo; + } + mb = ma + size; + if (mb > (uint64_t)tif->tif_size) + return (TIFFReadDirEntryErrIo); + _TIFFmemcpy(dest, tif->tif_base + ma, size); + } + return (TIFFReadDirEntryErrOk); } -static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover) +static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, + const char *module, const char *tagname, + int recover) { - if (!recover) { - switch (err) { - case TIFFReadDirEntryErrCount: - TIFFErrorExt(tif->tif_clientdata, module, - "Incorrect count for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrType: - TIFFErrorExt(tif->tif_clientdata, module, - "Incompatible type for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrIo: - TIFFErrorExt(tif->tif_clientdata, module, - "IO error during reading of \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrRange: - TIFFErrorExt(tif->tif_clientdata, module, - "Incorrect value for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrPsdif: - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle different values per sample for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrSizesan: - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on size of \"%s\" value failed", - tagname); - break; - case TIFFReadDirEntryErrAlloc: - TIFFErrorExt(tif->tif_clientdata, module, - "Out of memory reading of \"%s\"", - tagname); - break; - default: - assert(0); /* we should never get here */ - break; - } - } else { - switch (err) { - case TIFFReadDirEntryErrCount: - TIFFWarningExt(tif->tif_clientdata, module, - "Incorrect count for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrType: - TIFFWarningExt(tif->tif_clientdata, module, - "Incompatible type for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrIo: - TIFFWarningExt(tif->tif_clientdata, module, - "IO error during reading of \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrRange: - TIFFWarningExt(tif->tif_clientdata, module, - "Incorrect value for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrPsdif: - TIFFWarningExt(tif->tif_clientdata, module, - "Cannot handle different values per sample for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrSizesan: - TIFFWarningExt(tif->tif_clientdata, module, - "Sanity check on size of \"%s\" value failed; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrAlloc: - TIFFWarningExt(tif->tif_clientdata, module, - "Out of memory reading of \"%s\"; tag ignored", - tagname); - break; - default: - assert(0); /* we should never get here */ - break; - } - } + if (!recover) + { + switch (err) + { + case TIFFReadDirEntryErrCount: + TIFFErrorExtR(tif, module, "Incorrect count for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrType: + TIFFErrorExtR(tif, module, "Incompatible type for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrIo: + TIFFErrorExtR(tif, module, "IO error during reading of \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrRange: + TIFFErrorExtR(tif, module, "Incorrect value for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrPsdif: + TIFFErrorExtR( + tif, module, + "Cannot handle different values per sample for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrSizesan: + TIFFErrorExtR(tif, module, + "Sanity check on size of \"%s\" value failed", + tagname); + break; + case TIFFReadDirEntryErrAlloc: + TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"", + tagname); + break; + default: + assert(0); /* we should never get here */ + break; + } + } + else + { + switch (err) + { + case TIFFReadDirEntryErrCount: + TIFFWarningExtR(tif, module, + "Incorrect count for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrType: + TIFFWarningExtR(tif, module, + "Incompatible type for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrIo: + TIFFWarningExtR( + tif, module, + "IO error during reading of \"%s\"; tag ignored", tagname); + break; + case TIFFReadDirEntryErrRange: + TIFFWarningExtR(tif, module, + "Incorrect value for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrPsdif: + TIFFWarningExtR(tif, module, + "Cannot handle different values per sample for " + "\"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrSizesan: + TIFFWarningExtR( + tif, module, + "Sanity check on size of \"%s\" value failed; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrAlloc: + TIFFWarningExtR(tif, module, + "Out of memory reading of \"%s\"; tag ignored", + tagname); + break; + default: + assert(0); /* we should never get here */ + break; + } + } } /* @@ -3506,1254 +4028,1709 @@ static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, c * type. 0 is returned if photometric type isn't supported or no default value * is defined by the specification. */ -static int _TIFFGetMaxColorChannels( uint16 photometric ) +static int _TIFFGetMaxColorChannels(uint16_t photometric) { - switch (photometric) { - case PHOTOMETRIC_PALETTE: - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: + switch (photometric) + { + case PHOTOMETRIC_PALETTE: + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: return 1; - case PHOTOMETRIC_YCBCR: - case PHOTOMETRIC_RGB: - case PHOTOMETRIC_CIELAB: - case PHOTOMETRIC_LOGLUV: - case PHOTOMETRIC_ITULAB: - case PHOTOMETRIC_ICCLAB: + case PHOTOMETRIC_YCBCR: + case PHOTOMETRIC_RGB: + case PHOTOMETRIC_CIELAB: + case PHOTOMETRIC_LOGLUV: + case PHOTOMETRIC_ITULAB: + case PHOTOMETRIC_ICCLAB: return 3; - case PHOTOMETRIC_SEPARATED: - case PHOTOMETRIC_MASK: + case PHOTOMETRIC_SEPARATED: + case PHOTOMETRIC_MASK: return 4; - case PHOTOMETRIC_LOGL: - case PHOTOMETRIC_CFA: - default: + case PHOTOMETRIC_LOGL: + case PHOTOMETRIC_CFA: + default: return 0; } } -static int ByteCountLooksBad(TIFF* tif) +static int ByteCountLooksBad(TIFF *tif) { /* - * Assume we have wrong StripByteCount value (in case - * of single strip) in following cases: - * - it is equal to zero along with StripOffset; - * - it is larger than file itself (in case of uncompressed - * image); - * - it is smaller than the size of the bytes per row - * multiplied on the number of rows. The last case should - * not be checked in the case of writing new image, - * because we may do not know the exact strip size - * until the whole image will be written and directory - * dumped out. - */ - uint64 bytecount = TIFFGetStrileByteCount(tif, 0); - uint64 offset = TIFFGetStrileOffset(tif, 0); - uint64 filesize; + * Assume we have wrong StripByteCount value (in case + * of single strip) in following cases: + * - it is equal to zero along with StripOffset; + * - it is larger than file itself (in case of uncompressed + * image); + * - it is smaller than the size of the bytes per row + * multiplied on the number of rows. The last case should + * not be checked in the case of writing new image, + * because we may do not know the exact strip size + * until the whole image will be written and directory + * dumped out. + */ + uint64_t bytecount = TIFFGetStrileByteCount(tif, 0); + uint64_t offset = TIFFGetStrileOffset(tif, 0); + uint64_t filesize; - if( offset == 0 ) + if (offset == 0) return 0; if (bytecount == 0) return 1; - if ( tif->tif_dir.td_compression != COMPRESSION_NONE ) + if (tif->tif_dir.td_compression != COMPRESSION_NONE) return 0; filesize = TIFFGetFileSize(tif); - if( offset <= filesize && bytecount > filesize - offset ) + if (offset <= filesize && bytecount > filesize - offset) return 1; - if( tif->tif_mode == O_RDONLY ) + if (tif->tif_mode == O_RDONLY) { - uint64 scanlinesize = TIFFScanlineSize64(tif); - if( tif->tif_dir.td_imagelength > 0 && - scanlinesize > TIFF_UINT64_MAX / tif->tif_dir.td_imagelength ) + uint64_t scanlinesize = TIFFScanlineSize64(tif); + if (tif->tif_dir.td_imagelength > 0 && + scanlinesize > UINT64_MAX / tif->tif_dir.td_imagelength) { return 1; } - if( bytecount < scanlinesize * tif->tif_dir.td_imagelength) + if (bytecount < scanlinesize * tif->tif_dir.td_imagelength) return 1; } return 0; } - /* * Read the next TIFF directory from a file and convert it to the internal * format. We read directories sequentially. */ -int -TIFFReadDirectory(TIFF* tif) +int TIFFReadDirectory(TIFF *tif) { - static const char module[] = "TIFFReadDirectory"; - TIFFDirEntry* dir; - uint16 dircount; - TIFFDirEntry* dp; - uint16 di; - const TIFFField* fip; - uint32 fii=FAILED_FII; - toff_t nextdiroff; + static const char module[] = "TIFFReadDirectory"; + TIFFDirEntry *dir; + uint16_t dircount; + TIFFDirEntry *dp; + uint16_t di; + const TIFFField *fip; + uint32_t fii = FAILED_FII; + toff_t nextdiroff; int bitspersample_read = FALSE; - int color_channels; + int color_channels; - tif->tif_diroff=tif->tif_nextdiroff; - if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff)) - return 0; /* last offset or bad offset (IFD looping) */ - (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ - tif->tif_curdir++; - nextdiroff = tif->tif_nextdiroff; - dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff); - if (!dircount) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff); - return 0; - } - TIFFReadDirectoryCheckOrder(tif,dir,dircount); - - /* - * Mark duplicates of any tag to be ignored (bugzilla 1994) - * to avoid certain pathological problems. + if (tif->tif_nextdiroff == 0) + { + /* In this special case, tif_diroff needs also to be set to 0. + * This is behind the last IFD, thus no checking or reading necessary. */ - { - TIFFDirEntry* ma; - uint16 mb; - for (ma=dir, mb=0; mbtdir_tag == na->tdir_tag) { - na->tdir_ignore = TRUE; - } - } - } - } - - tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ - tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */ - tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS; + tif->tif_diroff = tif->tif_nextdiroff; + return 0; + } - /* free any old stuff and reinit */ - TIFFFreeDirectory(tif); - TIFFDefaultDirectory(tif); - /* - * Electronic Arts writes gray-scale TIFF files - * without a PlanarConfiguration directory entry. - * Thus we setup a default value here, even though - * the TIFF spec says there is no default value. - */ - TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG); - /* - * Setup default value and then make a pass over - * the fields to check type and tag information, - * and to extract info required to size data - * structures. A second pass is made afterwards - * to read in everything not taken in the first pass. - * But we must process the Compression tag first - * in order to merge in codec-private tag definitions (otherwise - * we may get complaints about unknown tags). However, the - * Compression tag may be dependent on the SamplesPerPixel - * tag value because older TIFF specs permitted Compression - * to be written as a SamplesPerPixel-count tag entry. - * Thus if we don't first figure out the correct SamplesPerPixel - * tag value then we may end up ignoring the Compression tag - * value because it has an incorrect count value (if the - * true value of SamplesPerPixel is not 1). - */ - dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL); - if (dp) - { - if (!TIFFFetchNormalTag(tif,dp,0)) - goto bad; - dp->tdir_ignore = TRUE; - } - dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION); - if (dp) - { - /* - * The 5.0 spec says the Compression tag has one value, while - * earlier specs say it has one value per sample. Because of - * this, we accept the tag if one value is supplied with either - * count. - */ - uint16 value; - enum TIFFReadDirEntryErr err; - err=TIFFReadDirEntryShort(tif,dp,&value); - if (err==TIFFReadDirEntryErrCount) - err=TIFFReadDirEntryPersampleShort(tif,dp,&value); - if (err!=TIFFReadDirEntryErrOk) - { - TIFFReadDirEntryOutputErr(tif,err,module,"Compression",0); - goto bad; - } - if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value)) - goto bad; - dp->tdir_ignore = TRUE; - } - else - { - if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE)) - goto bad; - } - /* - * First real pass over the directory. - */ - for (di=0, dp=dir; ditdir_ignore) - { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - if (fii == FAILED_FII) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Unknown field with tag %d (0x%x) encountered", - dp->tdir_tag,dp->tdir_tag); - /* the following knowingly leaks the - anonymous field structure */ - if (!_TIFFMergeFields(tif, - _TIFFCreateAnonField(tif, - dp->tdir_tag, - (TIFFDataType) dp->tdir_type), - 1)) { - TIFFWarningExt(tif->tif_clientdata, - module, - "Registering anonymous field with tag %d (0x%x) failed", - dp->tdir_tag, - dp->tdir_tag); - dp->tdir_ignore = TRUE; - } else { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - assert(fii != FAILED_FII); - } - } - } - if (!dp->tdir_ignore) - { - fip=tif->tif_fields[fii]; - if (fip->field_bit==FIELD_IGNORE) - dp->tdir_ignore = TRUE; - else - { - switch (dp->tdir_tag) - { - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEOFFSETS: - case TIFFTAG_TILEBYTECOUNTS: - TIFFSetFieldBit(tif,fip->field_bit); - break; - case TIFFTAG_IMAGEWIDTH: - case TIFFTAG_IMAGELENGTH: - case TIFFTAG_IMAGEDEPTH: - case TIFFTAG_TILELENGTH: - case TIFFTAG_TILEWIDTH: - case TIFFTAG_TILEDEPTH: - case TIFFTAG_PLANARCONFIG: - case TIFFTAG_ROWSPERSTRIP: - case TIFFTAG_EXTRASAMPLES: - if (!TIFFFetchNormalTag(tif,dp,0)) - goto bad; - dp->tdir_ignore = TRUE; - break; - default: - if( !_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag) ) - dp->tdir_ignore = TRUE; - break; - } - } - } - } - /* - * XXX: OJPEG hack. - * If a) compression is OJPEG, b) planarconfig tag says it's separate, - * c) strip offsets/bytecounts tag are both present and - * d) both contain exactly one value, then we consistently find - * that the buggy implementation of the buggy compression scheme - * matches contig planarconfig best. So we 'fix-up' the tag here - */ - if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&& - (tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE)) - { - if (!_TIFFFillStriles(tif)) - goto bad; - dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS); - if ((dp!=0)&&(dp->tdir_count==1)) - { - dp=TIFFReadDirectoryFindEntry(tif,dir,dircount, - TIFFTAG_STRIPBYTECOUNTS); - if ((dp!=0)&&(dp->tdir_count==1)) - { - tif->tif_dir.td_planarconfig=PLANARCONFIG_CONTIG; - TIFFWarningExt(tif->tif_clientdata,module, - "Planarconfig tag value assumed incorrect, " - "assuming data is contig instead of chunky"); - } - } - } - /* - * Allocate directory structure and setup defaults. - */ - if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) - { - MissingRequired(tif,"ImageLength"); - goto bad; - } - /* - * Setup appropriate structures (by strip or by tile) - */ - if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { - tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); - tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; - tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; - tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; - tif->tif_flags &= ~TIFF_ISTILED; - } else { - tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); - tif->tif_flags |= TIFF_ISTILED; - } - if (!tif->tif_dir.td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle zero number of %s", - isTiled(tif) ? "tiles" : "strips"); - goto bad; - } - tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; - if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) - tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; - if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) { + nextdiroff = tif->tif_nextdiroff; + /* tif_curdir++ and tif_nextdiroff should only be updated after SUCCESSFUL + * reading of the directory. Otherwise, invalid IFD offsets could corrupt + * the IFD list. */ + if (!_TIFFCheckDirNumberAndOffset(tif, + tif->tif_curdir == + TIFF_NON_EXISTENT_DIR_NUMBER + ? 0 + : tif->tif_curdir + 1, + nextdiroff)) + { + return 0; /* bad offset (IFD looping or more than TIFF_MAX_DIR_COUNT + IFDs) */ + } + dircount = TIFFFetchDirectory(tif, nextdiroff, &dir, &tif->tif_nextdiroff); + if (!dircount) + { + TIFFErrorExtR(tif, module, + "Failed to read directory at offset %" PRIu64, + nextdiroff); + return 0; + } + /* Set global values after a valid directory has been fetched. + * tif_diroff is already set to nextdiroff in TIFFFetchDirectory() in the + * beginning. */ + if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER) + tif->tif_curdir = 0; + else + tif->tif_curdir++; + (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ + + TIFFReadDirectoryCheckOrder(tif, dir, dircount); + + /* + * Mark duplicates of any tag to be ignored (bugzilla 1994) + * to avoid certain pathological problems. + */ + { + TIFFDirEntry *ma; + uint16_t mb; + for (ma = dir, mb = 0; mb < dircount; ma++, mb++) + { + TIFFDirEntry *na; + uint16_t nb; + for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++) + { + if (ma->tdir_tag == na->tdir_tag) + { + na->tdir_ignore = TRUE; + } + } + } + } + + tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ + tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */ + tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS; + + /* free any old stuff and reinit */ + TIFFFreeDirectory(tif); + TIFFDefaultDirectory(tif); + /* + * Electronic Arts writes gray-scale TIFF files + * without a PlanarConfiguration directory entry. + * Thus we setup a default value here, even though + * the TIFF spec says there is no default value. + * After PlanarConfiguration is preset in TIFFDefaultDirectory() + * the following setting is not needed, but does not harm either. + */ + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + /* + * Setup default value and then make a pass over + * the fields to check type and tag information, + * and to extract info required to size data + * structures. A second pass is made afterwards + * to read in everything not taken in the first pass. + * But we must process the Compression tag first + * in order to merge in codec-private tag definitions (otherwise + * we may get complaints about unknown tags). However, the + * Compression tag may be dependent on the SamplesPerPixel + * tag value because older TIFF specs permitted Compression + * to be written as a SamplesPerPixel-count tag entry. + * Thus if we don't first figure out the correct SamplesPerPixel + * tag value then we may end up ignoring the Compression tag + * value because it has an incorrect count value (if the + * true value of SamplesPerPixel is not 1). + */ + dp = + TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_SAMPLESPERPIXEL); + if (dp) + { + if (!TIFFFetchNormalTag(tif, dp, 0)) + goto bad; + dp->tdir_ignore = TRUE; + } + dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_COMPRESSION); + if (dp) + { + /* + * The 5.0 spec says the Compression tag has one value, while + * earlier specs say it has one value per sample. Because of + * this, we accept the tag if one value is supplied with either + * count. + */ + uint16_t value; + enum TIFFReadDirEntryErr err; + err = TIFFReadDirEntryShort(tif, dp, &value); + if (err == TIFFReadDirEntryErrCount) + err = TIFFReadDirEntryPersampleShort(tif, dp, &value); + if (err != TIFFReadDirEntryErrOk) + { + TIFFReadDirEntryOutputErr(tif, err, module, "Compression", 0); + goto bad; + } + if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, value)) + goto bad; + dp->tdir_ignore = TRUE; + } + else + { + if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE)) + goto bad; + } + /* + * First real pass over the directory. + */ + for (di = 0, dp = dir; di < dircount; di++, dp++) + { + if (!dp->tdir_ignore) + { + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + if (fii == FAILED_FII) + { + TIFFWarningExtR(tif, module, + "Unknown field with tag %" PRIu16 " (0x%" PRIx16 + ") encountered", + dp->tdir_tag, dp->tdir_tag); + /* the following knowingly leaks the + anonymous field structure */ + if (!_TIFFMergeFields( + tif, + _TIFFCreateAnonField(tif, dp->tdir_tag, + (TIFFDataType)dp->tdir_type), + 1)) + { + TIFFWarningExtR( + tif, module, + "Registering anonymous field with tag %" PRIu16 + " (0x%" PRIx16 ") failed", + dp->tdir_tag, dp->tdir_tag); + dp->tdir_ignore = TRUE; + } + else + { + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + assert(fii != FAILED_FII); + } + } + } + if (!dp->tdir_ignore) + { + fip = tif->tif_fields[fii]; + if (fip->field_bit == FIELD_IGNORE) + dp->tdir_ignore = TRUE; + else + { + switch (dp->tdir_tag) + { + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEOFFSETS: + case TIFFTAG_TILEBYTECOUNTS: + TIFFSetFieldBit(tif, fip->field_bit); + break; + case TIFFTAG_IMAGEWIDTH: + case TIFFTAG_IMAGELENGTH: + case TIFFTAG_IMAGEDEPTH: + case TIFFTAG_TILELENGTH: + case TIFFTAG_TILEWIDTH: + case TIFFTAG_TILEDEPTH: + case TIFFTAG_PLANARCONFIG: + case TIFFTAG_ROWSPERSTRIP: + case TIFFTAG_EXTRASAMPLES: + if (!TIFFFetchNormalTag(tif, dp, 0)) + goto bad; + dp->tdir_ignore = TRUE; + break; + default: + if (!_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag)) + dp->tdir_ignore = TRUE; + break; + } + } + } + } + /* + * XXX: OJPEG hack. + * If a) compression is OJPEG, b) planarconfig tag says it's separate, + * c) strip offsets/bytecounts tag are both present and + * d) both contain exactly one value, then we consistently find + * that the buggy implementation of the buggy compression scheme + * matches contig planarconfig best. So we 'fix-up' the tag here + */ + if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) && + (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)) + { + if (!_TIFFFillStriles(tif)) + goto bad; + dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, + TIFFTAG_STRIPOFFSETS); + if ((dp != 0) && (dp->tdir_count == 1)) + { + dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, + TIFFTAG_STRIPBYTECOUNTS); + if ((dp != 0) && (dp->tdir_count == 1)) + { + tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG; + TIFFWarningExtR(tif, module, + "Planarconfig tag value assumed incorrect, " + "assuming data is contig instead of chunky"); + } + } + } + /* + * Allocate directory structure and setup defaults. + */ + if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) + { + MissingRequired(tif, "ImageLength"); + goto bad; + } + + /* + * Second pass: extract other information. + */ + for (di = 0, dp = dir; di < dircount; di++, dp++) + { + if (!dp->tdir_ignore) + { + switch (dp->tdir_tag) + { + case TIFFTAG_MINSAMPLEVALUE: + case TIFFTAG_MAXSAMPLEVALUE: + case TIFFTAG_BITSPERSAMPLE: + case TIFFTAG_DATATYPE: + case TIFFTAG_SAMPLEFORMAT: + /* + * The MinSampleValue, MaxSampleValue, BitsPerSample + * DataType and SampleFormat tags are supposed to be + * written as one value/sample, but some vendors + * incorrectly write one value only -- so we accept + * that as well (yuck). Other vendors write correct + * value for NumberOfSamples, but incorrect one for + * BitsPerSample and friends, and we will read this + * too. + */ + { + uint16_t value; + enum TIFFReadDirEntryErr err; + err = TIFFReadDirEntryShort(tif, dp, &value); + if (err == TIFFReadDirEntryErrCount) + err = + TIFFReadDirEntryPersampleShort(tif, dp, &value); + if (err != TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFReadDirEntryOutputErr( + tif, err, module, + fip ? fip->field_name : "unknown tagname", 0); + goto bad; + } + if (!TIFFSetField(tif, dp->tdir_tag, value)) + goto bad; + if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE) + bitspersample_read = TRUE; + } + break; + case TIFFTAG_SMINSAMPLEVALUE: + case TIFFTAG_SMAXSAMPLEVALUE: + { + + double *data = NULL; + enum TIFFReadDirEntryErr err; + uint32_t saved_flags; + int m; + if (dp->tdir_count != + (uint64_t)tif->tif_dir.td_samplesperpixel) + err = TIFFReadDirEntryErrCount; + else + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err != TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFReadDirEntryOutputErr( + tif, err, module, + fip ? fip->field_name : "unknown tagname", 0); + goto bad; + } + saved_flags = tif->tif_flags; + tif->tif_flags |= TIFF_PERSAMPLE; + m = TIFFSetField(tif, dp->tdir_tag, data); + tif->tif_flags = saved_flags; + _TIFFfreeExt(tif, data); + if (!m) + goto bad; + } + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: + switch (dp->tdir_type) + { + case TIFF_SHORT: + case TIFF_LONG: + case TIFF_LONG8: + break; + default: + /* Warn except if directory typically created with + * TIFFDeferStrileArrayWriting() */ + if (!(tif->tif_mode == O_RDWR && + dp->tdir_count == 0 && dp->tdir_type == 0 && + dp->tdir_offset.toff_long8 == 0)) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFWarningExtR( + tif, module, "Invalid data type for tag %s", + fip ? fip->field_name : "unknown tagname"); + } + break; + } + _TIFFmemcpy(&(tif->tif_dir.td_stripoffset_entry), dp, + sizeof(TIFFDirEntry)); + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: + switch (dp->tdir_type) + { + case TIFF_SHORT: + case TIFF_LONG: + case TIFF_LONG8: + break; + default: + /* Warn except if directory typically created with + * TIFFDeferStrileArrayWriting() */ + if (!(tif->tif_mode == O_RDWR && + dp->tdir_count == 0 && dp->tdir_type == 0 && + dp->tdir_offset.toff_long8 == 0)) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFWarningExtR( + tif, module, "Invalid data type for tag %s", + fip ? fip->field_name : "unknown tagname"); + } + break; + } + _TIFFmemcpy(&(tif->tif_dir.td_stripbytecount_entry), dp, + sizeof(TIFFDirEntry)); + break; + case TIFFTAG_COLORMAP: + case TIFFTAG_TRANSFERFUNCTION: + { + enum TIFFReadDirEntryErr err; + uint32_t countpersample; + uint32_t countrequired; + uint32_t incrementpersample; + uint16_t *value = NULL; + /* It would be dangerous to instantiate those tag values */ + /* since if td_bitspersample has not yet been read (due to + */ + /* unordered tags), it could be read afterwards with a */ + /* values greater than the default one (1), which may cause + */ + /* crashes in user code */ + if (!bitspersample_read) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFWarningExtR( + tif, module, + "Ignoring %s since BitsPerSample tag not found", + fip ? fip->field_name : "unknown tagname"); + continue; + } + /* ColorMap or TransferFunction for high bit */ + /* depths do not make much sense and could be */ + /* used as a denial of service vector */ + if (tif->tif_dir.td_bitspersample > 24) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFWarningExtR( + tif, module, + "Ignoring %s because BitsPerSample=%" PRIu16 ">24", + fip ? fip->field_name : "unknown tagname", + tif->tif_dir.td_bitspersample); + continue; + } + countpersample = (1U << tif->tif_dir.td_bitspersample); + if ((dp->tdir_tag == TIFFTAG_TRANSFERFUNCTION) && + (dp->tdir_count == (uint64_t)countpersample)) + { + countrequired = countpersample; + incrementpersample = 0; + } + else + { + countrequired = 3 * countpersample; + incrementpersample = countpersample; + } + if (dp->tdir_count != (uint64_t)countrequired) + err = TIFFReadDirEntryErrCount; + else + err = TIFFReadDirEntryShortArray(tif, dp, &value); + if (err != TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFReadDirEntryOutputErr( + tif, err, module, + fip ? fip->field_name : "unknown tagname", 1); + } + else + { + TIFFSetField(tif, dp->tdir_tag, value, + value + incrementpersample, + value + 2 * incrementpersample); + _TIFFfreeExt(tif, value); + } + } + break; + /* BEGIN REV 4.0 COMPATIBILITY */ + case TIFFTAG_OSUBFILETYPE: + { + uint16_t valueo; + uint32_t value; + if (TIFFReadDirEntryShort(tif, dp, &valueo) == + TIFFReadDirEntryErrOk) + { + switch (valueo) + { + case OFILETYPE_REDUCEDIMAGE: + value = FILETYPE_REDUCEDIMAGE; + break; + case OFILETYPE_PAGE: + value = FILETYPE_PAGE; + break; + default: + value = 0; + break; + } + if (value != 0) + TIFFSetField(tif, TIFFTAG_SUBFILETYPE, value); + } + } + break; + /* END REV 4.0 COMPATIBILITY */ +#if 0 + case TIFFTAG_EP_BATTERYLEVEL: + /* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII. + * LibTiff defines it as ASCII and converts RATIONAL to an + * ASCII string. */ + switch (dp->tdir_type) + { + case TIFF_RATIONAL: + { + /* Read rational and convert to ASCII*/ + enum TIFFReadDirEntryErr err; + TIFFRational_t rValue; + err = TIFFReadDirEntryCheckedRationalDirect( + tif, dp, &rValue); + if (err != TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFReadDirEntryOutputErr( + tif, err, module, + fip ? fip->field_name : "unknown tagname", + 1); + } + else + { + char szAux[32]; + snprintf(szAux, sizeof(szAux) - 1, "%d/%d", + rValue.uNum, rValue.uDenom); + TIFFSetField(tif, dp->tdir_tag, szAux); + } + } + break; + case TIFF_ASCII: + (void)TIFFFetchNormalTag(tif, dp, TRUE); + break; + default: + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFWarningExtR(tif, module, + "Invalid data type for tag %s. " + "ASCII or RATIONAL expected", + fip ? fip->field_name + : "unknown tagname"); + break; + } + break; +#endif + default: + (void)TIFFFetchNormalTag(tif, dp, TRUE); + break; + } + } /* -- if (!dp->tdir_ignore) */ + } /* -- for-loop -- */ + + /* + * OJPEG hack: + * - If a) compression is OJPEG, and b) photometric tag is missing, + * then we consistently find that photometric should be YCbCr + * - If a) compression is OJPEG, and b) photometric tag says it's RGB, + * then we consistently find that the buggy implementation of the + * buggy compression scheme matches photometric YCbCr instead. + * - If a) compression is OJPEG, and b) bitspersample tag is missing, + * then we consistently find bitspersample should be 8. + * - If a) compression is OJPEG, b) samplesperpixel tag is missing, + * and c) photometric is RGB or YCbCr, then we consistently find + * samplesperpixel should be 3 + * - If a) compression is OJPEG, b) samplesperpixel tag is missing, + * and c) photometric is MINISWHITE or MINISBLACK, then we consistently + * find samplesperpixel should be 3 + */ + if (tif->tif_dir.td_compression == COMPRESSION_OJPEG) + { + if (!TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) + { + TIFFWarningExtR( + tif, module, + "Photometric tag is missing, assuming data is YCbCr"); + if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR)) + goto bad; + } + else if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB) + { + tif->tif_dir.td_photometric = PHOTOMETRIC_YCBCR; + TIFFWarningExtR(tif, module, + "Photometric tag value assumed incorrect, " + "assuming data is YCbCr instead of RGB"); + } + if (!TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) + { + TIFFWarningExtR( + tif, module, + "BitsPerSample tag is missing, assuming 8 bits per sample"); + if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8)) + goto bad; + } + if (!TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + { + if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag is missing, " + "assuming correct SamplesPerPixel value is 3"); + if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3)) + goto bad; + } + if (tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag is missing, " + "applying correct SamplesPerPixel value of 3"); + if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3)) + goto bad; + } + else if ((tif->tif_dir.td_photometric == PHOTOMETRIC_MINISWHITE) || + (tif->tif_dir.td_photometric == PHOTOMETRIC_MINISBLACK)) + { + /* + * SamplesPerPixel tag is missing, but is not required + * by spec. Assume correct SamplesPerPixel value of 1. + */ + if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1)) + goto bad; + } + } + } + + /* + * Setup appropriate structures (by strip or by tile) + * We do that only after the above OJPEG hack which alters SamplesPerPixel + * and thus influences the number of strips in the separate planarconfig. + */ + if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) + { + tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); + tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; + tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; + tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; + tif->tif_flags &= ~TIFF_ISTILED; + } + else + { + tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); + tif->tif_flags |= TIFF_ISTILED; + } + if (!tif->tif_dir.td_nstrips) + { + TIFFErrorExtR(tif, module, "Cannot handle zero number of %s", + isTiled(tif) ? "tiles" : "strips"); + goto bad; + } + tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; + if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) + tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; + if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) + { #ifdef OJPEG_SUPPORT - if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) && - (isTiled(tif)==0) && - (tif->tif_dir.td_nstrips==1)) { - /* - * XXX: OJPEG hack. - * If a) compression is OJPEG, b) it's not a tiled TIFF, - * and c) the number of strips is 1, - * then we tolerate the absence of stripoffsets tag, - * because, presumably, all required data is in the - * JpegInterchangeFormat stream. - */ - TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); - } else + if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) && + (isTiled(tif) == 0) && (tif->tif_dir.td_nstrips == 1)) + { + /* + * XXX: OJPEG hack. + * If a) compression is OJPEG, b) it's not a tiled TIFF, + * and c) the number of strips is 1, + * then we tolerate the absence of stripoffsets tag, + * because, presumably, all required data is in the + * JpegInterchangeFormat stream. + */ + TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); + } + else #endif { - MissingRequired(tif, - isTiled(tif) ? "TileOffsets" : "StripOffsets"); - goto bad; - } - } - /* - * Second pass: extract other information. - */ - for (di=0, dp=dir; ditdir_ignore) { - switch (dp->tdir_tag) - { - case TIFFTAG_MINSAMPLEVALUE: - case TIFFTAG_MAXSAMPLEVALUE: - case TIFFTAG_BITSPERSAMPLE: - case TIFFTAG_DATATYPE: - case TIFFTAG_SAMPLEFORMAT: - /* - * The MinSampleValue, MaxSampleValue, BitsPerSample - * DataType and SampleFormat tags are supposed to be - * written as one value/sample, but some vendors - * incorrectly write one value only -- so we accept - * that as well (yuck). Other vendors write correct - * value for NumberOfSamples, but incorrect one for - * BitsPerSample and friends, and we will read this - * too. - */ - { - uint16 value; - enum TIFFReadDirEntryErr err; - err=TIFFReadDirEntryShort(tif,dp,&value); - if (err==TIFFReadDirEntryErrCount) - err=TIFFReadDirEntryPersampleShort(tif,dp,&value); - if (err!=TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); - goto bad; - } - if (!TIFFSetField(tif,dp->tdir_tag,value)) - goto bad; - if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE ) - bitspersample_read = TRUE; - } - break; - case TIFFTAG_SMINSAMPLEVALUE: - case TIFFTAG_SMAXSAMPLEVALUE: - { - - double *data = NULL; - enum TIFFReadDirEntryErr err; - uint32 saved_flags; - int m; - if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel) - err = TIFFReadDirEntryErrCount; - else - err = TIFFReadDirEntryDoubleArray(tif, dp, &data); - if (err!=TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); - goto bad; - } - saved_flags = tif->tif_flags; - tif->tif_flags |= TIFF_PERSAMPLE; - m = TIFFSetField(tif,dp->tdir_tag,data); - tif->tif_flags = saved_flags; - _TIFFfree(data); - if (!m) - goto bad; - } - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_TILEOFFSETS: - switch( dp->tdir_type ) - { - case TIFF_SHORT: - case TIFF_LONG: - case TIFF_LONG8: - break; - default: - /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */ - if( !(tif->tif_mode == O_RDWR && - dp->tdir_count == 0 && - dp->tdir_type == 0 && - dp->tdir_offset.toff_long8 == 0) ) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFWarningExt(tif->tif_clientdata,module, - "Invalid data type for tag %s", - fip ? fip->field_name : "unknown tagname"); - } - break; - } - _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry), - dp, sizeof(TIFFDirEntry) ); - break; - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEBYTECOUNTS: - switch( dp->tdir_type ) - { - case TIFF_SHORT: - case TIFF_LONG: - case TIFF_LONG8: - break; - default: - /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */ - if( !(tif->tif_mode == O_RDWR && - dp->tdir_count == 0 && - dp->tdir_type == 0 && - dp->tdir_offset.toff_long8 == 0) ) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFWarningExt(tif->tif_clientdata,module, - "Invalid data type for tag %s", - fip ? fip->field_name : "unknown tagname"); - } - break; - } - _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry), - dp, sizeof(TIFFDirEntry) ); - break; - case TIFFTAG_COLORMAP: - case TIFFTAG_TRANSFERFUNCTION: - { - enum TIFFReadDirEntryErr err; - uint32 countpersample; - uint32 countrequired; - uint32 incrementpersample; - uint16* value=NULL; - /* It would be dangerous to instantiate those tag values */ - /* since if td_bitspersample has not yet been read (due to */ - /* unordered tags), it could be read afterwards with a */ - /* values greater than the default one (1), which may cause */ - /* crashes in user code */ - if( !bitspersample_read ) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFWarningExt(tif->tif_clientdata,module, - "Ignoring %s since BitsPerSample tag not found", - fip ? fip->field_name : "unknown tagname"); - continue; - } - /* ColorMap or TransferFunction for high bit */ - /* depths do not make much sense and could be */ - /* used as a denial of service vector */ - if (tif->tif_dir.td_bitspersample > 24) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFWarningExt(tif->tif_clientdata,module, - "Ignoring %s because BitsPerSample=%d>24", - fip ? fip->field_name : "unknown tagname", - tif->tif_dir.td_bitspersample); - continue; - } - countpersample=(1U<tif_dir.td_bitspersample); - if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample)) - { - countrequired=countpersample; - incrementpersample=0; - } - else - { - countrequired=3*countpersample; - incrementpersample=countpersample; - } - if (dp->tdir_count!=(uint64)countrequired) - err=TIFFReadDirEntryErrCount; - else - err=TIFFReadDirEntryShortArray(tif,dp,&value); - if (err!=TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1); - } - else - { - TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample); - _TIFFfree(value); - } - } - break; -/* BEGIN REV 4.0 COMPATIBILITY */ - case TIFFTAG_OSUBFILETYPE: - { - uint16 valueo; - uint32 value; - if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk) - { - switch (valueo) - { - case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break; - case OFILETYPE_PAGE: value=FILETYPE_PAGE; break; - default: value=0; break; - } - if (value!=0) - TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value); - } - } - break; -/* END REV 4.0 COMPATIBILITY */ - default: - (void) TIFFFetchNormalTag(tif, dp, TRUE); - break; - } - } /* -- if (!dp->tdir_ignore) */ - } /* -- for-loop -- */ - - if( tif->tif_mode == O_RDWR && - tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 ) - { - /* Directory typically created with TIFFDeferStrileArrayWriting() */ - TIFFSetupStrips(tif); + MissingRequired(tif, isTiled(tif) ? "TileOffsets" : "StripOffsets"); + goto bad; } - else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) ) + } + + if (tif->tif_mode == O_RDWR && + tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && + tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) + { + /* Directory typically created with TIFFDeferStrileArrayWriting() */ + TIFFSetupStrips(tif); + } + else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD)) + { + if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0) { - if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 ) + if (!TIFFFetchStripThing(tif, &(tif->tif_dir.td_stripoffset_entry), + tif->tif_dir.td_nstrips, + &tif->tif_dir.td_stripoffset_p)) { - if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry), - tif->tif_dir.td_nstrips, - &tif->tif_dir.td_stripoffset_p)) - { - goto bad; - } - } - if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 ) - { - if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry), - tif->tif_dir.td_nstrips, - &tif->tif_dir.td_stripbytecount_p)) - { - goto bad; - } + goto bad; } } + if (tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0) + { + if (!TIFFFetchStripThing( + tif, &(tif->tif_dir.td_stripbytecount_entry), + tif->tif_dir.td_nstrips, &tif->tif_dir.td_stripbytecount_p)) + { + goto bad; + } + } + } - /* - * OJPEG hack: - * - If a) compression is OJPEG, and b) photometric tag is missing, - * then we consistently find that photometric should be YCbCr - * - If a) compression is OJPEG, and b) photometric tag says it's RGB, - * then we consistently find that the buggy implementation of the - * buggy compression scheme matches photometric YCbCr instead. - * - If a) compression is OJPEG, and b) bitspersample tag is missing, - * then we consistently find bitspersample should be 8. - * - If a) compression is OJPEG, b) samplesperpixel tag is missing, - * and c) photometric is RGB or YCbCr, then we consistently find - * samplesperpixel should be 3 - * - If a) compression is OJPEG, b) samplesperpixel tag is missing, - * and c) photometric is MINISWHITE or MINISBLACK, then we consistently - * find samplesperpixel should be 3 - */ - if (tif->tif_dir.td_compression==COMPRESSION_OJPEG) - { - if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Photometric tag is missing, assuming data is YCbCr"); - if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR)) - goto bad; - } - else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB) - { - tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR; - TIFFWarningExt(tif->tif_clientdata, module, - "Photometric tag value assumed incorrect, " - "assuming data is YCbCr instead of RGB"); - } - if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) - { - TIFFWarningExt(tif->tif_clientdata,module, - "BitsPerSample tag is missing, assuming 8 bits per sample"); - if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8)) - goto bad; - } - if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) - { - if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB) - { - TIFFWarningExt(tif->tif_clientdata,module, - "SamplesPerPixel tag is missing, " - "assuming correct SamplesPerPixel value is 3"); - if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3)) - goto bad; - } - if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR) - { - TIFFWarningExt(tif->tif_clientdata,module, - "SamplesPerPixel tag is missing, " - "applying correct SamplesPerPixel value of 3"); - if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3)) - goto bad; - } - else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE) - || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK)) - { - /* - * SamplesPerPixel tag is missing, but is not required - * by spec. Assume correct SamplesPerPixel value of 1. - */ - if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1)) - goto bad; - } - } - } + /* + * Make sure all non-color channels are extrasamples. + * If it's not the case, define them as such. + */ + color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); + if (color_channels && + tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > + color_channels) + { + uint16_t old_extrasamples; + uint16_t *new_sampleinfo; - /* - * Make sure all non-color channels are extrasamples. - * If it's not the case, define them as such. - */ - color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); - if (color_channels && tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > color_channels) { - uint16 old_extrasamples; - uint16 *new_sampleinfo; + TIFFWarningExtR( + tif, module, + "Sum of Photometric type-related " + "color channels and ExtraSamples doesn't match SamplesPerPixel. " + "Defining non-color channels as ExtraSamples."); - TIFFWarningExt(tif->tif_clientdata,module, "Sum of Photometric type-related " - "color channels and ExtraSamples doesn't match SamplesPerPixel. " - "Defining non-color channels as ExtraSamples."); + old_extrasamples = tif->tif_dir.td_extrasamples; + tif->tif_dir.td_extrasamples = + (uint16_t)(tif->tif_dir.td_samplesperpixel - color_channels); - old_extrasamples = tif->tif_dir.td_extrasamples; - tif->tif_dir.td_extrasamples = (uint16) (tif->tif_dir.td_samplesperpixel - color_channels); - - // sampleinfo should contain information relative to these new extra samples - new_sampleinfo = (uint16*) _TIFFcalloc(tif->tif_dir.td_extrasamples, sizeof(uint16)); - if (!new_sampleinfo) { - TIFFErrorExt(tif->tif_clientdata, module, "Failed to allocate memory for " - "temporary new sampleinfo array (%d 16 bit elements)", - tif->tif_dir.td_extrasamples); - goto bad; - } - - memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16)); - _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples); - _TIFFfree(new_sampleinfo); + // sampleinfo should contain information relative to these new extra + // samples + new_sampleinfo = (uint16_t *)_TIFFcallocExt( + tif, tif->tif_dir.td_extrasamples, sizeof(uint16_t)); + if (!new_sampleinfo) + { + TIFFErrorExtR(tif, module, + "Failed to allocate memory for " + "temporary new sampleinfo array " + "(%" PRIu16 " 16 bit elements)", + tif->tif_dir.td_extrasamples); + goto bad; } - /* - * Verify Palette image has a Colormap. - */ - if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE && - !TIFFFieldSet(tif, FIELD_COLORMAP)) { - if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3) - tif->tif_dir.td_photometric = PHOTOMETRIC_RGB; - else if (tif->tif_dir.td_bitspersample>=8) - tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK; - else { - MissingRequired(tif, "Colormap"); - goto bad; - } - } - /* - * OJPEG hack: - * We do no further messing with strip/tile offsets/bytecounts in OJPEG - * TIFFs - */ - if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG) - { - /* - * Attempt to deal with a missing StripByteCounts tag. - */ - if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) { - /* - * Some manufacturers violate the spec by not giving - * the size of the strips. In this case, assume there - * is one uncompressed strip of data. - */ - if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && - tif->tif_dir.td_nstrips > 1) || - (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE && - tif->tif_dir.td_nstrips != (uint32)tif->tif_dir.td_samplesperpixel)) { - MissingRequired(tif, "StripByteCounts"); - goto bad; - } - TIFFWarningExt(tif->tif_clientdata, module, - "TIFF directory is missing required " - "\"StripByteCounts\" field, calculating from imagelength"); - if (EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; + if (old_extrasamples > 0) + memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, + old_extrasamples * sizeof(uint16_t)); + _TIFFsetShortArrayExt(tif, &tif->tif_dir.td_sampleinfo, new_sampleinfo, + tif->tif_dir.td_extrasamples); + _TIFFfreeExt(tif, new_sampleinfo); + } - } else if (tif->tif_dir.td_nstrips == 1 - && !(tif->tif_flags&TIFF_ISTILED) - && ByteCountLooksBad(tif)) { - /* - * XXX: Plexus (and others) sometimes give a value of - * zero for a tag when they don't know what the - * correct value is! Try and handle the simple case - * of estimating the size of a one strip image. - */ - TIFFWarningExt(tif->tif_clientdata, module, - "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength"); - if(EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - - } else if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD) - && tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG - && tif->tif_dir.td_nstrips > 2 - && tif->tif_dir.td_compression == COMPRESSION_NONE - && TIFFGetStrileByteCount(tif, 0) != TIFFGetStrileByteCount(tif, 1) - && TIFFGetStrileByteCount(tif, 0) != 0 - && TIFFGetStrileByteCount(tif, 1) != 0 ) { - /* - * XXX: Some vendors fill StripByteCount array with - * absolutely wrong values (it can be equal to - * StripOffset array, for example). Catch this case - * here. - * - * We avoid this check if deferring strile loading - * as it would always force us to load the strip/tile - * information. - */ - TIFFWarningExt(tif->tif_clientdata, module, - "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength"); - if (EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - } - } - if (dir) - { - _TIFFfree(dir); - dir=NULL; - } - if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) - { - if (tif->tif_dir.td_bitspersample>=16) - tif->tif_dir.td_maxsamplevalue=0xFFFF; - else - tif->tif_dir.td_maxsamplevalue = (uint16)((1L<tif_dir.td_bitspersample)-1); - } + /* + * Verify Palette image has a Colormap. + */ + if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE && + !TIFFFieldSet(tif, FIELD_COLORMAP)) + { + if (tif->tif_dir.td_bitspersample >= 8 && + tif->tif_dir.td_samplesperpixel == 3) + tif->tif_dir.td_photometric = PHOTOMETRIC_RGB; + else if (tif->tif_dir.td_bitspersample >= 8) + tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK; + else + { + MissingRequired(tif, "Colormap"); + goto bad; + } + } + /* + * OJPEG hack: + * We do no further messing with strip/tile offsets/bytecounts in OJPEG + * TIFFs + */ + if (tif->tif_dir.td_compression != COMPRESSION_OJPEG) + { + /* + * Attempt to deal with a missing StripByteCounts tag. + */ + if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) + { + /* + * Some manufacturers violate the spec by not giving + * the size of the strips. In this case, assume there + * is one uncompressed strip of data. + */ + if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && + tif->tif_dir.td_nstrips > 1) || + (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE && + tif->tif_dir.td_nstrips != + (uint32_t)tif->tif_dir.td_samplesperpixel)) + { + MissingRequired(tif, "StripByteCounts"); + goto bad; + } + TIFFWarningExtR( + tif, module, + "TIFF directory is missing required " + "\"StripByteCounts\" field, calculating from imagelength"); + if (EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; + } + else if (tif->tif_dir.td_nstrips == 1 && + !(tif->tif_flags & TIFF_ISTILED) && ByteCountLooksBad(tif)) + { + /* + * XXX: Plexus (and others) sometimes give a value of + * zero for a tag when they don't know what the + * correct value is! Try and handle the simple case + * of estimating the size of a one strip image. + */ + TIFFWarningExtR(tif, module, + "Bogus \"StripByteCounts\" field, ignoring and " + "calculating from imagelength"); + if (EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; + } + else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && + tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && + tif->tif_dir.td_nstrips > 2 && + tif->tif_dir.td_compression == COMPRESSION_NONE && + TIFFGetStrileByteCount(tif, 0) != + TIFFGetStrileByteCount(tif, 1) && + TIFFGetStrileByteCount(tif, 0) != 0 && + TIFFGetStrileByteCount(tif, 1) != 0) + { + /* + * XXX: Some vendors fill StripByteCount array with + * absolutely wrong values (it can be equal to + * StripOffset array, for example). Catch this case + * here. + * + * We avoid this check if deferring strile loading + * as it would always force us to load the strip/tile + * information. + */ + TIFFWarningExtR(tif, module, + "Wrong \"StripByteCounts\" field, ignoring and " + "calculating from imagelength"); + if (EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; + } + } + if (dir) + { + _TIFFfreeExt(tif, dir); + dir = NULL; + } + if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) + { + if (tif->tif_dir.td_bitspersample >= 16) + tif->tif_dir.td_maxsamplevalue = 0xFFFF; + else + tif->tif_dir.td_maxsamplevalue = + (uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1); + } #ifdef STRIPBYTECOUNTSORTED_UNUSED - /* - * XXX: We can optimize checking for the strip bounds using the sorted - * bytecounts array. See also comments for TIFFAppendToStrip() - * function in tif_write.c. - */ - if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1) { - uint32 strip; + /* + * XXX: We can optimize checking for the strip bounds using the sorted + * bytecounts array. See also comments for TIFFAppendToStrip() + * function in tif_write.c. + */ + if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1) + { + uint32_t strip; - tif->tif_dir.td_stripbytecountsorted = 1; - for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { - if (TIFFGetStrileOffset(tif, strip - 1) > - TIFFGetStrileOffset(tif, strip)) { - tif->tif_dir.td_stripbytecountsorted = 0; - break; - } - } - } + tif->tif_dir.td_stripbytecountsorted = 1; + for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) + { + if (TIFFGetStrileOffset(tif, strip - 1) > + TIFFGetStrileOffset(tif, strip)) + { + tif->tif_dir.td_stripbytecountsorted = 0; + break; + } + } + } #endif - /* - * An opportunity for compression mode dependent tag fixup - */ - (*tif->tif_fixuptags)(tif); + /* + * An opportunity for compression mode dependent tag fixup + */ + (*tif->tif_fixuptags)(tif); - /* - * Some manufacturers make life difficult by writing - * large amounts of uncompressed data as a single strip. - * This is contrary to the recommendations of the spec. - * The following makes an attempt at breaking such images - * into strips closer to the recommended 8k bytes. A - * side effect, however, is that the RowsPerStrip tag - * value may be changed. - */ - if ((tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& - (tif->tif_dir.td_nstrips==1)&& - (tif->tif_dir.td_compression==COMPRESSION_NONE)&& - ((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP)) + /* + * Some manufacturers make life difficult by writing + * large amounts of uncompressed data as a single strip. + * This is contrary to the recommendations of the spec. + * The following makes an attempt at breaking such images + * into strips closer to the recommended 8k bytes. A + * side effect, however, is that the RowsPerStrip tag + * value may be changed. + */ + if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) && + (tif->tif_dir.td_nstrips == 1) && + (tif->tif_dir.td_compression == COMPRESSION_NONE) && + ((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP)) + { + ChopUpSingleUncompressedStrip(tif); + } + + /* There are also uncompressed striped files with strips larger than */ + /* 2 GB, which make them unfriendly with a lot of code. If possible, */ + /* try to expose smaller "virtual" strips. */ + if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && + tif->tif_dir.td_compression == COMPRESSION_NONE && + (tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP && + TIFFStripSize64(tif) > 0x7FFFFFFFUL) + { + TryChopUpUncompressedBigTiff(tif); + } + + /* + * Clear the dirty directory flag. + */ + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + + /* + * Reinitialize i/o since we are starting on a new directory. + */ + tif->tif_row = (uint32_t)-1; + tif->tif_curstrip = (uint32_t)-1; + tif->tif_col = (uint32_t)-1; + tif->tif_curtile = (uint32_t)-1; + tif->tif_tilesize = (tmsize_t)-1; + + tif->tif_scanlinesize = TIFFScanlineSize(tif); + if (!tif->tif_scanlinesize) + { + TIFFErrorExtR(tif, module, "Cannot handle zero scanline size"); + return (0); + } + + if (isTiled(tif)) + { + tif->tif_tilesize = TIFFTileSize(tif); + if (!tif->tif_tilesize) { - ChopUpSingleUncompressedStrip(tif); + TIFFErrorExtR(tif, module, "Cannot handle zero tile size"); + return (0); } - - /* There are also uncompressed striped files with strips larger than */ - /* 2 GB, which make them unfriendly with a lot of code. If possible, */ - /* try to expose smaller "virtual" strips. */ - if( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && - tif->tif_dir.td_compression == COMPRESSION_NONE && - (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP && - TIFFStripSize64(tif) > 0x7FFFFFFFUL ) + } + else + { + if (!TIFFStripSize(tif)) { - TryChopUpUncompressedBigTiff(tif); + TIFFErrorExtR(tif, module, "Cannot handle zero strip size"); + return (0); } - - /* - * Clear the dirty directory flag. - */ - tif->tif_flags &= ~TIFF_DIRTYDIRECT; - tif->tif_flags &= ~TIFF_DIRTYSTRIP; - - /* - * Reinitialize i/o since we are starting on a new directory. - */ - tif->tif_row = (uint32) -1; - tif->tif_curstrip = (uint32) -1; - tif->tif_col = (uint32) -1; - tif->tif_curtile = (uint32) -1; - tif->tif_tilesize = (tmsize_t) -1; - - tif->tif_scanlinesize = TIFFScanlineSize(tif); - if (!tif->tif_scanlinesize) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle zero scanline size"); - return (0); - } - - if (isTiled(tif)) { - tif->tif_tilesize = TIFFTileSize(tif); - if (!tif->tif_tilesize) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle zero tile size"); - return (0); - } - } else { - if (!TIFFStripSize(tif)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle zero strip size"); - return (0); - } - } - return (1); + } + return (1); bad: - if (dir) - _TIFFfree(dir); - return (0); + if (dir) + _TIFFfreeExt(tif, dir); + return (0); } -static void -TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) +static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount) { - static const char module[] = "TIFFReadDirectoryCheckOrder"; - uint32 m; - uint16 n; - TIFFDirEntry* o; - m=0; - for (n=0, o=dir; ntdir_tagtif_clientdata,module, - "Invalid TIFF directory; tags are not sorted in ascending order"); - break; - } - m=o->tdir_tag+1; - } + static const char module[] = "TIFFReadDirectoryCheckOrder"; + uint32_t m; + uint16_t n; + TIFFDirEntry *o; + m = 0; + for (n = 0, o = dir; n < dircount; n++, o++) + { + if (o->tdir_tag < m) + { + TIFFWarningExtR(tif, module, + "Invalid TIFF directory; tags are not sorted in " + "ascending order"); + break; + } + m = o->tdir_tag + 1; + } } -static TIFFDirEntry* -TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid) +static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount, + uint16_t tagid) { - TIFFDirEntry* m; - uint16 n; - (void) tif; - for (m=dir, n=0; ntdir_tag==tagid) - return(m); - } - return(0); + TIFFDirEntry *m; + uint16_t n; + (void)tif; + for (m = dir, n = 0; n < dircount; m++, n++) + { + if (m->tdir_tag == tagid) + return (m); + } + return (0); } -static void -TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii) +static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid, + uint32_t *fii) { - int32 ma,mb,mc; - ma=-1; - mc=(int32)tif->tif_nfields; - while (1) - { - if (ma+1==mc) - { - *fii = FAILED_FII; - return; - } - mb=(ma+mc)/2; - if (tif->tif_fields[mb]->field_tag==(uint32)tagid) - break; - if (tif->tif_fields[mb]->field_tag<(uint32)tagid) - ma=mb; - else - mc=mb; - } - while (1) - { - if (mb==0) - break; - if (tif->tif_fields[mb-1]->field_tag!=(uint32)tagid) - break; - mb--; - } - *fii=mb; + int32_t ma, mb, mc; + ma = -1; + mc = (int32_t)tif->tif_nfields; + while (1) + { + if (ma + 1 == mc) + { + *fii = FAILED_FII; + return; + } + mb = (ma + mc) / 2; + if (tif->tif_fields[mb]->field_tag == (uint32_t)tagid) + break; + if (tif->tif_fields[mb]->field_tag < (uint32_t)tagid) + ma = mb; + else + mc = mb; + } + while (1) + { + if (mb == 0) + break; + if (tif->tif_fields[mb - 1]->field_tag != (uint32_t)tagid) + break; + mb--; + } + *fii = mb; } /* * Read custom directory from the arbitrary offset. * The code is very similar to TIFFReadDirectory(). */ -int -TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, - const TIFFFieldArray* infoarray) +int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, + const TIFFFieldArray *infoarray) { - static const char module[] = "TIFFReadCustomDirectory"; - TIFFDirEntry* dir; - uint16 dircount; - TIFFDirEntry* dp; - uint16 di; - const TIFFField* fip; - uint32 fii; - (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ - _TIFFSetupFields(tif, infoarray); - dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL); - if (!dircount) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Failed to read custom directory at offset " TIFF_UINT64_FORMAT,diroff); - return 0; - } - TIFFFreeDirectory(tif); - _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); - TIFFReadDirectoryCheckOrder(tif,dir,dircount); - for (di=0, dp=dir; ditdir_tag,&fii); - if (fii == FAILED_FII) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Unknown field with tag %d (0x%x) encountered", - dp->tdir_tag, dp->tdir_tag); - if (!_TIFFMergeFields(tif, _TIFFCreateAnonField(tif, - dp->tdir_tag, - (TIFFDataType) dp->tdir_type), - 1)) { - TIFFWarningExt(tif->tif_clientdata, module, - "Registering anonymous field with tag %d (0x%x) failed", - dp->tdir_tag, dp->tdir_tag); - dp->tdir_ignore = TRUE; - } else { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - assert( fii != FAILED_FII ); - } - } - if (!dp->tdir_ignore) - { - fip=tif->tif_fields[fii]; - if (fip->field_bit==FIELD_IGNORE) - dp->tdir_ignore = TRUE; - else - { - /* check data type */ - while ((fip->field_type!=TIFF_ANY)&&(fip->field_type!=dp->tdir_type)) - { - fii++; - if ((fii==tif->tif_nfields)|| - (tif->tif_fields[fii]->field_tag!=(uint32)dp->tdir_tag)) - { - fii=0xFFFF; - break; - } - fip=tif->tif_fields[fii]; - } - if (fii==0xFFFF) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Wrong data type %d for \"%s\"; tag ignored", - dp->tdir_type,fip->field_name); - dp->tdir_ignore = TRUE; - } - else - { - /* check count if known in advance */ - if ((fip->field_readcount!=TIFF_VARIABLE)&& - (fip->field_readcount!=TIFF_VARIABLE2)) - { - uint32 expected; - if (fip->field_readcount==TIFF_SPP) - expected=(uint32)tif->tif_dir.td_samplesperpixel; - else - expected=(uint32)fip->field_readcount; - if (!CheckDirCount(tif,dp,expected)) - dp->tdir_ignore = TRUE; - } - } - } - if (!dp->tdir_ignore) { - switch (dp->tdir_tag) - { - case EXIFTAG_SUBJECTDISTANCE: - (void)TIFFFetchSubjectDistance(tif, dp); - break; - default: - (void)TIFFFetchNormalTag(tif, dp, TRUE); - break; - } - } /*-- if (!dp->tdir_ignore) */ - } - } - if (dir) - _TIFFfree(dir); - return 1; + static const char module[] = "TIFFReadCustomDirectory"; + TIFFDirEntry *dir; + uint16_t dircount; + TIFFDirEntry *dp; + uint16_t di; + const TIFFField *fip; + uint32_t fii; + (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ + _TIFFSetupFields(tif, infoarray); + dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL); + if (!dircount) + { + TIFFErrorExtR(tif, module, + "Failed to read custom directory at offset %" PRIu64, + diroff); + return 0; + } + TIFFFreeDirectory(tif); + _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); + TIFFReadDirectoryCheckOrder(tif, dir, dircount); + for (di = 0, dp = dir; di < dircount; di++, dp++) + { + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + if (fii == FAILED_FII) + { + TIFFWarningExtR(tif, module, + "Unknown field with tag %" PRIu16 " (0x%" PRIx16 + ") encountered", + dp->tdir_tag, dp->tdir_tag); + if (!_TIFFMergeFields( + tif, + _TIFFCreateAnonField(tif, dp->tdir_tag, + (TIFFDataType)dp->tdir_type), + 1)) + { + TIFFWarningExtR(tif, module, + "Registering anonymous field with tag %" PRIu16 + " (0x%" PRIx16 ") failed", + dp->tdir_tag, dp->tdir_tag); + dp->tdir_ignore = TRUE; + } + else + { + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + assert(fii != FAILED_FII); + } + } + if (!dp->tdir_ignore) + { + fip = tif->tif_fields[fii]; + if (fip->field_bit == FIELD_IGNORE) + dp->tdir_ignore = TRUE; + else + { + /* check data type */ + while ((fip->field_type != TIFF_ANY) && + (fip->field_type != dp->tdir_type)) + { + fii++; + if ((fii == tif->tif_nfields) || + (tif->tif_fields[fii]->field_tag != + (uint32_t)dp->tdir_tag)) + { + fii = 0xFFFF; + break; + } + fip = tif->tif_fields[fii]; + } + if (fii == 0xFFFF) + { + TIFFWarningExtR(tif, module, + "Wrong data type %" PRIu16 + " for \"%s\"; tag ignored", + dp->tdir_type, fip->field_name); + dp->tdir_ignore = TRUE; + } + else + { + /* check count if known in advance */ + if ((fip->field_readcount != TIFF_VARIABLE) && + (fip->field_readcount != TIFF_VARIABLE2)) + { + uint32_t expected; + if (fip->field_readcount == TIFF_SPP) + expected = + (uint32_t)tif->tif_dir.td_samplesperpixel; + else + expected = (uint32_t)fip->field_readcount; + if (!CheckDirCount(tif, dp, expected)) + dp->tdir_ignore = TRUE; + } + } + } + if (!dp->tdir_ignore) + { + switch (dp->tdir_tag) + { + case EXIFTAG_SUBJECTDISTANCE: + if (!TIFFFieldIsAnonymous(fip)) + { + /* should only be called on a Exif directory */ + /* when exifFields[] is active */ + (void)TIFFFetchSubjectDistance(tif, dp); + } + else + { + (void)TIFFFetchNormalTag(tif, dp, TRUE); + } + break; + default: + (void)TIFFFetchNormalTag(tif, dp, TRUE); + break; + } + } /*-- if (!dp->tdir_ignore) */ + } + } + /* To be able to return from SubIFD or custom-IFD to main-IFD */ + tif->tif_setdirectory_force_absolute = TRUE; + if (dir) + _TIFFfreeExt(tif, dir); + return 1; } /* * EXIF is important special case of custom IFD, so we have a special * function to read it. */ -int -TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff) +int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff) { - const TIFFFieldArray* exifFieldArray; - exifFieldArray = _TIFFGetExifFields(); - return TIFFReadCustomDirectory(tif, diroff, exifFieldArray); + const TIFFFieldArray *exifFieldArray; + exifFieldArray = _TIFFGetExifFields(); + return TIFFReadCustomDirectory(tif, diroff, exifFieldArray); } /* *--: EXIF-GPS custom directory reading as another special case of custom IFD. */ -int -TIFFReadGPSDirectory(TIFF* tif, toff_t diroff) +int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff) { - const TIFFFieldArray* gpsFieldArray; - gpsFieldArray = _TIFFGetGpsFields(); - return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray); + const TIFFFieldArray *gpsFieldArray; + gpsFieldArray = _TIFFGetGpsFields(); + return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray); } -static int -EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) +static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount) { - static const char module[] = "EstimateStripByteCounts"; + static const char module[] = "EstimateStripByteCounts"; - TIFFDirEntry *dp; - TIFFDirectory *td = &tif->tif_dir; - uint32 strip; + TIFFDirEntry *dp; + TIFFDirectory *td = &tif->tif_dir; + uint32_t strip; /* Do not try to load stripbytecount as we will compute it */ - if( !_TIFFFillStrilesInternal( tif, 0 ) ) + if (!_TIFFFillStrilesInternal(tif, 0)) + return -1; + + if (td->td_stripbytecount_p) + _TIFFfreeExt(tif, td->td_stripbytecount_p); + td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc( + tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array"); + if (td->td_stripbytecount_p == NULL) + return -1; + + if (td->td_compression != COMPRESSION_NONE) + { + uint64_t space; + uint64_t filesize; + uint16_t n; + filesize = TIFFGetFileSize(tif); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4; + else + space = sizeof(TIFFHeaderBig) + 8 + dircount * 20 + 8; + /* calculate amount of space used by indirect values */ + for (dp = dir, n = dircount; n > 0; n--, dp++) + { + uint32_t typewidth; + uint64_t datasize; + typewidth = TIFFDataWidth((TIFFDataType)dp->tdir_type); + if (typewidth == 0) + { + TIFFErrorExtR( + tif, module, + "Cannot determine size of unknown tag type %" PRIu16, + dp->tdir_type); + return -1; + } + if (dp->tdir_count > UINT64_MAX / typewidth) + return -1; + datasize = (uint64_t)typewidth * dp->tdir_count; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (datasize <= 4) + datasize = 0; + } + else + { + if (datasize <= 8) + datasize = 0; + } + if (space > UINT64_MAX - datasize) + return -1; + space += datasize; + } + if (filesize < space) + /* we should perhaps return in error ? */ + space = filesize; + else + space = filesize - space; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + space /= td->td_samplesperpixel; + for (strip = 0; strip < td->td_nstrips; strip++) + td->td_stripbytecount_p[strip] = space; + /* + * This gross hack handles the case were the offset to + * the last strip is past the place where we think the strip + * should begin. Since a strip of data must be contiguous, + * it's safe to assume that we've overestimated the amount + * of data in the strip and trim this number back accordingly. + */ + strip--; + if (td->td_stripoffset_p[strip] > + UINT64_MAX - td->td_stripbytecount_p[strip]) return -1; + if (td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip] > + filesize) + { + if (td->td_stripoffset_p[strip] >= filesize) + { + /* Not sure what we should in that case... */ + td->td_stripbytecount_p[strip] = 0; + } + else + { + td->td_stripbytecount_p[strip] = + filesize - td->td_stripoffset_p[strip]; + } + } + } + else if (isTiled(tif)) + { + uint64_t bytespertile = TIFFTileSize64(tif); - if (td->td_stripbytecount_p) - _TIFFfree(td->td_stripbytecount_p); - td->td_stripbytecount_p = (uint64*) - _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), - "for \"StripByteCounts\" array"); - if( td->td_stripbytecount_p == NULL ) - return -1; - - if (td->td_compression != COMPRESSION_NONE) { - uint64 space; - uint64 filesize; - uint16 n; - filesize = TIFFGetFileSize(tif); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - space=sizeof(TIFFHeaderClassic)+2+dircount*12+4; - else - space=sizeof(TIFFHeaderBig)+8+dircount*20+8; - /* calculate amount of space used by indirect values */ - for (dp = dir, n = dircount; n > 0; n--, dp++) - { - uint32 typewidth; - uint64 datasize; - typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type); - if (typewidth == 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot determine size of unknown tag type %d", - dp->tdir_type); - return -1; - } - if( dp->tdir_count > TIFF_UINT64_MAX / typewidth ) - return -1; - datasize=(uint64)typewidth*dp->tdir_count; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (datasize<=4) - datasize=0; - } - else - { - if (datasize<=8) - datasize=0; - } - if( space > TIFF_UINT64_MAX - datasize ) - return -1; - space+=datasize; - } - if( filesize < space ) - /* we should perhaps return in error ? */ - space = filesize; - else - space = filesize - space; - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - space /= td->td_samplesperpixel; - for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount_p[strip] = space; - /* - * This gross hack handles the case were the offset to - * the last strip is past the place where we think the strip - * should begin. Since a strip of data must be contiguous, - * it's safe to assume that we've overestimated the amount - * of data in the strip and trim this number back accordingly. - */ - strip--; - if (td->td_stripoffset_p[strip] > TIFF_UINT64_MAX - td->td_stripbytecount_p[strip]) - return -1; - if (td->td_stripoffset_p[strip]+td->td_stripbytecount_p[strip] > filesize) { - if( td->td_stripoffset_p[strip] >= filesize ) { - /* Not sure what we should in that case... */ - td->td_stripbytecount_p[strip] = 0; - } else { - td->td_stripbytecount_p[strip] = filesize - td->td_stripoffset_p[strip]; - } - } - } else if (isTiled(tif)) { - uint64 bytespertile = TIFFTileSize64(tif); - - for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount_p[strip] = bytespertile; - } else { - uint64 rowbytes = TIFFScanlineSize64(tif); - uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage; - for (strip = 0; strip < td->td_nstrips; strip++) - { - if( rowbytes > 0 && rowsperstrip > TIFF_UINT64_MAX / rowbytes ) - return -1; - td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip; - } - } - TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); - if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) - td->td_rowsperstrip = td->td_imagelength; - return 1; + for (strip = 0; strip < td->td_nstrips; strip++) + td->td_stripbytecount_p[strip] = bytespertile; + } + else + { + uint64_t rowbytes = TIFFScanlineSize64(tif); + uint32_t rowsperstrip = td->td_imagelength / td->td_stripsperimage; + for (strip = 0; strip < td->td_nstrips; strip++) + { + if (rowbytes > 0 && rowsperstrip > UINT64_MAX / rowbytes) + return -1; + td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip; + } + } + TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); + if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) + td->td_rowsperstrip = td->td_imagelength; + return 1; } -static void -MissingRequired(TIFF* tif, const char* tagname) +static void MissingRequired(TIFF *tif, const char *tagname) { - static const char module[] = "MissingRequired"; + static const char module[] = "MissingRequired"; - TIFFErrorExt(tif->tif_clientdata, module, - "TIFF directory is missing required \"%s\" field", - tagname); + TIFFErrorExtR(tif, module, + "TIFF directory is missing required \"%s\" field", tagname); +} + +static unsigned long hashFuncOffsetToNumber(const void *elt) +{ + const TIFFOffsetAndDirNumber *offsetAndDirNumber = + (const TIFFOffsetAndDirNumber *)elt; + const uint32_t hash = (uint32_t)(offsetAndDirNumber->offset >> 32) ^ + ((uint32_t)offsetAndDirNumber->offset & 0xFFFFFFFFU); + return hash; +} + +static bool equalFuncOffsetToNumber(const void *elt1, const void *elt2) +{ + const TIFFOffsetAndDirNumber *offsetAndDirNumber1 = + (const TIFFOffsetAndDirNumber *)elt1; + const TIFFOffsetAndDirNumber *offsetAndDirNumber2 = + (const TIFFOffsetAndDirNumber *)elt2; + return offsetAndDirNumber1->offset == offsetAndDirNumber2->offset; +} + +static unsigned long hashFuncNumberToOffset(const void *elt) +{ + const TIFFOffsetAndDirNumber *offsetAndDirNumber = + (const TIFFOffsetAndDirNumber *)elt; + return offsetAndDirNumber->dirNumber; +} + +static bool equalFuncNumberToOffset(const void *elt1, const void *elt2) +{ + const TIFFOffsetAndDirNumber *offsetAndDirNumber1 = + (const TIFFOffsetAndDirNumber *)elt1; + const TIFFOffsetAndDirNumber *offsetAndDirNumber2 = + (const TIFFOffsetAndDirNumber *)elt2; + return offsetAndDirNumber1->dirNumber == offsetAndDirNumber2->dirNumber; } /* - * Check the directory offset against the list of already seen directory - * offsets. This is a trick to prevent IFD looping. The one can create TIFF - * file with looped directory pointers. We will maintain a list of already - * seen directories and check every IFD offset against that list. + * Check the directory number and offset against the list of already seen + * directory numbers and offsets. This is a trick to prevent IFD looping. + * The one can create TIFF file with looped directory pointers. We will + * maintain a list of already seen directories and check every IFD offset + * and its IFD number against that list. However, the offset of an IFD number + * can change - e.g. when writing updates to file. + * Returns 1 if all is ok; 0 if last directory or IFD loop is encountered, + * or an error has occurred. */ -static int -TIFFCheckDirOffset(TIFF* tif, uint64 diroff) +int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff) { - uint16 n; + if (diroff == 0) /* no more directories */ + return 0; - if (diroff == 0) /* no more directories */ - return 0; - if (tif->tif_dirnumber == 65535) { - TIFFErrorExt(tif->tif_clientdata, "TIFFCheckDirOffset", - "Cannot handle more than 65535 TIFF directories"); - return 0; - } + if (tif->tif_map_dir_offset_to_number == NULL) + { + tif->tif_map_dir_offset_to_number = TIFFHashSetNew( + hashFuncOffsetToNumber, equalFuncOffsetToNumber, free); + if (tif->tif_map_dir_offset_to_number == NULL) + { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "Not enough memory"); + return 1; + } + } - for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) { - if (tif->tif_dirlist[n] == diroff) - return 0; - } + if (tif->tif_map_dir_number_to_offset == NULL) + { + /* No free callback for this map, as it shares the same items as + * tif->tif_map_dir_offset_to_number. */ + tif->tif_map_dir_number_to_offset = TIFFHashSetNew( + hashFuncNumberToOffset, equalFuncNumberToOffset, NULL); + if (tif->tif_map_dir_number_to_offset == NULL) + { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "Not enough memory"); + return 1; + } + } - tif->tif_dirnumber++; + /* Check if offset is already in the list: + * - yes: check, if offset is at the same IFD number - if not, it is an IFD + * loop + * - no: add to list or update offset at that IFD number + */ + TIFFOffsetAndDirNumber entry; + entry.offset = diroff; + entry.dirNumber = dirn; - if (tif->tif_dirlist == NULL || tif->tif_dirnumber > tif->tif_dirlistsize) { - uint64* new_dirlist; + TIFFOffsetAndDirNumber *foundEntry = + (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( + tif->tif_map_dir_offset_to_number, &entry); + if (foundEntry) + { + if (foundEntry->dirNumber == dirn) + { + return 1; + } + else + { + TIFFWarningExtR(tif, "_TIFFCheckDirNumberAndOffset", + "TIFF directory %d has IFD looping to directory %u " + "at offset 0x%" PRIx64 " (%" PRIu64 ")", + (int)dirn - 1, foundEntry->dirNumber, diroff, + diroff); + return 0; + } + } - /* - * XXX: Reduce memory allocation granularity of the dirlist - * array. - */ - new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist, - tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list"); - if (!new_dirlist) - return 0; - if( tif->tif_dirnumber >= 32768 ) - tif->tif_dirlistsize = 65535; - else - tif->tif_dirlistsize = 2 * tif->tif_dirnumber; - tif->tif_dirlist = new_dirlist; - } + /* Check if offset of an IFD has been changed and update offset of that IFD + * number. */ + foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( + tif->tif_map_dir_number_to_offset, &entry); + if (foundEntry) + { + if (foundEntry->offset != diroff) + { + TIFFOffsetAndDirNumber entryOld; + entryOld.offset = foundEntry->offset; + entryOld.dirNumber = dirn; + /* We must remove first from tif_map_dir_number_to_offset as the */ + /* entry is owned (and thus freed) by */ + /* tif_map_dir_offset_to_number */ + TIFFOffsetAndDirNumber *foundEntryOld = + (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( + tif->tif_map_dir_number_to_offset, &entryOld); + if (foundEntryOld) + { + TIFFHashSetRemove(tif->tif_map_dir_number_to_offset, + foundEntryOld); + } + foundEntryOld = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( + tif->tif_map_dir_offset_to_number, &entryOld); + if (foundEntryOld) + { + TIFFHashSetRemove(tif->tif_map_dir_offset_to_number, + foundEntryOld); + } - tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff; + TIFFOffsetAndDirNumber *entryPtr = (TIFFOffsetAndDirNumber *)malloc( + sizeof(TIFFOffsetAndDirNumber)); + if (entryPtr == NULL) + { + return 0; + } - return 1; -} + /* Add IFD offset and dirn to IFD directory list */ + *entryPtr = entry; + + if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr)) + { + TIFFErrorExtR( + tif, "_TIFFCheckDirNumberAndOffset", + "Insertion in tif_map_dir_offset_to_number failed"); + return 0; + } + if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr)) + { + TIFFErrorExtR( + tif, "_TIFFCheckDirNumberAndOffset", + "Insertion in tif_map_dir_number_to_offset failed"); + return 0; + } + } + return 1; + } + + /* Arbitrary (hopefully big enough) limit */ + if (TIFFHashSetSize(tif->tif_map_dir_offset_to_number) >= + TIFF_MAX_DIR_COUNT) + { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "Cannot handle more than %u TIFF directories", + TIFF_MAX_DIR_COUNT); + return 0; + } + + TIFFOffsetAndDirNumber *entryPtr = + (TIFFOffsetAndDirNumber *)malloc(sizeof(TIFFOffsetAndDirNumber)); + if (entryPtr == NULL) + { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "malloc(sizeof(TIFFOffsetAndDirNumber)) failed"); + return 0; + } + + /* Add IFD offset and dirn to IFD directory list */ + *entryPtr = entry; + + if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr)) + { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "Insertion in tif_map_dir_offset_to_number failed"); + return 0; + } + if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr)) + { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "Insertion in tif_map_dir_number_to_offset failed"); + return 0; + } + + return 1; +} /* --- _TIFFCheckDirNumberAndOffset() ---*/ + +/* + * Retrieve the matching IFD directory number of a given IFD offset + * from the list of directories already seen. + * Returns 1 if the offset was in the list and the directory number + * can be returned. + * Otherwise returns 0 or if an error occurred. + */ +int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, tdir_t *dirn) +{ + if (diroff == 0) /* no more directories */ + return 0; + + /* Check if offset is already in the list and return matching directory + * number. Otherwise update IFD list using TIFFNumberOfDirectories() and + * search again in IFD list. + */ + if (tif->tif_map_dir_offset_to_number == NULL) + return 0; + TIFFOffsetAndDirNumber entry; + entry.offset = diroff; + entry.dirNumber = 0; /* not used */ + + TIFFOffsetAndDirNumber *foundEntry = + (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( + tif->tif_map_dir_offset_to_number, &entry); + if (foundEntry) + { + *dirn = foundEntry->dirNumber; + return 1; + } + + /* This updates the directory list for all main-IFDs in the file. */ + TIFFNumberOfDirectories(tif); + + foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( + tif->tif_map_dir_offset_to_number, &entry); + if (foundEntry) + { + *dirn = foundEntry->dirNumber; + return 1; + } + + return 0; +} /*--- _TIFFGetDirNumberFromOffset() ---*/ + +/* + * Retrieve the matching IFD directory offset of a given IFD number + * from the list of directories already seen. + * Returns 1 if the offset was in the list of already seen IFDs and the + * directory offset can be returned. The directory list is not updated. + * Otherwise returns 0 or if an error occurred. + */ +int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn, uint64_t *diroff) +{ + + if (tif->tif_map_dir_number_to_offset == NULL) + return 0; + TIFFOffsetAndDirNumber entry; + entry.offset = 0; /* not used */ + entry.dirNumber = dirn; + + TIFFOffsetAndDirNumber *foundEntry = + (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( + tif->tif_map_dir_number_to_offset, &entry); + if (foundEntry) + { + *diroff = foundEntry->offset; + return 1; + } + + return 0; +} /*--- _TIFFGetOffsetFromDirNumber() ---*/ + +/* + * Remove an entry from the directory list of already seen directories + * by directory offset. + * If an entry is to be removed from the list, it is also okay if the entry + * is not in the list or the list does not exist. + */ +int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif, uint64_t diroff) +{ + if (tif->tif_map_dir_offset_to_number == NULL) + return 1; + + TIFFOffsetAndDirNumber entryOld; + entryOld.offset = diroff; + entryOld.dirNumber = 0; + /* We must remove first from tif_map_dir_number_to_offset as the + * entry is owned (and thus freed) by tif_map_dir_offset_to_number. + * However, we need firstly to find the directory number from offset. */ + + TIFFOffsetAndDirNumber *foundEntryOldOff = + (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( + tif->tif_map_dir_offset_to_number, &entryOld); + if (foundEntryOldOff) + { + entryOld.dirNumber = foundEntryOldOff->dirNumber; + if (tif->tif_map_dir_number_to_offset != NULL) + { + TIFFOffsetAndDirNumber *foundEntryOldDir = + (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( + tif->tif_map_dir_number_to_offset, &entryOld); + if (foundEntryOldDir) + { + TIFFHashSetRemove(tif->tif_map_dir_number_to_offset, + foundEntryOldDir); + TIFFHashSetRemove(tif->tif_map_dir_offset_to_number, + foundEntryOldOff); + return 1; + } + } + else + { + TIFFErrorExtR(tif, "_TIFFRemoveEntryFromDirectoryListByOffset", + "Unexpectedly tif_map_dir_number_to_offset is " + "missing but tif_map_dir_offset_to_number exists."); + return 0; + } + } + return 1; +} /*--- _TIFFRemoveEntryFromDirectoryListByOffset() ---*/ /* * Check the count field of a directory entry against a known value. The * caller is expected to skip/ignore the tag if there is a mismatch. */ -static int -CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count) +static int CheckDirCount(TIFF *tif, TIFFDirEntry *dir, uint32_t count) { - if ((uint64)count > dir->tdir_count) { - const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag ignored", - fip ? fip->field_name : "unknown tagname", - dir->tdir_count, count); - return (0); - } else if ((uint64)count < dir->tdir_count) { - const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag trimmed", - fip ? fip->field_name : "unknown tagname", - dir->tdir_count, count); - dir->tdir_count = count; - return (1); - } - return (1); + if ((uint64_t)count > dir->tdir_count) + { + const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFWarningExtR(tif, tif->tif_name, + "incorrect count for field \"%s\" (%" PRIu64 + ", expecting %" PRIu32 "); tag ignored", + fip ? fip->field_name : "unknown tagname", + dir->tdir_count, count); + return (0); + } + else if ((uint64_t)count < dir->tdir_count) + { + const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFWarningExtR(tif, tif->tif_name, + "incorrect count for field \"%s\" (%" PRIu64 + ", expecting %" PRIu32 "); tag trimmed", + fip ? fip->field_name : "unknown tagname", + dir->tdir_count, count); + dir->tdir_count = count; + return (1); + } + return (1); } /* @@ -4761,1112 +5738,1546 @@ CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count) * nextdiroff variable has been specified, read it too. Function returns a * number of fields in the directory or 0 if failed. */ -static uint16 -TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, - uint64 *nextdiroff) +static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, + TIFFDirEntry **pdir, uint64_t *nextdiroff) { - static const char module[] = "TIFFFetchDirectory"; + static const char module[] = "TIFFFetchDirectory"; - void* origdir; - uint16 dircount16; - uint32 dirsize; - TIFFDirEntry* dir; - uint8* ma; - TIFFDirEntry* mb; - uint16 n; + void *origdir; + uint16_t dircount16; + uint32_t dirsize; + TIFFDirEntry *dir; + uint8_t *ma; + TIFFDirEntry *mb; + uint16_t n; - assert(pdir); + assert(pdir); - tif->tif_diroff = diroff; - if (nextdiroff) - *nextdiroff = 0; - if (!isMapped(tif)) { - if (!SeekOK(tif, tif->tif_diroff)) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); - return 0; - } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (!ReadOK(tif, &dircount16, sizeof (uint16))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount16); - if (dircount16>4096) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dirsize = 12; - } else { - uint64 dircount64; - if (!ReadOK(tif, &dircount64, sizeof (uint64))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>4096) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dircount16 = (uint16)dircount64; - dirsize = 20; - } - origdir = _TIFFCheckMalloc(tif, dircount16, - dirsize, "to read TIFF directory"); - if (origdir == NULL) - return 0; - if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%.100s: Can not read TIFF directory", - tif->tif_name); - _TIFFfree(origdir); - return 0; - } - /* - * Read offset to next directory for sequential scans if - * needed. - */ - if (nextdiroff) - { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32 nextdiroff32; - if (!ReadOK(tif, &nextdiroff32, sizeof(uint32))) - nextdiroff32 = 0; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nextdiroff32); - *nextdiroff=nextdiroff32; - } else { - if (!ReadOK(tif, nextdiroff, sizeof(uint64))) - *nextdiroff = 0; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - } else { - tmsize_t m; - tmsize_t off; - if (tif->tif_diroff > (uint64)TIFF_INT64_MAX) - { - TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count"); - return(0); - } - off = (tmsize_t) tif->tif_diroff; + tif->tif_diroff = diroff; + if (nextdiroff) + *nextdiroff = 0; + if (!isMapped(tif)) + { + if (!SeekOK(tif, tif->tif_diroff)) + { + TIFFErrorExtR(tif, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); + return 0; + } + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (!ReadOK(tif, &dircount16, sizeof(uint16_t))) + { + TIFFErrorExtR(tif, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount16); + if (dircount16 > 4096) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, this is " + "probably not a valid IFD offset"); + return 0; + } + dirsize = 12; + } + else + { + uint64_t dircount64; + if (!ReadOK(tif, &dircount64, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 4096) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, this is " + "probably not a valid IFD offset"); + return 0; + } + dircount16 = (uint16_t)dircount64; + dirsize = 20; + } + origdir = _TIFFCheckMalloc(tif, dircount16, dirsize, + "to read TIFF directory"); + if (origdir == NULL) + return 0; + if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize))) + { + TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory", + tif->tif_name); + _TIFFfreeExt(tif, origdir); + return 0; + } + /* + * Read offset to next directory for sequential scans if + * needed. + */ + if (nextdiroff) + { + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t nextdiroff32; + if (!ReadOK(tif, &nextdiroff32, sizeof(uint32_t))) + nextdiroff32 = 0; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdiroff32); + *nextdiroff = nextdiroff32; + } + else + { + if (!ReadOK(tif, nextdiroff, sizeof(uint64_t))) + *nextdiroff = 0; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + } + else + { + tmsize_t m; + tmsize_t off; + if (tif->tif_diroff > (uint64_t)INT64_MAX) + { + TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); + return (0); + } + off = (tmsize_t)tif->tif_diroff; - /* - * Check for integer overflow when validating the dir_off, - * otherwise a very high offset may cause an OOB read and - * crash the client. Make two comparisons instead of - * - * off + sizeof(uint16) > tif->tif_size - * - * to avoid overflow. - */ - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - m=off+sizeof(uint16); - if ((mtif->tif_size)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not read TIFF directory count"); - return 0; - } else { - _TIFFmemcpy(&dircount16, tif->tif_base + off, - sizeof(uint16)); - } - off += sizeof (uint16); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount16); - if (dircount16>4096) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dirsize = 12; - } - else - { - uint64 dircount64; - m=off+sizeof(uint64); - if ((mtif->tif_size)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not read TIFF directory count"); - return 0; - } else { - _TIFFmemcpy(&dircount64, tif->tif_base + off, - sizeof(uint64)); - } - off += sizeof (uint64); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>4096) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dircount16 = (uint16)dircount64; - dirsize = 20; - } - if (dircount16 == 0 ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on directory count failed, zero tag directories not supported"); - return 0; - } - origdir = _TIFFCheckMalloc(tif, dircount16, - dirsize, - "to read TIFF directory"); - if (origdir == NULL) - return 0; - m=off+dircount16*dirsize; - if ((mtif->tif_size)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not read TIFF directory"); - _TIFFfree(origdir); - return 0; - } else { - _TIFFmemcpy(origdir, tif->tif_base + off, - dircount16 * dirsize); - } - if (nextdiroff) { - off += dircount16 * dirsize; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32 nextdiroff32; - m=off+sizeof(uint32); - if ((mtif->tif_size)) - nextdiroff32 = 0; - else - _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, - sizeof (uint32)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nextdiroff32); - *nextdiroff = nextdiroff32; - } - else - { - m=off+sizeof(uint64); - if ((mtif->tif_size)) - *nextdiroff = 0; - else - _TIFFmemcpy(nextdiroff, tif->tif_base + off, - sizeof (uint64)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - } - dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16, - sizeof(TIFFDirEntry), - "to read TIFF directory"); - if (dir==0) - { - _TIFFfree(origdir); - return 0; - } - ma=(uint8*)origdir; - mb=dir; - for (n=0; ntdir_ignore = FALSE; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - mb->tdir_tag=*(uint16*)ma; - ma+=sizeof(uint16); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)ma); - mb->tdir_type=*(uint16*)ma; - ma+=sizeof(uint16); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)ma); - mb->tdir_count=(uint64)(*(uint32*)ma); - ma+=sizeof(uint32); - mb->tdir_offset.toff_long8=0; - *(uint32*)(&mb->tdir_offset)=*(uint32*)ma; - ma+=sizeof(uint32); - } - else - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)ma); - mb->tdir_count=TIFFReadUInt64(ma); - ma+=sizeof(uint64); - mb->tdir_offset.toff_long8=TIFFReadUInt64(ma); - ma+=sizeof(uint64); - } - mb++; - } - _TIFFfree(origdir); - *pdir = dir; - return dircount16; + /* + * Check for integer overflow when validating the dir_off, + * otherwise a very high offset may cause an OOB read and + * crash the client. Make two comparisons instead of + * + * off + sizeof(uint16_t) > tif->tif_size + * + * to avoid overflow. + */ + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + m = off + sizeof(uint16_t); + if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) || + (m > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); + return 0; + } + else + { + _TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t)); + } + off += sizeof(uint16_t); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount16); + if (dircount16 > 4096) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, this is " + "probably not a valid IFD offset"); + return 0; + } + dirsize = 12; + } + else + { + uint64_t dircount64; + m = off + sizeof(uint64_t); + if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || + (m > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); + return 0; + } + else + { + _TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t)); + } + off += sizeof(uint64_t); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 4096) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, this is " + "probably not a valid IFD offset"); + return 0; + } + dircount16 = (uint16_t)dircount64; + dirsize = 20; + } + if (dircount16 == 0) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, zero tag " + "directories not supported"); + return 0; + } + origdir = _TIFFCheckMalloc(tif, dircount16, dirsize, + "to read TIFF directory"); + if (origdir == NULL) + return 0; + m = off + dircount16 * dirsize; + if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) || + (m > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Can not read TIFF directory"); + _TIFFfreeExt(tif, origdir); + return 0; + } + else + { + _TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize); + } + if (nextdiroff) + { + off += dircount16 * dirsize; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t nextdiroff32; + m = off + sizeof(uint32_t); + if ((m < off) || (m < (tmsize_t)sizeof(uint32_t)) || + (m > tif->tif_size)) + nextdiroff32 = 0; + else + _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, + sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdiroff32); + *nextdiroff = nextdiroff32; + } + else + { + m = off + sizeof(uint64_t); + if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || + (m > tif->tif_size)) + *nextdiroff = 0; + else + _TIFFmemcpy(nextdiroff, tif->tif_base + off, + sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + } + dir = (TIFFDirEntry *)_TIFFCheckMalloc( + tif, dircount16, sizeof(TIFFDirEntry), "to read TIFF directory"); + if (dir == 0) + { + _TIFFfreeExt(tif, origdir); + return 0; + } + ma = (uint8_t *)origdir; + mb = dir; + for (n = 0; n < dircount16; n++) + { + mb->tdir_ignore = FALSE; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + mb->tdir_tag = *(uint16_t *)ma; + ma += sizeof(uint16_t); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + mb->tdir_type = *(uint16_t *)ma; + ma += sizeof(uint16_t); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + mb->tdir_count = (uint64_t)(*(uint32_t *)ma); + ma += sizeof(uint32_t); + mb->tdir_offset.toff_long8 = 0; + *(uint32_t *)(&mb->tdir_offset) = *(uint32_t *)ma; + ma += sizeof(uint32_t); + } + else + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + mb->tdir_count = TIFFReadUInt64(ma); + ma += sizeof(uint64_t); + mb->tdir_offset.toff_long8 = TIFFReadUInt64(ma); + ma += sizeof(uint64_t); + } + mb++; + } + _TIFFfreeExt(tif, origdir); + *pdir = dir; + return dircount16; } /* * Fetch a tag that is not handled by special case code. */ -static int -TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) +static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) { - static const char module[] = "TIFFFetchNormalTag"; - enum TIFFReadDirEntryErr err; - uint32 fii; - const TIFFField* fip = NULL; - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - if( fii == FAILED_FII ) + static const char module[] = "TIFFFetchNormalTag"; + enum TIFFReadDirEntryErr err; + uint32_t fii; + const TIFFField *fip = NULL; + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + if (fii == FAILED_FII) + { + TIFFErrorExtR(tif, "TIFFFetchNormalTag", + "No definition found for tag %" PRIu16, dp->tdir_tag); + return 0; + } + fip = tif->tif_fields[fii]; + assert(fip != NULL); /* should not happen */ + assert(fip->set_field_type != + TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with + this in specialized code */ + assert(fip->set_field_type != + TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only + the case for pseudo-tags */ + err = TIFFReadDirEntryErrOk; + switch (fip->set_field_type) + { + case TIFF_SETGET_UNDEFINED: + TIFFErrorExtR( + tif, "TIFFFetchNormalTag", + "Defined set_field_type of custom tag %u (%s) is " + "TIFF_SETGET_UNDEFINED and thus tag is not read from file", + fip->field_tag, fip->field_name); + break; + case TIFF_SETGET_ASCII: { - TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag", - "No definition found for tag %d", - dp->tdir_tag); - return 0; + uint8_t *data; + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + size_t mb = 0; + int n; + if (data != NULL) + { + if (dp->tdir_count > 0 && data[dp->tdir_count - 1] == 0) + { + /* optimization: if data is known to be 0 terminated, we + * can use strlen() */ + mb = strlen((const char *)data); + } + else + { + /* general case. equivalent to non-portable */ + /* mb = strnlen((const char*)data, + * (uint32_t)dp->tdir_count); */ + uint8_t *ma = data; + while (mb < (uint32_t)dp->tdir_count) + { + if (*ma == 0) + break; + ma++; + mb++; + } + } + } + if (mb + 1 < (uint32_t)dp->tdir_count) + TIFFWarningExtR( + tif, module, + "ASCII value for tag \"%s\" contains null byte in " + "value; value incorrectly truncated during reading due " + "to implementation limitations", + fip->field_name); + else if (mb + 1 > (uint32_t)dp->tdir_count) + { + uint8_t *o; + TIFFWarningExtR( + tif, module, + "ASCII value for tag \"%s\" does not end in null byte", + fip->field_name); + /* TIFFReadDirEntryArrayWithLimit() ensures this can't be + * larger than MAX_SIZE_TAG_DATA */ + assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1); + o = _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); + if (o == NULL) + { + if (data != NULL) + _TIFFfreeExt(tif, data); + return (0); + } + if (dp->tdir_count > 0) + { + _TIFFmemcpy(o, data, (uint32_t)dp->tdir_count); + } + o[(uint32_t)dp->tdir_count] = 0; + if (data != 0) + _TIFFfreeExt(tif, data); + data = o; + } + n = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!n) + return (0); + } } - fip=tif->tif_fields[fii]; - assert(fip != NULL); /* should not happen */ - assert(fip->set_field_type!=TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with this in specialized code */ - assert(fip->set_field_type!=TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */ - err=TIFFReadDirEntryErrOk; - switch (fip->set_field_type) - { - case TIFF_SETGET_UNDEFINED: - break; - case TIFF_SETGET_ASCII: - { - uint8* data; - assert(fip->field_passcount==0); - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - uint32 mb = 0; - int n; - if (data != NULL) - { - uint8* ma = data; - while (mb<(uint32)dp->tdir_count) - { - if (*ma==0) - break; - ma++; - mb++; - } - } - if (mb+1<(uint32)dp->tdir_count) - TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name); - else if (mb+1>(uint32)dp->tdir_count) - { - uint8* o; - TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name); - if ((uint32)dp->tdir_count+1!=dp->tdir_count+1) - o=NULL; - else - o=_TIFFmalloc((uint32)dp->tdir_count+1); - if (o==NULL) - { - if (data!=NULL) - _TIFFfree(data); - return(0); - } - _TIFFmemcpy(o,data,(uint32)dp->tdir_count); - o[(uint32)dp->tdir_count]=0; - if (data!=0) - _TIFFfree(data); - data=o; - } - n=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!n) - return(0); - } - } - break; - case TIFF_SETGET_UINT8: - { - uint8 data=0; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryByte(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_UINT16: - { - uint16 data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryShort(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_UINT32: - { - uint32 data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryLong(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_UINT64: - { - uint64 data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryLong8(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_FLOAT: - { - float data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryFloat(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_DOUBLE: - { - double data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryDouble(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_IFD8: - { - uint64 data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryIfd8(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_UINT16_PAIR: - { - uint16* data; - assert(fip->field_readcount==2); - assert(fip->field_passcount==0); - if (dp->tdir_count!=2) { - TIFFWarningExt(tif->tif_clientdata,module, - "incorrect count for field \"%s\", expected 2, got %d", - fip->field_name,(int)dp->tdir_count); - return(0); - } - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - assert(data); /* avoid CLang static Analyzer false positive */ - m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]); - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C0_UINT8: - { - uint8* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64)fip->field_readcount) { - TIFFWarningExt(tif->tif_clientdata,module, - "incorrect count for field \"%s\", expected %d, got %d", - fip->field_name,(int) fip->field_readcount, (int)dp->tdir_count); - return 0; - } - else - { - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_UINT16: - { - uint16* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64)fip->field_readcount) - /* corrupt file */; - else - { - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_UINT32: - { - uint32* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64)fip->field_readcount) - /* corrupt file */; - else - { - err=TIFFReadDirEntryLongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_FLOAT: - { - float* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64)fip->field_readcount) - /* corrupt file */; - else - { - err=TIFFReadDirEntryFloatArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read into Double-Arrays. */ - case TIFF_SETGET_C0_DOUBLE: - { - double* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64)fip->field_readcount) - /* corrupt file */; - else - { - err=TIFFReadDirEntryDoubleArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_ASCII: - { - uint8* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) - { - TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); - data[dp->tdir_count-1] = '\0'; - } - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT8: - { - uint8* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT16: - { - uint16* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT32: - { - uint32* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryLongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT64: - { - uint64* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryLong8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_FLOAT: - { - float* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryFloatArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_DOUBLE: - { - double* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryDoubleArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_IFD8: - { - uint64* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryIfd8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C32_ASCII: - { - uint8* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) - { - TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); - data[dp->tdir_count-1] = '\0'; - } - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT8: - { - uint8* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT8: - { - int8* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySbyteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT16: - { - uint16* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT16: - { - int16* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySshortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT32: - { - uint32* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryLongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT32: - { - int32* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySlongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT64: - { - uint64* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryLong8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT64: - { - int64* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySlong8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_FLOAT: - { - float* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryFloatArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_DOUBLE: - { - double* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryDoubleArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_IFD8: - { - uint64* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryIfd8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); - if (data!=0) - _TIFFfree(data); - if (!m) - return(0); - } - } - break; - default: - assert(0); /* we should never get here */ - break; - } - if (err!=TIFFReadDirEntryErrOk) - { - TIFFReadDirEntryOutputErr(tif,err,module,fip->field_name,recover); - return(0); - } - return(1); + break; + case TIFF_SETGET_UINT8: + { + uint8_t data = 0; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryByte(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_SINT8: + { + int8_t data = 0; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntrySbyte(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_UINT16: + { + uint16_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryShort(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_SINT16: + { + int16_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntrySshort(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_UINT32: + { + uint32_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryLong(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_SINT32: + { + int32_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntrySlong(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_UINT64: + { + uint64_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryLong8(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_SINT64: + { + int64_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntrySlong8(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_FLOAT: + { + float data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryFloat(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_DOUBLE: + { + double data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryDouble(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_IFD8: + { + uint64_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryIfd8(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_UINT16_PAIR: + { + uint16_t *data; + assert(fip->field_readcount == 2); + assert(fip->field_passcount == 0); + if (dp->tdir_count != 2) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected 2, " + "got %" PRIu64, + fip->field_name, dp->tdir_count); + return (0); + } + err = TIFFReadDirEntryShortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + assert(data); /* avoid CLang static Analyzer false positive */ + m = TIFFSetField(tif, dp->tdir_tag, data[0], data[1]); + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C0_UINT8: + { + uint8_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_SINT8: + { + int8_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntrySbyteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_UINT16: + { + uint16_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryShortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_SINT16: + { + int16_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntrySshortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_UINT32: + { + uint32_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryLongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_SINT32: + { + int32_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntrySlongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_UINT64: + { + uint64_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryLong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_SINT64: + { + int64_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntrySlong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_FLOAT: + { + float *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryFloatArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read + * into Double-Arrays. */ + case TIFF_SETGET_C0_DOUBLE: + { + double *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_ASCII: + { + uint8_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + if (data != 0 && dp->tdir_count > 0 && + data[dp->tdir_count - 1] != '\0') + { + TIFFWarningExtR( + tif, module, + "ASCII value for tag \"%s\" does not end in null " + "byte. Forcing it to be null", + fip->field_name); + data[dp->tdir_count - 1] = '\0'; + } + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_UINT8: + { + uint8_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_SINT8: + { + int8_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntrySbyteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_UINT16: + { + uint16_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryShortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_SINT16: + { + int16_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntrySshortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_UINT32: + { + uint32_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryLongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_SINT32: + { + int32_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntrySlongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_UINT64: + { + uint64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryLong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_SINT64: + { + int64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntrySlong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_FLOAT: + { + float *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryFloatArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_DOUBLE: + { + double *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_IFD8: + { + uint64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryIfd8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C32_ASCII: + { + uint8_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + if (data != 0 && dp->tdir_count > 0 && + data[dp->tdir_count - 1] != '\0') + { + TIFFWarningExtR(tif, module, + "ASCII value for tag \"%s\" does not end " + "in null byte. Forcing it to be null", + fip->field_name); + data[dp->tdir_count - 1] = '\0'; + } + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_UINT8: + { + uint8_t *data; + uint32_t count = 0; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + if (fip->field_tag == TIFFTAG_RICHTIFFIPTC && + dp->tdir_type == TIFF_LONG) + { + /* Adobe's software (wrongly) writes RichTIFFIPTC tag with + * data type LONG instead of UNDEFINED. Work around this + * frequently found issue */ + void *origdata; + err = TIFFReadDirEntryArray(tif, dp, &count, 4, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + data = NULL; + } + else + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)origdata, count); + data = (uint8_t *)origdata; + count = (uint32_t)(count * 4); + } + } + else + { + err = TIFFReadDirEntryByteArray(tif, dp, &data); + count = (uint32_t)(dp->tdir_count); + } + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, count, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_SINT8: + { + int8_t *data = NULL; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntrySbyteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_UINT16: + { + uint16_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryShortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_SINT16: + { + int16_t *data = NULL; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntrySshortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_UINT32: + { + uint32_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryLongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_SINT32: + { + int32_t *data = NULL; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntrySlongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_UINT64: + { + uint64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryLong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_SINT64: + { + int64_t *data = NULL; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntrySlong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_FLOAT: + { + float *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryFloatArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_DOUBLE: + { + double *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_IFD8: + { + uint64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryIfd8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + default: + assert(0); /* we should never get here */ + break; + } + if (err != TIFFReadDirEntryErrOk) + { + TIFFReadDirEntryOutputErr(tif, err, module, fip->field_name, recover); + return (0); + } + return (1); } /* * Fetch a set of offsets or lengths. * While this routine says "strips", in fact it's also used for tiles. */ -static int -TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp) +static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips, + uint64_t **lpp) { - static const char module[] = "TIFFFetchStripThing"; - enum TIFFReadDirEntryErr err; - uint64* data; - err=TIFFReadDirEntryLong8ArrayWithLimit(tif,dir,&data,nstrips); - if (err!=TIFFReadDirEntryErrOk) - { - const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); - TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); - return(0); - } - if (dir->tdir_count<(uint64)nstrips) - { - uint64* resizeddata; - const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); - const char* pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT"); - uint32 max_nstrips = 1000000; - if( pszMax ) - max_nstrips = (uint32) atoi(pszMax); - TIFFReadDirEntryOutputErr(tif,TIFFReadDirEntryErrCount, - module, - fip ? fip->field_name : "unknown tagname", - ( nstrips <= max_nstrips ) ); + static const char module[] = "TIFFFetchStripThing"; + enum TIFFReadDirEntryErr err; + uint64_t *data; + err = TIFFReadDirEntryLong8ArrayWithLimit(tif, dir, &data, nstrips); + if (err != TIFFReadDirEntryErrOk) + { + const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFReadDirEntryOutputErr(tif, err, module, + fip ? fip->field_name : "unknown tagname", 0); + return (0); + } + if (dir->tdir_count < (uint64_t)nstrips) + { + uint64_t *resizeddata; + const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); + const char *pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT"); + uint32_t max_nstrips = 1000000; + if (pszMax) + max_nstrips = (uint32_t)atoi(pszMax); + TIFFReadDirEntryOutputErr(tif, TIFFReadDirEntryErrCount, module, + fip ? fip->field_name : "unknown tagname", + (nstrips <= max_nstrips)); - if( nstrips > max_nstrips ) - { - _TIFFfree(data); - return(0); - } + if (nstrips > max_nstrips) + { + _TIFFfreeExt(tif, data); + return (0); + } - resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array"); - if (resizeddata==0) { - _TIFFfree(data); - return(0); - } - _TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64)); - _TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64)); - _TIFFfree(data); - data=resizeddata; - } - *lpp=data; - return(1); + resizeddata = (uint64_t *)_TIFFCheckMalloc( + tif, nstrips, sizeof(uint64_t), "for strip array"); + if (resizeddata == 0) + { + _TIFFfreeExt(tif, data); + return (0); + } + if (dir->tdir_count) + _TIFFmemcpy(resizeddata, data, + (uint32_t)dir->tdir_count * sizeof(uint64_t)); + _TIFFmemset(resizeddata + (uint32_t)dir->tdir_count, 0, + (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t)); + _TIFFfreeExt(tif, data); + data = resizeddata; + } + *lpp = data; + return (1); } /* * Fetch and set the SubjectDistance EXIF tag. */ -static int -TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir) +static int TIFFFetchSubjectDistance(TIFF *tif, TIFFDirEntry *dir) { - static const char module[] = "TIFFFetchSubjectDistance"; - enum TIFFReadDirEntryErr err; - UInt64Aligned_t m; - m.l=0; - assert(sizeof(double)==8); - assert(sizeof(uint64)==8); - assert(sizeof(uint32)==4); - if (dir->tdir_count!=1) - err=TIFFReadDirEntryErrCount; - else if (dir->tdir_type!=TIFF_RATIONAL) - err=TIFFReadDirEntryErrType; - else - { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32 offset; - offset=*(uint32*)(&dir->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,m.i); - } - else - { - m.l=dir->tdir_offset.toff_long8; - err=TIFFReadDirEntryErrOk; - } - } - if (err==TIFFReadDirEntryErrOk) - { - double n; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m.i,2); - if (m.i[0]==0) - n=0.0; - else if (m.i[0]==0xFFFFFFFF || m.i[1]==0) - /* - * XXX: Numerator 0xFFFFFFFF means that we have infinite - * distance. Indicate that with a negative floating point - * SubjectDistance value. - */ - n=-1.0; - else - n=(double)m.i[0]/(double)m.i[1]; - return(TIFFSetField(tif,dir->tdir_tag,n)); - } - else - { - TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE); - return(0); - } + static const char module[] = "TIFFFetchSubjectDistance"; + enum TIFFReadDirEntryErr err; + UInt64Aligned_t m; + m.l = 0; + assert(sizeof(double) == 8); + assert(sizeof(uint64_t) == 8); + assert(sizeof(uint32_t) == 4); + if (dir->tdir_count != 1) + err = TIFFReadDirEntryErrCount; + else if (dir->tdir_type != TIFF_RATIONAL) + err = TIFFReadDirEntryErrType; + else + { + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t offset; + offset = *(uint32_t *)(&dir->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, m.i); + } + else + { + m.l = dir->tdir_offset.toff_long8; + err = TIFFReadDirEntryErrOk; + } + } + if (err == TIFFReadDirEntryErrOk) + { + double n; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m.i, 2); + if (m.i[0] == 0) + n = 0.0; + else if (m.i[0] == 0xFFFFFFFF || m.i[1] == 0) + /* + * XXX: Numerator 0xFFFFFFFF means that we have infinite + * distance. Indicate that with a negative floating point + * SubjectDistance value. + */ + n = -1.0; + else + n = (double)m.i[0] / (double)m.i[1]; + return (TIFFSetField(tif, dir->tdir_tag, n)); + } + else + { + TIFFReadDirEntryOutputErr(tif, err, module, "SubjectDistance", TRUE); + return (0); + } } -static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips, - uint64 stripbytes, uint32 rowsperstrip) +static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips, + uint64_t stripbytes, + uint32_t rowsperstrip) { TIFFDirectory *td = &tif->tif_dir; - uint64 bytecount; - uint64 offset; - uint64 last_offset; - uint64 last_bytecount; - uint32 i; - uint64 *newcounts; - uint64 *newoffsets; + uint64_t bytecount; + uint64_t offset; + uint64_t last_offset; + uint64_t last_bytecount; + uint32_t i; + uint64_t *newcounts; + uint64_t *newoffsets; offset = TIFFGetStrileOffset(tif, 0); - last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1); - last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1); - if( last_offset > TIFF_UINT64_MAX - last_bytecount || - last_offset + last_bytecount < offset ) + last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1); + last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips - 1); + if (last_offset > UINT64_MAX - last_bytecount || + last_offset + last_bytecount < offset) { return; } bytecount = last_offset + last_bytecount - offset; - newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), - "for chopped \"StripByteCounts\" array"); - newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), - "for chopped \"StripOffsets\" array"); - if (newcounts == NULL || newoffsets == NULL) { + newcounts = + (uint64_t *)_TIFFCheckMalloc(tif, nstrips, sizeof(uint64_t), + "for chopped \"StripByteCounts\" array"); + newoffsets = (uint64_t *)_TIFFCheckMalloc( + tif, nstrips, sizeof(uint64_t), "for chopped \"StripOffsets\" array"); + if (newcounts == NULL || newoffsets == NULL) + { /* - * Unable to allocate new strip information, give up and use - * the original one strip information. - */ + * Unable to allocate new strip information, give up and use + * the original one strip information. + */ if (newcounts != NULL) - _TIFFfree(newcounts); + _TIFFfreeExt(tif, newcounts); if (newoffsets != NULL) - _TIFFfree(newoffsets); + _TIFFfreeExt(tif, newoffsets); return; } @@ -5890,8 +7301,8 @@ static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips, td->td_stripsperimage = td->td_nstrips = nstrips; TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); - _TIFFfree(td->td_stripbytecount_p); - _TIFFfree(td->td_stripoffset_p); + _TIFFfreeExt(tif, td->td_stripbytecount_p); + _TIFFfreeExt(tif, td->td_stripoffset_p); td->td_stripbytecount_p = newcounts; td->td_stripoffset_p = newoffsets; #ifdef STRIPBYTECOUNTSORTED_UNUSED @@ -5900,140 +7311,140 @@ static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips, tif->tif_flags |= TIFF_CHOPPEDUPARRAYS; } - /* * Replace a single strip (tile) of uncompressed data by multiple strips * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for * dealing with large images or for dealing with machines with a limited * amount memory. */ -static void -ChopUpSingleUncompressedStrip(TIFF* tif) +static void ChopUpSingleUncompressedStrip(TIFF *tif) { - register TIFFDirectory *td = &tif->tif_dir; - uint64 bytecount; - uint64 offset; - uint32 rowblock; - uint64 rowblockbytes; - uint64 stripbytes; - uint32 nstrips; - uint32 rowsperstrip; + register TIFFDirectory *td = &tif->tif_dir; + uint64_t bytecount; + uint64_t offset; + uint32_t rowblock; + uint64_t rowblockbytes; + uint64_t stripbytes; + uint32_t nstrips; + uint32_t rowsperstrip; - bytecount = TIFFGetStrileByteCount(tif, 0); - /* On a newly created file, just re-opened to be filled, we */ - /* don't want strip chop to trigger as it is going to cause issues */ - /* later ( StripOffsets and StripByteCounts improperly filled) . */ - if( bytecount == 0 && tif->tif_mode != O_RDONLY ) - return; - offset = TIFFGetStrileByteCount(tif, 0); - assert(td->td_planarconfig == PLANARCONFIG_CONTIG); - if ((td->td_photometric == PHOTOMETRIC_YCBCR)&& - (!isUpSampled(tif))) - rowblock = td->td_ycbcrsubsampling[1]; - else - rowblock = 1; - rowblockbytes = TIFFVTileSize64(tif, rowblock); - /* - * Make the rows hold at least one scanline, but fill specified amount - * of data if possible. - */ - if (rowblockbytes > STRIP_SIZE_DEFAULT) { - stripbytes = rowblockbytes; - rowsperstrip = rowblock; - } else if (rowblockbytes > 0 ) { - uint32 rowblocksperstrip; - rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes); - rowsperstrip = rowblocksperstrip * rowblock; - stripbytes = rowblocksperstrip * rowblockbytes; - } - else - return; + bytecount = TIFFGetStrileByteCount(tif, 0); + /* On a newly created file, just re-opened to be filled, we */ + /* don't want strip chop to trigger as it is going to cause issues */ + /* later ( StripOffsets and StripByteCounts improperly filled) . */ + if (bytecount == 0 && tif->tif_mode != O_RDONLY) + return; + offset = TIFFGetStrileByteCount(tif, 0); + assert(td->td_planarconfig == PLANARCONFIG_CONTIG); + if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) + rowblock = td->td_ycbcrsubsampling[1]; + else + rowblock = 1; + rowblockbytes = TIFFVTileSize64(tif, rowblock); + /* + * Make the rows hold at least one scanline, but fill specified amount + * of data if possible. + */ + if (rowblockbytes > STRIP_SIZE_DEFAULT) + { + stripbytes = rowblockbytes; + rowsperstrip = rowblock; + } + else if (rowblockbytes > 0) + { + uint32_t rowblocksperstrip; + rowblocksperstrip = (uint32_t)(STRIP_SIZE_DEFAULT / rowblockbytes); + rowsperstrip = rowblocksperstrip * rowblock; + stripbytes = rowblocksperstrip * rowblockbytes; + } + else + return; - /* - * never increase the number of rows per strip - */ - if (rowsperstrip >= td->td_rowsperstrip) - return; - nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); - if( nstrips == 0 ) - return; + /* + * never increase the number of rows per strip + */ + if (rowsperstrip >= td->td_rowsperstrip) + return; + nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); + if (nstrips == 0) + return; - /* If we are going to allocate a lot of memory, make sure that the */ - /* file is as big as needed */ - if( tif->tif_mode == O_RDONLY && - nstrips > 1000000 && - (offset >= TIFFGetFileSize(tif) || - stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1)) ) - { - return; - } + /* If we are going to allocate a lot of memory, make sure that the */ + /* file is as big as needed */ + if (tif->tif_mode == O_RDONLY && nstrips > 1000000 && + (offset >= TIFFGetFileSize(tif) || + stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1))) + { + return; + } - allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); + allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); } - /* * Replace a file with contiguous strips > 2 GB of uncompressed data by * multiple smaller strips. This is useful for * dealing with large images or for dealing with machines with a limited * amount memory. */ -static void TryChopUpUncompressedBigTiff( TIFF* tif ) +static void TryChopUpUncompressedBigTiff(TIFF *tif) { TIFFDirectory *td = &tif->tif_dir; - uint32 rowblock; - uint64 rowblockbytes; - uint32 i; - uint64 stripsize; - uint32 rowblocksperstrip; - uint32 rowsperstrip; - uint64 stripbytes; - uint32 nstrips; + uint32_t rowblock; + uint64_t rowblockbytes; + uint32_t i; + uint64_t stripsize; + uint32_t rowblocksperstrip; + uint32_t rowsperstrip; + uint64_t stripbytes; + uint32_t nstrips; stripsize = TIFFStripSize64(tif); - assert( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG ); - assert( tif->tif_dir.td_compression == COMPRESSION_NONE ); - assert( (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP ); - assert( stripsize > 0x7FFFFFFFUL ); + assert(tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG); + assert(tif->tif_dir.td_compression == COMPRESSION_NONE); + assert((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == + TIFF_STRIPCHOP); + assert(stripsize > 0x7FFFFFFFUL); /* On a newly created file, just re-opened to be filled, we */ /* don't want strip chop to trigger as it is going to cause issues */ /* later ( StripOffsets and StripByteCounts improperly filled) . */ - if( TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY ) + if (TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY) return; - if ((td->td_photometric == PHOTOMETRIC_YCBCR)&& - (!isUpSampled(tif))) + if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) rowblock = td->td_ycbcrsubsampling[1]; else rowblock = 1; rowblockbytes = TIFFVStripSize64(tif, rowblock); - if( rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL ) + if (rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL) { /* In case of file with gigantic width */ return; } /* Check that the strips are contiguous and of the expected size */ - for( i = 0; i < td->td_nstrips; i++ ) + for (i = 0; i < td->td_nstrips; i++) { - if( i == td->td_nstrips - 1 ) + if (i == td->td_nstrips - 1) { - if( TIFFGetStrileByteCount(tif, i) < TIFFVStripSize64( - tif, td->td_imagelength - i * td->td_rowsperstrip ) ) + if (TIFFGetStrileByteCount(tif, i) < + TIFFVStripSize64(tif, + td->td_imagelength - i * td->td_rowsperstrip)) { return; } } else { - if( TIFFGetStrileByteCount(tif, i) != stripsize ) + if (TIFFGetStrileByteCount(tif, i) != stripsize) { return; } - if( i > 0 && TIFFGetStrileOffset(tif, i) != - TIFFGetStrileOffset(tif, i-1) + TIFFGetStrileByteCount(tif, i-1) ) + if (i > 0 && TIFFGetStrileOffset(tif, i) != + TIFFGetStrileOffset(tif, i - 1) + + TIFFGetStrileByteCount(tif, i - 1)) { return; } @@ -6041,27 +7452,26 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif ) } /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */ - rowblocksperstrip = (uint32) (512 * 1024 * 1024 / rowblockbytes); - if( rowblocksperstrip == 0 ) + rowblocksperstrip = (uint32_t)(512 * 1024 * 1024 / rowblockbytes); + if (rowblocksperstrip == 0) rowblocksperstrip = 1; rowsperstrip = rowblocksperstrip * rowblock; stripbytes = rowblocksperstrip * rowblockbytes; - assert( stripbytes <= 0x7FFFFFFFUL ); + assert(stripbytes <= 0x7FFFFFFFUL); nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); - if( nstrips == 0 ) + if (nstrips == 0) return; /* If we are going to allocate a lot of memory, make sure that the */ /* file is as big as needed */ - if( tif->tif_mode == O_RDONLY && - nstrips > 1000000 ) + if (tif->tif_mode == O_RDONLY && nstrips > 1000000) { - uint64 last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1); - uint64 filesize = TIFFGetFileSize(tif); - uint64 last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1); - if( last_offset > filesize || - last_bytecount > filesize - last_offset ) + uint64_t last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1); + uint64_t filesize = TIFFGetFileSize(tif); + uint64_t last_bytecount = + TIFFGetStrileByteCount(tif, td->td_nstrips - 1); + if (last_offset > filesize || last_bytecount > filesize - last_offset) { return; } @@ -6070,9 +7480,8 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif ) allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); } - TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static uint64 _TIFFUnsanitizedAddUInt64AndInt(uint64 a, int b) +static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b) { return a + b; } @@ -6081,9 +7490,8 @@ static uint64 _TIFFUnsanitizedAddUInt64AndInt(uint64 a, int b) * strip/tile of number strile. Also fetch the neighbouring values using a * 4096 byte page size. */ -static -int _TIFFPartialReadStripArray( TIFF* tif, TIFFDirEntry* dirent, - int strile, uint64* panVals ) +static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent, + int strile, uint64_t *panVals) { static const char module[] = "_TIFFPartialReadStripArray"; #define IO_CACHE_PAGE_SIZE 4096 @@ -6091,89 +7499,88 @@ int _TIFFPartialReadStripArray( TIFF* tif, TIFFDirEntry* dirent, size_t sizeofval; const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0; int sizeofvalint; - uint64 nBaseOffset; - uint64 nOffset; - uint64 nOffsetStartPage; - uint64 nOffsetEndPage; + uint64_t nBaseOffset; + uint64_t nOffset; + uint64_t nOffsetStartPage; + uint64_t nOffsetEndPage; tmsize_t nToRead; tmsize_t nRead; - uint64 nLastStripOffset; + uint64_t nLastStripOffset; int iStartBefore; int i; - const uint32 arraySize = tif->tif_dir.td_stripoffsetbyteallocsize; + const uint32_t arraySize = tif->tif_dir.td_stripoffsetbyteallocsize; unsigned char buffer[2 * IO_CACHE_PAGE_SIZE]; - assert( dirent->tdir_count > 4 ); + assert(dirent->tdir_count > 4); - if( dirent->tdir_type == TIFF_SHORT ) + if (dirent->tdir_type == TIFF_SHORT) { - sizeofval = sizeof(uint16); + sizeofval = sizeof(uint16_t); } - else if( dirent->tdir_type == TIFF_LONG ) + else if (dirent->tdir_type == TIFF_LONG) { - sizeofval = sizeof(uint32); + sizeofval = sizeof(uint32_t); } - else if( dirent->tdir_type == TIFF_LONG8 ) + else if (dirent->tdir_type == TIFF_LONG8) { - sizeofval = sizeof(uint64); + sizeofval = sizeof(uint64_t); } - else if( dirent->tdir_type == TIFF_SLONG8 ) + else if (dirent->tdir_type == TIFF_SLONG8) { /* Non conformant but used by some images as in */ /* https://github.com/OSGeo/gdal/issues/2165 */ - sizeofval = sizeof(int64); + sizeofval = sizeof(int64_t); } else { - TIFFErrorExt(tif->tif_clientdata, module, - "Invalid type for [Strip|Tile][Offset/ByteCount] tag"); + TIFFErrorExtR(tif, module, + "Invalid type for [Strip|Tile][Offset/ByteCount] tag"); panVals[strile] = 0; return 0; } sizeofvalint = (int)(sizeofval); - if( tif->tif_flags&TIFF_BIGTIFF ) + if (tif->tif_flags & TIFF_BIGTIFF) { - uint64 offset = dirent->tdir_offset.toff_long8; - if( bSwab ) + uint64_t offset = dirent->tdir_offset.toff_long8; + if (bSwab) TIFFSwabLong8(&offset); nBaseOffset = offset; } else { - uint32 offset = dirent->tdir_offset.toff_long; - if( bSwab ) + uint32_t offset = dirent->tdir_offset.toff_long; + if (bSwab) TIFFSwabLong(&offset); nBaseOffset = offset; } /* To avoid later unsigned integer overflows */ - if( nBaseOffset > (uint64)TIFF_INT64_MAX ) + if (nBaseOffset > (uint64_t)INT64_MAX) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot read offset/size for strile %d", strile); + TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d", + strile); panVals[strile] = 0; return 0; } nOffset = nBaseOffset + sizeofval * strile; - nOffsetStartPage = - (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE; + nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE; nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE; - if( nOffset + sizeofval > nOffsetEndPage ) + if (nOffset + sizeofval > nOffsetEndPage) nOffsetEndPage += IO_CACHE_PAGE_SIZE; #undef IO_CACHE_PAGE_SIZE nLastStripOffset = nBaseOffset + arraySize * sizeofval; - if( nLastStripOffset < nOffsetEndPage ) + if (nLastStripOffset < nOffsetEndPage) nOffsetEndPage = nLastStripOffset; - if( nOffsetStartPage >= nOffsetEndPage ) + if (nOffsetStartPage >= nOffsetEndPage) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot read offset/size for strile %d", strile); + TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d", + strile); panVals[strile] = 0; return 0; } - if (!SeekOK(tif,nOffsetStartPage)) + if (!SeekOK(tif, nOffsetStartPage)) { panVals[strile] = 0; return 0; @@ -6181,159 +7588,160 @@ int _TIFFPartialReadStripArray( TIFF* tif, TIFFDirEntry* dirent, nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage); nRead = TIFFReadFile(tif, buffer, nToRead); - if( nRead < nToRead ) + if (nRead < nToRead) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot read offset/size for strile around ~%d", strile); + TIFFErrorExtR(tif, module, + "Cannot read offset/size for strile around ~%d", strile); return 0; } iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval); - if( strile + iStartBefore < 0 ) + if (strile + iStartBefore < 0) iStartBefore = -strile; - for( i = iStartBefore; - (uint32)(strile + i) < arraySize && - _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <= nOffsetEndPage; - ++i ) + for (i = iStartBefore; + (uint32_t)(strile + i) < arraySize && + _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <= + nOffsetEndPage; + ++i) { - if( dirent->tdir_type == TIFF_SHORT ) + if (dirent->tdir_type == TIFF_SHORT) { - uint16 val; + uint16_t val; memcpy(&val, buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, sizeof(val)); - if( bSwab ) + if (bSwab) TIFFSwabShort(&val); panVals[strile + i] = val; } - else if( dirent->tdir_type == TIFF_LONG ) + else if (dirent->tdir_type == TIFF_LONG) { - uint32 val; + uint32_t val; memcpy(&val, buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, sizeof(val)); - if( bSwab ) + if (bSwab) TIFFSwabLong(&val); panVals[strile + i] = val; } - else if( dirent->tdir_type == TIFF_LONG8 ) + else if (dirent->tdir_type == TIFF_LONG8) { - uint64 val; + uint64_t val; memcpy(&val, buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, sizeof(val)); - if( bSwab ) + if (bSwab) TIFFSwabLong8(&val); panVals[strile + i] = val; } else /* if( dirent->tdir_type == TIFF_SLONG8 ) */ { /* Non conformant data type */ - int64 val; + int64_t val; memcpy(&val, buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, sizeof(val)); - if( bSwab ) - TIFFSwabLong8((uint64*) &val); - panVals[strile + i] = (uint64) val; + if (bSwab) + TIFFSwabLong8((uint64_t *)&val); + panVals[strile + i] = (uint64_t)val; } } return 1; } -static int _TIFFFetchStrileValue(TIFF* tif, - uint32 strile, - TIFFDirEntry* dirent, - uint64** parray) +static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile, + TIFFDirEntry *dirent, uint64_t **parray) { static const char module[] = "_TIFFFetchStrileValue"; TIFFDirectory *td = &tif->tif_dir; - if( strile >= dirent->tdir_count ) + if (strile >= dirent->tdir_count) { return 0; } - if( strile >= td->td_stripoffsetbyteallocsize ) + if (strile >= td->td_stripoffsetbyteallocsize) { - uint32 nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize; - uint32 nStripArrayAllocNew; - uint64 nArraySize64; + uint32_t nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize; + uint32_t nStripArrayAllocNew; + uint64_t nArraySize64; size_t nArraySize; - uint64* offsetArray; - uint64* bytecountArray; + uint64_t *offsetArray; + uint64_t *bytecountArray; - if( strile > 1000000 ) + if (strile > 1000000) { - uint64 filesize = TIFFGetFileSize(tif); + uint64_t filesize = TIFFGetFileSize(tif); /* Avoid excessive memory allocation attempt */ /* For such a big blockid we need at least a TIFF_LONG per strile */ /* for the offset array. */ - if( strile > filesize / sizeof(uint32) ) + if (strile > filesize / sizeof(uint32_t)) { - TIFFErrorExt(tif->tif_clientdata, module, "File too short"); + TIFFErrorExtR(tif, module, "File too short"); return 0; } } - if( td->td_stripoffsetbyteallocsize == 0 && - td->td_nstrips < 1024 * 1024 ) + if (td->td_stripoffsetbyteallocsize == 0 && + td->td_nstrips < 1024 * 1024) { nStripArrayAllocNew = td->td_nstrips; } else { -#define TIFF_MAX(a,b) (((a)>(b)) ? (a) : (b)) -#define TIFF_MIN(a,b) (((a)<(b)) ? (a) : (b)) - nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U ); - if( nStripArrayAllocNew < 0xFFFFFFFFU / 2 ) +#define TIFF_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define TIFF_MIN(a, b) (((a) < (b)) ? (a) : (b)) + nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U); + if (nStripArrayAllocNew < 0xFFFFFFFFU / 2) nStripArrayAllocNew *= 2; nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips); } - assert( strile < nStripArrayAllocNew ); - nArraySize64 = (uint64)sizeof(uint64) * nStripArrayAllocNew; + assert(strile < nStripArrayAllocNew); + nArraySize64 = (uint64_t)sizeof(uint64_t) * nStripArrayAllocNew; nArraySize = (size_t)(nArraySize64); #if SIZEOF_SIZE_T == 4 - if( nArraySize != nArraySize64 ) + if (nArraySize != nArraySize64) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot allocate strip offset and bytecount arrays"); + TIFFErrorExtR(tif, module, + "Cannot allocate strip offset and bytecount arrays"); return 0; } #endif - offsetArray = (uint64*)( - _TIFFrealloc( td->td_stripoffset_p, nArraySize ) ); - bytecountArray = (uint64*)( - _TIFFrealloc( td->td_stripbytecount_p, nArraySize ) ); - if( offsetArray ) + offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p, + nArraySize)); + bytecountArray = (uint64_t *)(_TIFFreallocExt( + tif, td->td_stripbytecount_p, nArraySize)); + if (offsetArray) td->td_stripoffset_p = offsetArray; - if( bytecountArray ) + if (bytecountArray) td->td_stripbytecount_p = bytecountArray; - if( offsetArray && bytecountArray ) + if (offsetArray && bytecountArray) { td->td_stripoffsetbyteallocsize = nStripArrayAllocNew; /* Initialize new entries to ~0 / -1 */ - memset(td->td_stripoffset_p + nStripArrayAllocBefore, - 0xFF, - (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64) ); - memset(td->td_stripbytecount_p + nStripArrayAllocBefore, - 0xFF, - (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64) ); + /* coverity[overrun-buffer-arg] */ + memset(td->td_stripoffset_p + nStripArrayAllocBefore, 0xFF, + (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * + sizeof(uint64_t)); + /* coverity[overrun-buffer-arg] */ + memset(td->td_stripbytecount_p + nStripArrayAllocBefore, 0xFF, + (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * + sizeof(uint64_t)); } else { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot allocate strip offset and bytecount arrays"); - _TIFFfree(td->td_stripoffset_p); + TIFFErrorExtR(tif, module, + "Cannot allocate strip offset and bytecount arrays"); + _TIFFfreeExt(tif, td->td_stripoffset_p); td->td_stripoffset_p = NULL; - _TIFFfree(td->td_stripbytecount_p); + _TIFFfreeExt(tif, td->td_stripbytecount_p); td->td_stripbytecount_p = NULL; td->td_stripoffsetbyteallocsize = 0; } } - if( *parray == NULL || strile >= td->td_stripoffsetbyteallocsize ) + if (*parray == NULL || strile >= td->td_stripoffsetbyteallocsize) return 0; - if( ~((*parray)[strile]) == 0 ) + if (~((*parray)[strile]) == 0) { - if( !_TIFFPartialReadStripArray( tif, dirent, strile, *parray ) ) + if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray)) { (*parray)[strile] = 0; return 0; @@ -6343,24 +7751,25 @@ static int _TIFFFetchStrileValue(TIFF* tif, return 1; } -static uint64 _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32 strile, - TIFFDirEntry* dirent, - uint64** parray, - int *pbErr) +static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile, + TIFFDirEntry *dirent, + uint64_t **parray, + int *pbErr) { TIFFDirectory *td = &tif->tif_dir; - if( pbErr ) + if (pbErr) *pbErr = 0; - if( (tif->tif_flags&TIFF_DEFERSTRILELOAD) && !(tif->tif_flags&TIFF_CHOPPEDUPARRAYS) ) + if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) && + !(tif->tif_flags & TIFF_CHOPPEDUPARRAYS)) { - if( !(tif->tif_flags&TIFF_LAZYSTRILELOAD) || + if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) || /* If the values may fit in the toff_long/toff_long8 member */ /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */ - dirent->tdir_count <= 4 ) + dirent->tdir_count <= 4) { - if( !_TIFFFillStriles(tif) ) + if (!_TIFFFillStriles(tif)) { - if( pbErr ) + if (pbErr) *pbErr = 1; /* Do not return, as we want this function to always */ /* return the same value if called several times with */ @@ -6369,73 +7778,74 @@ static uint64 _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32 strile, } else { - if( !_TIFFFetchStrileValue(tif, strile, dirent, parray) ) - { - if( pbErr ) + if (!_TIFFFetchStrileValue(tif, strile, dirent, parray)) + { + if (pbErr) *pbErr = 1; - return 0; - } + return 0; + } } } - if( *parray == NULL || strile >= td->td_nstrips ) + if (*parray == NULL || strile >= td->td_nstrips) { - if( pbErr ) + if (pbErr) *pbErr = 1; return 0; } return (*parray)[strile]; } -/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */ -uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile) +/* Return the value of the TileOffsets/StripOffsets array for the specified + * tile/strile */ +uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile) { return TIFFGetStrileOffsetWithErr(tif, strile, NULL); } -/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */ -uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr) +/* Return the value of the TileOffsets/StripOffsets array for the specified + * tile/strile */ +uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, int *pbErr) { TIFFDirectory *td = &tif->tif_dir; return _TIFFGetStrileOffsetOrByteCountValue(tif, strile, - &(td->td_stripoffset_entry), - &(td->td_stripoffset_p), pbErr); + &(td->td_stripoffset_entry), + &(td->td_stripoffset_p), pbErr); } -/* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */ -uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile) +/* Return the value of the TileByteCounts/StripByteCounts array for the + * specified tile/strile */ +uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile) { return TIFFGetStrileByteCountWithErr(tif, strile, NULL); } -/* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */ -uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr) +/* Return the value of the TileByteCounts/StripByteCounts array for the + * specified tile/strile */ +uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, int *pbErr) { TIFFDirectory *td = &tif->tif_dir; - return _TIFFGetStrileOffsetOrByteCountValue(tif, strile, - &(td->td_stripbytecount_entry), - &(td->td_stripbytecount_p), pbErr); + return _TIFFGetStrileOffsetOrByteCountValue( + tif, strile, &(td->td_stripbytecount_entry), &(td->td_stripbytecount_p), + pbErr); } +int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); } -int _TIFFFillStriles( TIFF *tif ) -{ - return _TIFFFillStrilesInternal( tif, 1 ); -} - -static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount ) +static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount) { register TIFFDirectory *td = &tif->tif_dir; int return_value = 1; /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */ - if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) || (tif->tif_flags&TIFF_CHOPPEDUPARRAYS) != 0 ) + if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) || + (tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0) return 1; - if( tif->tif_flags&TIFF_LAZYSTRILELOAD ) + if (tif->tif_flags & TIFF_LAZYSTRILELOAD) { /* In case of lazy loading, reload completely the arrays */ - _TIFFfree(td->td_stripoffset_p); - _TIFFfree(td->td_stripbytecount_p); + _TIFFfreeExt(tif, td->td_stripoffset_p); + _TIFFfreeExt(tif, td->td_stripbytecount_p); td->td_stripoffset_p = NULL; td->td_stripbytecount_p = NULL; td->td_stripoffsetbyteallocsize = 0; @@ -6443,53 +7853,46 @@ static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount ) } /* If stripoffset array is already loaded, exit with success */ - if( td->td_stripoffset_p != NULL ) - return 1; + if (td->td_stripoffset_p != NULL) + return 1; /* If tdir_count was canceled, then we already got there, but in error */ - if( td->td_stripoffset_entry.tdir_count == 0 ) - return 0; + if (td->td_stripoffset_entry.tdir_count == 0) + return 0; - if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry), - td->td_nstrips,&td->td_stripoffset_p)) + if (!TIFFFetchStripThing(tif, &(td->td_stripoffset_entry), td->td_nstrips, + &td->td_stripoffset_p)) { - return_value = 0; + return_value = 0; } if (loadStripByteCount && - !TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry), - td->td_nstrips,&td->td_stripbytecount_p)) + !TIFFFetchStripThing(tif, &(td->td_stripbytecount_entry), + td->td_nstrips, &td->td_stripbytecount_p)) { - return_value = 0; + return_value = 0; } - _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); - _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); #ifdef STRIPBYTECOUNTSORTED_UNUSED - if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) { - uint32 strip; + if (tif->tif_dir.td_nstrips > 1 && return_value == 1) + { + uint32_t strip; - tif->tif_dir.td_stripbytecountsorted = 1; - for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { - if (tif->tif_dir.td_stripoffset_p[strip - 1] > - tif->tif_dir.td_stripoffset_p[strip]) { - tif->tif_dir.td_stripbytecountsorted = 0; - break; - } + tif->tif_dir.td_stripbytecountsorted = 1; + for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) + { + if (tif->tif_dir.td_stripoffset_p[strip - 1] > + tif->tif_dir.td_stripoffset_p[strip]) + { + tif->tif_dir.td_stripbytecountsorted = 0; + break; } + } } #endif return return_value; } - - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_dirwrite.c b/3rdparty/libtiff/tif_dirwrite.c index f481250e3b..d8844bbd8a 100644 --- a/3rdparty/libtiff/tif_dirwrite.c +++ b/3rdparty/libtiff/tif_dirwrite.c @@ -28,161 +28,203 @@ * Directory Write Support Routines. */ #include "tiffiop.h" -#include /*--: for Rational2Double */ -#include /*--: for Rational2Double */ +#include /*--: for Rational2Double */ +#include /*--: for Rational2Double */ #ifdef HAVE_IEEEFP #define TIFFCvtNativeToIEEEFloat(tif, n, fp) #define TIFFCvtNativeToIEEEDouble(tif, n, dp) #else -extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32 n, float* fp); -extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32 n, double* dp); +extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp); +extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp); #endif -static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff); +static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, + uint64_t *pdiroff); -static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); -#if 0 -static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); -#endif +static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + double *value); -static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value); -static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); -#ifdef notdef -static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value); -#endif -static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); -#if 0 -static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value); -#endif -#ifdef notdef -static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value); -#endif -static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value); -#if 0 -static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value); -#endif -static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value); -static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value); -static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value); -#ifdef notdef -static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value); -#endif -static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value); -#if 0 -static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value); -#endif -static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); -static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); -#if 0 -static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); -#endif -#ifdef notdef -static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value); -#endif -static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value); -#if 0 -static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value); -#endif -#ifdef notdef -static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value); -#endif -static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); -#ifdef notdef -static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value); -#endif -static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value); -static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); -static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); -static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); -#ifdef notdef -static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value); -#endif -static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); -#if 0 -static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value); -#endif -#ifdef notdef -static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); -#endif -static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); -#if 0 -static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); -#endif -static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); -#ifdef notdef -static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); -#endif -static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); -static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); -static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); -#ifdef notdef -static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); -#endif -static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir); -static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir); -static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir); +static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, char *value); +static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint8_t *value); +static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint8_t *value); +static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int8_t *value); +static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value); +static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint16_t *value); +static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value); +static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int16_t *value); +static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value); +static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value); +static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int32_t *value); +static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value); +static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int64_t *value); +static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + double value); +static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value); +static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value); +static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value); +static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, double *value); +static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value); +static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value); +static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value); +static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value); +static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir); +static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir); +static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir); -static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value); -static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); -#ifdef notdef -static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value); -#endif -static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); -#ifdef notdef -static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value); -#endif -static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value); -static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value); -static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value); -#ifdef notdef -static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value); -#endif -static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value); -static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); -static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); -#ifdef notdef -static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value); -#endif -static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value); -#ifdef notdef -static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value); -#endif -static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); -#ifdef notdef -static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value); -#endif -static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value); -static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); -static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); -static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, char *value); +static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + uint8_t *value); +static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint8_t *value); +static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int8_t *value); +static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value); +static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint16_t *value); +static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int16_t *value); +static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value); +static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint32_t *value); +static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int32_t *value); +static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint64_t *value); +static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int64_t *value); +static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + double value); +static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + float *value); +static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + float *value); -/*--: Rational2Double: New functions to support true double-precision for custom rational tag types. */ -static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); -static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); -static int TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); -static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); -static void DoubleToRational(double value, uint32 *num, uint32 *denom); -static void DoubleToSrational(double value, int32 *num, int32 *denom); -#if 0 -static void DoubleToRational_direct(double value, unsigned long *num, unsigned long *denom); -static void DoubleToSrational_direct(double value, long *num, long *denom); -#endif +/*--: Rational2Double: New functions to support true double-precision for custom + * rational tag types. */ +static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + double *value); +static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + double *value); +static int +TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, double *value); +static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray( + TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count, + double *value); +static void DoubleToRational(double value, uint32_t *num, uint32_t *denom); +static void DoubleToSrational(double value, int32_t *num, int32_t *denom); -#ifdef notdef -static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value); -#endif -static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); -#ifdef notdef -static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); -#endif -static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); -static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); -static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + float *value); +static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + double *value); +static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, + uint32_t *value); +static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint64_t *value); -static int TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data); +static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t datatype, uint32_t count, + uint32_t datalength, void *data); -static int TIFFLinkDirectory(TIFF*); +static int TIFFLinkDirectory(TIFF *); /* * Write the contents of the current directory @@ -190,10 +232,9 @@ static int TIFFLinkDirectory(TIFF*); * handle overwriting a directory with auxiliary * storage that's been changed. */ -int -TIFFWriteDirectory(TIFF* tif) +int TIFFWriteDirectory(TIFF *tif) { - return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL); + return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL); } /* @@ -221,19 +262,17 @@ TIFFWriteDirectory(TIFF* tif) * * Returns 1 in case of success, 0 otherwise. */ -int TIFFDeferStrileArrayWriting(TIFF* tif) +int TIFFDeferStrileArrayWriting(TIFF *tif) { static const char module[] = "TIFFDeferStrileArrayWriting"; if (tif->tif_mode == O_RDONLY) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "File opened in read-only mode"); + TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode"); return 0; } - if( tif->tif_diroff != 0 ) + if (tif->tif_diroff != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Directory has already been written"); + TIFFErrorExtR(tif, module, "Directory has already been written"); return 0; } @@ -247,359 +286,430 @@ int TIFFDeferStrileArrayWriting(TIFF* tif) * written again. This will make a partially written TIFF file * readable before it is successfully completed/closed. */ -int -TIFFCheckpointDirectory(TIFF* tif) +int TIFFCheckpointDirectory(TIFF *tif) { - int rc; - /* Setup the strips arrays, if they haven't already been. */ - if (tif->tif_dir.td_stripoffset_p == NULL) - (void) TIFFSetupStrips(tif); - rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL); - (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END)); - return rc; + int rc; + /* Setup the strips arrays, if they haven't already been. */ + if (tif->tif_dir.td_stripoffset_p == NULL) + (void)TIFFSetupStrips(tif); + rc = TIFFWriteDirectorySec(tif, TRUE, FALSE, NULL); + (void)TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END)); + return rc; } -int -TIFFWriteCustomDirectory(TIFF* tif, uint64* pdiroff) +int TIFFWriteCustomDirectory(TIFF *tif, uint64_t *pdiroff) { - return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff); + return TIFFWriteDirectorySec(tif, FALSE, FALSE, pdiroff); } /* * Similar to TIFFWriteDirectory(), but if the directory has already * been written once, it is relocated to the end of the file, in case it * has changed in size. Note that this will result in the loss of the - * previously used directory space. - */ -int -TIFFRewriteDirectory( TIFF *tif ) + * previously used directory space. + */ +int TIFFRewriteDirectory(TIFF *tif) { - static const char module[] = "TIFFRewriteDirectory"; + static const char module[] = "TIFFRewriteDirectory"; - /* We don't need to do anything special if it hasn't been written. */ - if( tif->tif_diroff == 0 ) - return TIFFWriteDirectory( tif ); + /* We don't need to do anything special if it hasn't been written. */ + if (tif->tif_diroff == 0) + return TIFFWriteDirectory(tif); - /* - * Find and zero the pointer to this directory, so that TIFFLinkDirectory - * will cause it to be added after this directories current pre-link. - */ + /* + * Find and zero the pointer to this directory, so that TIFFLinkDirectory + * will cause it to be added after this directories current pre-link. + */ + uint64_t torewritediroff = tif->tif_diroff; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff) - { - tif->tif_header.classic.tiff_diroff = 0; - tif->tif_diroff = 0; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff) + { + tif->tif_header.classic.tiff_diroff = 0; + tif->tif_diroff = 0; - TIFFSeekFile(tif,4,SEEK_SET); - if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4)) - { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error updating TIFF header"); - return (0); - } - } - else - { - uint32 nextdir; - nextdir = tif->tif_header.classic.tiff_diroff; - while(1) { - uint16 dircount; - uint32 nextnextdir; + TIFFSeekFile(tif, 4, SEEK_SET); + if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4)) + { + TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header"); + return (0); + } + } + else if (tif->tif_diroff > 0xFFFFFFFFU) + { + TIFFErrorExtR(tif, module, + "tif->tif_diroff exceeds 32 bit range allowed for " + "Classic TIFF"); + return (0); + } + else + { + uint32_t nextdir; + nextdir = tif->tif_header.classic.tiff_diroff; + while (1) + { + uint16_t dircount; + uint32_t nextnextdir; - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount, 2)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - (void) TIFFSeekFile(tif, - nextdir+2+dircount*12, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 4)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextnextdir); - if (nextnextdir==tif->tif_diroff) - { - uint32 m; - m=0; - (void) TIFFSeekFile(tif, - nextdir+2+dircount*12, SEEK_SET); - if (!WriteOK(tif, &m, 4)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing directory link"); - return (0); - } - tif->tif_diroff=0; - break; - } - nextdir=nextnextdir; - } - } - } - else - { - if (tif->tif_header.big.tiff_diroff == tif->tif_diroff) - { - tif->tif_header.big.tiff_diroff = 0; - tif->tif_diroff = 0; + if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2)) + { + TIFFErrorExtR(tif, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 4)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextnextdir); + if (nextnextdir == tif->tif_diroff) + { + uint32_t m; + m = 0; + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, + SEEK_SET); + if (!WriteOK(tif, &m, 4)) + { + TIFFErrorExtR(tif, module, + "Error writing directory link"); + return (0); + } + tif->tif_diroff = 0; + /* Force a full-traversal to reach the zeroed pointer */ + tif->tif_lastdiroff = 0; + break; + } + nextdir = nextnextdir; + } + } + /* Remove skipped offset from IFD loop directory list. */ + _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff); + } + else + { + if (tif->tif_header.big.tiff_diroff == tif->tif_diroff) + { + tif->tif_header.big.tiff_diroff = 0; + tif->tif_diroff = 0; - TIFFSeekFile(tif,8,SEEK_SET); - if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8)) - { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error updating TIFF header"); - return (0); - } - } - else - { - uint64 nextdir; - nextdir = tif->tif_header.big.tiff_diroff; - while(1) { - uint64 dircount64; - uint16 dircount; - uint64 nextnextdir; + TIFFSeekFile(tif, 8, SEEK_SET); + if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff), 8)) + { + TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header"); + return (0); + } + } + else + { + uint64_t nextdir; + nextdir = tif->tif_header.big.tiff_diroff; + while (1) + { + uint64_t dircount64; + uint16_t dircount; + uint64_t nextnextdir; - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount64, 8)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>0xFFFF) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on tag count failed, likely corrupt TIFF"); - return (0); - } - dircount=(uint16)dircount64; - (void) TIFFSeekFile(tif, - nextdir+8+dircount*20, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 8)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&nextnextdir); - if (nextnextdir==tif->tif_diroff) - { - uint64 m; - m=0; - (void) TIFFSeekFile(tif, - nextdir+8+dircount*20, SEEK_SET); - if (!WriteOK(tif, &m, 8)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing directory link"); - return (0); - } - tif->tif_diroff=0; - break; - } - nextdir=nextnextdir; - } - } - } + if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8)) + { + TIFFErrorExtR(tif, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 0xFFFF) + { + TIFFErrorExtR(tif, module, + "Sanity check on tag count failed, likely " + "corrupt TIFF"); + return (0); + } + dircount = (uint16_t)dircount64; + (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 8)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextnextdir); + if (nextnextdir == tif->tif_diroff) + { + uint64_t m; + m = 0; + (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, + SEEK_SET); + if (!WriteOK(tif, &m, 8)) + { + TIFFErrorExtR(tif, module, + "Error writing directory link"); + return (0); + } + tif->tif_diroff = 0; + /* Force a full-traversal to reach the zeroed pointer */ + tif->tif_lastdiroff = 0; + break; + } + nextdir = nextnextdir; + } + } + /* Remove skipped offset from IFD loop directory list. */ + _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff); + } - /* - * Now use TIFFWriteDirectory() normally. - */ + /* + * Now use TIFFWriteDirectory() normally. + */ - return TIFFWriteDirectory( tif ); + return TIFFWriteDirectory(tif); } -static int -TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff) +static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, + uint64_t *pdiroff) { - static const char module[] = "TIFFWriteDirectorySec"; - uint32 ndir; - TIFFDirEntry* dir; - uint32 dirsize; - void* dirmem; - uint32 m; - if (tif->tif_mode == O_RDONLY) - return (1); + static const char module[] = "TIFFWriteDirectorySec"; + uint32_t ndir; + TIFFDirEntry *dir; + uint32_t dirsize; + void *dirmem; + uint32_t m; + if (tif->tif_mode == O_RDONLY) + return (1); - _TIFFFillStriles( tif ); - - /* - * Clear write state so that subsequent images with - * different characteristics get the right buffers - * setup for them. - */ - if (imagedone) - { - if (tif->tif_flags & TIFF_POSTENCODE) - { - tif->tif_flags &= ~TIFF_POSTENCODE; - if (!(*tif->tif_postencode)(tif)) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Error post-encoding before directory write"); - return (0); - } - } - (*tif->tif_close)(tif); /* shutdown encoder */ - /* - * Flush any data that might have been written - * by the compression close+cleanup routines. But - * be careful not to write stuff if we didn't add data - * in the previous steps as the "rawcc" data may well be - * a previously read tile/strip in mixed read/write mode. - */ - if (tif->tif_rawcc > 0 - && (tif->tif_flags & TIFF_BEENWRITING) != 0 ) - { - if( !TIFFFlushData1(tif) ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Error flushing data before directory write"); - return (0); - } - } - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) - { - _TIFFfree(tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawcc = 0; - tif->tif_rawdatasize = 0; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = 0; - } - tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP); - } - dir=NULL; - dirmem=NULL; - dirsize=0; - while (1) - { - ndir=0; - if (isimage) - { - if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) - { - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth)) - goto bad; - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) - { - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth)) - goto bad; - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_RESOLUTION)) - { - if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution)) - goto bad; - if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_POSITION)) - { - if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition)) - goto bad; - if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) - { - if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) - { - if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_COMPRESSION)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_FILLORDER)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_ORIENTATION)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) - { - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_PAGENUMBER)) - { - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0])) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS)) - { - if (!isTiled(tif)) - { - if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p)) - goto bad; - } - else - { - if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p)) - goto bad; - } - } - if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) - { - if (!isTiled(tif)) - { + _TIFFFillStriles(tif); + + /* + * Clear write state so that subsequent images with + * different characteristics get the right buffers + * setup for them. + */ + if (imagedone) + { + if (tif->tif_flags & TIFF_POSTENCODE) + { + tif->tif_flags &= ~TIFF_POSTENCODE; + if (!(*tif->tif_postencode)(tif)) + { + TIFFErrorExtR(tif, module, + "Error post-encoding before directory write"); + return (0); + } + } + (*tif->tif_close)(tif); /* shutdown encoder */ + /* + * Flush any data that might have been written + * by the compression close+cleanup routines. But + * be careful not to write stuff if we didn't add data + * in the previous steps as the "rawcc" data may well be + * a previously read tile/strip in mixed read/write mode. + */ + if (tif->tif_rawcc > 0 && (tif->tif_flags & TIFF_BEENWRITING) != 0) + { + if (!TIFFFlushData1(tif)) + { + TIFFErrorExtR(tif, module, + "Error flushing data before directory write"); + return (0); + } + } + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawcc = 0; + tif->tif_rawdatasize = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + } + tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP); + } + + if (TIFFFieldSet(tif, FIELD_COMPRESSION) && + (tif->tif_dir.td_compression == COMPRESSION_DEFLATE)) + { + TIFFWarningExtR(tif, module, + "Creating TIFF with legacy Deflate codec identifier, " + "COMPRESSION_ADOBE_DEFLATE is more widely supported"); + } + dir = NULL; + dirmem = NULL; + dirsize = 0; + while (1) + { + ndir = 0; + if (isimage) + { + if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) + { + if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, + TIFFTAG_IMAGEWIDTH, + tif->tif_dir.td_imagewidth)) + goto bad; + if (!TIFFWriteDirectoryTagShortLong( + tif, &ndir, dir, TIFFTAG_IMAGELENGTH, + tif->tif_dir.td_imagelength)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) + { + if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, + TIFFTAG_TILEWIDTH, + tif->tif_dir.td_tilewidth)) + goto bad; + if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, + TIFFTAG_TILELENGTH, + tif->tif_dir.td_tilelength)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_RESOLUTION)) + { + if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, + TIFFTAG_XRESOLUTION, + tif->tif_dir.td_xresolution)) + goto bad; + if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, + TIFFTAG_YRESOLUTION, + tif->tif_dir.td_yresolution)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_POSITION)) + { + if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, + TIFFTAG_XPOSITION, + tif->tif_dir.td_xposition)) + goto bad; + if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, + TIFFTAG_YPOSITION, + tif->tif_dir.td_yposition)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SUBFILETYPE)) + { + if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, + TIFFTAG_SUBFILETYPE, + tif->tif_dir.td_subfiletype)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) + { + if (!TIFFWriteDirectoryTagShortPerSample( + tif, &ndir, dir, TIFFTAG_BITSPERSAMPLE, + tif->tif_dir.td_bitspersample)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_COMPRESSION)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_COMPRESSION, + tif->tif_dir.td_compression)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_PHOTOMETRIC, + tif->tif_dir.td_photometric)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_THRESHHOLDING)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_THRESHHOLDING, + tif->tif_dir.td_threshholding)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_FILLORDER)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_FILLORDER, + tif->tif_dir.td_fillorder)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_ORIENTATION)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_ORIENTATION, + tif->tif_dir.td_orientation)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + { + if (!TIFFWriteDirectoryTagShort( + tif, &ndir, dir, TIFFTAG_SAMPLESPERPIXEL, + tif->tif_dir.td_samplesperpixel)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) + { + if (!TIFFWriteDirectoryTagShortLong( + tif, &ndir, dir, TIFFTAG_ROWSPERSTRIP, + tif->tif_dir.td_rowsperstrip)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagShortPerSample( + tif, &ndir, dir, TIFFTAG_MINSAMPLEVALUE, + tif->tif_dir.td_minsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagShortPerSample( + tif, &ndir, dir, TIFFTAG_MAXSAMPLEVALUE, + tif->tif_dir.td_maxsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_PLANARCONFIG)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_PLANARCONFIG, + tif->tif_dir.td_planarconfig)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_RESOLUTIONUNIT, + tif->tif_dir.td_resolutionunit)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_PAGENUMBER)) + { + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, TIFFTAG_PAGENUMBER, 2, + &tif->tif_dir.td_pagenumber[0])) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) + { + if (!isTiled(tif)) + { + if (!TIFFWriteDirectoryTagLongLong8Array( + tif, &ndir, dir, TIFFTAG_STRIPBYTECOUNTS, + tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripbytecount_p)) + goto bad; + } + else + { + if (!TIFFWriteDirectoryTagLongLong8Array( + tif, &ndir, dir, TIFFTAG_TILEBYTECOUNTS, + tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripbytecount_p)) + goto bad; + } + } + if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) + { + if (!isTiled(tif)) + { /* td_stripoffset_p might be NULL in an odd OJPEG case. See * tif_dirread.c around line 3634. * XXX: OJPEG hack. @@ -610,1174 +720,1108 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff) * JpegInterchangeFormat stream. * We can get here when using tiffset on such a file. * See http://bugzilla.maptools.org/show_bug.cgi?id=2500 - */ + */ if (tif->tif_dir.td_stripoffset_p != NULL && - !TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p)) + !TIFFWriteDirectoryTagLongLong8Array( + tif, &ndir, dir, TIFFTAG_STRIPOFFSETS, + tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripoffset_p)) goto bad; - } - else - { - if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p)) - goto bad; - } - } - if (TIFFFieldSet(tif,FIELD_COLORMAP)) - { - if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES)) - { - if (tif->tif_dir.td_extrasamples) - { - uint16 na; - uint16* nb; - TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb); - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb)) - goto bad; - } - } - if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) - { - if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH)) - { - if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_TILEDEPTH)) - { - if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS)) - { - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0])) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING)) - { - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0])) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) - { - if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) - { - if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_INKNAMES)) - { - if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SUBIFD)) - { - if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir)) - goto bad; - } - { - uint32 n; - for (n=0; ntif_nfields; n++) { - const TIFFField* o; - o = tif->tif_fields[n]; - if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit))) - { - switch (o->get_field_type) - { - case TIFF_SETGET_ASCII: - { - uint32 pa; - char* pb; - assert(o->field_type==TIFF_ASCII); - assert(o->field_readcount==TIFF_VARIABLE); - assert(o->field_passcount==0); - TIFFGetField(tif,o->field_tag,&pb); - pa=(uint32)(strlen(pb)); - if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,(uint16)o->field_tag,pa,pb)) - goto bad; - } - break; - case TIFF_SETGET_UINT16: - { - uint16 p; - assert(o->field_type==TIFF_SHORT); - assert(o->field_readcount==1); - assert(o->field_passcount==0); - TIFFGetField(tif,o->field_tag,&p); - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,(uint16)o->field_tag,p)) - goto bad; - } - break; - case TIFF_SETGET_UINT32: - { - uint32 p; - assert(o->field_type==TIFF_LONG); - assert(o->field_readcount==1); - assert(o->field_passcount==0); - TIFFGetField(tif,o->field_tag,&p); - if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,(uint16)o->field_tag,p)) - goto bad; - } - break; - case TIFF_SETGET_C32_UINT8: - { - uint32 pa; - void* pb; - assert(o->field_type==TIFF_UNDEFINED); - assert(o->field_readcount==TIFF_VARIABLE2); - assert(o->field_passcount==1); - TIFFGetField(tif,o->field_tag,&pa,&pb); - if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,(uint16)o->field_tag,pa,pb)) - goto bad; - } - break; - default: - TIFFErrorExt(tif->tif_clientdata,module, - "Cannot write tag %d (%s)", - TIFFFieldTag(o), - o->field_name ? o->field_name : "unknown"); - goto bad; - } - } - } - } - } - for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++) - { - uint16 tag = (uint16)tif->tif_dir.td_customValues[m].info->field_tag; - uint32 count = tif->tif_dir.td_customValues[m].count; - switch (tif->tif_dir.td_customValues[m].info->field_type) - { - case TIFF_ASCII: - if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_UNDEFINED: - if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_BYTE: - if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SBYTE: - if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SHORT: - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SSHORT: - if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_LONG: - if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SLONG: - if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_LONG8: - if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SLONG8: - if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_RATIONAL: - { - /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ - int tv_size; - tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type); - if (tv_size == 8) { - if (!TIFFWriteDirectoryTagRationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - } else { - /*-- default should be tv_size == 4 */ - if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */ - if (tv_size != 4) { - TIFFErrorExt(0,"TIFFLib: _TIFFWriteDirectorySec()", "Rational2Double: .set_field_type in not 4 but %d", tv_size); - } - } - } - break; - case TIFF_SRATIONAL: - { - /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ - int tv_size; - tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type); - if (tv_size == 8) { - if (!TIFFWriteDirectoryTagSrationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - } else { - /*-- default should be tv_size == 4 */ - if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */ - if (tv_size != 4) { - TIFFErrorExt(0,"TIFFLib: _TIFFWriteDirectorySec()", "Rational2Double: .set_field_type in not 4 but %d", tv_size); - } - } - } - break; - case TIFF_FLOAT: - if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_DOUBLE: - if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_IFD: - if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_IFD8: - if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - default: - assert(0); /* we should never get here */ - break; - } - } - if (dir!=NULL) - break; - dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry)); - if (dir==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - goto bad; - } - if (isimage) - { - if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif))) - goto bad; - } - else - tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~((toff_t)1)); - if (pdiroff!=NULL) - *pdiroff=tif->tif_diroff; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - dirsize=2+ndir*12+4; - else - dirsize=8+ndir*20+8; - tif->tif_dataoff=tif->tif_diroff+dirsize; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - tif->tif_dataoff=(uint32)tif->tif_dataoff; - if ((tif->tif_dataofftif_diroff)||(tif->tif_dataoff<(uint64)dirsize)) - { - TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded"); - goto bad; - } - if (tif->tif_dataoff&1) - tif->tif_dataoff++; - if (isimage) - tif->tif_curdir++; - } - if (isimage) - { - if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0)) - { - uint32 na; - TIFFDirEntry* nb; - for (na=0, nb=dir; ; na++, nb++) - { - if( na == ndir ) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Cannot find SubIFD tag"); + } + else + { + if (!TIFFWriteDirectoryTagLongLong8Array( + tif, &ndir, dir, TIFFTAG_TILEOFFSETS, + tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripoffset_p)) + goto bad; + } + } + if (TIFFFieldSet(tif, FIELD_COLORMAP)) + { + if (!TIFFWriteDirectoryTagColormap(tif, &ndir, dir)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES)) + { + if (tif->tif_dir.td_extrasamples) + { + uint16_t na; + uint16_t *nb; + TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &na, &nb); + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, TIFFTAG_EXTRASAMPLES, na, nb)) + goto bad; + } + } + if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT)) + { + if (!TIFFWriteDirectoryTagShortPerSample( + tif, &ndir, dir, TIFFTAG_SAMPLEFORMAT, + tif->tif_dir.td_sampleformat)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagSampleformatArray( + tif, &ndir, dir, TIFFTAG_SMINSAMPLEVALUE, + tif->tif_dir.td_samplesperpixel, + tif->tif_dir.td_sminsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagSampleformatArray( + tif, &ndir, dir, TIFFTAG_SMAXSAMPLEVALUE, + tif->tif_dir.td_samplesperpixel, + tif->tif_dir.td_smaxsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH)) + { + if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, + TIFFTAG_IMAGEDEPTH, + tif->tif_dir.td_imagedepth)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_TILEDEPTH)) + { + if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, + TIFFTAG_TILEDEPTH, + tif->tif_dir.td_tiledepth)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS)) + { + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, TIFFTAG_HALFTONEHINTS, 2, + &tif->tif_dir.td_halftonehints[0])) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING)) + { + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, TIFFTAG_YCBCRSUBSAMPLING, 2, + &tif->tif_dir.td_ycbcrsubsampling[0])) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING)) + { + if (!TIFFWriteDirectoryTagShort( + tif, &ndir, dir, TIFFTAG_YCBCRPOSITIONING, + tif->tif_dir.td_ycbcrpositioning)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE)) + { + if (!TIFFWriteDirectoryTagRationalArray( + tif, &ndir, dir, TIFFTAG_REFERENCEBLACKWHITE, 6, + tif->tif_dir.td_refblackwhite)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION)) + { + if (!TIFFWriteDirectoryTagTransferfunction(tif, &ndir, dir)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_INKNAMES)) + { + if (!TIFFWriteDirectoryTagAscii( + tif, &ndir, dir, TIFFTAG_INKNAMES, + tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_NUMBEROFINKS, + tif->tif_dir.td_numberofinks)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SUBIFD)) + { + if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir)) + goto bad; + } + { + uint32_t n; + for (n = 0; n < tif->tif_nfields; n++) + { + const TIFFField *o; + o = tif->tif_fields[n]; + if ((o->field_bit >= FIELD_CODEC) && + (TIFFFieldSet(tif, o->field_bit))) + { + switch (o->get_field_type) + { + case TIFF_SETGET_ASCII: + { + uint32_t pa; + char *pb; + assert(o->field_type == TIFF_ASCII); + assert(o->field_readcount == TIFF_VARIABLE); + assert(o->field_passcount == 0); + TIFFGetField(tif, o->field_tag, &pb); + pa = (uint32_t)(strlen(pb)); + if (!TIFFWriteDirectoryTagAscii( + tif, &ndir, dir, (uint16_t)o->field_tag, + pa, pb)) goto bad; - } - if (nb->tdir_tag==TIFFTAG_SUBIFD) - break; - } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - tif->tif_subifdoff=tif->tif_diroff+2+na*12+8; - else - tif->tif_subifdoff=tif->tif_diroff+8+na*20+12; - } - } - dirmem=_TIFFmalloc(dirsize); - if (dirmem==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - goto bad; - } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint8* n; - uint32 nTmp; - TIFFDirEntry* o; - n=dirmem; - *(uint16*)n=(uint16)ndir; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)n); - n+=2; - o=dir; - for (m=0; mtdir_tag; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)n); - n+=2; - *(uint16*)n=o->tdir_type; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)n); - n+=2; - nTmp = (uint32)o->tdir_count; - _TIFFmemcpy(n,&nTmp,4); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)n); - n+=4; - /* This is correct. The data has been */ - /* swabbed previously in TIFFWriteDirectoryTagData */ - _TIFFmemcpy(n,&o->tdir_offset,4); - n+=4; - o++; - } - nTmp = (uint32)tif->tif_nextdiroff; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nTmp); - _TIFFmemcpy(n,&nTmp,4); - } - else - { - uint8* n; - TIFFDirEntry* o; - n=dirmem; - *(uint64*)n=ndir; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)n); - n+=8; - o=dir; - for (m=0; mtdir_tag; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)n); - n+=2; - *(uint16*)n=o->tdir_type; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)n); - n+=2; - _TIFFmemcpy(n,&o->tdir_count,8); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)n); - n+=8; - _TIFFmemcpy(n,&o->tdir_offset,8); - n+=8; - o++; - } - _TIFFmemcpy(n,&tif->tif_nextdiroff,8); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)n); - } - _TIFFfree(dir); - dir=NULL; - if (!SeekOK(tif,tif->tif_diroff)) - { - TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory"); - goto bad; - } - if (!WriteOK(tif,dirmem,(tmsize_t)dirsize)) - { - TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory"); - goto bad; - } - _TIFFfree(dirmem); - if (imagedone) - { - TIFFFreeDirectory(tif); - tif->tif_flags &= ~TIFF_DIRTYDIRECT; - tif->tif_flags &= ~TIFF_DIRTYSTRIP; - (*tif->tif_cleanup)(tif); - /* - * Reset directory-related state for subsequent - * directories. - */ - TIFFCreateDirectory(tif); - } - return(1); + } + break; + case TIFF_SETGET_UINT16: + { + uint16_t p; + assert(o->field_type == TIFF_SHORT); + assert(o->field_readcount == 1); + assert(o->field_passcount == 0); + TIFFGetField(tif, o->field_tag, &p); + if (!TIFFWriteDirectoryTagShort( + tif, &ndir, dir, (uint16_t)o->field_tag, + p)) + goto bad; + } + break; + case TIFF_SETGET_UINT32: + { + uint32_t p; + assert(o->field_type == TIFF_LONG); + assert(o->field_readcount == 1); + assert(o->field_passcount == 0); + TIFFGetField(tif, o->field_tag, &p); + if (!TIFFWriteDirectoryTagLong( + tif, &ndir, dir, (uint16_t)o->field_tag, + p)) + goto bad; + } + break; + case TIFF_SETGET_C32_UINT8: + { + uint32_t pa; + void *pb; + assert(o->field_type == TIFF_UNDEFINED); + assert(o->field_readcount == TIFF_VARIABLE2); + assert(o->field_passcount == 1); + TIFFGetField(tif, o->field_tag, &pa, &pb); + if (!TIFFWriteDirectoryTagUndefinedArray( + tif, &ndir, dir, (uint16_t)o->field_tag, + pa, pb)) + goto bad; + } + break; + default: + TIFFErrorExtR( + tif, module, + "Cannot write tag %" PRIu32 " (%s)", + TIFFFieldTag(o), + o->field_name ? o->field_name : "unknown"); + goto bad; + } + } + } + } + } + for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++) + { + uint16_t tag = + (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag; + uint32_t count = tif->tif_dir.td_customValues[m].count; + switch (tif->tif_dir.td_customValues[m].info->field_type) + { + case TIFF_ASCII: + if (!TIFFWriteDirectoryTagAscii( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_UNDEFINED: + if (!TIFFWriteDirectoryTagUndefinedArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_BYTE: + if (!TIFFWriteDirectoryTagByteArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SBYTE: + if (!TIFFWriteDirectoryTagSbyteArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SHORT: + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SSHORT: + if (!TIFFWriteDirectoryTagSshortArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_LONG: + if (!TIFFWriteDirectoryTagLongArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SLONG: + if (!TIFFWriteDirectoryTagSlongArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_LONG8: + if (!TIFFWriteDirectoryTagLong8Array( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SLONG8: + if (!TIFFWriteDirectoryTagSlong8Array( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_RATIONAL: + { + /*-- Rational2Double: For Rationals evaluate + * "set_field_type" to determine internal storage size. */ + int tv_size; + tv_size = TIFFFieldSetGetSize( + tif->tif_dir.td_customValues[m].info); + if (tv_size == 8) + { + if (!TIFFWriteDirectoryTagRationalDoubleArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + } + else + { + /*-- default should be tv_size == 4 */ + if (!TIFFWriteDirectoryTagRationalArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + /*-- ToDo: After Testing, this should be removed and + * tv_size==4 should be set as default. */ + if (tv_size != 4) + { + TIFFErrorExtR(tif, + "TIFFLib: _TIFFWriteDirectorySec()", + "Rational2Double: .set_field_type is " + "not 4 but %d", + tv_size); + } + } + } + break; + case TIFF_SRATIONAL: + { + /*-- Rational2Double: For Rationals evaluate + * "set_field_type" to determine internal storage size. */ + int tv_size; + tv_size = TIFFFieldSetGetSize( + tif->tif_dir.td_customValues[m].info); + if (tv_size == 8) + { + if (!TIFFWriteDirectoryTagSrationalDoubleArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + } + else + { + /*-- default should be tv_size == 4 */ + if (!TIFFWriteDirectoryTagSrationalArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + /*-- ToDo: After Testing, this should be removed and + * tv_size==4 should be set as default. */ + if (tv_size != 4) + { + TIFFErrorExtR(tif, + "TIFFLib: _TIFFWriteDirectorySec()", + "Rational2Double: .set_field_type is " + "not 4 but %d", + tv_size); + } + } + } + break; + case TIFF_FLOAT: + if (!TIFFWriteDirectoryTagFloatArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_DOUBLE: + if (!TIFFWriteDirectoryTagDoubleArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_IFD: + if (!TIFFWriteDirectoryTagIfdArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_IFD8: + if (!TIFFWriteDirectoryTagIfdIfd8Array( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + default: + assert(0); /* we should never get here */ + break; + } + } + if (dir != NULL) + break; + dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry)); + if (dir == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + goto bad; + } + if (isimage) + { + if ((tif->tif_diroff == 0) && (!TIFFLinkDirectory(tif))) + goto bad; + } + else + tif->tif_diroff = + (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1)); + if (pdiroff != NULL) + *pdiroff = tif->tif_diroff; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + dirsize = 2 + ndir * 12 + 4; + else + dirsize = 8 + ndir * 20 + 8; + tif->tif_dataoff = tif->tif_diroff + dirsize; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + tif->tif_dataoff = (uint32_t)tif->tif_dataoff; + if ((tif->tif_dataoff < tif->tif_diroff) || + (tif->tif_dataoff < (uint64_t)dirsize)) + { + TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); + goto bad; + } + if (tif->tif_dataoff & 1) + tif->tif_dataoff++; + if (isimage) + { + if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER) + tif->tif_curdir = 0; + else + tif->tif_curdir++; + } + } + if (isimage) + { + if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0)) + { + uint32_t na; + TIFFDirEntry *nb; + for (na = 0, nb = dir;; na++, nb++) + { + if (na == ndir) + { + TIFFErrorExtR(tif, module, "Cannot find SubIFD tag"); + goto bad; + } + if (nb->tdir_tag == TIFFTAG_SUBIFD) + break; + } + if (!(tif->tif_flags & TIFF_BIGTIFF)) + tif->tif_subifdoff = tif->tif_diroff + 2 + na * 12 + 8; + else + tif->tif_subifdoff = tif->tif_diroff + 8 + na * 20 + 12; + } + } + dirmem = _TIFFmallocExt(tif, dirsize); + if (dirmem == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + goto bad; + } + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint8_t *n; + uint32_t nTmp; + TIFFDirEntry *o; + n = dirmem; + *(uint16_t *)n = (uint16_t)ndir; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + o = dir; + for (m = 0; m < ndir; m++) + { + *(uint16_t *)n = o->tdir_tag; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + *(uint16_t *)n = o->tdir_type; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + nTmp = (uint32_t)o->tdir_count; + _TIFFmemcpy(n, &nTmp, 4); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)n); + n += 4; + /* This is correct. The data has been */ + /* swabbed previously in TIFFWriteDirectoryTagData */ + _TIFFmemcpy(n, &o->tdir_offset, 4); + n += 4; + o++; + } + nTmp = (uint32_t)tif->tif_nextdiroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nTmp); + _TIFFmemcpy(n, &nTmp, 4); + } + else + { + uint8_t *n; + TIFFDirEntry *o; + n = dirmem; + *(uint64_t *)n = ndir; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)n); + n += 8; + o = dir; + for (m = 0; m < ndir; m++) + { + *(uint16_t *)n = o->tdir_tag; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + *(uint16_t *)n = o->tdir_type; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + _TIFFmemcpy(n, &o->tdir_count, 8); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)n); + n += 8; + _TIFFmemcpy(n, &o->tdir_offset, 8); + n += 8; + o++; + } + _TIFFmemcpy(n, &tif->tif_nextdiroff, 8); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)n); + } + _TIFFfreeExt(tif, dir); + dir = NULL; + if (!SeekOK(tif, tif->tif_diroff)) + { + TIFFErrorExtR(tif, module, "IO error writing directory"); + goto bad; + } + if (!WriteOK(tif, dirmem, (tmsize_t)dirsize)) + { + TIFFErrorExtR(tif, module, "IO error writing directory"); + goto bad; + } + _TIFFfreeExt(tif, dirmem); + if (imagedone) + { + TIFFFreeDirectory(tif); + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + (*tif->tif_cleanup)(tif); + /* + * Reset directory-related state for subsequent + * directories. + */ + TIFFCreateDirectory(tif); + } + return (1); bad: - if (dir!=NULL) - _TIFFfree(dir); - if (dirmem!=NULL) - _TIFFfree(dirmem); - return(0); + if (dir != NULL) + _TIFFfreeExt(tif, dir); + if (dirmem != NULL) + _TIFFfreeExt(tif, dirmem); + return (0); } -static int8 TIFFClampDoubleToInt8( double val ) +static int8_t TIFFClampDoubleToInt8(double val) { - if( val > 127 ) + if (val > 127) return 127; - if( val < -128 || val != val ) + if (val < -128 || val != val) return -128; - return (int8)val; + return (int8_t)val; } -static int16 TIFFClampDoubleToInt16( double val ) +static int16_t TIFFClampDoubleToInt16(double val) { - if( val > 32767 ) + if (val > 32767) return 32767; - if( val < -32768 || val != val ) + if (val < -32768 || val != val) return -32768; - return (int16)val; + return (int16_t)val; } -static int32 TIFFClampDoubleToInt32( double val ) +static int32_t TIFFClampDoubleToInt32(double val) { - if( val > 0x7FFFFFFF ) + if (val > 0x7FFFFFFF) return 0x7FFFFFFF; - if( val < -0x7FFFFFFF-1 || val != val ) - return -0x7FFFFFFF-1; - return (int32)val; + if (val < -0x7FFFFFFF - 1 || val != val) + return -0x7FFFFFFF - 1; + return (int32_t)val; } -static uint8 TIFFClampDoubleToUInt8( double val ) +static uint8_t TIFFClampDoubleToUInt8(double val) { - if( val < 0 ) + if (val < 0) return 0; - if( val > 255 || val != val ) + if (val > 255 || val != val) return 255; - return (uint8)val; + return (uint8_t)val; } -static uint16 TIFFClampDoubleToUInt16( double val ) +static uint16_t TIFFClampDoubleToUInt16(double val) { - if( val < 0 ) + if (val < 0) return 0; - if( val > 65535 || val != val ) + if (val > 65535 || val != val) return 65535; - return (uint16)val; + return (uint16_t)val; } -static uint32 TIFFClampDoubleToUInt32( double val ) +static uint32_t TIFFClampDoubleToUInt32(double val) { - if( val < 0 ) + if (val < 0) return 0; - if( val > 0xFFFFFFFFU || val != val ) + if (val > 0xFFFFFFFFU || val != val) return 0xFFFFFFFFU; - return (uint32)val; + return (uint32_t)val; } -static int -TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + double *value) { - static const char module[] = "TIFFWriteDirectoryTagSampleformatArray"; - void* conv; - uint32 i; - int ok; - conv = _TIFFmalloc(count*sizeof(double)); - if (conv == NULL) - { - TIFFErrorExt(tif->tif_clientdata, module, "Out of memory"); - return (0); - } + static const char module[] = "TIFFWriteDirectoryTagSampleformatArray"; + void *conv; + uint32_t i; + int ok; + conv = _TIFFmallocExt(tif, count * sizeof(double)); + if (conv == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } - switch (tif->tif_dir.td_sampleformat) - { - case SAMPLEFORMAT_IEEEFP: - if (tif->tif_dir.td_bitspersample<=32) - { - for (i = 0; i < count; ++i) - ((float*)conv)[i] = _TIFFClampDoubleToFloat(value[i]); - ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv); - } - else - { - ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value); - } - break; - case SAMPLEFORMAT_INT: - if (tif->tif_dir.td_bitspersample<=8) - { - for (i = 0; i < count; ++i) - ((int8*)conv)[i] = TIFFClampDoubleToInt8(value[i]); - ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv); - } - else if (tif->tif_dir.td_bitspersample<=16) - { - for (i = 0; i < count; ++i) - ((int16*)conv)[i] = TIFFClampDoubleToInt16(value[i]); - ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv); - } - else - { - for (i = 0; i < count; ++i) - ((int32*)conv)[i] = TIFFClampDoubleToInt32(value[i]); - ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv); - } - break; - case SAMPLEFORMAT_UINT: - if (tif->tif_dir.td_bitspersample<=8) - { - for (i = 0; i < count; ++i) - ((uint8*)conv)[i] = TIFFClampDoubleToUInt8(value[i]); - ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv); - } - else if (tif->tif_dir.td_bitspersample<=16) - { - for (i = 0; i < count; ++i) - ((uint16*)conv)[i] = TIFFClampDoubleToUInt16(value[i]); - ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv); - } - else - { - for (i = 0; i < count; ++i) - ((uint32*)conv)[i] = TIFFClampDoubleToUInt32(value[i]); - ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv); - } - break; - default: - ok = 0; - } + switch (tif->tif_dir.td_sampleformat) + { + case SAMPLEFORMAT_IEEEFP: + if (tif->tif_dir.td_bitspersample <= 32) + { + for (i = 0; i < count; ++i) + ((float *)conv)[i] = _TIFFClampDoubleToFloat(value[i]); + ok = TIFFWriteDirectoryTagFloatArray(tif, ndir, dir, tag, count, + (float *)conv); + } + else + { + ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag, + count, value); + } + break; + case SAMPLEFORMAT_INT: + if (tif->tif_dir.td_bitspersample <= 8) + { + for (i = 0; i < count; ++i) + ((int8_t *)conv)[i] = TIFFClampDoubleToInt8(value[i]); + ok = TIFFWriteDirectoryTagSbyteArray(tif, ndir, dir, tag, count, + (int8_t *)conv); + } + else if (tif->tif_dir.td_bitspersample <= 16) + { + for (i = 0; i < count; ++i) + ((int16_t *)conv)[i] = TIFFClampDoubleToInt16(value[i]); + ok = TIFFWriteDirectoryTagSshortArray(tif, ndir, dir, tag, + count, (int16_t *)conv); + } + else + { + for (i = 0; i < count; ++i) + ((int32_t *)conv)[i] = TIFFClampDoubleToInt32(value[i]); + ok = TIFFWriteDirectoryTagSlongArray(tif, ndir, dir, tag, count, + (int32_t *)conv); + } + break; + case SAMPLEFORMAT_UINT: + if (tif->tif_dir.td_bitspersample <= 8) + { + for (i = 0; i < count; ++i) + ((uint8_t *)conv)[i] = TIFFClampDoubleToUInt8(value[i]); + ok = TIFFWriteDirectoryTagByteArray(tif, ndir, dir, tag, count, + (uint8_t *)conv); + } + else if (tif->tif_dir.td_bitspersample <= 16) + { + for (i = 0; i < count; ++i) + ((uint16_t *)conv)[i] = TIFFClampDoubleToUInt16(value[i]); + ok = TIFFWriteDirectoryTagShortArray(tif, ndir, dir, tag, count, + (uint16_t *)conv); + } + else + { + for (i = 0; i < count; ++i) + ((uint32_t *)conv)[i] = TIFFClampDoubleToUInt32(value[i]); + ok = TIFFWriteDirectoryTagLongArray(tif, ndir, dir, tag, count, + (uint32_t *)conv); + } + break; + default: + ok = 0; + } - _TIFFfree(conv); - return (ok); + _TIFFfreeExt(tif, conv); + return (ok); } -#if 0 -static int -TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, char *value) { - switch (tif->tif_dir.td_sampleformat) - { - case SAMPLEFORMAT_IEEEFP: - if (tif->tif_dir.td_bitspersample<=32) - return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value)); - else - return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value)); - case SAMPLEFORMAT_INT: - if (tif->tif_dir.td_bitspersample<=8) - return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value)); - else if (tif->tif_dir.td_bitspersample<=16) - return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value)); - else - return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value)); - case SAMPLEFORMAT_UINT: - if (tif->tif_dir.td_bitspersample<=8) - return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value)); - else if (tif->tif_dir.td_bitspersample<=16) - return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value)); - else - return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value)); - default: - return(1); - } -} -#endif - -static int -TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return ( + TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value)); } -static int -TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) +static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint8_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag, + count, value)); } -#ifdef notdef -static int -TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value) +static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint8_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value)); -} -#endif - -static int -TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count, + value)); } -#if 0 -static int -TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value) +static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int8_t *value) { - static const char module[] = "TIFFWriteDirectoryTagBytePerSample"; - uint8* m; - uint8* na; - uint16 nb; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) - *na=value; - o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); - _TIFFfree(m); - return(o); -} -#endif - -#ifdef notdef -static int -TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value)); -} -#endif - -static int -TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count, + value)); } -#if 0 -static int -TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value) +static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value) { - static const char module[] = "TIFFWriteDirectoryTagSbytePerSample"; - int8* m; - int8* na; - uint16 nb; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) - *na=value; - o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); - _TIFFfree(m); - return(o); -} -#endif - -static int -TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value)); } -static int -TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value) +static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint16_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count, + value)); } -static int -TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value) +static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value) { - static const char module[] = "TIFFWriteDirectoryTagShortPerSample"; - uint16* m; - uint16* na; - uint16 nb; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) - *na=value; - o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); - _TIFFfree(m); - return(o); + static const char module[] = "TIFFWriteDirectoryTagShortPerSample"; + uint16_t *m; + uint16_t *na; + uint16_t nb; + int o; + if (dir == NULL) + { + (*ndir)++; + return (1); + } + m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++) + *na = value; + o = TIFFWriteDirectoryTagCheckedShortArray( + tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m); + _TIFFfreeExt(tif, m); + return (o); } -#ifdef notdef -static int -TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value) +static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int16_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value)); -} -#endif - -static int -TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count, + value)); } -#if 0 -static int -TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value) +static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value) { - static const char module[] = "TIFFWriteDirectoryTagSshortPerSample"; - int16* m; - int16* na; - uint16 nb; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) - *na=value; - o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); - _TIFFfree(m); - return(o); -} -#endif - -static int -TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value)); } -static int -TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, + value)); } -#if 0 -static int -TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int32_t *value) { - static const char module[] = "TIFFWriteDirectoryTagLongPerSample"; - uint32* m; - uint32* na; - uint16 nb; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) - *na=value; - o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); - _TIFFfree(m); - return(o); -} -#endif - -#ifdef notdef -static int -TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value)); -} -#endif - -static int -TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, + value)); } -#if 0 -static int -TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value) +/************************************************************************/ +/* TIFFWriteDirectoryTagLong8Array() */ +/* */ +/* Write either Long8 or Long array depending on file type. */ +/************************************************************************/ +static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value) { - static const char module[] = "TIFFWriteDirectoryTagSlongPerSample"; - int32* m; - int32* na; - uint16 nb; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) - *na=value; - o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); - _TIFFfree(m); - return(o); -} -#endif + static const char module[] = "TIFFWriteDirectoryTagLong8Array"; + uint64_t *ma; + uint32_t mb; + uint32_t *p; + uint32_t *q; + int o; -#ifdef notdef -static int -TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value)); -} -#endif + /* is this just a counting pass? */ + if (dir == NULL) + { + (*ndir)++; + return (1); + } -static int -TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value)); + /* We always write Long8 for BigTIFF, no checking needed. */ + if (tif->tif_flags & TIFF_BIGTIFF) + return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag, + count, value)); + + /* + ** For classic tiff we want to verify everything is in range for long + ** and convert to long format. + */ + p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + if (p == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + + for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) + { + if (*ma > 0xFFFFFFFF) + { + TIFFErrorExtR(tif, module, + "Attempt to write unsigned long value %" PRIu64 + " larger than 0xFFFFFFFF for tag %d in Classic TIFF " + "file. TIFF file writing aborted", + *ma, tag); + _TIFFfreeExt(tif, p); + return (0); + } + *q = (uint32_t)(*ma); + } + + o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p); + _TIFFfreeExt(tif, p); + + return (o); } -#ifdef notdef -static int -TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value) +/************************************************************************/ +/* TIFFWriteDirectoryTagSlong8Array() */ +/* */ +/* Write either SLong8 or SLong array depending on file type. */ +/************************************************************************/ +static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int64_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value)); -} -#endif + static const char module[] = "TIFFWriteDirectoryTagSlong8Array"; + int64_t *ma; + uint32_t mb; + int32_t *p; + int32_t *q; + int o; -static int -TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value)); + /* is this just a counting pass? */ + if (dir == NULL) + { + (*ndir)++; + return (1); + } + /* We always write SLong8 for BigTIFF, no checking needed. */ + if (tif->tif_flags & TIFF_BIGTIFF) + return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag, + count, value)); + + /* + ** For classic tiff we want to verify everything is in range for signed-long + ** and convert to signed-long format. + */ + p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + if (p == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + + for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) + { + if (*ma > (2147483647)) + { + TIFFErrorExtR(tif, module, + "Attempt to write signed long value %" PRIi64 + " larger than 0x7FFFFFFF (2147483647) for tag %d in " + "Classic TIFF file. TIFF writing to file aborted", + *ma, tag); + _TIFFfreeExt(tif, p); + return (0); + } + else if (*ma < (-2147483647 - 1)) + { + TIFFErrorExtR(tif, module, + "Attempt to write signed long value %" PRIi64 + " smaller than 0x80000000 (-2147483648) for tag %d " + "in Classic TIFF file. TIFF writing to file aborted", + *ma, tag); + _TIFFfreeExt(tif, p); + return (0); + } + *q = (int32_t)(*ma); + } + + o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p); + _TIFFfreeExt(tif, p); + + return (o); } -static int -TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + double value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value)); } -static int -TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag, + count, value)); } -static int -TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag, + count, value)); } /*-- Rational2Double: additional write functions */ -static int -TIFFWriteDirectoryTagRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + double *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag, + count, value)); } -static int -TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + double *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSrationalDoubleArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray( + tif, ndir, dir, tag, count, value)); } -#ifdef notdef -static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value) +static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value)); -} -#endif - -static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count, + value)); } -#if 0 -static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value) +static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, double *value) { - static const char module[] = "TIFFWriteDirectoryTagFloatPerSample"; - float* m; - float* na; - uint16 nb; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) - *na=value; - o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); - _TIFFfree(m); - return(o); -} -#endif - -#ifdef notdef -static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value)); -} -#endif - -static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count, + value)); } -#if 0 -static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value) { - static const char module[] = "TIFFWriteDirectoryTagDoublePerSample"; - double* m; - double* na; - uint16 nb; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) - *na=value; - o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); - _TIFFfree(m); - return(o); -} -#endif - -static int -TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, + value)); } -#ifdef notdef -static int -TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value)); -} -#endif - -static int -TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) -{ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - if (value<=0xFFFF) - return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value)); - else - return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + if (value <= 0xFFFF) + return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, + (uint16_t)value)); + else + return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value)); } -static int _WriteAsType(TIFF* tif, uint64 strile_size, uint64 uncompressed_threshold) +static int _WriteAsType(TIFF *tif, uint64_t strile_size, + uint64_t uncompressed_threshold) { - const uint16 compression = tif->tif_dir.td_compression; - if ( compression == COMPRESSION_NONE ) + const uint16_t compression = tif->tif_dir.td_compression; + if (compression == COMPRESSION_NONE) { return strile_size > uncompressed_threshold; } - else if ( compression == COMPRESSION_JPEG || - compression == COMPRESSION_LZW || - compression == COMPRESSION_ADOBE_DEFLATE || - compression == COMPRESSION_LZMA || - compression == COMPRESSION_LERC || - compression == COMPRESSION_ZSTD || - compression == COMPRESSION_WEBP ) + else if (compression == COMPRESSION_JPEG || + compression == COMPRESSION_LZW || + compression == COMPRESSION_ADOBE_DEFLATE || + compression == COMPRESSION_DEFLATE || + compression == COMPRESSION_LZMA || + compression == COMPRESSION_LERC || + compression == COMPRESSION_ZSTD || + compression == COMPRESSION_WEBP || compression == COMPRESSION_JXL) { /* For a few select compression types, we assume that in the worst */ /* case the compressed size will be 10 times the uncompressed size */ @@ -1787,12 +1831,12 @@ static int _WriteAsType(TIFF* tif, uint64 strile_size, uint64 uncompressed_thres return 1; } -static int WriteAsLong8(TIFF* tif, uint64 strile_size) +static int WriteAsLong8(TIFF *tif, uint64_t strile_size) { return _WriteAsType(tif, strile_size, 0xFFFFFFFFU); } -static int WriteAsLong4(TIFF* tif, uint64 strile_size) +static int WriteAsLong4(TIFF *tif, uint64_t strile_size) { return _WriteAsType(tif, strile_size, 0xFFFFU); } @@ -1804,121 +1848,128 @@ static int WriteAsLong4(TIFF* tif, uint64 strile_size) /* on strile size and Classic/BigTIFF mode. */ /************************************************************************/ -static int -TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value) { static const char module[] = "TIFFWriteDirectoryTagLongLong8Array"; int o; int write_aslong4; /* is this just a counting pass? */ - if (dir==NULL) + if (dir == NULL) { (*ndir)++; - return(1); + return (1); } - if( tif->tif_dir.td_deferstrilearraywriting ) + if (tif->tif_dir.td_deferstrilearraywriting) { - return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0, NULL); + return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0, + NULL); } - if( tif->tif_flags&TIFF_BIGTIFF ) + if (tif->tif_flags & TIFF_BIGTIFF) { int write_aslong8 = 1; /* In the case of ByteCounts array, we may be able to write them on */ /* LONG if the strip/tilesize is not too big. */ - /* Also do that for count > 1 in the case someone would want to create */ + /* Also do that for count > 1 in the case someone would want to create + */ /* a single-strip file with a growing height, in which case using */ /* LONG8 will be safer. */ - if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS ) + if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) { write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif)); } - else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS ) + else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) { write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif)); } - if( write_aslong8 ) + if (write_aslong8) { - return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir, - tag,count,value); + return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag, + count, value); } } write_aslong4 = 1; - if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS ) + if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) { write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif)); } - else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS ) + else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) { write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif)); } - if( write_aslong4 ) + if (write_aslong4) { /* ** For classic tiff we want to verify everything is in range for LONG ** and convert to long format. */ - uint32* p = _TIFFmalloc(count*sizeof(uint32)); - uint32* q; - uint64* ma; - uint32 mb; + uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + uint32_t *q; + uint64_t *ma; + uint32_t mb; - if (p==NULL) + if (p == NULL) { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); } - for (q=p, ma=value, mb=0; mb0xFFFFFFFF) + if (*ma > 0xFFFFFFFF) { - TIFFErrorExt(tif->tif_clientdata,module, - "Attempt to write value larger than 0xFFFFFFFF in LONG array."); - _TIFFfree(p); - return(0); + TIFFErrorExtR(tif, module, + "Attempt to write value larger than 0xFFFFFFFF " + "in LONG array."); + _TIFFfreeExt(tif, p); + return (0); } - *q= (uint32)(*ma); + *q = (uint32_t)(*ma); } - o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p); - _TIFFfree(p); + o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, + p); + _TIFFfreeExt(tif, p); } else { - uint16* p = _TIFFmalloc(count*sizeof(uint16)); - uint16* q; - uint64* ma; - uint32 mb; + uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t)); + uint16_t *q; + uint64_t *ma; + uint32_t mb; - if (p==NULL) + if (p == NULL) { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); } - for (q=p, ma=value, mb=0; mb0xFFFF) + if (*ma > 0xFFFF) { /* Should not happen normally given the check we did before */ - TIFFErrorExt(tif->tif_clientdata,module, - "Attempt to write value larger than 0xFFFF in SHORT array."); - _TIFFfree(p); - return(0); + TIFFErrorExtR(tif, module, + "Attempt to write value larger than 0xFFFF in " + "SHORT array."); + _TIFFfreeExt(tif, p); + return (0); } - *q= (uint16)(*ma); + *q = (uint16_t)(*ma); } - o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p); - _TIFFfree(p); + o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count, + p); + _TIFFfreeExt(tif, p); } - return(o); + return (o); } /************************************************************************/ @@ -1927,781 +1978,555 @@ TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, /* Write either IFD8 or IFD array depending on file type. */ /************************************************************************/ -static int -TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value) { static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array"; - uint64* ma; - uint32 mb; - uint32* p; - uint32* q; + uint64_t *ma; + uint32_t mb; + uint32_t *p; + uint32_t *q; int o; /* is this just a counting pass? */ - if (dir==NULL) + if (dir == NULL) { (*ndir)++; - return(1); + return (1); } /* We always write IFD8 for BigTIFF, no checking needed. */ - if( tif->tif_flags&TIFF_BIGTIFF ) - return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir, - tag,count,value); + if (tif->tif_flags & TIFF_BIGTIFF) + return TIFFWriteDirectoryTagCheckedIfd8Array(tif, ndir, dir, tag, count, + value); /* ** For classic tiff we want to verify everything is in range for IFD ** and convert to long format. */ - p = _TIFFmalloc(count*sizeof(uint32)); - if (p==NULL) + p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + if (p == NULL) { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); } - for (q=p, ma=value, mb=0; mb0xFFFFFFFF) + if (*ma > 0xFFFFFFFF) { - TIFFErrorExt(tif->tif_clientdata,module, - "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file."); - _TIFFfree(p); - return(0); + TIFFErrorExtR(tif, module, + "Attempt to write value larger than 0xFFFFFFFF in " + "Classic TIFF file."); + _TIFFfreeExt(tif, p); + return (0); } - *q= (uint32)(*ma); + *q = (uint32_t)(*ma); } - o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p); - _TIFFfree(p); + o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p); + _TIFFfreeExt(tif, p); - return(o); + return (o); } -#ifdef notdef -static int -TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir) { - static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array"; - uint64* ma; - uint32 mb; - uint8 n; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - n=0; - for (ma=value, mb=0; mb0xFFFF)) - n=1; - if ((n==1)&&(*ma>0xFFFFFFFF)) - { - n=2; - break; - } - } - if (n==0) - { - uint16* p; - uint16* q; - p=_TIFFmalloc(count*sizeof(uint16)); - if (p==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (ma=value, mb=0, q=p; mbtif_clientdata,module,"Out of memory"); - return(0); - } - for (ma=value, mb=0, q=p; mbtif_dir.td_bitspersample); - n=_TIFFmalloc(3*m*sizeof(uint16)); - if (n==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - _TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16)); - _TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16)); - _TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16)); - o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n); - _TIFFfree(n); - return(o); + static const char module[] = "TIFFWriteDirectoryTagColormap"; + uint32_t m; + uint16_t *n; + int o; + if (dir == NULL) + { + (*ndir)++; + return (1); + } + m = (1 << tif->tif_dir.td_bitspersample); + n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t)); + if (n == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + _TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t)); + _TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t)); + _TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t)); + o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP, + 3 * m, n); + _TIFFfreeExt(tif, n); + return (o); } -static int -TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir) +static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir) { - static const char module[] = "TIFFWriteDirectoryTagTransferfunction"; - uint32 m; - uint16 n; - uint16* o; - int p; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=(1<tif_dir.td_bitspersample); - n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples; - /* - * Check if the table can be written as a single column, - * or if it must be written as 3 columns. Note that we - * write a 3-column tag if there are 2 samples/pixel and - * a single column of data won't suffice--hmm. - */ - if (n>3) - n=3; - if (n==3) - { - if (tif->tif_dir.td_transferfunction[2] == NULL || - !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16))) - n=2; - } - if (n==2) - { - if (tif->tif_dir.td_transferfunction[1] == NULL || - !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16))) - n=1; - } - if (n==0) - n=1; - o=_TIFFmalloc(n*m*sizeof(uint16)); - if (o==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - _TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16)); - if (n>1) - _TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)); - if (n>2) - _TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)); - p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o); - _TIFFfree(o); - return(p); + static const char module[] = "TIFFWriteDirectoryTagTransferfunction"; + uint32_t m; + uint16_t n; + uint16_t *o; + int p; + if (dir == NULL) + { + (*ndir)++; + return (1); + } + /* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with + * (1 << BitsPerSample) * uint16_t values. + */ + m = (1 << tif->tif_dir.td_bitspersample); + /* clang-format off */ + n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1; + /* clang-format on */ + + /* Check for proper number of transferfunctions */ + for (int i = 0; i < n; i++) + { + if (tif->tif_dir.td_transferfunction[i] == NULL) + { + TIFFWarningExtR( + tif, module, + "Too few TransferFunctions provided. Tag not written to file"); + return (1); /* Not an error; only tag is not written. */ + } + } + /* + * Check if the table can be written as a single column, + * or if it must be written as 3 columns. Note that we + * write a 3-column tag if there are 2 samples/pixel and + * a single column of data won't suffice--hmm. + */ + if (n == 3) + { + if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0], + tif->tif_dir.td_transferfunction[2], + m * sizeof(uint16_t)) && + !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0], + tif->tif_dir.td_transferfunction[1], + m * sizeof(uint16_t))) + n = 1; + } + o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t)); + if (o == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0], + m * sizeof(uint16_t)); + if (n > 1) + _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1], + m * sizeof(uint16_t)); + if (n > 2) + _TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2], + m * sizeof(uint16_t)); + p = TIFFWriteDirectoryTagCheckedShortArray( + tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o); + _TIFFfreeExt(tif, o); + return (p); } -static int -TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir) +static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir) { - static const char module[] = "TIFFWriteDirectoryTagSubifd"; - uint64 m; - int n; - if (tif->tif_dir.td_nsubifd==0) - return(1); - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=tif->tif_dataoff; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32* o; - uint64* pa; - uint32* pb; - uint16 p; - o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32)); - if (o==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - pa=tif->tif_dir.td_subifd; - pb=o; - for (p=0; p < tif->tif_dir.td_nsubifd; p++) - { - assert(pa != 0); + static const char module[] = "TIFFWriteDirectoryTagSubifd"; + uint64_t m; + int n; + if (tif->tif_dir.td_nsubifd == 0) + return (1); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + m = tif->tif_dataoff; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t *o; + uint64_t *pa; + uint32_t *pb; + uint16_t p; + o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t)); + if (o == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + pa = tif->tif_dir.td_subifd; + pb = o; + for (p = 0; p < tif->tif_dir.td_nsubifd; p++) + { + assert(pa != 0); - /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which is illegal) */ - if( *pa > 0xFFFFFFFFUL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Illegal value for SubIFD tag"); - _TIFFfree(o); - return(0); - } - *pb++=(uint32)(*pa++); - } - n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o); - _TIFFfree(o); - } - else - n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd); - if (!n) - return(0); - /* - * Total hack: if this directory includes a SubIFD - * tag then force the next directories to be - * written as ``sub directories'' of this one. This - * is used to write things like thumbnails and - * image masks that one wants to keep out of the - * normal directory linkage access mechanism. - */ - tif->tif_flags|=TIFF_INSUBIFD; - tif->tif_nsubifd=tif->tif_dir.td_nsubifd; - if (tif->tif_dir.td_nsubifd==1) - tif->tif_subifdoff=0; - else - tif->tif_subifdoff=m; - return(1); + /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which + * is illegal) */ + if (*pa > 0xFFFFFFFFUL) + { + TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag"); + _TIFFfreeExt(tif, o); + return (0); + } + *pb++ = (uint32_t)(*pa++); + } + n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD, + tif->tif_dir.td_nsubifd, o); + _TIFFfreeExt(tif, o); + } + else + n = TIFFWriteDirectoryTagCheckedIfd8Array( + tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd, + tif->tif_dir.td_subifd); + if (!n) + return (0); + /* + * Total hack: if this directory includes a SubIFD + * tag then force the next directories to be + * written as ``sub directories'' of this one. This + * is used to write things like thumbnails and + * image masks that one wants to keep out of the + * normal directory linkage access mechanism. + */ + tif->tif_flags |= TIFF_INSUBIFD; + tif->tif_nsubifd = tif->tif_dir.td_nsubifd; + if (tif->tif_dir.td_nsubifd == 1) + tif->tif_subifdoff = 0; + else + tif->tif_subifdoff = m; + return (1); } -static int -TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value) +static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, char *value) { - assert(sizeof(char)==1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value)); + assert(sizeof(char) == 1); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count, + count, value)); } -static int -TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) +static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + uint8_t *value) { - assert(sizeof(uint8)==1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value)); + assert(sizeof(uint8_t) == 1); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED, + count, count, value)); } -#ifdef notdef -static int -TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value) +static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint8_t *value) { - assert(sizeof(uint8)==1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value)); -} -#endif - -static int -TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) -{ - assert(sizeof(uint8)==1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value)); + assert(sizeof(uint8_t) == 1); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count, + count, value)); } -#ifdef notdef -static int -TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value) +static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int8_t *value) { - assert(sizeof(int8)==1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value)); -} -#endif - -static int -TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value) -{ - assert(sizeof(int8)==1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value)); + assert(sizeof(int8_t) == 1); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count, + count, value)); } -static int -TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value) +static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value) { - uint16 m; - assert(sizeof(uint16)==2); - m=value; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(&m); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m)); + uint16_t m; + assert(sizeof(uint16_t) == 2); + m = value; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&m); + return ( + TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m)); } -static int -TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value) +static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint16_t *value) { - assert(count<0x80000000); - assert(sizeof(uint16)==2); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value)); + assert(count < 0x80000000); + assert(sizeof(uint16_t) == 2); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count, + count * 2, value)); } -#ifdef notdef -static int -TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value) +static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int16_t *value) { - int16 m; - assert(sizeof(int16)==2); - m=value; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16*)(&m)); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m)); -} -#endif - -static int -TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value) -{ - assert(count<0x80000000); - assert(sizeof(int16)==2); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort((uint16*)value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value)); + assert(count < 0x80000000); + assert(sizeof(int16_t) == 2); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort((uint16_t *)value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count, + count * 2, value)); } -static int -TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value) { - uint32 m; - assert(sizeof(uint32)==4); - m=value; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&m); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m)); + uint32_t m; + assert(sizeof(uint32_t) == 4); + m = value; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + return ( + TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m)); } -static int -TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint32_t *value) { - assert(count<0x40000000); - assert(sizeof(uint32)==4); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value)); + assert(count < 0x40000000); + assert(sizeof(uint32_t) == 4); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count, + count * 4, value)); } -#ifdef notdef -static int -TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value) +static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int32_t *value) { - int32 m; - assert(sizeof(int32)==4); - m=value; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32*)(&m)); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m)); -} -#endif - -static int -TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value) -{ - assert(count<0x40000000); - assert(sizeof(int32)==4); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32*)value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value)); + assert(count < 0x40000000); + assert(sizeof(int32_t) == 4); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count, + count * 4, value)); } -#ifdef notdef -static int -TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value) +static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint64_t *value) { - uint64 m; - assert(sizeof(uint64)==8); - if( !(tif->tif_flags&TIFF_BIGTIFF) ) { - TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8","LONG8 not allowed for ClassicTIFF"); - return(0); - } - m=value; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(&m); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m)); -} -#endif - -static int -TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) -{ - assert(count<0x20000000); - assert(sizeof(uint64)==8); - if( !(tif->tif_flags&TIFF_BIGTIFF) ) { - TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8Array","LONG8 not allowed for ClassicTIFF"); - return(0); - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value)); + assert(count < 0x20000000); + assert(sizeof(uint64_t) == 8); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array", + "LONG8 not allowed for ClassicTIFF"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count, + count * 8, value)); } -#ifdef notdef -static int -TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value) +static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int64_t *value) { - int64 m; - assert(sizeof(int64)==8); - if( !(tif->tif_flags&TIFF_BIGTIFF) ) { - TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8","SLONG8 not allowed for ClassicTIFF"); - return(0); - } - m=value; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64*)(&m)); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m)); -} -#endif - -static int -TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value) -{ - assert(count<0x20000000); - assert(sizeof(int64)==8); - if( !(tif->tif_flags&TIFF_BIGTIFF) ) { - TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8Array","SLONG8 not allowed for ClassicTIFF"); - return(0); - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64*)value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value)); + assert(count < 0x20000000); + assert(sizeof(int64_t) == 8); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array", + "SLONG8 not allowed for ClassicTIFF"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64_t *)value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count, + count * 8, value)); } -static int -TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + double value) { - static const char module[] = "TIFFWriteDirectoryTagCheckedRational"; - uint32 m[2]; - assert(sizeof(uint32)==4); - if (value < 0) - { - TIFFErrorExt(tif->tif_clientdata, module, "Negative value is illegal"); - return 0; - } - else if (value != value) - { - TIFFErrorExt(tif->tif_clientdata, module, "Not-a-number value is illegal"); - return 0; - } -#ifdef not_def - else if (value==0.0) - { - m[0]=0; - m[1]=1; - } - else if (value <= 0xFFFFFFFFU && value==(double)(uint32)value) - { - m[0]=(uint32)value; - m[1]=1; - } - else if (value<1.0) - { - m[0]=(uint32)(value*0xFFFFFFFF); - m[1]=0xFFFFFFFF; - } - else - { - m[0]=0xFFFFFFFF; - m[1]=(uint32)(0xFFFFFFFF/value); - } -#else - /*--Rational2Double: New function also used for non-custom rational tags. - * However, could be omitted here, because TIFFWriteDirectoryTagCheckedRational() is not used by code for custom tags, - * only by code for named-tiff-tags like FIELD_RESOLUTION and FIELD_POSITION */ - else { - DoubleToRational(value, &m[0], &m[1]); - } -#endif + static const char module[] = "TIFFWriteDirectoryTagCheckedRational"; + uint32_t m[2]; + assert(sizeof(uint32_t) == 4); + if (value < 0) + { + TIFFErrorExtR(tif, module, "Negative value is illegal"); + return 0; + } + else if (value != value) + { + TIFFErrorExtR(tif, module, "Not-a-number value is illegal"); + return 0; + } + /*--Rational2Double: New function also used for non-custom rational tags. + * However, could be omitted here, because + * TIFFWriteDirectoryTagCheckedRational() is not used by code for custom + * tags, only by code for named-tiff-tags like FIELD_RESOLUTION and + * FIELD_POSITION */ + else + { + DoubleToRational(value, &m[0], &m[1]); + } - if (tif->tif_flags&TIFF_SWAB) - { - TIFFSwabLong(&m[0]); - TIFFSwabLong(&m[1]); - } - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0])); + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabLong(&m[0]); + TIFFSwabLong(&m[1]); + } + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8, + &m[0])); } -static int -TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + float *value) { - static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray"; - uint32* m; - float* na; - uint32* nb; - uint32 nc; - int o; - assert(sizeof(uint32)==4); - m=_TIFFmalloc(count*2*sizeof(uint32)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=value, nb=m, nc=0; nc= 0 && *na <= (float)0xFFFFFFFFU && - *na==(float)(uint32)(*na)) - { - nb[0]=(uint32)(*na); - nb[1]=1; - } - else if (*na<1.0) - { - nb[0]=(uint32)((double)(*na)*0xFFFFFFFF); - nb[1]=0xFFFFFFFF; - } - else - { - nb[0]=0xFFFFFFFF; - nb[1]=(uint32)((double)0xFFFFFFFF/(*na)); - } -#else - /*-- Rational2Double: Also for float precision accuracy is sometimes enhanced --*/ - DoubleToRational(*na, &nb[0], &nb[1]); -#endif - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m,count*2); - o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]); - _TIFFfree(m); - return(o); + static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray"; + uint32_t *m; + float *na; + uint32_t *nb; + uint32_t nc; + int o; + assert(sizeof(uint32_t) == 4); + m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) + { + DoubleToRational(*na, &nb[0], &nb[1]); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m, count * 2); + o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count, + count * 8, &m[0]); + _TIFFfreeExt(tif, m); + return (o); } -static int -TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + float *value) { - static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray"; - int32* m; - float* na; - int32* nb; - uint32 nc; - int o; - assert(sizeof(int32)==4); - m=_TIFFmalloc(count*2*sizeof(int32)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=value, nb=m, nc=0; nc-1.0) - { - nb[0]=-(int32)((double)(-*na)*0x7FFFFFFF); - nb[1]=0x7FFFFFFF; - } - else - { - nb[0]=-0x7FFFFFFF; - nb[1]=(int32)((double)0x7FFFFFFF/(-*na)); - } - } - else - { - if (*na==(int32)(*na)) - { - nb[0]=(int32)(*na); - nb[1]=1; - } - else if (*na<1.0) - { - nb[0]=(int32)((double)(*na)*0x7FFFFFFF); - nb[1]=0x7FFFFFFF; - } - else - { - nb[0]=0x7FFFFFFF; - nb[1]=(int32)((double)0x7FFFFFFF/(*na)); - } - } -#else - /*-- Rational2Double: Also for float precision accuracy is sometimes enhanced --*/ - DoubleToSrational(*na, &nb[0], &nb[1]); -#endif - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32*)m,count*2); - o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]); - _TIFFfree(m); - return(o); + static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray"; + int32_t *m; + float *na; + int32_t *nb; + uint32_t nc; + int o; + assert(sizeof(int32_t) == 4); + m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) + { + DoubleToSrational(*na, &nb[0], &nb[1]); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)m, count * 2); + o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count, + count * 8, &m[0]); + _TIFFfreeExt(tif, m); + return (o); } /*-- Rational2Double: additional write functions for double arrays */ static int -TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, double *value) { - static const char module[] = "TIFFWriteDirectoryTagCheckedRationalDoubleArray"; - uint32* m; - double* na; - uint32* nb; - uint32 nc; - int o; - assert(sizeof(uint32)==4); - m=_TIFFmalloc(count*2*sizeof(uint32)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=value, nb=m, nc=0; nctif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m,count*2); - o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]); - _TIFFfree(m); - return(o); + static const char module[] = + "TIFFWriteDirectoryTagCheckedRationalDoubleArray"; + uint32_t *m; + double *na; + uint32_t *nb; + uint32_t nc; + int o; + assert(sizeof(uint32_t) == 4); + m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) + { + DoubleToRational(*na, &nb[0], &nb[1]); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m, count * 2); + o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count, + count * 8, &m[0]); + _TIFFfreeExt(tif, m); + return (o); } /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */ -static int -TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray( + TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count, + double *value) { - static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalDoubleArray"; - int32* m; - double* na; - int32* nb; - uint32 nc; - int o; - assert(sizeof(int32)==4); - m=_TIFFmalloc(count*2*sizeof(int32)); - if (m==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - for (na=value, nb=m, nc=0; nctif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32*)m,count*2); - o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]); - _TIFFfree(m); - return(o); + static const char module[] = + "TIFFWriteDirectoryTagCheckedSrationalDoubleArray"; + int32_t *m; + double *na; + int32_t *nb; + uint32_t nc; + int o; + assert(sizeof(int32_t) == 4); + m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) + { + DoubleToSrational(*na, &nb[0], &nb[1]); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)m, count * 2); + o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count, + count * 8, &m[0]); + _TIFFfreeExt(tif, m); + return (o); } /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */ -#if 0 -static -void DoubleToRational_direct(double value, unsigned long *num, unsigned long *denom) -{ - /*--- OLD Code for debugging and comparison ---- */ - /* code merged from TIFFWriteDirectoryTagCheckedRationalArray() and TIFFWriteDirectoryTagCheckedRational() */ - - /* First check for zero and also check for negative numbers (which are illegal for RATIONAL) - * and also check for "not-a-number". In each case just set this to zero to support also rational-arrays. - */ - if (value<=0.0 || value != value) - { - *num=0; - *denom=1; - } - else if (value <= 0xFFFFFFFFU && (value==(double)(uint32)(value))) /* check for integer values */ - { - *num=(uint32)(value); - *denom=1; - } - else if (value<1.0) - { - *num = (uint32)((value) * (double)0xFFFFFFFFU); - *denom=0xFFFFFFFFU; - } - else - { - *num=0xFFFFFFFFU; - *denom=(uint32)((double)0xFFFFFFFFU/(value)); - } -} /*-- DoubleToRational_direct() -------------- */ -#endif - -#if 0 -static -void DoubleToSrational_direct(double value, long *num, long *denom) -{ - /*--- OLD Code for debugging and comparison -- SIGNED-version ----*/ - /* code was amended from original TIFFWriteDirectoryTagCheckedSrationalArray() */ - - /* First check for zero and also check for negative numbers (which are illegal for RATIONAL) - * and also check for "not-a-number". In each case just set this to zero to support also rational-arrays. - */ - if (value<0.0) - { - if (value==(int32)(value)) - { - *num=(int32)(value); - *denom=1; - } - else if (value>-1.0) - { - *num=-(int32)((-value) * (double)0x7FFFFFFF); - *denom=0x7FFFFFFF; - } - else - { - *num=-0x7FFFFFFF; - *denom=(int32)((double)0x7FFFFFFF / (-value)); - } - } - else - { - if (value==(int32)(value)) - { - *num=(int32)(value); - *denom=1; - } - else if (value<1.0) - { - *num=(int32)((value) *(double)0x7FFFFFFF); - *denom=0x7FFFFFFF; - } - else - { - *num=0x7FFFFFFF; - *denom=(int32)((double)0x7FFFFFFF / (value)); - } - } -} /*-- DoubleToSrational_direct() --------------*/ -#endif - -//#define DOUBLE2RAT_DEBUGOUTPUT -/** ----- Rational2Double: Double To Rational Conversion ---------------------------------------------------------- -* There is a mathematical theorem to convert real numbers into a rational (integer fraction) number. -* This is called "continuous fraction" which uses the Euclidean algorithm to find the greatest common divisor (GCD). -* (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or https://en.wikipedia.org/wiki/Continued_fraction +/** ----- Rational2Double: Double To Rational Conversion +---------------------------------------------------------- +* There is a mathematical theorem to convert real numbers into a rational +(integer fraction) number. +* This is called "continuous fraction" which uses the Euclidean algorithm to +find the greatest common divisor (GCD). +* (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or +https://en.wikipedia.org/wiki/Continued_fraction * https://en.wikipedia.org/wiki/Euclidean_algorithm) * The following functions implement the -* - ToRationalEuclideanGCD() auxiliary function which mainly implements euclidean GCD -* - DoubleToRational() conversion function for un-signed rationals +* - ToRationalEuclideanGCD() auxiliary function which mainly +implements euclidean GCD +* - DoubleToRational() conversion function for un-signed +rationals * - DoubleToSrational() conversion function for signed rationals ------------------------------------------------------------------------------------------------------------------*/ @@ -2709,583 +2534,627 @@ void DoubleToSrational_direct(double value, long *num, long *denom) * Calculates the rational fractional of a double input value * using the Euclidean algorithm to find the greatest common divisor (GCD) ------------------------------------------------------------------------*/ -static -void ToRationalEuclideanGCD(double value, int blnUseSignedRange, int blnUseSmallRange, unsigned long long *ullNum, unsigned long long *ullDenom) +static void ToRationalEuclideanGCD(double value, int blnUseSignedRange, + int blnUseSmallRange, uint64_t *ullNum, + uint64_t *ullDenom) { - /* Internally, the integer variables can be bigger than the external ones, - * as long as the result will fit into the external variable size. - */ - unsigned long long val, numSum[3] = { 0, 1, 0 }, denomSum[3] = { 1, 0, 0 }; - unsigned long long aux, bigNum, bigDenom; - unsigned long long returnLimit; - int i; - unsigned long long nMax; - double fMax; - unsigned long maxDenom; - /*-- nMax and fMax defines the initial accuracy of the starting fractional, - * or better, the highest used integer numbers used within the starting fractional (bigNum/bigDenom). - * There are two approaches, which can accidentally lead to different accuracies just depending on the value. - * Therefore, blnUseSmallRange steers this behavior. - * For long long nMax = ((9223372036854775807-1)/2); for long nMax = ((2147483647-1)/2); - */ - if (blnUseSmallRange) { - nMax = (unsigned long long)((2147483647 - 1) / 2); /* for ULONG range */ - } - else { - nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */ - } - fMax = (double)nMax; + /* Internally, the integer variables can be bigger than the external ones, + * as long as the result will fit into the external variable size. + */ + uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0}; + uint64_t aux, bigNum, bigDenom; + uint64_t returnLimit; + int i; + uint64_t nMax; + double fMax; + unsigned long maxDenom; + /*-- nMax and fMax defines the initial accuracy of the starting fractional, + * or better, the highest used integer numbers used within the starting + * fractional (bigNum/bigDenom). There are two approaches, which can + * accidentally lead to different accuracies just depending on the value. + * Therefore, blnUseSmallRange steers this behavior. + * For long long nMax = ((9223372036854775807-1)/2); for long nMax = + * ((2147483647-1)/2); + */ + if (blnUseSmallRange) + { + nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */ + } + else + { + nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */ + } + fMax = (double)nMax; - /*-- For the Euclidean GCD define the denominator range, so that it stays within size of unsigned long variables. - * maxDenom should be LONG_MAX for negative values and ULONG_MAX for positive ones. - * Also the final returned value of ullNum and ullDenom is limited according to signed- or unsigned-range. - */ - if (blnUseSignedRange) { - maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/ - returnLimit = maxDenom; - } - else { - maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/ - returnLimit = maxDenom; - } + /*-- For the Euclidean GCD define the denominator range, so that it stays + * within size of unsigned long variables. maxDenom should be LONG_MAX for + * negative values and ULONG_MAX for positive ones. Also the final returned + * value of ullNum and ullDenom is limited according to signed- or + * unsigned-range. + */ + if (blnUseSignedRange) + { + maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/ + returnLimit = maxDenom; + } + else + { + maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/ + returnLimit = maxDenom; + } - /*-- First generate a rational fraction (bigNum/bigDenom) which represents the value - * as a rational number with the highest accuracy. Therefore, unsigned long long (uint64) is needed. - * This rational fraction is then reduced using the Euclidean algorithm to find the greatest common divisor (GCD). - * bigNum = big numinator of value without fraction (or cut residual fraction) - * bigDenom = big denominator of value - *-- Break-criteria so that uint64 cast to "bigNum" introduces no error and bigDenom has no overflow, - * and stop with enlargement of fraction when the double-value of it reaches an integer number without fractional part. - */ - bigDenom = 1; - while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax)) { - bigDenom <<= 1; - value *= 2; - } - bigNum = (unsigned long long)value; + /*-- First generate a rational fraction (bigNum/bigDenom) which represents + *the value as a rational number with the highest accuracy. Therefore, + *uint64_t (uint64_t) is needed. This rational fraction is then reduced + *using the Euclidean algorithm to find the greatest common divisor (GCD). + * bigNum = big numinator of value without fraction (or cut residual + *fraction) bigDenom = big denominator of value + *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error + *and bigDenom has no overflow, and stop with enlargement of fraction when + *the double-value of it reaches an integer number without fractional part. + */ + bigDenom = 1; + while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax)) + { + bigDenom <<= 1; + value *= 2; + } + bigNum = (uint64_t)value; - /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) -- */ + /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) -- + */ #define MAX_ITERATIONS 64 - for (i = 0; i < MAX_ITERATIONS; i++) { - /* if bigDenom is not zero, calculate integer part of fraction. */ - if (bigDenom == 0) { - val = 0; - break; - } - else { - val = bigNum / bigDenom; - } + for (i = 0; i < MAX_ITERATIONS; i++) + { + uint64_t val; + /* if bigDenom is not zero, calculate integer part of fraction. */ + if (bigDenom == 0) + { + break; + } + val = bigNum / bigDenom; - /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous denominator bigDenom. */ - aux = bigNum; - bigNum = bigDenom; - bigDenom = aux % bigDenom; + /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous + * denominator bigDenom. */ + aux = bigNum; + bigNum = bigDenom; + bigDenom = aux % bigDenom; - /* calculate next denominator and check for its given maximum */ - aux = val; - if (denomSum[1] * val + denomSum[0] >= maxDenom) { - aux = (maxDenom - denomSum[0]) / denomSum[1]; - if (aux * 2 >= val || denomSum[1] >= maxDenom) - i = (MAX_ITERATIONS + 1); /* exit but execute rest of for-loop */ - else - break; - } - /* calculate next numerator to numSum2 and save previous one to numSum0; numSum1 just copy of numSum2. */ - numSum[2] = aux * numSum[1] + numSum[0]; - numSum[0] = numSum[1]; - numSum[1] = numSum[2]; - /* calculate next denominator to denomSum2 and save previous one to denomSum0; denomSum1 just copy of denomSum2. */ - denomSum[2] = aux * denomSum[1] + denomSum[0]; - denomSum[0] = denomSum[1]; - denomSum[1] = denomSum[2]; - } + /* calculate next denominator and check for its given maximum */ + aux = val; + if (denomSum[1] * val + denomSum[0] >= maxDenom) + { + aux = (maxDenom - denomSum[0]) / denomSum[1]; + if (aux * 2 >= val || denomSum[1] >= maxDenom) + i = (MAX_ITERATIONS + + 1); /* exit but execute rest of for-loop */ + else + break; + } + /* calculate next numerator to numSum2 and save previous one to numSum0; + * numSum1 just copy of numSum2. */ + numSum[2] = aux * numSum[1] + numSum[0]; + numSum[0] = numSum[1]; + numSum[1] = numSum[2]; + /* calculate next denominator to denomSum2 and save previous one to + * denomSum0; denomSum1 just copy of denomSum2. */ + denomSum[2] = aux * denomSum[1] + denomSum[0]; + denomSum[0] = denomSum[1]; + denomSum[1] = denomSum[2]; + } - /*-- Check and adapt for final variable size and return values; reduces internal accuracy; denominator is kept in ULONG-range with maxDenom -- */ - while (numSum[1] > returnLimit || denomSum[1] > returnLimit) { - numSum[1] = numSum[1] / 2; - denomSum[1] = denomSum[1] / 2; - } + /*-- Check and adapt for final variable size and return values; reduces + * internal accuracy; denominator is kept in ULONG-range with maxDenom -- */ + while (numSum[1] > returnLimit || denomSum[1] > returnLimit) + { + numSum[1] = numSum[1] / 2; + denomSum[1] = denomSum[1] / 2; + } - /* return values */ - *ullNum = numSum[1]; - *ullDenom = denomSum[1]; - -} /*-- ToRationalEuclideanGCD() -------------- */ + /* return values */ + *ullNum = numSum[1]; + *ullDenom = denomSum[1]; +} /*-- ToRationalEuclideanGCD() -------------- */ /**---- DoubleToRational() ----------------------------------------------- * Calculates the rational fractional of a double input value * for UN-SIGNED rationals, * using the Euclidean algorithm to find the greatest common divisor (GCD) ------------------------------------------------------------------------*/ -static -void DoubleToRational(double value, uint32 *num, uint32 *denom) +static void DoubleToRational(double value, uint32_t *num, uint32_t *denom) { - /*---- UN-SIGNED RATIONAL ---- */ - double dblDiff, dblDiff2; - unsigned long long ullNum, ullDenom, ullNum2, ullDenom2; + /*---- UN-SIGNED RATIONAL ---- */ + double dblDiff, dblDiff2; + uint64_t ullNum, ullDenom, ullNum2, ullDenom2; - /*-- Check for negative values. If so it is an error. */ - /* Test written that way to catch NaN */ - if (!(value >= 0)) { - *num = *denom = 0; - TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Negative Value for Unsigned Rational given."); - return; - } + /*-- Check for negative values. If so it is an error. */ + /* Test written that way to catch NaN */ + if (!(value >= 0)) + { + *num = *denom = 0; + TIFFErrorExt(0, "TIFFLib: DoubleToRational()", + " Negative Value for Unsigned Rational given."); + return; + } - /*-- Check for too big numbers (> ULONG_MAX) -- */ - if (value > 0xFFFFFFFFUL) { - *num = 0xFFFFFFFFU; - *denom = 0; - return; - } - /*-- Check for easy integer numbers -- */ - if (value == (uint32)(value)) { - *num = (uint32)value; - *denom = 1; - return; - } - /*-- Check for too small numbers for "unsigned long" type rationals -- */ - if (value < 1.0 / (double)0xFFFFFFFFUL) { - *num = 0; - *denom = 0xFFFFFFFFU; - return; - } + /*-- Check for too big numbers (> ULONG_MAX) -- */ + if (value > 0xFFFFFFFFUL) + { + *num = 0xFFFFFFFFU; + *denom = 0; + return; + } + /*-- Check for easy integer numbers -- */ + if (value == (uint32_t)(value)) + { + *num = (uint32_t)value; + *denom = 1; + return; + } + /*-- Check for too small numbers for "unsigned long" type rationals -- */ + if (value < 1.0 / (double)0xFFFFFFFFUL) + { + *num = 0; + *denom = 0xFFFFFFFFU; + return; + } - /*-- There are two approaches using the Euclidean algorithm, - * which can accidentally lead to different accuracies just depending on the value. - * Try both and define which one was better. - */ - ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom); - ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2); - /*-- Double-Check, that returned values fit into ULONG :*/ - if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL || ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Num or Denom exceeds ULONG: val=%14.6f, num=%I64u, denom=%I64u | num2=%I64u, denom2=%I64u", value, ullNum, ullDenom, ullNum2, ullDenom2); -#else - TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Num or Denom exceeds ULONG: val=%14.6f, num=%12llu, denom=%12llu | num2=%12llu, denom2=%12llu", value, ullNum, ullDenom, ullNum2, ullDenom2); -#endif - assert(0); - } + /*-- There are two approaches using the Euclidean algorithm, + * which can accidentally lead to different accuracies just depending on + * the value. Try both and define which one was better. + */ + ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom); + ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2); + /*-- Double-Check, that returned values fit into ULONG :*/ + if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL || + ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL) + { + TIFFErrorExt(0, "TIFFLib: DoubleToRational()", + " Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64 + ", denom=%12" PRIu64 " | num2=%12" PRIu64 + ", denom2=%12" PRIu64 "", + value, ullNum, ullDenom, ullNum2, ullDenom2); + assert(0); + } - /* Check, which one has higher accuracy and take that. */ - dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); - dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); - if (dblDiff < dblDiff2) { - *num = (uint32)ullNum; - *denom = (uint32)ullDenom; - } - else { - *num = (uint32)ullNum2; - *denom = (uint32)ullDenom2; - } -} /*-- DoubleToRational() -------------- */ + /* Check, which one has higher accuracy and take that. */ + dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); + dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); + if (dblDiff < dblDiff2) + { + *num = (uint32_t)ullNum; + *denom = (uint32_t)ullDenom; + } + else + { + *num = (uint32_t)ullNum2; + *denom = (uint32_t)ullDenom2; + } +} /*-- DoubleToRational() -------------- */ /**---- DoubleToSrational() ----------------------------------------------- * Calculates the rational fractional of a double input value * for SIGNED rationals, * using the Euclidean algorithm to find the greatest common divisor (GCD) ------------------------------------------------------------------------*/ -static -void DoubleToSrational(double value, int32 *num, int32 *denom) +static void DoubleToSrational(double value, int32_t *num, int32_t *denom) { - /*---- SIGNED RATIONAL ----*/ - int neg = 1; - double dblDiff, dblDiff2; - unsigned long long ullNum, ullDenom, ullNum2, ullDenom2; + /*---- SIGNED RATIONAL ----*/ + int neg = 1; + double dblDiff, dblDiff2; + uint64_t ullNum, ullDenom, ullNum2, ullDenom2; - /*-- Check for negative values and use then the positive one for internal calculations, but take the sign into account before returning. */ - if (value < 0) { neg = -1; value = -value; } + /*-- Check for negative values and use then the positive one for internal + * calculations, but take the sign into account before returning. */ + if (value < 0) + { + neg = -1; + value = -value; + } - /*-- Check for too big numbers (> LONG_MAX) -- */ - if (value > 0x7FFFFFFFL) { - *num = 0x7FFFFFFFL; - *denom = 0; - return; - } - /*-- Check for easy numbers -- */ - if (value == (int32)(value)) { - *num = (int32)(neg * value); - *denom = 1; - return; - } - /*-- Check for too small numbers for "long" type rationals -- */ - if (value < 1.0 / (double)0x7FFFFFFFL) { - *num = 0; - *denom = 0x7FFFFFFFL; - return; - } + /*-- Check for too big numbers (> LONG_MAX) -- */ + if (value > 0x7FFFFFFFL) + { + *num = 0x7FFFFFFFL; + *denom = 0; + return; + } + /*-- Check for easy numbers -- */ + if (value == (int32_t)(value)) + { + *num = (int32_t)(neg * value); + *denom = 1; + return; + } + /*-- Check for too small numbers for "long" type rationals -- */ + if (value < 1.0 / (double)0x7FFFFFFFL) + { + *num = 0; + *denom = 0x7FFFFFFFL; + return; + } - /*-- There are two approaches using the Euclidean algorithm, - * which can accidentally lead to different accuracies just depending on the value. - * Try both and define which one was better. - * Furthermore, set behavior of ToRationalEuclideanGCD() to the range of signed-long. - */ - ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom); - ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2); - /*-- Double-Check, that returned values fit into LONG :*/ - if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL || ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(0, "TIFFLib: DoubleToSrational()", " Num or Denom exceeds LONG: val=%14.6f, num=%I64u, denom=%I64u | num2=%I64u, denom2=%I64u", neg*value, ullNum, ullDenom, ullNum2, ullDenom2); -#else - TIFFErrorExt(0, "TIFFLib: DoubleToSrational()", " Num or Denom exceeds LONG: val=%14.6f, num=%12llu, denom=%12llu | num2=%12llu, denom2=%12llu", neg*value, ullNum, ullDenom, ullNum2, ullDenom2); -#endif - assert(0); - } + /*-- There are two approaches using the Euclidean algorithm, + * which can accidentally lead to different accuracies just depending on + * the value. Try both and define which one was better. Furthermore, set + * behavior of ToRationalEuclideanGCD() to the range of signed-long. + */ + ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom); + ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2); + /*-- Double-Check, that returned values fit into LONG :*/ + if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL || + ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL) + { + TIFFErrorExt(0, "TIFFLib: DoubleToSrational()", + " Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64 + ", denom=%12" PRIu64 " | num2=%12" PRIu64 + ", denom2=%12" PRIu64 "", + neg * value, ullNum, ullDenom, ullNum2, ullDenom2); + assert(0); + } - /* Check, which one has higher accuracy and take that. */ - dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); - dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); - if (dblDiff < dblDiff2) { - *num = (int32)(neg * (long)ullNum); - *denom = (int32)ullDenom; - } - else { - *num = (int32)(neg * (long)ullNum2); - *denom = (int32)ullDenom2; - } -} /*-- DoubleToSrational() --------------*/ + /* Check, which one has higher accuracy and take that. */ + dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); + dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); + if (dblDiff < dblDiff2) + { + *num = (int32_t)(neg * (long)ullNum); + *denom = (int32_t)ullDenom; + } + else + { + *num = (int32_t)(neg * (long)ullNum2); + *denom = (int32_t)ullDenom2; + } +} /*-- DoubleToSrational() --------------*/ - - - - -#ifdef notdef -static int -TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value) +static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + float *value) { - float m; - assert(sizeof(float)==4); - m=value; - TIFFCvtNativeToIEEEFloat(tif,1,&m); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabFloat(&m); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m)); -} -#endif - -static int -TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) -{ - assert(count<0x40000000); - assert(sizeof(float)==4); - TIFFCvtNativeToIEEEFloat(tif,count,&value); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfFloat(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value)); + assert(count < 0x40000000); + assert(sizeof(float) == 4); + TIFFCvtNativeToIEEEFloat(tif, count, &value); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfFloat(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count, + count * 4, value)); } -#ifdef notdef -static int -TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + double *value) { - double m; - assert(sizeof(double)==8); - m=value; - TIFFCvtNativeToIEEEDouble(tif,1,&m); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabDouble(&m); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m)); -} -#endif - -static int -TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) -{ - assert(count<0x20000000); - assert(sizeof(double)==8); - TIFFCvtNativeToIEEEDouble(tif,count,&value); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfDouble(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value)); + assert(count < 0x20000000); + assert(sizeof(double) == 8); + TIFFCvtNativeToIEEEDouble(tif, count, &value); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfDouble(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count, + count * 8, value)); } -static int -TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value) { - assert(count<0x40000000); - assert(sizeof(uint32)==4); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value)); + assert(count < 0x40000000); + assert(sizeof(uint32_t) == 4); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count, + count * 4, value)); } -static int -TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint64_t *value) { - assert(count<0x20000000); - assert(sizeof(uint64)==8); - assert(tif->tif_flags&TIFF_BIGTIFF); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value)); + assert(count < 0x20000000); + assert(sizeof(uint64_t) == 8); + assert(tif->tif_flags & TIFF_BIGTIFF); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count, + count * 8, value)); } -static int -TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data) +static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t datatype, uint32_t count, + uint32_t datalength, void *data) { - static const char module[] = "TIFFWriteDirectoryTagData"; - uint32 m; - m=0; - while (m<(*ndir)) - { - assert(dir[m].tdir_tag!=tag); - if (dir[m].tdir_tag>tag) - break; - m++; - } - if (m<(*ndir)) - { - uint32 n; - for (n=*ndir; n>m; n--) - dir[n]=dir[n-1]; - } - dir[m].tdir_tag=tag; - dir[m].tdir_type=datatype; - dir[m].tdir_count=count; - dir[m].tdir_offset.toff_long8 = 0; - if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U)) + static const char module[] = "TIFFWriteDirectoryTagData"; + uint32_t m; + m = 0; + while (m < (*ndir)) + { + assert(dir[m].tdir_tag != tag); + if (dir[m].tdir_tag > tag) + break; + m++; + } + if (m < (*ndir)) + { + uint32_t n; + for (n = *ndir; n > m; n--) + dir[n] = dir[n - 1]; + } + dir[m].tdir_tag = tag; + dir[m].tdir_type = datatype; + dir[m].tdir_count = count; + dir[m].tdir_offset.toff_long8 = 0; + if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U)) + { + if (data && datalength) { - if( data && datalength ) - { - _TIFFmemcpy(&dir[m].tdir_offset,data,datalength); - } + _TIFFmemcpy(&dir[m].tdir_offset, data, datalength); } - else - { - uint64 na,nb; - na=tif->tif_dataoff; - nb=na+datalength; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - nb=(uint32)nb; - if ((nbtif_clientdata,module,"Maximum TIFF file size exceeded"); - return(0); - } - if (!SeekOK(tif,na)) - { - TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); - return(0); - } - assert(datalength<0x80000000UL); - if (!WriteOK(tif,data,(tmsize_t)datalength)) - { - TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); - return(0); - } - tif->tif_dataoff=nb; - if (tif->tif_dataoff&1) - tif->tif_dataoff++; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32 o; - o=(uint32)na; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&o); - _TIFFmemcpy(&dir[m].tdir_offset,&o,4); - } - else - { - dir[m].tdir_offset.toff_long8 = na; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(&dir[m].tdir_offset.toff_long8); - } - } - (*ndir)++; - return(1); + } + else + { + uint64_t na, nb; + na = tif->tif_dataoff; + nb = na + datalength; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + nb = (uint32_t)nb; + if ((nb < na) || (nb < datalength)) + { + TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); + return (0); + } + if (!SeekOK(tif, na)) + { + TIFFErrorExtR(tif, module, "IO error writing tag data"); + return (0); + } + if (datalength >= 0x80000000UL) + { + TIFFErrorExtR(tif, module, + "libtiff does not allow writing more than 2147483647 " + "bytes in a tag"); + return (0); + } + if (!WriteOK(tif, data, (tmsize_t)datalength)) + { + TIFFErrorExtR(tif, module, "IO error writing tag data"); + return (0); + } + tif->tif_dataoff = nb; + if (tif->tif_dataoff & 1) + tif->tif_dataoff++; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t o; + o = (uint32_t)na; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&o); + _TIFFmemcpy(&dir[m].tdir_offset, &o, 4); + } + else + { + dir[m].tdir_offset.toff_long8 = na; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dir[m].tdir_offset.toff_long8); + } + } + (*ndir)++; + return (1); } /* * Link the current directory into the directory chain for the file. */ -static int -TIFFLinkDirectory(TIFF* tif) +static int TIFFLinkDirectory(TIFF *tif) { - static const char module[] = "TIFFLinkDirectory"; + static const char module[] = "TIFFLinkDirectory"; - tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) & (~((toff_t)1)); + tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1)); - /* - * Handle SubIFDs - */ - if (tif->tif_flags & TIFF_INSUBIFD) - { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32 m; - m = (uint32)tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&m); - (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); - if (!WriteOK(tif, &m, 4)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing SubIFD directory link"); - return (0); - } - /* - * Advance to the next SubIFD or, if this is - * the last one configured, revert back to the - * normal directory linkage. - */ - if (--tif->tif_nsubifd) - tif->tif_subifdoff += 4; - else - tif->tif_flags &= ~TIFF_INSUBIFD; - return (1); - } - else - { - uint64 m; - m = tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&m); - (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); - if (!WriteOK(tif, &m, 8)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing SubIFD directory link"); - return (0); - } - /* - * Advance to the next SubIFD or, if this is - * the last one configured, revert back to the - * normal directory linkage. - */ - if (--tif->tif_nsubifd) - tif->tif_subifdoff += 8; - else - tif->tif_flags &= ~TIFF_INSUBIFD; - return (1); - } - } + /* + * Handle SubIFDs + */ + if (tif->tif_flags & TIFF_INSUBIFD) + { + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t m; + m = (uint32_t)tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &m, 4)) + { + TIFFErrorExtR(tif, module, + "Error writing SubIFD directory link"); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += 4; + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); + } + else + { + uint64_t m; + m = tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&m); + (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &m, 8)) + { + TIFFErrorExtR(tif, module, + "Error writing SubIFD directory link"); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += 8; + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); + } + } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32 m; - uint32 nextdir; - m = (uint32)(tif->tif_diroff); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&m); - if (tif->tif_header.classic.tiff_diroff == 0) { - /* - * First directory, overwrite offset in header. - */ - tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff; - (void) TIFFSeekFile(tif,4, SEEK_SET); - if (!WriteOK(tif, &m, 4)) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing TIFF header"); - return (0); - } - return (1); - } - /* - * Not the first directory, search to the last and append. - */ - nextdir = tif->tif_header.classic.tiff_diroff; - while(1) { - uint16 dircount; - uint32 nextnextdir; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t m; + uint32_t nextdir; + m = (uint32_t)(tif->tif_diroff); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + if (tif->tif_header.classic.tiff_diroff == 0) + { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.classic.tiff_diroff = (uint32_t)tif->tif_diroff; + tif->tif_lastdiroff = tif->tif_diroff; + (void)TIFFSeekFile(tif, 4, SEEK_SET); + if (!WriteOK(tif, &m, 4)) + { + TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header"); + return (0); + } + return (1); + } + /* + * Not the first directory, search to the last and append. + */ + if (tif->tif_lastdiroff != 0) + { + nextdir = (uint32_t)tif->tif_lastdiroff; + } + else + { + nextdir = tif->tif_header.classic.tiff_diroff; + } - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount, 2)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - (void) TIFFSeekFile(tif, - nextdir+2+dircount*12, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 4)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextnextdir); - if (nextnextdir==0) - { - (void) TIFFSeekFile(tif, - nextdir+2+dircount*12, SEEK_SET); - if (!WriteOK(tif, &m, 4)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing directory link"); - return (0); - } - break; - } - nextdir=nextnextdir; - } - } - else - { - uint64 m; - uint64 nextdir; - m = tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&m); - if (tif->tif_header.big.tiff_diroff == 0) { - /* - * First directory, overwrite offset in header. - */ - tif->tif_header.big.tiff_diroff = tif->tif_diroff; - (void) TIFFSeekFile(tif,8, SEEK_SET); - if (!WriteOK(tif, &m, 8)) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing TIFF header"); - return (0); - } - return (1); - } - /* - * Not the first directory, search to the last and append. - */ - nextdir = tif->tif_header.big.tiff_diroff; - while(1) { - uint64 dircount64; - uint16 dircount; - uint64 nextnextdir; + while (1) + { + uint16_t dircount; + uint32_t nextnextdir; - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount64, 8)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>0xFFFF) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sanity check on tag count failed, likely corrupt TIFF"); - return (0); - } - dircount=(uint16)dircount64; - (void) TIFFSeekFile(tif, - nextdir+8+dircount*20, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 8)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&nextnextdir); - if (nextnextdir==0) - { - (void) TIFFSeekFile(tif, - nextdir+8+dircount*20, SEEK_SET); - if (!WriteOK(tif, &m, 8)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing directory link"); - return (0); - } - break; - } - nextdir=nextnextdir; - } - } - return (1); + if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2)) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 4)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextnextdir); + if (nextnextdir == 0) + { + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); + if (!WriteOK(tif, &m, 4)) + { + TIFFErrorExtR(tif, module, "Error writing directory link"); + return (0); + } + tif->tif_lastdiroff = tif->tif_diroff; + break; + } + nextdir = nextnextdir; + } + } + else + { + uint64_t m; + uint64_t nextdir; + m = tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&m); + if (tif->tif_header.big.tiff_diroff == 0) + { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.big.tiff_diroff = tif->tif_diroff; + tif->tif_lastdiroff = tif->tif_diroff; + (void)TIFFSeekFile(tif, 8, SEEK_SET); + if (!WriteOK(tif, &m, 8)) + { + TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header"); + return (0); + } + return (1); + } + /* + * Not the first directory, search to the last and append. + */ + if (tif->tif_lastdiroff != 0) + { + nextdir = tif->tif_lastdiroff; + } + else + { + nextdir = tif->tif_header.big.tiff_diroff; + } + while (1) + { + uint64_t dircount64; + uint16_t dircount; + uint64_t nextnextdir; + + if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8)) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 0xFFFF) + { + TIFFErrorExtR( + tif, module, + "Sanity check on tag count failed, likely corrupt TIFF"); + return (0); + } + dircount = (uint16_t)dircount64; + (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 8)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextnextdir); + if (nextnextdir == 0) + { + (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); + if (!WriteOK(tif, &m, 8)) + { + TIFFErrorExtR(tif, module, "Error writing directory link"); + return (0); + } + tif->tif_lastdiroff = tif->tif_diroff; + break; + } + nextdir = nextnextdir; + } + } + return (1); } /************************************************************************/ @@ -3301,183 +3170,186 @@ TIFFLinkDirectory(TIFF* tif) /* Returns zero on failure, and one on success. */ /************************************************************************/ -int -_TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype, - tmsize_t count, void* data) +int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, + tmsize_t count, void *data) { static const char module[] = "TIFFResetField"; /* const TIFFField* fip = NULL; */ - uint16 dircount; + uint16_t dircount; tmsize_t dirsize; - uint8 direntry_raw[20]; - uint16 entry_tag = 0; - uint16 entry_type = 0; - uint64 entry_count = 0; - uint64 entry_offset = 0; - int value_in_entry = 0; - uint64 read_offset; - uint8 *buf_to_write = NULL; + uint8_t direntry_raw[20]; + uint16_t entry_tag = 0; + uint16_t entry_type = 0; + uint64_t entry_count = 0; + uint64_t entry_offset = 0; + int value_in_entry = 0; + uint64_t read_offset; + uint8_t *buf_to_write = NULL; TIFFDataType datatype; -/* -------------------------------------------------------------------- */ -/* Find field definition. */ -/* -------------------------------------------------------------------- */ - /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY); + /* -------------------------------------------------------------------- */ + /* Find field definition. */ + /* -------------------------------------------------------------------- */ + /*fip =*/TIFFFindField(tif, tag, TIFF_ANY); -/* -------------------------------------------------------------------- */ -/* Do some checking this is a straight forward case. */ -/* -------------------------------------------------------------------- */ - if( isMapped(tif) ) + /* -------------------------------------------------------------------- */ + /* Do some checking this is a straight forward case. */ + /* -------------------------------------------------------------------- */ + if (isMapped(tif)) { - TIFFErrorExt( tif->tif_clientdata, module, - "Memory mapped files not currently supported for this operation." ); + TIFFErrorExtR( + tif, module, + "Memory mapped files not currently supported for this operation."); return 0; } - if( tif->tif_diroff == 0 ) + if (tif->tif_diroff == 0) { - TIFFErrorExt( tif->tif_clientdata, module, - "Attempt to reset field on directory not already on disk." ); + TIFFErrorExtR( + tif, module, + "Attempt to reset field on directory not already on disk."); return 0; } -/* -------------------------------------------------------------------- */ -/* Read the directory entry count. */ -/* -------------------------------------------------------------------- */ - if (!SeekOK(tif, tif->tif_diroff)) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); + /* -------------------------------------------------------------------- */ + /* Read the directory entry count. */ + /* -------------------------------------------------------------------- */ + if (!SeekOK(tif, tif->tif_diroff)) + { + TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory", + tif->tif_name); return 0; } read_offset = tif->tif_diroff; - if (!(tif->tif_flags&TIFF_BIGTIFF)) + if (!(tif->tif_flags & TIFF_BIGTIFF)) { - if (!ReadOK(tif, &dircount, sizeof (uint16))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory count", - tif->tif_name); + if (!ReadOK(tif, &dircount, sizeof(uint16_t))) + { + TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count", + tif->tif_name); return 0; } if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); dirsize = 12; read_offset += 2; - } else { - uint64 dircount64; - if (!ReadOK(tif, &dircount64, sizeof (uint64))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory count", - tif->tif_name); + } + else + { + uint64_t dircount64; + if (!ReadOK(tif, &dircount64, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count", + tif->tif_name); return 0; } if (tif->tif_flags & TIFF_SWAB) TIFFSwabLong8(&dircount64); - dircount = (uint16)dircount64; + dircount = (uint16_t)dircount64; dirsize = 20; read_offset += 8; } -/* -------------------------------------------------------------------- */ -/* Read through directory to find target tag. */ -/* -------------------------------------------------------------------- */ - while( dircount > 0 ) + /* -------------------------------------------------------------------- */ + /* Read through directory to find target tag. */ + /* -------------------------------------------------------------------- */ + while (dircount > 0) { - if (!ReadOK(tif, direntry_raw, dirsize)) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory entry.", - tif->tif_name); + if (!ReadOK(tif, direntry_raw, dirsize)) + { + TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.", + tif->tif_name); return 0; } - memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort( &entry_tag ); + memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&entry_tag); - if( entry_tag == tag ) + if (entry_tag == tag) break; read_offset += dirsize; } - if( entry_tag != tag ) + if (entry_tag != tag) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Could not find tag %d.", - tif->tif_name, tag ); + TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".", + tif->tif_name, tag); return 0; } -/* -------------------------------------------------------------------- */ -/* Extract the type, count and offset for this entry. */ -/* -------------------------------------------------------------------- */ - memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort( &entry_type ); + /* -------------------------------------------------------------------- */ + /* Extract the type, count and offset for this entry. */ + /* -------------------------------------------------------------------- */ + memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&entry_type); - if (!(tif->tif_flags&TIFF_BIGTIFF)) + if (!(tif->tif_flags & TIFF_BIGTIFF)) { - uint32 value; - - memcpy( &value, direntry_raw + 4, sizeof(uint32) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong( &value ); + uint32_t value; + + memcpy(&value, direntry_raw + 4, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&value); entry_count = value; - memcpy( &value, direntry_raw + 8, sizeof(uint32) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong( &value ); + memcpy(&value, direntry_raw + 8, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&value); entry_offset = value; } else { - memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8( &entry_count ); + memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&entry_count); - memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8( &entry_offset ); + memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&entry_offset); } -/* -------------------------------------------------------------------- */ -/* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */ -/* -------------------------------------------------------------------- */ - if( entry_offset == 0 && entry_count == 0 && entry_type == 0 ) + /* -------------------------------------------------------------------- */ + /* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */ + /* -------------------------------------------------------------------- */ + if (entry_offset == 0 && entry_count == 0 && entry_type == 0) { - if( tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS ) + if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) { - entry_type = (tif->tif_flags&TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG; + entry_type = + (tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG; } else { int write_aslong8 = 1; - if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS ) + if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) { write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif)); } - else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS ) + else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) { write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif)); } - if( write_aslong8 ) + if (write_aslong8) { entry_type = TIFF_LONG8; } else { int write_aslong4 = 1; - if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS ) + if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) { write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif)); } - else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS ) + else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) { write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif)); } - if( write_aslong4 ) + if (write_aslong4) { entry_type = TIFF_LONG; } @@ -3489,123 +3361,120 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype, } } -/* -------------------------------------------------------------------- */ -/* What data type do we want to write this as? */ -/* -------------------------------------------------------------------- */ - if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) ) + /* -------------------------------------------------------------------- */ + /* What data type do we want to write this as? */ + /* -------------------------------------------------------------------- */ + if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF)) { - if( in_datatype == TIFF_LONG8 ) + if (in_datatype == TIFF_LONG8) datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG; - else if( in_datatype == TIFF_SLONG8 ) + else if (in_datatype == TIFF_SLONG8) datatype = TIFF_SLONG; - else if( in_datatype == TIFF_IFD8 ) + else if (in_datatype == TIFF_IFD8) datatype = TIFF_IFD; else datatype = in_datatype; } else { - if( in_datatype == TIFF_LONG8 && + if (in_datatype == TIFF_LONG8 && (entry_type == TIFF_SHORT || entry_type == TIFF_LONG || - entry_type == TIFF_LONG8 ) ) + entry_type == TIFF_LONG8)) datatype = entry_type; - else if( in_datatype == TIFF_SLONG8 && - (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8 ) ) + else if (in_datatype == TIFF_SLONG8 && + (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8)) datatype = entry_type; - else if( in_datatype == TIFF_IFD8 && - (entry_type == TIFF_IFD || entry_type == TIFF_IFD8 ) ) + else if (in_datatype == TIFF_IFD8 && + (entry_type == TIFF_IFD || entry_type == TIFF_IFD8)) datatype = entry_type; else datatype = in_datatype; } -/* -------------------------------------------------------------------- */ -/* Prepare buffer of actual data to write. This includes */ -/* swabbing as needed. */ -/* -------------------------------------------------------------------- */ - buf_to_write = - (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype), - "for field buffer."); + /* -------------------------------------------------------------------- */ + /* Prepare buffer of actual data to write. This includes */ + /* swabbing as needed. */ + /* -------------------------------------------------------------------- */ + buf_to_write = (uint8_t *)_TIFFCheckMalloc( + tif, count, TIFFDataWidth(datatype), "for field buffer."); if (!buf_to_write) return 0; - if( datatype == in_datatype ) - memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) ); - else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 ) + if (datatype == in_datatype) + memcpy(buf_to_write, data, count * TIFFDataWidth(datatype)); + else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8) { - tmsize_t i; + tmsize_t i; - for( i = 0; i < count; i++ ) + for (i = 0; i < count; i++) { - ((int32 *) buf_to_write)[i] = - (int32) ((int64 *) data)[i]; - if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] ) + ((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i]; + if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i]) { - _TIFFfree( buf_to_write ); - TIFFErrorExt( tif->tif_clientdata, module, - "Value exceeds 32bit range of output type." ); + _TIFFfreeExt(tif, buf_to_write); + TIFFErrorExtR(tif, module, + "Value exceeds 32bit range of output type."); return 0; } } } - else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8) - || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) ) + else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) || + (datatype == TIFF_IFD && in_datatype == TIFF_IFD8)) { - tmsize_t i; + tmsize_t i; - for( i = 0; i < count; i++ ) + for (i = 0; i < count; i++) { - ((uint32 *) buf_to_write)[i] = - (uint32) ((uint64 *) data)[i]; - if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] ) + ((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i]; + if ((uint64_t)((uint32_t *)buf_to_write)[i] != + ((uint64_t *)data)[i]) { - _TIFFfree( buf_to_write ); - TIFFErrorExt( tif->tif_clientdata, module, - "Value exceeds 32bit range of output type." ); + _TIFFfreeExt(tif, buf_to_write); + TIFFErrorExtR(tif, module, + "Value exceeds 32bit range of output type."); return 0; } } } - else if( datatype == TIFF_SHORT && in_datatype == TIFF_LONG8 ) + else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8) { - tmsize_t i; + tmsize_t i; - for( i = 0; i < count; i++ ) + for (i = 0; i < count; i++) { - ((uint16 *) buf_to_write)[i] = - (uint16) ((uint64 *) data)[i]; - if( (uint64) ((uint16 *) buf_to_write)[i] != ((uint64 *) data)[i] ) + ((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i]; + if ((uint64_t)((uint16_t *)buf_to_write)[i] != + ((uint64_t *)data)[i]) { - _TIFFfree( buf_to_write ); - TIFFErrorExt( tif->tif_clientdata, module, - "Value exceeds 16bit range of output type." ); + _TIFFfreeExt(tif, buf_to_write); + TIFFErrorExtR(tif, module, + "Value exceeds 16bit range of output type."); return 0; } } } else { - TIFFErrorExt( tif->tif_clientdata, module, - "Unhandled type conversion." ); + TIFFErrorExtR(tif, module, "Unhandled type conversion."); return 0; } - if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) ) + if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB)) { - if( TIFFDataWidth(datatype) == 2 ) - TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count ); - else if( TIFFDataWidth(datatype) == 4 ) - TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count ); - else if( TIFFDataWidth(datatype) == 8 ) - TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count ); + if (TIFFDataWidth(datatype) == 2) + TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count); + else if (TIFFDataWidth(datatype) == 4) + TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count); + else if (TIFFDataWidth(datatype) == 8) + TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count); } -/* -------------------------------------------------------------------- */ -/* Is this a value that fits into the directory entry? */ -/* -------------------------------------------------------------------- */ - if (!(tif->tif_flags&TIFF_BIGTIFF)) + /* -------------------------------------------------------------------- */ + /* Is this a value that fits into the directory entry? */ + /* -------------------------------------------------------------------- */ + if (!(tif->tif_flags & TIFF_BIGTIFF)) { - if( TIFFDataWidth(datatype) * count <= 4 ) + if (TIFFDataWidth(datatype) * count <= 4) { entry_offset = read_offset + 8; value_in_entry = 1; @@ -3613,136 +3482,139 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype, } else { - if( TIFFDataWidth(datatype) * count <= 8 ) + if (TIFFDataWidth(datatype) * count <= 8) { entry_offset = read_offset + 12; value_in_entry = 1; } } - if( (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) && + if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) && tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 ) + tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0) { tif->tif_dir.td_stripoffset_entry.tdir_type = datatype; tif->tif_dir.td_stripoffset_entry.tdir_count = count; } - else if( (tag == TIFFTAG_TILEBYTECOUNTS || tag == TIFFTAG_STRIPBYTECOUNTS) && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 ) + else if ((tag == TIFFTAG_TILEBYTECOUNTS || + tag == TIFFTAG_STRIPBYTECOUNTS) && + tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) { tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype; tif->tif_dir.td_stripbytecount_entry.tdir_count = count; } -/* -------------------------------------------------------------------- */ -/* If the tag type, and count match, then we just write it out */ -/* over the old values without altering the directory entry at */ -/* all. */ -/* -------------------------------------------------------------------- */ - if( entry_count == (uint64)count && entry_type == (uint16) datatype ) + /* -------------------------------------------------------------------- */ + /* If the tag type, and count match, then we just write it out */ + /* over the old values without altering the directory entry at */ + /* all. */ + /* -------------------------------------------------------------------- */ + if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype) { - if (!SeekOK(tif, entry_offset)) { - _TIFFfree( buf_to_write ); - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); + if (!SeekOK(tif, entry_offset)) + { + _TIFFfreeExt(tif, buf_to_write); + TIFFErrorExtR(tif, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); return 0; } - if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) { - _TIFFfree( buf_to_write ); - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing directory link"); + if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype))) + { + _TIFFfreeExt(tif, buf_to_write); + TIFFErrorExtR(tif, module, "Error writing directory link"); return (0); } - _TIFFfree( buf_to_write ); + _TIFFfreeExt(tif, buf_to_write); return 1; } -/* -------------------------------------------------------------------- */ -/* Otherwise, we write the new tag data at the end of the file. */ -/* -------------------------------------------------------------------- */ - if( !value_in_entry ) + /* -------------------------------------------------------------------- */ + /* Otherwise, we write the new tag data at the end of the file. */ + /* -------------------------------------------------------------------- */ + if (!value_in_entry) { - entry_offset = TIFFSeekFile(tif,0,SEEK_END); - - if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) { - _TIFFfree( buf_to_write ); - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing directory link"); + entry_offset = TIFFSeekFile(tif, 0, SEEK_END); + + if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype))) + { + _TIFFfreeExt(tif, buf_to_write); + TIFFErrorExtR(tif, module, "Error writing directory link"); return (0); } } else { - memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype)); + if (count * TIFFDataWidth(datatype) == 4) + { + uint32_t value; + memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype)); + entry_offset = value; + } + else + { + memcpy(&entry_offset, buf_to_write, + count * TIFFDataWidth(datatype)); + } } - _TIFFfree( buf_to_write ); + _TIFFfreeExt(tif, buf_to_write); buf_to_write = 0; -/* -------------------------------------------------------------------- */ -/* Adjust the directory entry. */ -/* -------------------------------------------------------------------- */ + /* -------------------------------------------------------------------- */ + /* Adjust the directory entry. */ + /* -------------------------------------------------------------------- */ entry_type = datatype; - entry_count = (uint64)count; - memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort( (uint16 *) (direntry_raw + 2) ); + entry_count = (uint64_t)count; + memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)(direntry_raw + 2)); - if (!(tif->tif_flags&TIFF_BIGTIFF)) + if (!(tif->tif_flags & TIFF_BIGTIFF)) { - uint32 value; + uint32_t value; - value = (uint32) entry_count; - memcpy( direntry_raw + 4, &value, sizeof(uint32) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong( (uint32 *) (direntry_raw + 4) ); + value = (uint32_t)entry_count; + memcpy(direntry_raw + 4, &value, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)(direntry_raw + 4)); - value = (uint32) entry_offset; - memcpy( direntry_raw + 8, &value, sizeof(uint32) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong( (uint32 *) (direntry_raw + 8) ); + value = (uint32_t)entry_offset; + memcpy(direntry_raw + 8, &value, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)(direntry_raw + 8)); } else { - memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8( (uint64 *) (direntry_raw + 4) ); + memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)(direntry_raw + 4)); - memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8( (uint64 *) (direntry_raw + 12) ); + memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)(direntry_raw + 12)); } -/* -------------------------------------------------------------------- */ -/* Write the directory entry out to disk. */ -/* -------------------------------------------------------------------- */ - if (!SeekOK(tif, read_offset )) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); - return 0; - } - - if (!WriteOK(tif, direntry_raw,dirsize)) + /* -------------------------------------------------------------------- */ + /* Write the directory entry out to disk. */ + /* -------------------------------------------------------------------- */ + if (!SeekOK(tif, read_offset)) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not write TIFF directory entry.", - tif->tif_name); + TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory", + tif->tif_name); return 0; } - + + if (!WriteOK(tif, direntry_raw, dirsize)) + { + TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.", + tif->tif_name); + return 0; + } + return 1; } -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_dumpmode.c b/3rdparty/libtiff/tif_dumpmode.c index 4a0b07f504..267d5d2d7a 100644 --- a/3rdparty/libtiff/tif_dumpmode.c +++ b/3rdparty/libtiff/tif_dumpmode.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,113 +29,94 @@ */ #include "tiffiop.h" -static int -DumpFixupTags(TIFF* tif) +static int DumpFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } /* * Encode a hunk of pixels. */ -static int -DumpModeEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) +static int DumpModeEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) s; - while (cc > 0) { - tmsize_t n; + (void)s; + while (cc > 0) + { + tmsize_t n; - n = cc; - if (tif->tif_rawcc + n > tif->tif_rawdatasize) - n = tif->tif_rawdatasize - tif->tif_rawcc; + n = cc; + if (tif->tif_rawcc + n > tif->tif_rawdatasize) + n = tif->tif_rawdatasize - tif->tif_rawcc; - assert( n > 0 ); + assert(n > 0); - /* - * Avoid copy if client has setup raw - * data buffer to avoid extra copy. - */ - if (tif->tif_rawcp != pp) - _TIFFmemcpy(tif->tif_rawcp, pp, n); - tif->tif_rawcp += n; - tif->tif_rawcc += n; - pp += n; - cc -= n; - if (tif->tif_rawcc >= tif->tif_rawdatasize && - !TIFFFlushData1(tif)) - return (0); - } - return (1); + /* + * Avoid copy if client has setup raw + * data buffer to avoid extra copy. + */ + if (tif->tif_rawcp != pp) + _TIFFmemcpy(tif->tif_rawcp, pp, n); + tif->tif_rawcp += n; + tif->tif_rawcc += n; + pp += n; + cc -= n; + if (tif->tif_rawcc >= tif->tif_rawdatasize && !TIFFFlushData1(tif)) + return (0); + } + return (1); } /* * Decode a hunk of pixels. */ -static int -DumpModeDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - static const char module[] = "DumpModeDecode"; - (void) s; - if (tif->tif_rawcc < cc) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, -"Not enough data for scanline %lu, expected a request for at most %I64d bytes, got a request for %I64d bytes", - (unsigned long) tif->tif_row, - (signed __int64) tif->tif_rawcc, - (signed __int64) cc); -#else - TIFFErrorExt(tif->tif_clientdata, module, -"Not enough data for scanline %lu, expected a request for at most %lld bytes, got a request for %lld bytes", - (unsigned long) tif->tif_row, - (signed long long) tif->tif_rawcc, - (signed long long) cc); -#endif - return (0); - } - /* - * Avoid copy if client has setup raw - * data buffer to avoid extra copy. - */ - if (tif->tif_rawcp != buf) - _TIFFmemcpy(buf, tif->tif_rawcp, cc); - tif->tif_rawcp += cc; - tif->tif_rawcc -= cc; - return (1); + static const char module[] = "DumpModeDecode"; + (void)s; + if (tif->tif_rawcc < cc) + { + TIFFErrorExtR(tif, module, + "Not enough data for scanline %" PRIu32 + ", expected a request for at most %" TIFF_SSIZE_FORMAT + " bytes, got a request for %" TIFF_SSIZE_FORMAT " bytes", + tif->tif_row, tif->tif_rawcc, cc); + return (0); + } + /* + * Avoid copy if client has setup raw + * data buffer to avoid extra copy. + */ + if (tif->tif_rawcp != buf) + _TIFFmemcpy(buf, tif->tif_rawcp, cc); + tif->tif_rawcp += cc; + tif->tif_rawcc -= cc; + return (1); } /* * Seek forwards nrows in the current strip. */ -static int -DumpModeSeek(TIFF* tif, uint32 nrows) +static int DumpModeSeek(TIFF *tif, uint32_t nrows) { - tif->tif_rawcp += nrows * tif->tif_scanlinesize; - tif->tif_rawcc -= nrows * tif->tif_scanlinesize; - return (1); + tif->tif_rawcp += nrows * tif->tif_scanlinesize; + tif->tif_rawcc -= nrows * tif->tif_scanlinesize; + return (1); } /* * Initialize dump mode. */ -int -TIFFInitDumpMode(TIFF* tif, int scheme) +int TIFFInitDumpMode(TIFF *tif, int scheme) { - (void) scheme; - tif->tif_fixuptags = DumpFixupTags; - tif->tif_decoderow = DumpModeDecode; - tif->tif_decodestrip = DumpModeDecode; - tif->tif_decodetile = DumpModeDecode; - tif->tif_encoderow = DumpModeEncode; - tif->tif_encodestrip = DumpModeEncode; - tif->tif_encodetile = DumpModeEncode; - tif->tif_seek = DumpModeSeek; - return (1); + (void)scheme; + tif->tif_fixuptags = DumpFixupTags; + tif->tif_decoderow = DumpModeDecode; + tif->tif_decodestrip = DumpModeDecode; + tif->tif_decodetile = DumpModeDecode; + tif->tif_encoderow = DumpModeEncode; + tif->tif_encodestrip = DumpModeEncode; + tif->tif_encodetile = DumpModeEncode; + tif->tif_seek = DumpModeSeek; + return (1); } -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_error.c b/3rdparty/libtiff/tif_error.c index 651168f7dc..ac0b9c373a 100644 --- a/3rdparty/libtiff/tif_error.c +++ b/3rdparty/libtiff/tif_error.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,58 +29,104 @@ TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL; -TIFFErrorHandler -TIFFSetErrorHandler(TIFFErrorHandler handler) +TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler handler) { - TIFFErrorHandler prev = _TIFFerrorHandler; - _TIFFerrorHandler = handler; - return (prev); + TIFFErrorHandler prev = _TIFFerrorHandler; + _TIFFerrorHandler = handler; + return (prev); } -TIFFErrorHandlerExt -TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler) +TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler) { - TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt; - _TIFFerrorHandlerExt = handler; - return (prev); + TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt; + _TIFFerrorHandlerExt = handler; + return (prev); } -void -TIFFError(const char* module, const char* fmt, ...) +void TIFFError(const char *module, const char *fmt, ...) { - va_list ap; - if (_TIFFerrorHandler) { - va_start(ap, fmt); - (*_TIFFerrorHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFerrorHandlerExt) { - va_start(ap, fmt); - (*_TIFFerrorHandlerExt)(0, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (_TIFFerrorHandler) + { + va_start(ap, fmt); + (*_TIFFerrorHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFerrorHandlerExt) + { + va_start(ap, fmt); + (*_TIFFerrorHandlerExt)(0, module, fmt, ap); + va_end(ap); + } } -void -TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...) +void TIFFErrorExt(thandle_t fd, const char *module, const char *fmt, ...) { - va_list ap; - if (_TIFFerrorHandler) { - va_start(ap, fmt); - (*_TIFFerrorHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFerrorHandlerExt) { - va_start(ap, fmt); - (*_TIFFerrorHandlerExt)(fd, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (_TIFFerrorHandler) + { + va_start(ap, fmt); + (*_TIFFerrorHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFerrorHandlerExt) + { + va_start(ap, fmt); + (*_TIFFerrorHandlerExt)(fd, module, fmt, ap); + va_end(ap); + } } -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ +void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata, + const char *module, const char *fmt, ...) +{ + va_list ap; + if (opts && opts->errorhandler) + { + va_start(ap, fmt); + int stop = opts->errorhandler(NULL, opts->errorhandler_user_data, + module, fmt, ap); + va_end(ap); + if (stop) + return; + } + if (_TIFFerrorHandler) + { + va_start(ap, fmt); + (*_TIFFerrorHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFerrorHandlerExt) + { + va_start(ap, fmt); + (*_TIFFerrorHandlerExt)(clientdata, module, fmt, ap); + va_end(ap); + } +} + +void TIFFErrorExtR(TIFF *tif, const char *module, const char *fmt, ...) +{ + va_list ap; + if (tif && tif->tif_errorhandler) + { + va_start(ap, fmt); + int stop = (*tif->tif_errorhandler)( + tif, tif->tif_errorhandler_user_data, module, fmt, ap); + va_end(ap); + if (stop) + return; + } + if (_TIFFerrorHandler) + { + va_start(ap, fmt); + (*_TIFFerrorHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFerrorHandlerExt) + { + va_start(ap, fmt); + (*_TIFFerrorHandlerExt)(tif ? tif->tif_clientdata : NULL, module, fmt, + ap); + va_end(ap); + } +} diff --git a/3rdparty/libtiff/tif_extension.c b/3rdparty/libtiff/tif_extension.c index 87d3cfcbc7..1a09e987a5 100644 --- a/3rdparty/libtiff/tif_extension.c +++ b/3rdparty/libtiff/tif_extension.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -26,26 +26,26 @@ * TIFF Library. * * Various routines support external extension of the tag set, and other - * application extension capabilities. + * application extension capabilities. */ #include "tiffiop.h" -int TIFFGetTagListCount( TIFF *tif ) +int TIFFGetTagListCount(TIFF *tif) { - TIFFDirectory* td = &tif->tif_dir; - + TIFFDirectory *td = &tif->tif_dir; + return td->td_customValueCount; } -uint32 TIFFGetTagListEntry( TIFF *tif, int tag_index ) +uint32_t TIFFGetTagListEntry(TIFF *tif, int tag_index) { - TIFFDirectory* td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; - if( tag_index < 0 || tag_index >= td->td_customValueCount ) - return (uint32)(-1); + if (tag_index < 0 || tag_index >= td->td_customValueCount) + return (uint32_t)(-1); else return td->td_customValues[tag_index].info->field_tag; } @@ -55,27 +55,27 @@ uint32 TIFFGetTagListEntry( TIFF *tif, int tag_index ) ** structure to application code without giving access to the private ** TIFF structure. */ -TIFFTagMethods *TIFFAccessTagMethods( TIFF *tif ) +TIFFTagMethods *TIFFAccessTagMethods(TIFF *tif) { return &(tif->tif_tagmethods); } -void *TIFFGetClientInfo( TIFF *tif, const char *name ) +void *TIFFGetClientInfo(TIFF *tif, const char *name) { TIFFClientInfoLink *psLink = tif->tif_clientinfo; - while( psLink != NULL && strcmp(psLink->name,name) != 0 ) + while (psLink != NULL && strcmp(psLink->name, name) != 0) psLink = psLink->next; - if( psLink != NULL ) + if (psLink != NULL) return psLink->data; else return NULL; } -void TIFFSetClientInfo( TIFF *tif, void *data, const char *name ) +void TIFFSetClientInfo(TIFF *tif, void *data, const char *name) { TIFFClientInfoLink *psLink = tif->tif_clientinfo; @@ -84,10 +84,10 @@ void TIFFSetClientInfo( TIFF *tif, void *data, const char *name ) ** Do we have an existing link with this name? If so, just ** set it. */ - while( psLink != NULL && strcmp(psLink->name,name) != 0 ) + while (psLink != NULL && strcmp(psLink->name, name) != 0) psLink = psLink->next; - if( psLink != NULL ) + if (psLink != NULL) { psLink->data = data; return; @@ -97,20 +97,14 @@ void TIFFSetClientInfo( TIFF *tif, void *data, const char *name ) ** Create a new link. */ - psLink = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink)); - assert (psLink != NULL); + psLink = + (TIFFClientInfoLink *)_TIFFmallocExt(tif, sizeof(TIFFClientInfoLink)); + assert(psLink != NULL); psLink->next = tif->tif_clientinfo; - psLink->name = (char *) _TIFFmalloc((tmsize_t)(strlen(name)+1)); - assert (psLink->name != NULL); + psLink->name = (char *)_TIFFmallocExt(tif, (tmsize_t)(strlen(name) + 1)); + assert(psLink->name != NULL); strcpy(psLink->name, name); psLink->data = data; tif->tif_clientinfo = psLink; } -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_fax3.c b/3rdparty/libtiff/tif_fax3.c index 9ab5b26ad3..a3c645cb68 100644 --- a/3rdparty/libtiff/tif_fax3.c +++ b/3rdparty/libtiff/tif_fax3.c @@ -2,23 +2,23 @@ * Copyright (c) 1990-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -37,7 +37,7 @@ * Copyright (C) 1990, 1995 Frank D. Cringle. */ #include "tif_fax3.h" -#define G3CODES +#define G3CODES #include "t4.h" #include @@ -45,51 +45,57 @@ * Compression+decompression state blocks are * derived from this ``base state'' block. */ -typedef struct { - int rw_mode; /* O_RDONLY for decode, else encode */ - int mode; /* operating mode */ - tmsize_t rowbytes; /* bytes in a decoded scanline */ - uint32 rowpixels; /* pixels in a scanline */ +typedef struct +{ + int rw_mode; /* O_RDONLY for decode, else encode */ + int mode; /* operating mode */ + tmsize_t rowbytes; /* bytes in a decoded scanline */ + uint32_t rowpixels; /* pixels in a scanline */ - uint16 cleanfaxdata; /* CleanFaxData tag */ - uint32 badfaxrun; /* BadFaxRun tag */ - uint32 badfaxlines; /* BadFaxLines tag */ - uint32 groupoptions; /* Group 3/4 options tag */ + uint16_t cleanfaxdata; /* CleanFaxData tag */ + uint32_t badfaxrun; /* BadFaxRun tag */ + uint32_t badfaxlines; /* BadFaxLines tag */ + uint32_t groupoptions; /* Group 3/4 options tag */ - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ } Fax3BaseState; -#define Fax3State(tif) ((Fax3BaseState*) (tif)->tif_data) +#define Fax3State(tif) ((Fax3BaseState *)(tif)->tif_data) -typedef enum { G3_1D, G3_2D } Ttag; -typedef struct { - Fax3BaseState b; +typedef enum +{ + G3_1D, + G3_2D +} Ttag; +typedef struct +{ + Fax3BaseState b; - /* Decoder state info */ - const unsigned char* bitmap; /* bit reversal table */ - uint32 data; /* current i/o byte/word */ - int bit; /* current i/o bit in byte */ - int EOLcnt; /* count of EOL codes recognized */ - TIFFFaxFillFunc fill; /* fill routine */ - uint32* runs; /* b&w runs for current/previous row */ - uint32 nruns; /* size of the refruns / curruns arrays */ - uint32* refruns; /* runs for reference line */ - uint32* curruns; /* runs for current line */ + /* Decoder state info */ + const unsigned char *bitmap; /* bit reversal table */ + uint32_t data; /* current i/o byte/word */ + int bit; /* current i/o bit in byte */ + int EOLcnt; /* count of EOL codes recognized */ + TIFFFaxFillFunc fill; /* fill routine */ + uint32_t *runs; /* b&w runs for current/previous row */ + uint32_t nruns; /* size of the refruns / curruns arrays */ + uint32_t *refruns; /* runs for reference line */ + uint32_t *curruns; /* runs for current line */ - /* Encoder state info */ - Ttag tag; /* encoding state */ - unsigned char* refline; /* reference line for 2d decoding */ - int k; /* #rows left that can be 2d encoded */ - int maxk; /* max #rows that can be 2d encoded */ + /* Encoder state info */ + Ttag tag; /* encoding state */ + unsigned char *refline; /* reference line for 2d decoding */ + int k; /* #rows left that can be 2d encoded */ + int maxk; /* max #rows that can be 2d encoded */ - int line; + int line; } Fax3CodecState; -#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif)) -#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif)) +#define DecoderState(tif) ((Fax3CodecState *)Fax3State(tif)) +#define EncoderState(tif) ((Fax3CodecState *)Fax3State(tif)) #define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING) -#define isAligned(p,t) ((((size_t)(p)) & (sizeof (t)-1)) == 0) +#define isAligned(p, t) ((((size_t)(p)) & (sizeof(t) - 1)) == 0) /* * Group 3 and Group 4 Decoding. @@ -99,76 +105,81 @@ typedef struct { * These macros glue the TIFF library state to * the state expected by Frank's decoder. */ -#define DECLARE_STATE(tif, sp, mod) \ - static const char module[] = mod; \ - Fax3CodecState* sp = DecoderState(tif); \ - int a0; /* reference element */ \ - int lastx = sp->b.rowpixels; /* last element in row */ \ - uint32 BitAcc; /* bit accumulator */ \ - int BitsAvail; /* # valid bits in BitAcc */ \ - int RunLength; /* length of current run */ \ - unsigned char* cp; /* next byte of input data */ \ - unsigned char* ep; /* end of input data */ \ - uint32* pa; /* place to stuff next run */ \ - uint32* thisrun; /* current row's run array */ \ - int EOLcnt; /* # EOL codes recognized */ \ - const unsigned char* bitmap = sp->bitmap; /* input data bit reverser */ \ - const TIFFFaxTabEnt* TabEnt -#define DECLARE_STATE_2D(tif, sp, mod) \ - DECLARE_STATE(tif, sp, mod); \ - int b1; /* next change on prev line */ \ - uint32* pb /* next run in reference line */\ -/* - * Load any state that may be changed during decoding. - */ -#define CACHE_STATE(tif, sp) do { \ - BitAcc = sp->data; \ - BitsAvail = sp->bit; \ - EOLcnt = sp->EOLcnt; \ - cp = (unsigned char*) tif->tif_rawcp; \ - ep = cp + tif->tif_rawcc; \ -} while (0) +#define DECLARE_STATE(tif, sp, mod) \ + static const char module[] = mod; \ + Fax3CodecState *sp = DecoderState(tif); \ + int a0; /* reference element */ \ + int lastx = sp->b.rowpixels; /* last element in row */ \ + uint32_t BitAcc; /* bit accumulator */ \ + int BitsAvail; /* # valid bits in BitAcc */ \ + int RunLength; /* length of current run */ \ + unsigned char *cp; /* next byte of input data */ \ + unsigned char *ep; /* end of input data */ \ + uint32_t *pa; /* place to stuff next run */ \ + uint32_t *thisrun; /* current row's run array */ \ + int EOLcnt; /* # EOL codes recognized */ \ + const unsigned char *bitmap = sp->bitmap; /* input data bit reverser */ \ + const TIFFFaxTabEnt *TabEnt +#define DECLARE_STATE_2D(tif, sp, mod) \ + DECLARE_STATE(tif, sp, mod); \ + int b1; /* next change on prev line */ \ + uint32_t \ + *pb /* next run in reference line */ /* \ + * Load any state that may be \ + * changed during decoding. \ + */ +#define CACHE_STATE(tif, sp) \ + do \ + { \ + BitAcc = sp->data; \ + BitsAvail = sp->bit; \ + EOLcnt = sp->EOLcnt; \ + cp = (unsigned char *)tif->tif_rawcp; \ + ep = cp + tif->tif_rawcc; \ + } while (0) /* * Save state possibly changed during decoding. */ -#define UNCACHE_STATE(tif, sp) do { \ - sp->bit = BitsAvail; \ - sp->data = BitAcc; \ - sp->EOLcnt = EOLcnt; \ - tif->tif_rawcc -= (tmsize_t)((uint8*) cp - tif->tif_rawcp); \ - tif->tif_rawcp = (uint8*) cp; \ -} while (0) +#define UNCACHE_STATE(tif, sp) \ + do \ + { \ + sp->bit = BitsAvail; \ + sp->data = BitAcc; \ + sp->EOLcnt = EOLcnt; \ + tif->tif_rawcc -= (tmsize_t)((uint8_t *)cp - tif->tif_rawcp); \ + tif->tif_rawcp = (uint8_t *)cp; \ + } while (0) /* * Setup state for decoding a strip. */ -static int -Fax3PreDecode(TIFF* tif, uint16 s) +static int Fax3PreDecode(TIFF *tif, uint16_t s) { - Fax3CodecState* sp = DecoderState(tif); + Fax3CodecState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); - sp->bit = 0; /* force initial read */ - sp->data = 0; - sp->EOLcnt = 0; /* force initial scan for EOL */ - /* - * Decoder assumes lsb-to-msb bit order. Note that we select - * this here rather than in Fax3SetupState so that viewers can - * hold the image open, fiddle with the FillOrder tag value, - * and then re-decode the image. Otherwise they'd need to close - * and open the image to get the state reset. - */ - sp->bitmap = - TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB); - sp->curruns = sp->runs; - if (sp->refruns) { /* init reference line to white */ - sp->refruns = sp->runs + sp->nruns; - sp->refruns[0] = (uint32) sp->b.rowpixels; - sp->refruns[1] = 0; - } - sp->line = 0; - return (1); + (void)s; + assert(sp != NULL); + sp->bit = 0; /* force initial read */ + sp->data = 0; + sp->EOLcnt = 0; /* force initial scan for EOL */ + /* + * Decoder assumes lsb-to-msb bit order. Note that we select + * this here rather than in Fax3SetupState so that viewers can + * hold the image open, fiddle with the FillOrder tag value, + * and then re-decode the image. Otherwise they'd need to close + * and open the image to get the state reset. + */ + sp->bitmap = + TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB); + sp->curruns = sp->runs; + if (sp->refruns) + { /* init reference line to white */ + sp->refruns = sp->runs + sp->nruns; + sp->refruns[0] = (uint32_t)sp->b.rowpixels; + sp->refruns[1] = 0; + } + sp->line = 0; + return (1); } /* @@ -177,49 +188,53 @@ Fax3PreDecode(TIFF* tif, uint16 s) * overriding the definitions used by the decoder. */ -static void -Fax3Unexpected(const char* module, TIFF* tif, uint32 line, uint32 a0) +static void Fax3Unexpected(const char *module, TIFF *tif, uint32_t line, + uint32_t a0) { - TIFFErrorExt(tif->tif_clientdata, module, "Bad code word at line %u of %s %u (x %u)", - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0); + TIFFErrorExtR(tif, module, + "Bad code word at line %" PRIu32 " of %s %" PRIu32 + " (x %" PRIu32 ")", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0); } -#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0) +#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0) -static void -Fax3Extension(const char* module, TIFF* tif, uint32 line, uint32 a0) +static void Fax3Extension(const char *module, TIFF *tif, uint32_t line, + uint32_t a0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Uncompressed data (not supported) at line %u of %s %u (x %u)", - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0); + TIFFErrorExtR(tif, module, + "Uncompressed data (not supported) at line %" PRIu32 + " of %s %" PRIu32 " (x %" PRIu32 ")", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0); } -#define extension(a0) Fax3Extension(module, tif, sp->line, a0) +#define extension(a0) Fax3Extension(module, tif, sp->line, a0) -static void -Fax3BadLength(const char* module, TIFF* tif, uint32 line, uint32 a0, uint32 lastx) +static void Fax3BadLength(const char *module, TIFF *tif, uint32_t line, + uint32_t a0, uint32_t lastx) { - TIFFWarningExt(tif->tif_clientdata, module, "%s at line %u of %s %u (got %u, expected %u)", - a0 < lastx ? "Premature EOL" : "Line length mismatch", - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0, lastx); + TIFFWarningExtR(tif, module, + "%s at line %" PRIu32 " of %s %" PRIu32 " (got %" PRIu32 + ", expected %" PRIu32 ")", + a0 < lastx ? "Premature EOL" : "Line length mismatch", line, + isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0, + lastx); } -#define badlength(a0,lastx) Fax3BadLength(module, tif, sp->line, a0, lastx) +#define badlength(a0, lastx) Fax3BadLength(module, tif, sp->line, a0, lastx) -static void -Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0) +static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line, + uint32_t a0) { - TIFFWarningExt(tif->tif_clientdata, module, "Premature EOF at line %u of %s %u (x %u)", - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0); + TIFFWarningExtR(tif, module, + "Premature EOF at line %" PRIu32 " of %s %" PRIu32 + " (x %" PRIu32 ")", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0); } -#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0) +#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0) -#define Nop +#define Nop /** * Decode the requested amount of G3 1D-encoded data. @@ -228,275 +243,240 @@ Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0) * @param s number of planes (ignored) * @returns 1 for success, -1 in case of error */ -static int -Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - DECLARE_STATE(tif, sp, "Fax3Decode1D"); - (void) s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - thisrun = sp->curruns; - while (occ > 0) { - a0 = 0; - RunLength = 0; - pa = thisrun; + DECLARE_STATE(tif, sp, "Fax3Decode1D"); + (void)s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + thisrun = sp->curruns; + while (occ > 0) + { + a0 = 0; + RunLength = 0; + pa = thisrun; #ifdef FAX3_DEBUG - printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %d\n", tif->tif_row); - fflush(stdout); + printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %" PRIu32 "\n", tif->tif_row); + fflush(stdout); #endif - SYNC_EOL(EOF1D); - EXPAND1D(EOF1Da); - (*sp->fill)(buf, thisrun, pa, lastx); - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOF1D: /* premature EOF */ - CLEANUP_RUNS(); - EOF1Da: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (-1); - } - UNCACHE_STATE(tif, sp); - return (1); + SYNC_EOL(EOF1D); + EXPAND1D(EOF1Da); + (*sp->fill)(buf, thisrun, pa, lastx); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOF1D: /* premature EOF */ + CLEANUP_RUNS(); + EOF1Da: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); } -#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +#define SWAP(t, a, b) \ + { \ + t x; \ + x = (a); \ + (a) = (b); \ + (b) = x; \ + } /* * Decode the requested amount of G3 2D-encoded data. */ -static int -Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - DECLARE_STATE_2D(tif, sp, "Fax3Decode2D"); - int is1D; /* current line is 1d/2d-encoded */ - (void) s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - while (occ > 0) { - a0 = 0; - RunLength = 0; - pa = thisrun = sp->curruns; + DECLARE_STATE_2D(tif, sp, "Fax3Decode2D"); + int is1D; /* current line is 1d/2d-encoded */ + (void)s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + while (occ > 0) + { + a0 = 0; + RunLength = 0; + pa = thisrun = sp->curruns; #ifdef FAX3_DEBUG - printf("\nBitAcc=%08X, BitsAvail = %d EOLcnt = %d", - BitAcc, BitsAvail, EOLcnt); + printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d EOLcnt = %d", BitAcc, + BitsAvail, EOLcnt); #endif - SYNC_EOL(EOF2D); - NeedBits8(1, EOF2D); - is1D = GetBits(1); /* 1D/2D-encoding tag bit */ - ClrBits(1); + SYNC_EOL(EOF2D); + NeedBits8(1, EOF2D); + is1D = GetBits(1); /* 1D/2D-encoding tag bit */ + ClrBits(1); #ifdef FAX3_DEBUG - printf(" %s\n-------------------- %d\n", - is1D ? "1D" : "2D", tif->tif_row); - fflush(stdout); + printf(" %s\n-------------------- %" PRIu32 "\n", is1D ? "1D" : "2D", + tif->tif_row); + fflush(stdout); #endif - pb = sp->refruns; - b1 = *pb++; - if (is1D) - EXPAND1D(EOF2Da); - else - EXPAND2D(EOF2Da); - (*sp->fill)(buf, thisrun, pa, lastx); - if (pa < thisrun + sp->nruns) { - SETVALUE(0); /* imaginary change for reference */ - } - SWAP(uint32*, sp->curruns, sp->refruns); - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOF2D: /* premature EOF */ - CLEANUP_RUNS(); - EOF2Da: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (-1); - } - UNCACHE_STATE(tif, sp); - return (1); + pb = sp->refruns; + b1 = *pb++; + if (is1D) + EXPAND1D(EOF2Da); + else + EXPAND2D(EOF2Da); + (*sp->fill)(buf, thisrun, pa, lastx); + if (pa < thisrun + sp->nruns) + { + SETVALUE(0); /* imaginary change for reference */ + } + SWAP(uint32_t *, sp->curruns, sp->refruns); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOF2D: /* premature EOF */ + CLEANUP_RUNS(); + EOF2Da: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); } #undef SWAP -/* - * The ZERO & FILL macros must handle spans < 2*sizeof(long) bytes. - * For machines with 64-bit longs this is <16 bytes; otherwise - * this is <8 bytes. We optimize the code here to reflect the - * machine characteristics. - */ -#if SIZEOF_UNSIGNED_LONG == 8 -# define FILL(n, cp) \ - switch (n) { \ - case 15:(cp)[14] = 0xff; /*-fallthrough*/ \ - case 14:(cp)[13] = 0xff; /*-fallthrough*/ \ - case 13:(cp)[12] = 0xff; /*-fallthrough*/ \ - case 12:(cp)[11] = 0xff; /*-fallthrough*/ \ - case 11:(cp)[10] = 0xff; /*-fallthrough*/ \ - case 10: (cp)[9] = 0xff; /*-fallthrough*/ \ - case 9: (cp)[8] = 0xff; /*-fallthrough*/ \ - case 8: (cp)[7] = 0xff; /*-fallthrough*/ \ - case 7: (cp)[6] = 0xff; /*-fallthrough*/ \ - case 6: (cp)[5] = 0xff; /*-fallthrough*/ \ - case 5: (cp)[4] = 0xff; /*-fallthrough*/ \ - case 4: (cp)[3] = 0xff; /*-fallthrough*/ \ - case 3: (cp)[2] = 0xff; /*-fallthrough*/ \ - case 2: (cp)[1] = 0xff; /*-fallthrough*/ \ - case 1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \ - case 0: ; \ - } -# define ZERO(n, cp) \ - switch (n) { \ - case 15:(cp)[14] = 0; /*-fallthrough*/ \ - case 14:(cp)[13] = 0; /*-fallthrough*/ \ - case 13:(cp)[12] = 0; /*-fallthrough*/ \ - case 12:(cp)[11] = 0; /*-fallthrough*/ \ - case 11:(cp)[10] = 0; /*-fallthrough*/ \ - case 10: (cp)[9] = 0; /*-fallthrough*/ \ - case 9: (cp)[8] = 0; /*-fallthrough*/ \ - case 8: (cp)[7] = 0; /*-fallthrough*/ \ - case 7: (cp)[6] = 0; /*-fallthrough*/ \ - case 6: (cp)[5] = 0; /*-fallthrough*/ \ - case 5: (cp)[4] = 0; /*-fallthrough*/ \ - case 4: (cp)[3] = 0; /*-fallthrough*/ \ - case 3: (cp)[2] = 0; /*-fallthrough*/ \ - case 2: (cp)[1] = 0; /*-fallthrough*/ \ - case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \ - case 0: ; \ - } -#else -# define FILL(n, cp) \ - switch (n) { \ - case 7: (cp)[6] = 0xff; /*-fallthrough*/ \ - case 6: (cp)[5] = 0xff; /*-fallthrough*/ \ - case 5: (cp)[4] = 0xff; /*-fallthrough*/ \ - case 4: (cp)[3] = 0xff; /*-fallthrough*/ \ - case 3: (cp)[2] = 0xff; /*-fallthrough*/ \ - case 2: (cp)[1] = 0xff; /*-fallthrough*/ \ - case 1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \ - case 0: ; \ - } -# define ZERO(n, cp) \ - switch (n) { \ - case 7: (cp)[6] = 0; /*-fallthrough*/ \ - case 6: (cp)[5] = 0; /*-fallthrough*/ \ - case 5: (cp)[4] = 0; /*-fallthrough*/ \ - case 4: (cp)[3] = 0; /*-fallthrough*/ \ - case 3: (cp)[2] = 0; /*-fallthrough*/ \ - case 2: (cp)[1] = 0; /*-fallthrough*/ \ - case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \ - case 0: ; \ - } -#endif +#define FILL(n, cp) \ + for (int32_t ifill = 0; ifill < (n); ++ifill) \ + { \ + (cp)[ifill] = 0xff; \ + } \ + (cp) += (n); + +#define ZERO(n, cp) \ + for (int32_t izero = 0; izero < (n); ++izero) \ + { \ + (cp)[izero] = 0; \ + } \ + (cp) += (n); /* * Bit-fill a row according to the white/black * runs generated during G3/G4 decoding. */ -void -_TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) +void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, + uint32_t lastx) { - static const unsigned char _fillmasks[] = - { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; - unsigned char* cp; - uint32 x, bx, run; - int32 n, nw; - long* lp; + static const unsigned char _fillmasks[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, + 0xf8, 0xfc, 0xfe, 0xff}; + unsigned char *cp; + uint32_t x, bx, run; + int32_t n, nw; + int64_t *lp; - if ((erun-runs)&1) - *erun++ = 0; - x = 0; - for (; runs < erun; runs += 2) { - run = runs[0]; - if (x+run > lastx || run > lastx ) - run = runs[0] = (uint32) (lastx - x); - if (run) { - cp = buf + (x>>3); - bx = x&7; - if (run > 8-bx) { - if (bx) { /* align to byte boundary */ - *cp++ &= 0xff << (8-bx); - run -= 8-bx; - } - if( (n = run >> 3) != 0 ) { /* multiple bytes to fill */ - if ((n/sizeof (long)) > 1) { - /* - * Align to longword boundary and fill. - */ - for (; n && !isAligned(cp, long); n--) - *cp++ = 0x00; - lp = (long*) cp; - nw = (int32)(n / sizeof (long)); - n -= nw * sizeof (long); - do { - *lp++ = 0L; - } while (--nw); - cp = (unsigned char*) lp; - } - ZERO(n, cp); - run &= 7; - } - if (run) - cp[0] &= 0xff >> run; - } else - cp[0] &= ~(_fillmasks[run]>>bx); - x += runs[0]; - } - run = runs[1]; - if (x+run > lastx || run > lastx ) - run = runs[1] = lastx - x; - if (run) { - cp = buf + (x>>3); - bx = x&7; - if (run > 8-bx) { - if (bx) { /* align to byte boundary */ - *cp++ |= 0xff >> bx; - run -= 8-bx; - } - if( (n = run>>3) != 0 ) { /* multiple bytes to fill */ - if ((n/sizeof (long)) > 1) { - /* - * Align to longword boundary and fill. - */ - for (; n && !isAligned(cp, long); n--) - *cp++ = 0xff; - lp = (long*) cp; - nw = (int32)(n / sizeof (long)); - n -= nw * sizeof (long); - do { - *lp++ = -1L; - } while (--nw); - cp = (unsigned char*) lp; - } - FILL(n, cp); - run &= 7; - } - /* Explicit 0xff masking to make icc -check=conversions happy */ - if (run) - cp[0] = (unsigned char)((cp[0] | (0xff00 >> run))&0xff); - } else - cp[0] |= _fillmasks[run]>>bx; - x += runs[1]; - } - } - assert(x == lastx); + if ((erun - runs) & 1) + *erun++ = 0; + x = 0; + for (; runs < erun; runs += 2) + { + run = runs[0]; + if (x + run > lastx || run > lastx) + run = runs[0] = (uint32_t)(lastx - x); + if (run) + { + cp = buf + (x >> 3); + bx = x & 7; + if (run > 8 - bx) + { + if (bx) + { /* align to byte boundary */ + *cp++ &= 0xff << (8 - bx); + run -= 8 - bx; + } + if ((n = run >> 3) != 0) + { /* multiple bytes to fill */ + if ((n / sizeof(int64_t)) > 1) + { + /* + * Align to int64_tword boundary and fill. + */ + for (; n && !isAligned(cp, int64_t); n--) + *cp++ = 0x00; + lp = (int64_t *)cp; + nw = (int32_t)(n / sizeof(int64_t)); + n -= nw * sizeof(int64_t); + do + { + *lp++ = 0L; + } while (--nw); + cp = (unsigned char *)lp; + } + ZERO(n, cp); + run &= 7; + } + if (run) + cp[0] &= 0xff >> run; + } + else + cp[0] &= ~(_fillmasks[run] >> bx); + x += runs[0]; + } + run = runs[1]; + if (x + run > lastx || run > lastx) + run = runs[1] = lastx - x; + if (run) + { + cp = buf + (x >> 3); + bx = x & 7; + if (run > 8 - bx) + { + if (bx) + { /* align to byte boundary */ + *cp++ |= 0xff >> bx; + run -= 8 - bx; + } + if ((n = run >> 3) != 0) + { /* multiple bytes to fill */ + if ((n / sizeof(int64_t)) > 1) + { + /* + * Align to int64_t boundary and fill. + */ + for (; n && !isAligned(cp, int64_t); n--) + *cp++ = 0xff; + lp = (int64_t *)cp; + nw = (int32_t)(n / sizeof(int64_t)); + n -= nw * sizeof(int64_t); + do + { + *lp++ = -1L; + } while (--nw); + cp = (unsigned char *)lp; + } + FILL(n, cp); + run &= 7; + } + /* Explicit 0xff masking to make icc -check=conversions happy */ + if (run) + cp[0] = (unsigned char)((cp[0] | (0xff00 >> run)) & 0xff); + } + else + cp[0] |= _fillmasks[run] >> bx; + x += runs[1]; + } + } + assert(x == lastx); } -#undef ZERO -#undef FILL +#undef ZERO +#undef FILL -static int -Fax3FixupTags(TIFF* tif) +static int Fax3FixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } /* @@ -506,175 +486,188 @@ Fax3FixupTags(TIFF* tif) * or not decoding or encoding is being done and whether * 1D- or 2D-encoded data is involved. */ -static int -Fax3SetupState(TIFF* tif) +static int Fax3SetupState(TIFF *tif) { - static const char module[] = "Fax3SetupState"; - TIFFDirectory* td = &tif->tif_dir; - Fax3BaseState* sp = Fax3State(tif); - int needsRefLine; - Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif); - tmsize_t rowbytes; - uint32 rowpixels; + static const char module[] = "Fax3SetupState"; + TIFFDirectory *td = &tif->tif_dir; + Fax3BaseState *sp = Fax3State(tif); + int needsRefLine; + Fax3CodecState *dsp = (Fax3CodecState *)Fax3State(tif); + tmsize_t rowbytes; + uint32_t rowpixels; - if (td->td_bitspersample != 1) { - TIFFErrorExt(tif->tif_clientdata, module, - "Bits/sample must be 1 for Group 3/4 encoding/decoding"); - return (0); - } - /* - * Calculate the scanline/tile widths. - */ - if (isTiled(tif)) { - rowbytes = TIFFTileRowSize(tif); - rowpixels = td->td_tilewidth; - } else { - rowbytes = TIFFScanlineSize(tif); - rowpixels = td->td_imagewidth; - } - if ((uint64)rowbytes < ((uint64)rowpixels + 7) / 8) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Inconsistent number of bytes per row : rowbytes=%lu rowpixels=%lu", - (unsigned long)(rowbytes), (unsigned long)(rowpixels)); - return (0); - } - sp->rowbytes = rowbytes; - sp->rowpixels = rowpixels; - /* - * Allocate any additional space required for decoding/encoding. - */ - needsRefLine = ( - (sp->groupoptions & GROUP3OPT_2DENCODING) || - td->td_compression == COMPRESSION_CCITTFAX4 - ); + if (td->td_bitspersample != 1) + { + TIFFErrorExtR(tif, module, + "Bits/sample must be 1 for Group 3/4 encoding/decoding"); + return (0); + } + /* + * Calculate the scanline/tile widths. + */ + if (isTiled(tif)) + { + rowbytes = TIFFTileRowSize(tif); + rowpixels = td->td_tilewidth; + } + else + { + rowbytes = TIFFScanlineSize(tif); + rowpixels = td->td_imagewidth; + } + if ((int64_t)rowbytes < ((int64_t)rowpixels + 7) / 8) + { + TIFFErrorExtR(tif, module, + "Inconsistent number of bytes per row : rowbytes=%" PRId64 + " rowpixels=%" PRIu32, + (int64_t)rowbytes, rowpixels); + return (0); + } + sp->rowbytes = rowbytes; + sp->rowpixels = rowpixels; + /* + * Allocate any additional space required for decoding/encoding. + */ + needsRefLine = ((sp->groupoptions & GROUP3OPT_2DENCODING) || + td->td_compression == COMPRESSION_CCITTFAX4); - /* - Assure that allocation computations do not overflow. - - TIFFroundup and TIFFSafeMultiply return zero on integer overflow - */ - dsp->runs=(uint32*) NULL; - dsp->nruns = TIFFroundup_32(rowpixels,32); - if (needsRefLine) { - dsp->nruns = TIFFSafeMultiply(uint32,dsp->nruns,2); - } - if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32,dsp->nruns,2) == 0)) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Row pixels integer overflow (rowpixels %u)", - rowpixels); - return (0); - } - dsp->runs = (uint32*) _TIFFCheckMalloc(tif, - TIFFSafeMultiply(uint32,dsp->nruns,2), - sizeof (uint32), - "for Group 3/4 run arrays"); - if (dsp->runs == NULL) - return (0); - memset( dsp->runs, 0, TIFFSafeMultiply(uint32,dsp->nruns,2)*sizeof(uint32)); - dsp->curruns = dsp->runs; - if (needsRefLine) - dsp->refruns = dsp->runs + dsp->nruns; - else - dsp->refruns = NULL; - if (td->td_compression == COMPRESSION_CCITTFAX3 - && is2DEncoding(dsp)) { /* NB: default is 1D routine */ - tif->tif_decoderow = Fax3Decode2D; - tif->tif_decodestrip = Fax3Decode2D; - tif->tif_decodetile = Fax3Decode2D; - } + /* + Assure that allocation computations do not overflow. - if (needsRefLine) { /* 2d encoding */ - Fax3CodecState* esp = EncoderState(tif); - /* - * 2d encoding requires a scanline - * buffer for the ``reference line''; the - * scanline against which delta encoding - * is referenced. The reference line must - * be initialized to be ``white'' (done elsewhere). - */ - esp->refline = (unsigned char*) _TIFFmalloc(rowbytes); - if (esp->refline == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, - "No space for Group 3/4 reference line"); - return (0); - } - } else /* 1d encoding */ - EncoderState(tif)->refline = NULL; + TIFFroundup and TIFFSafeMultiply return zero on integer overflow + */ + dsp->runs = (uint32_t *)NULL; + dsp->nruns = TIFFroundup_32(rowpixels + 1, 32); + if (needsRefLine) + { + dsp->nruns = TIFFSafeMultiply(uint32_t, dsp->nruns, 2); + } + if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32_t, dsp->nruns, 2) == 0)) + { + TIFFErrorExtR(tif, tif->tif_name, + "Row pixels integer overflow (rowpixels %" PRIu32 ")", + rowpixels); + return (0); + } + dsp->runs = (uint32_t *)_TIFFCheckMalloc( + tif, TIFFSafeMultiply(uint32_t, dsp->nruns, 2), sizeof(uint32_t), + "for Group 3/4 run arrays"); + if (dsp->runs == NULL) + return (0); + memset(dsp->runs, 0, + TIFFSafeMultiply(uint32_t, dsp->nruns, 2) * sizeof(uint32_t)); + dsp->curruns = dsp->runs; + if (needsRefLine) + dsp->refruns = dsp->runs + dsp->nruns; + else + dsp->refruns = NULL; + if (td->td_compression == COMPRESSION_CCITTFAX3 && is2DEncoding(dsp)) + { /* NB: default is 1D routine */ + tif->tif_decoderow = Fax3Decode2D; + tif->tif_decodestrip = Fax3Decode2D; + tif->tif_decodetile = Fax3Decode2D; + } - return (1); + if (needsRefLine) + { /* 2d encoding */ + Fax3CodecState *esp = EncoderState(tif); + /* + * 2d encoding requires a scanline + * buffer for the ``reference line''; the + * scanline against which delta encoding + * is referenced. The reference line must + * be initialized to be ``white'' (done elsewhere). + */ + esp->refline = (unsigned char *)_TIFFmallocExt(tif, rowbytes); + if (esp->refline == NULL) + { + TIFFErrorExtR(tif, module, "No space for Group 3/4 reference line"); + return (0); + } + } + else /* 1d encoding */ + EncoderState(tif)->refline = NULL; + + return (1); } /* * CCITT Group 3 FAX Encoding. */ -#define Fax3FlushBits(tif, sp) { \ - if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \ - if( !TIFFFlushData1(tif) ) \ - return 0; \ - } \ - *(tif)->tif_rawcp++ = (uint8) (sp)->data; \ - (tif)->tif_rawcc++; \ - (sp)->data = 0, (sp)->bit = 8; \ -} -#define _FlushBits(tif) { \ - if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \ - if( !TIFFFlushData1(tif) ) \ - return 0; \ - } \ - *(tif)->tif_rawcp++ = (uint8) data; \ - (tif)->tif_rawcc++; \ - data = 0, bit = 8; \ -} -static const int _msbmask[9] = - { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; -#define _PutBits(tif, bits, length) { \ - while (length > bit) { \ - data |= bits >> (length - bit); \ - length -= bit; \ - _FlushBits(tif); \ - } \ - assert( length < 9 ); \ - data |= (bits & _msbmask[length]) << (bit - length); \ - bit -= length; \ - if (bit == 0) \ - _FlushBits(tif); \ -} - +#define Fax3FlushBits(tif, sp) \ + { \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ + { \ + if (!TIFFFlushData1(tif)) \ + return 0; \ + } \ + *(tif)->tif_rawcp++ = (uint8_t)(sp)->data; \ + (tif)->tif_rawcc++; \ + (sp)->data = 0, (sp)->bit = 8; \ + } +#define _FlushBits(tif) \ + { \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ + { \ + if (!TIFFFlushData1(tif)) \ + return 0; \ + } \ + *(tif)->tif_rawcp++ = (uint8_t)data; \ + (tif)->tif_rawcc++; \ + data = 0, bit = 8; \ + } +static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, + 0x1f, 0x3f, 0x7f, 0xff}; +#define _PutBits(tif, bits, length) \ + { \ + while (length > bit) \ + { \ + data |= bits >> (length - bit); \ + length -= bit; \ + _FlushBits(tif); \ + } \ + assert(length < 9); \ + data |= (bits & _msbmask[length]) << (bit - length); \ + bit -= length; \ + if (bit == 0) \ + _FlushBits(tif); \ + } + /* * Write a variable-length bit-value to * the output stream. Values are * assumed to be at most 16 bits. */ -static int -Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length) +static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length) { - Fax3CodecState* sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; + Fax3CodecState *sp = EncoderState(tif); + unsigned int bit = sp->bit; + int data = sp->data; - _PutBits(tif, bits, length); + _PutBits(tif, bits, length); - sp->data = data; - sp->bit = bit; - return 1; + sp->data = data; + sp->bit = bit; + return 1; } /* * Write a code to the output stream. */ -#define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length) +#define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length) #ifdef FAX3_DEBUG -#define DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B") -#define DEBUG_PRINT(what,len) { \ - int t; \ - printf("%08X/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), len); \ - for (t = length-1; t >= 0; t--) \ - putchar(code & (1<= 0; t--) \ + putchar(code & (1 << t) ? '1' : '0'); \ + putchar('\n'); \ + } #endif /* @@ -683,46 +676,47 @@ Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length) * appropriate table that holds the make-up and * terminating codes is supplied. */ -static int -putspan(TIFF* tif, int32 span, const tableentry* tab) +static int putspan(TIFF *tif, int32_t span, const tableentry *tab) { - Fax3CodecState* sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; - unsigned int code, length; + Fax3CodecState *sp = EncoderState(tif); + unsigned int bit = sp->bit; + int data = sp->data; + unsigned int code, length; - while (span >= 2624) { - const tableentry* te = &tab[63 + (2560>>6)]; - code = te->code; - length = te->length; + while (span >= 2624) + { + const tableentry *te = &tab[63 + (2560 >> 6)]; + code = te->code; + length = te->length; #ifdef FAX3_DEBUG - DEBUG_PRINT("MakeUp", te->runlen); + DEBUG_PRINT("MakeUp", te->runlen); #endif - _PutBits(tif, code, length); - span -= te->runlen; - } - if (span >= 64) { - const tableentry* te = &tab[63 + (span>>6)]; - assert(te->runlen == 64*(span>>6)); - code = te->code; - length = te->length; + _PutBits(tif, code, length); + span -= te->runlen; + } + if (span >= 64) + { + const tableentry *te = &tab[63 + (span >> 6)]; + assert(te->runlen == 64 * (span >> 6)); + code = te->code; + length = te->length; #ifdef FAX3_DEBUG - DEBUG_PRINT("MakeUp", te->runlen); + DEBUG_PRINT("MakeUp", te->runlen); #endif - _PutBits(tif, code, length); - span -= te->runlen; - } - code = tab[span].code; - length = tab[span].length; + _PutBits(tif, code, length); + span -= te->runlen; + } + code = tab[span].code; + length = tab[span].length; #ifdef FAX3_DEBUG - DEBUG_PRINT(" Term", tab[span].runlen); + DEBUG_PRINT(" Term", tab[span].runlen); #endif - _PutBits(tif, code, length); + _PutBits(tif, code, length); - sp->data = data; - sp->bit = bit; + sp->data = data; + sp->bit = bit; - return 1; + return 1; } /* @@ -731,260 +725,266 @@ putspan(TIFF* tif, int32 span, const tableentry* tab) * here. We also handle writing the tag bit for the next * scanline when doing 2d encoding. */ -static int -Fax3PutEOL(TIFF* tif) +static int Fax3PutEOL(TIFF *tif) { - Fax3CodecState* sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; - unsigned int code, length, tparm; + Fax3CodecState *sp = EncoderState(tif); + unsigned int bit = sp->bit; + int data = sp->data; + unsigned int code, length, tparm; - if (sp->b.groupoptions & GROUP3OPT_FILLBITS) { - /* - * Force bit alignment so EOL will terminate on - * a byte boundary. That is, force the bit alignment - * to 16-12 = 4 before putting out the EOL code. - */ - int align = 8 - 4; - if (align != sp->bit) { - if (align > sp->bit) - align = sp->bit + (8 - align); - else - align = sp->bit - align; - tparm=align; - _PutBits(tif, 0, tparm); - } - } - code = EOL; - length = 12; - if (is2DEncoding(sp)) { - code = (code<<1) | (sp->tag == G3_1D); - length++; - } - _PutBits(tif, code, length); + if (sp->b.groupoptions & GROUP3OPT_FILLBITS) + { + /* + * Force bit alignment so EOL will terminate on + * a byte boundary. That is, force the bit alignment + * to 16-12 = 4 before putting out the EOL code. + */ + int align = 8 - 4; + if (align != sp->bit) + { + if (align > sp->bit) + align = sp->bit + (8 - align); + else + align = sp->bit - align; + tparm = align; + _PutBits(tif, 0, tparm); + } + } + code = EOL; + length = 12; + if (is2DEncoding(sp)) + { + code = (code << 1) | (sp->tag == G3_1D); + length++; + } + _PutBits(tif, code, length); - sp->data = data; - sp->bit = bit; + sp->data = data; + sp->bit = bit; - return 1; + return 1; } /* * Reset encoding state at the start of a strip. */ -static int -Fax3PreEncode(TIFF* tif, uint16 s) +static int Fax3PreEncode(TIFF *tif, uint16_t s) { - Fax3CodecState* sp = EncoderState(tif); + Fax3CodecState *sp = EncoderState(tif); - (void) s; - assert(sp != NULL); - sp->bit = 8; - sp->data = 0; - sp->tag = G3_1D; - /* - * This is necessary for Group 4; otherwise it isn't - * needed because the first scanline of each strip ends - * up being copied into the refline. - */ - if (sp->refline) - _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes); - if (is2DEncoding(sp)) { - float res = tif->tif_dir.td_yresolution; - /* - * The CCITT spec says that when doing 2d encoding, you - * should only do it on K consecutive scanlines, where K - * depends on the resolution of the image being encoded - * (2 for <= 200 lpi, 4 for > 200 lpi). Since the directory - * code initializes td_yresolution to 0, this code will - * select a K of 2 unless the YResolution tag is set - * appropriately. (Note also that we fudge a little here - * and use 150 lpi to avoid problems with units conversion.) - */ - if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER) - res *= 2.54f; /* convert to inches */ - sp->maxk = (res > 150 ? 4 : 2); - sp->k = sp->maxk-1; - } else - sp->k = sp->maxk = 0; - sp->line = 0; - return (1); + (void)s; + assert(sp != NULL); + sp->bit = 8; + sp->data = 0; + sp->tag = G3_1D; + /* + * This is necessary for Group 4; otherwise it isn't + * needed because the first scanline of each strip ends + * up being copied into the refline. + */ + if (sp->refline) + _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes); + if (is2DEncoding(sp)) + { + float res = tif->tif_dir.td_yresolution; + /* + * The CCITT spec says that when doing 2d encoding, you + * should only do it on K consecutive scanlines, where K + * depends on the resolution of the image being encoded + * (2 for <= 200 lpi, 4 for > 200 lpi). Since the directory + * code initializes td_yresolution to 0, this code will + * select a K of 2 unless the YResolution tag is set + * appropriately. (Note also that we fudge a little here + * and use 150 lpi to avoid problems with units conversion.) + */ + if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER) + res *= 2.54f; /* convert to inches */ + sp->maxk = (res > 150 ? 4 : 2); + sp->k = sp->maxk - 1; + } + else + sp->k = sp->maxk = 0; + sp->line = 0; + return (1); } static const unsigned char zeroruns[256] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */ + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */ }; static const unsigned char oneruns[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */ - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */ + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */ }; -/* - * On certain systems it pays to inline - * the routines that find pixel spans. - */ -#ifdef VAXC -static int32 find0span(unsigned char*, int32, int32); -static int32 find1span(unsigned char*, int32, int32); -#pragma inline(find0span,find1span) -#endif - /* * Find a span of ones or zeros using the supplied * table. The ``base'' of the bit string is supplied * along with the start+end bit indices. */ -inline static int32 -find0span(unsigned char* bp, int32 bs, int32 be) +static inline int32_t find0span(unsigned char *bp, int32_t bs, int32_t be) { - int32 bits = be - bs; - int32 n, span; + int32_t bits = be - bs; + int32_t n, span; - bp += bs>>3; - /* - * Check partial byte on lhs. - */ - if (bits > 0 && (n = (bs & 7)) != 0) { - span = zeroruns[(*bp << n) & 0xff]; - if (span > 8-n) /* table value too generous */ - span = 8-n; - if (span > bits) /* constrain span to bit range */ - span = bits; - if (n+span < 8) /* doesn't extend to edge of byte */ - return (span); - bits -= span; - bp++; - } else - span = 0; - if (bits >= (int32)(2 * 8 * sizeof(long))) { - long* lp; - /* - * Align to longword boundary and check longwords. - */ - while (!isAligned(bp, long)) { - if (*bp != 0x00) - return (span + zeroruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - lp = (long*) bp; - while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) { - span += 8*sizeof (long); - bits -= 8*sizeof (long); - lp++; - } - bp = (unsigned char*) lp; - } - /* - * Scan full bytes for all 0's. - */ - while (bits >= 8) { - if (*bp != 0x00) /* end of run */ - return (span + zeroruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - /* - * Check partial byte on rhs. - */ - if (bits > 0) { - n = zeroruns[*bp]; - span += (n > bits ? bits : n); - } - return (span); + bp += bs >> 3; + /* + * Check partial byte on lhs. + */ + if (bits > 0 && (n = (bs & 7)) != 0) + { + span = zeroruns[(*bp << n) & 0xff]; + if (span > 8 - n) /* table value too generous */ + span = 8 - n; + if (span > bits) /* constrain span to bit range */ + span = bits; + if (n + span < 8) /* doesn't extend to edge of byte */ + return (span); + bits -= span; + bp++; + } + else + span = 0; + if (bits >= (int32_t)(2 * 8 * sizeof(int64_t))) + { + int64_t *lp; + /* + * Align to int64_t boundary and check int64_t words. + */ + while (!isAligned(bp, int64_t)) + { + if (*bp != 0x00) + return (span + zeroruns[*bp]); + span += 8; + bits -= 8; + bp++; + } + lp = (int64_t *)bp; + while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (0 == *lp)) + { + span += 8 * sizeof(int64_t); + bits -= 8 * sizeof(int64_t); + lp++; + } + bp = (unsigned char *)lp; + } + /* + * Scan full bytes for all 0's. + */ + while (bits >= 8) + { + if (*bp != 0x00) /* end of run */ + return (span + zeroruns[*bp]); + span += 8; + bits -= 8; + bp++; + } + /* + * Check partial byte on rhs. + */ + if (bits > 0) + { + n = zeroruns[*bp]; + span += (n > bits ? bits : n); + } + return (span); } -inline static int32 -find1span(unsigned char* bp, int32 bs, int32 be) +static inline int32_t find1span(unsigned char *bp, int32_t bs, int32_t be) { - int32 bits = be - bs; - int32 n, span; + int32_t bits = be - bs; + int32_t n, span; - bp += bs>>3; - /* - * Check partial byte on lhs. - */ - if (bits > 0 && (n = (bs & 7)) != 0) { - span = oneruns[(*bp << n) & 0xff]; - if (span > 8-n) /* table value too generous */ - span = 8-n; - if (span > bits) /* constrain span to bit range */ - span = bits; - if (n+span < 8) /* doesn't extend to edge of byte */ - return (span); - bits -= span; - bp++; - } else - span = 0; - if (bits >= (int32)(2 * 8 * sizeof(long))) { - long* lp; - /* - * Align to longword boundary and check longwords. - */ - while (!isAligned(bp, long)) { - if (*bp != 0xff) - return (span + oneruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - lp = (long*) bp; - while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) { - span += 8*sizeof (long); - bits -= 8*sizeof (long); - lp++; - } - bp = (unsigned char*) lp; - } - /* - * Scan full bytes for all 1's. - */ - while (bits >= 8) { - if (*bp != 0xff) /* end of run */ - return (span + oneruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - /* - * Check partial byte on rhs. - */ - if (bits > 0) { - n = oneruns[*bp]; - span += (n > bits ? bits : n); - } - return (span); + bp += bs >> 3; + /* + * Check partial byte on lhs. + */ + if (bits > 0 && (n = (bs & 7)) != 0) + { + span = oneruns[(*bp << n) & 0xff]; + if (span > 8 - n) /* table value too generous */ + span = 8 - n; + if (span > bits) /* constrain span to bit range */ + span = bits; + if (n + span < 8) /* doesn't extend to edge of byte */ + return (span); + bits -= span; + bp++; + } + else + span = 0; + if (bits >= (int32_t)(2 * 8 * sizeof(int64_t))) + { + int64_t *lp; + /* + * Align to int64_t boundary and check int64_t words. + */ + while (!isAligned(bp, int64_t)) + { + if (*bp != 0xff) + return (span + oneruns[*bp]); + span += 8; + bits -= 8; + bp++; + } + lp = (int64_t *)bp; + while ((bits >= (int32_t)(8 * sizeof(int64_t))) && + (~((uint64_t)0) == (uint64_t)*lp)) + { + span += 8 * sizeof(int64_t); + bits -= 8 * sizeof(int64_t); + lp++; + } + bp = (unsigned char *)lp; + } + /* + * Scan full bytes for all 1's. + */ + while (bits >= 8) + { + if (*bp != 0xff) /* end of run */ + return (span + oneruns[*bp]); + span += 8; + bits -= 8; + bp++; + } + /* + * Check partial byte on rhs. + */ + if (bits > 0) + { + n = oneruns[*bp]; + span += (n > bits ? bits : n); + } + return (span); } /* @@ -993,474 +993,501 @@ find1span(unsigned char* bp, int32 bs, int32 be) * color. The end, be, is returned if no such bit * exists. */ -#define finddiff(_cp, _bs, _be, _color) \ - (_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be))) +#define finddiff(_cp, _bs, _be, _color) \ + (_bs + (_color ? find1span(_cp, _bs, _be) : find0span(_cp, _bs, _be))) /* * Like finddiff, but also check the starting bit * against the end in case start > end. */ -#define finddiff2(_cp, _bs, _be, _color) \ - (_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be) +#define finddiff2(_cp, _bs, _be, _color) \ + (_bs < _be ? finddiff(_cp, _bs, _be, _color) : _be) /* * 1d-encode a row of pixels. The encoding is * a sequence of all-white or all-black spans * of pixels encoded with Huffman codes. */ -static int -Fax3Encode1DRow(TIFF* tif, unsigned char* bp, uint32 bits) +static int Fax3Encode1DRow(TIFF *tif, unsigned char *bp, uint32_t bits) { - Fax3CodecState* sp = EncoderState(tif); - int32 span; - uint32 bs = 0; + Fax3CodecState *sp = EncoderState(tif); + int32_t span; + uint32_t bs = 0; - for (;;) { - span = find0span(bp, bs, bits); /* white span */ - if( !putspan(tif, span, TIFFFaxWhiteCodes) ) - return 0; - bs += span; - if (bs >= bits) - break; - span = find1span(bp, bs, bits); /* black span */ - if( !putspan(tif, span, TIFFFaxBlackCodes) ) - return 0; - bs += span; - if (bs >= bits) - break; - } - if (sp->b.mode & (FAXMODE_BYTEALIGN|FAXMODE_WORDALIGN)) { - if (sp->bit != 8) /* byte-align */ - Fax3FlushBits(tif, sp); - if ((sp->b.mode&FAXMODE_WORDALIGN) && - !isAligned(tif->tif_rawcp, uint16)) - Fax3FlushBits(tif, sp); - } - return (1); + for (;;) + { + span = find0span(bp, bs, bits); /* white span */ + if (!putspan(tif, span, TIFFFaxWhiteCodes)) + return 0; + bs += span; + if (bs >= bits) + break; + span = find1span(bp, bs, bits); /* black span */ + if (!putspan(tif, span, TIFFFaxBlackCodes)) + return 0; + bs += span; + if (bs >= bits) + break; + } + if (sp->b.mode & (FAXMODE_BYTEALIGN | FAXMODE_WORDALIGN)) + { + if (sp->bit != 8) /* byte-align */ + Fax3FlushBits(tif, sp); + if ((sp->b.mode & FAXMODE_WORDALIGN) && + !isAligned(tif->tif_rawcp, uint16_t)) + Fax3FlushBits(tif, sp); + } + return (1); } -static const tableentry horizcode = - { 3, 0x1, 0 }; /* 001 */ -static const tableentry passcode = - { 4, 0x1, 0 }; /* 0001 */ +static const tableentry horizcode = {3, 0x1, 0}; /* 001 */ +static const tableentry passcode = {4, 0x1, 0}; /* 0001 */ static const tableentry vcodes[7] = { - { 7, 0x03, 0 }, /* 0000 011 */ - { 6, 0x03, 0 }, /* 0000 11 */ - { 3, 0x03, 0 }, /* 011 */ - { 1, 0x1, 0 }, /* 1 */ - { 3, 0x2, 0 }, /* 010 */ - { 6, 0x02, 0 }, /* 0000 10 */ - { 7, 0x02, 0 } /* 0000 010 */ + {7, 0x03, 0}, /* 0000 011 */ + {6, 0x03, 0}, /* 0000 11 */ + {3, 0x03, 0}, /* 011 */ + {1, 0x1, 0}, /* 1 */ + {3, 0x2, 0}, /* 010 */ + {6, 0x02, 0}, /* 0000 10 */ + {7, 0x02, 0} /* 0000 010 */ }; /* * 2d-encode a row of pixels. Consult the CCITT * documentation for the algorithm. */ -static int -Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits) +static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp, + uint32_t bits) { -#define PIXEL(buf,ix) ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1) - uint32 a0 = 0; - uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0)); - uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0)); - uint32 a2, b2; +#define PIXEL(buf, ix) ((((buf)[(ix) >> 3]) >> (7 - ((ix)&7))) & 1) + uint32_t a0 = 0; + uint32_t a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0)); + uint32_t b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0)); + uint32_t a2, b2; - for (;;) { - b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1)); - if (b2 >= a1) { - /* Naive computation triggers -fsanitize=undefined,unsigned-integer-overflow */ - /* although it is correct unless the difference between both is < 31 bit */ - /* int32 d = b1 - a1; */ - int32 d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32)(b1 - a1): - (b1 < a1 && a1 - b1 <= 3U) ? -(int32)(a1 - b1) : 0x7FFFFFFF; - if (!(-3 <= d && d <= 3)) { /* horizontal mode */ - a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1)); - if( !putcode(tif, &horizcode) ) - return 0; - if (a0+a1 == 0 || PIXEL(bp, a0) == 0) { - if( !putspan(tif, a1-a0, TIFFFaxWhiteCodes) ) - return 0; - if( !putspan(tif, a2-a1, TIFFFaxBlackCodes) ) - return 0; - } else { - if( !putspan(tif, a1-a0, TIFFFaxBlackCodes) ) - return 0; - if( !putspan(tif, a2-a1, TIFFFaxWhiteCodes) ) - return 0; - } - a0 = a2; - } else { /* vertical mode */ - if( !putcode(tif, &vcodes[d+3]) ) - return 0; - a0 = a1; - } - } else { /* pass mode */ - if( !putcode(tif, &passcode) ) - return 0; - a0 = b2; - } - if (a0 >= bits) - break; - a1 = finddiff(bp, a0, bits, PIXEL(bp,a0)); - b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0)); - b1 = finddiff(rp, b1, bits, PIXEL(bp,a0)); - } - return (1); + for (;;) + { + b2 = finddiff2(rp, b1, bits, PIXEL(rp, b1)); + if (b2 >= a1) + { + /* Naive computation triggers + * -fsanitize=undefined,unsigned-integer-overflow */ + /* although it is correct unless the difference between both is < 31 + * bit */ + /* int32_t d = b1 - a1; */ + int32_t d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32_t)(b1 - a1) + : (b1 < a1 && a1 - b1 <= 3U) ? -(int32_t)(a1 - b1) + : 0x7FFFFFFF; + if (!(-3 <= d && d <= 3)) + { /* horizontal mode */ + a2 = finddiff2(bp, a1, bits, PIXEL(bp, a1)); + if (!putcode(tif, &horizcode)) + return 0; + if (a0 + a1 == 0 || PIXEL(bp, a0) == 0) + { + if (!putspan(tif, a1 - a0, TIFFFaxWhiteCodes)) + return 0; + if (!putspan(tif, a2 - a1, TIFFFaxBlackCodes)) + return 0; + } + else + { + if (!putspan(tif, a1 - a0, TIFFFaxBlackCodes)) + return 0; + if (!putspan(tif, a2 - a1, TIFFFaxWhiteCodes)) + return 0; + } + a0 = a2; + } + else + { /* vertical mode */ + if (!putcode(tif, &vcodes[d + 3])) + return 0; + a0 = a1; + } + } + else + { /* pass mode */ + if (!putcode(tif, &passcode)) + return 0; + a0 = b2; + } + if (a0 >= bits) + break; + a1 = finddiff(bp, a0, bits, PIXEL(bp, a0)); + b1 = finddiff(rp, a0, bits, !PIXEL(bp, a0)); + b1 = finddiff(rp, b1, bits, PIXEL(bp, a0)); + } + return (1); #undef PIXEL } /* * Encode a buffer of pixels. */ -static int -Fax3Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int Fax3Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "Fax3Encode"; - Fax3CodecState* sp = EncoderState(tif); - (void) s; - if (cc % sp->b.rowbytes) - { - TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written"); - return (0); - } - while (cc > 0) { - if ((sp->b.mode & FAXMODE_NOEOL) == 0) - { - if( !Fax3PutEOL(tif) ) - return 0; - } - if (is2DEncoding(sp)) { - if (sp->tag == G3_1D) { - if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) - return (0); - sp->tag = G3_2D; - } else { - if (!Fax3Encode2DRow(tif, bp, sp->refline, - sp->b.rowpixels)) - return (0); - sp->k--; - } - if (sp->k == 0) { - sp->tag = G3_1D; - sp->k = sp->maxk-1; - } else - _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); - } else { - if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) - return (0); - } - bp += sp->b.rowbytes; - cc -= sp->b.rowbytes; - } - return (1); + static const char module[] = "Fax3Encode"; + Fax3CodecState *sp = EncoderState(tif); + (void)s; + if (cc % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) + { + if ((sp->b.mode & FAXMODE_NOEOL) == 0) + { + if (!Fax3PutEOL(tif)) + return 0; + } + if (is2DEncoding(sp)) + { + if (sp->tag == G3_1D) + { + if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) + return (0); + sp->tag = G3_2D; + } + else + { + if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) + return (0); + sp->k--; + } + if (sp->k == 0) + { + sp->tag = G3_1D; + sp->k = sp->maxk - 1; + } + else + _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); + } + else + { + if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) + return (0); + } + bp += sp->b.rowbytes; + cc -= sp->b.rowbytes; + } + return (1); } -static int -Fax3PostEncode(TIFF* tif) +static int Fax3PostEncode(TIFF *tif) { - Fax3CodecState* sp = EncoderState(tif); + Fax3CodecState *sp = EncoderState(tif); - if (sp->bit != 8) - Fax3FlushBits(tif, sp); - return (1); + if (sp->bit != 8) + Fax3FlushBits(tif, sp); + return (1); } -static int -_Fax3Close(TIFF* tif) +static int _Fax3Close(TIFF *tif) { - if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) { - Fax3CodecState* sp = EncoderState(tif); - unsigned int code = EOL; - unsigned int length = 12; - int i; + if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) + { + Fax3CodecState *sp = EncoderState(tif); + unsigned int code = EOL; + unsigned int length = 12; + int i; - if (is2DEncoding(sp)) { - code = (code<<1) | (sp->tag == G3_1D); - length++; - } - for (i = 0; i < 6; i++) - Fax3PutBits(tif, code, length); - Fax3FlushBits(tif, sp); - } - return 1; + if (is2DEncoding(sp)) + { + code = (code << 1) | (sp->tag == G3_1D); + length++; + } + for (i = 0; i < 6; i++) + Fax3PutBits(tif, code, length); + Fax3FlushBits(tif, sp); + } + return 1; } -static void -Fax3Close(TIFF* tif) +static void Fax3Close(TIFF *tif) { _Fax3Close(tif); } + +static void Fax3Cleanup(TIFF *tif) { - _Fax3Close(tif); + Fax3CodecState *sp = DecoderState(tif); + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->b.vgetparent; + tif->tif_tagmethods.vsetfield = sp->b.vsetparent; + tif->tif_tagmethods.printdir = sp->b.printdir; + + if (sp->runs) + _TIFFfreeExt(tif, sp->runs); + if (sp->refline) + _TIFFfreeExt(tif, sp->refline); + + _TIFFfreeExt(tif, tif->tif_data); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); } -static void -Fax3Cleanup(TIFF* tif) -{ - Fax3CodecState* sp = DecoderState(tif); - - assert(sp != 0); +#define FIELD_BADFAXLINES (FIELD_CODEC + 0) +#define FIELD_CLEANFAXDATA (FIELD_CODEC + 1) +#define FIELD_BADFAXRUN (FIELD_CODEC + 2) - tif->tif_tagmethods.vgetfield = sp->b.vgetparent; - tif->tif_tagmethods.vsetfield = sp->b.vsetparent; - tif->tif_tagmethods.printdir = sp->b.printdir; - - if (sp->runs) - _TIFFfree(sp->runs); - if (sp->refline) - _TIFFfree(sp->refline); - - _TIFFfree(tif->tif_data); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -#define FIELD_BADFAXLINES (FIELD_CODEC+0) -#define FIELD_CLEANFAXDATA (FIELD_CODEC+1) -#define FIELD_BADFAXRUN (FIELD_CODEC+2) - -#define FIELD_OPTIONS (FIELD_CODEC+7) +#define FIELD_OPTIONS (FIELD_CODEC + 7) static const TIFFField faxFields[] = { - { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL }, - { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL }, - { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL }, - { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL }, - { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL }}; + {TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, + FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL}, + {TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL}, + {TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL}, + {TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL}, + {TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", + NULL}}; static const TIFFField fax3Fields[] = { - { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL }, + {TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL}, }; static const TIFFField fax4Fields[] = { - { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL }, + {TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL}, }; -static int -Fax3VSetField(TIFF* tif, uint32 tag, va_list ap) +static int Fax3VSetField(TIFF *tif, uint32_t tag, va_list ap) { - Fax3BaseState* sp = Fax3State(tif); - const TIFFField* fip; + Fax3BaseState *sp = Fax3State(tif); + const TIFFField *fip; - assert(sp != 0); - assert(sp->vsetparent != 0); + assert(sp != 0); + assert(sp->vsetparent != 0); - switch (tag) { - case TIFFTAG_FAXMODE: - sp->mode = (int) va_arg(ap, int); - return 1; /* NB: pseudo tag */ - case TIFFTAG_FAXFILLFUNC: - DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); - return 1; /* NB: pseudo tag */ - case TIFFTAG_GROUP3OPTIONS: - /* XXX: avoid reading options if compression mismatches. */ - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) - sp->groupoptions = (uint32) va_arg(ap, uint32); - break; - case TIFFTAG_GROUP4OPTIONS: - /* XXX: avoid reading options if compression mismatches. */ - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) - sp->groupoptions = (uint32) va_arg(ap, uint32); - break; - case TIFFTAG_BADFAXLINES: - sp->badfaxlines = (uint32) va_arg(ap, uint32); - break; - case TIFFTAG_CLEANFAXDATA: - sp->cleanfaxdata = (uint16) va_arg(ap, uint16_vap); - break; - case TIFFTAG_CONSECUTIVEBADFAXLINES: - sp->badfaxrun = (uint32) va_arg(ap, uint32); - break; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - - if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) - TIFFSetFieldBit(tif, fip->field_bit); - else - return 0; + switch (tag) + { + case TIFFTAG_FAXMODE: + sp->mode = (int)va_arg(ap, int); + return 1; /* NB: pseudo tag */ + case TIFFTAG_FAXFILLFUNC: + DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); + return 1; /* NB: pseudo tag */ + case TIFFTAG_GROUP3OPTIONS: + /* XXX: avoid reading options if compression mismatches. */ + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) + sp->groupoptions = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_GROUP4OPTIONS: + /* XXX: avoid reading options if compression mismatches. */ + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) + sp->groupoptions = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_BADFAXLINES: + sp->badfaxlines = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_CLEANFAXDATA: + sp->cleanfaxdata = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_CONSECUTIVEBADFAXLINES: + sp->badfaxrun = (uint32_t)va_arg(ap, uint32_t); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } - tif->tif_flags |= TIFF_DIRTYDIRECT; - return 1; + if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) + TIFFSetFieldBit(tif, fip->field_bit); + else + return 0; + + tif->tif_flags |= TIFF_DIRTYDIRECT; + return 1; } -static int -Fax3VGetField(TIFF* tif, uint32 tag, va_list ap) +static int Fax3VGetField(TIFF *tif, uint32_t tag, va_list ap) { - Fax3BaseState* sp = Fax3State(tif); + Fax3BaseState *sp = Fax3State(tif); - assert(sp != 0); + assert(sp != 0); - switch (tag) { - case TIFFTAG_FAXMODE: - *va_arg(ap, int*) = sp->mode; - break; - case TIFFTAG_FAXFILLFUNC: - *va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill; - break; - case TIFFTAG_GROUP3OPTIONS: - case TIFFTAG_GROUP4OPTIONS: - *va_arg(ap, uint32*) = sp->groupoptions; - break; - case TIFFTAG_BADFAXLINES: - *va_arg(ap, uint32*) = sp->badfaxlines; - break; - case TIFFTAG_CLEANFAXDATA: - *va_arg(ap, uint16*) = sp->cleanfaxdata; - break; - case TIFFTAG_CONSECUTIVEBADFAXLINES: - *va_arg(ap, uint32*) = sp->badfaxrun; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); + switch (tag) + { + case TIFFTAG_FAXMODE: + *va_arg(ap, int *) = sp->mode; + break; + case TIFFTAG_FAXFILLFUNC: + *va_arg(ap, TIFFFaxFillFunc *) = DecoderState(tif)->fill; + break; + case TIFFTAG_GROUP3OPTIONS: + case TIFFTAG_GROUP4OPTIONS: + *va_arg(ap, uint32_t *) = sp->groupoptions; + break; + case TIFFTAG_BADFAXLINES: + *va_arg(ap, uint32_t *) = sp->badfaxlines; + break; + case TIFFTAG_CLEANFAXDATA: + *va_arg(ap, uint16_t *) = sp->cleanfaxdata; + break; + case TIFFTAG_CONSECUTIVEBADFAXLINES: + *va_arg(ap, uint32_t *) = sp->badfaxrun; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); } -static void -Fax3PrintDir(TIFF* tif, FILE* fd, long flags) +static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags) { - Fax3BaseState* sp = Fax3State(tif); + Fax3BaseState *sp = Fax3State(tif); - assert(sp != 0); + assert(sp != 0); - (void) flags; - if (TIFFFieldSet(tif,FIELD_OPTIONS)) { - const char* sep = " "; - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) { - fprintf(fd, " Group 4 Options:"); - if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED) - fprintf(fd, "%suncompressed data", sep); - } else { + (void)flags; + if (TIFFFieldSet(tif, FIELD_OPTIONS)) + { + const char *sep = " "; + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) + { + fprintf(fd, " Group 4 Options:"); + if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED) + fprintf(fd, "%suncompressed data", sep); + } + else + { - fprintf(fd, " Group 3 Options:"); - if (sp->groupoptions & GROUP3OPT_2DENCODING) { - fprintf(fd, "%s2-d encoding", sep); - sep = "+"; - } - if (sp->groupoptions & GROUP3OPT_FILLBITS) { - fprintf(fd, "%sEOL padding", sep); - sep = "+"; - } - if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED) - fprintf(fd, "%suncompressed data", sep); - } - fprintf(fd, " (%lu = 0x%lx)\n", - (unsigned long) sp->groupoptions, - (unsigned long) sp->groupoptions); - } - if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) { - fprintf(fd, " Fax Data:"); - switch (sp->cleanfaxdata) { - case CLEANFAXDATA_CLEAN: - fprintf(fd, " clean"); - break; - case CLEANFAXDATA_REGENERATED: - fprintf(fd, " receiver regenerated"); - break; - case CLEANFAXDATA_UNCLEAN: - fprintf(fd, " uncorrected errors"); - break; - } - fprintf(fd, " (%u = 0x%x)\n", - sp->cleanfaxdata, sp->cleanfaxdata); - } - if (TIFFFieldSet(tif,FIELD_BADFAXLINES)) - fprintf(fd, " Bad Fax Lines: %lu\n", - (unsigned long) sp->badfaxlines); - if (TIFFFieldSet(tif,FIELD_BADFAXRUN)) - fprintf(fd, " Consecutive Bad Fax Lines: %lu\n", - (unsigned long) sp->badfaxrun); - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); + fprintf(fd, " Group 3 Options:"); + if (sp->groupoptions & GROUP3OPT_2DENCODING) + { + fprintf(fd, "%s2-d encoding", sep); + sep = "+"; + } + if (sp->groupoptions & GROUP3OPT_FILLBITS) + { + fprintf(fd, "%sEOL padding", sep); + sep = "+"; + } + if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED) + fprintf(fd, "%suncompressed data", sep); + } + fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", sp->groupoptions, + sp->groupoptions); + } + if (TIFFFieldSet(tif, FIELD_CLEANFAXDATA)) + { + fprintf(fd, " Fax Data:"); + switch (sp->cleanfaxdata) + { + case CLEANFAXDATA_CLEAN: + fprintf(fd, " clean"); + break; + case CLEANFAXDATA_REGENERATED: + fprintf(fd, " receiver regenerated"); + break; + case CLEANFAXDATA_UNCLEAN: + fprintf(fd, " uncorrected errors"); + break; + } + fprintf(fd, " (%" PRIu16 " = 0x%" PRIx16 ")\n", sp->cleanfaxdata, + sp->cleanfaxdata); + } + if (TIFFFieldSet(tif, FIELD_BADFAXLINES)) + fprintf(fd, " Bad Fax Lines: %" PRIu32 "\n", sp->badfaxlines); + if (TIFFFieldSet(tif, FIELD_BADFAXRUN)) + fprintf(fd, " Consecutive Bad Fax Lines: %" PRIu32 "\n", + sp->badfaxrun); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); } -static int -InitCCITTFax3(TIFF* tif) +static int InitCCITTFax3(TIFF *tif) { - static const char module[] = "InitCCITTFax3"; - Fax3BaseState* sp; + static const char module[] = "InitCCITTFax3"; + Fax3BaseState *sp; - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) { - TIFFErrorExt(tif->tif_clientdata, "InitCCITTFax3", - "Merging common CCITT Fax codec-specific tags failed"); - return 0; - } + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) + { + TIFFErrorExtR(tif, "InitCCITTFax3", + "Merging common CCITT Fax codec-specific tags failed"); + return 0; + } - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8*) - _TIFFmalloc(sizeof (Fax3CodecState)); + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(Fax3CodecState)); - if (tif->tif_data == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, - "No space for state block"); - return (0); - } - _TIFFmemset(tif->tif_data, 0, sizeof (Fax3CodecState)); + if (tif->tif_data == NULL) + { + TIFFErrorExtR(tif, module, "No space for state block"); + return (0); + } + _TIFFmemset(tif->tif_data, 0, sizeof(Fax3CodecState)); - sp = Fax3State(tif); - sp->rw_mode = tif->tif_mode; + sp = Fax3State(tif); + sp->rw_mode = tif->tif_mode; - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */ - sp->printdir = tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */ - sp->groupoptions = 0; + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */ + sp->printdir = tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */ + sp->groupoptions = 0; - if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */ - tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */ - DecoderState(tif)->runs = NULL; - TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns); - EncoderState(tif)->refline = NULL; + if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */ + tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */ + DecoderState(tif)->runs = NULL; + TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns); + EncoderState(tif)->refline = NULL; - /* - * Install codec methods. - */ - tif->tif_fixuptags = Fax3FixupTags; - tif->tif_setupdecode = Fax3SetupState; - tif->tif_predecode = Fax3PreDecode; - tif->tif_decoderow = Fax3Decode1D; - tif->tif_decodestrip = Fax3Decode1D; - tif->tif_decodetile = Fax3Decode1D; - tif->tif_setupencode = Fax3SetupState; - tif->tif_preencode = Fax3PreEncode; - tif->tif_postencode = Fax3PostEncode; - tif->tif_encoderow = Fax3Encode; - tif->tif_encodestrip = Fax3Encode; - tif->tif_encodetile = Fax3Encode; - tif->tif_close = Fax3Close; - tif->tif_cleanup = Fax3Cleanup; + /* + * Install codec methods. + */ + tif->tif_fixuptags = Fax3FixupTags; + tif->tif_setupdecode = Fax3SetupState; + tif->tif_predecode = Fax3PreDecode; + tif->tif_decoderow = Fax3Decode1D; + tif->tif_decodestrip = Fax3Decode1D; + tif->tif_decodetile = Fax3Decode1D; + tif->tif_setupencode = Fax3SetupState; + tif->tif_preencode = Fax3PreEncode; + tif->tif_postencode = Fax3PostEncode; + tif->tif_encoderow = Fax3Encode; + tif->tif_encodestrip = Fax3Encode; + tif->tif_encodetile = Fax3Encode; + tif->tif_close = Fax3Close; + tif->tif_cleanup = Fax3Cleanup; - return (1); + return (1); } -int -TIFFInitCCITTFax3(TIFF* tif, int scheme) +int TIFFInitCCITTFax3(TIFF *tif, int scheme) { - (void) scheme; - if (InitCCITTFax3(tif)) { - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, fax3Fields, - TIFFArrayCount(fax3Fields))) { - TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3", - "Merging CCITT Fax 3 codec-specific tags failed"); - return 0; - } + (void)scheme; + if (InitCCITTFax3(tif)) + { + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, fax3Fields, TIFFArrayCount(fax3Fields))) + { + TIFFErrorExtR(tif, "TIFFInitCCITTFax3", + "Merging CCITT Fax 3 codec-specific tags failed"); + return 0; + } - /* - * The default format is Class/F-style w/o RTC. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); - } else - return 01; + /* + * The default format is Class/F-style w/o RTC. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); + } + else + return 01; } /* @@ -1468,138 +1495,146 @@ TIFFInitCCITTFax3(TIFF* tif, int scheme) * Compression Scheme Support. */ -#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +#define SWAP(t, a, b) \ + { \ + t x; \ + x = (a); \ + (a) = (b); \ + (b) = x; \ + } /* * Decode the requested amount of G4-encoded data. */ -static int -Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - DECLARE_STATE_2D(tif, sp, "Fax4Decode"); - (void) s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - while (occ > 0) { - a0 = 0; - RunLength = 0; - pa = thisrun = sp->curruns; - pb = sp->refruns; - b1 = *pb++; + DECLARE_STATE_2D(tif, sp, "Fax4Decode"); + (void)s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + while (occ > 0) + { + a0 = 0; + RunLength = 0; + pa = thisrun = sp->curruns; + pb = sp->refruns; + b1 = *pb++; #ifdef FAX3_DEBUG - printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %d\n", tif->tif_row); - fflush(stdout); + printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", tif->tif_row); + fflush(stdout); #endif - EXPAND2D(EOFG4); - if (EOLcnt) - goto EOFG4; - if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ - { - TIFFErrorExt(tif->tif_clientdata, module, - "Buffer overrun detected : %d bytes available, %d bits needed", - (int)occ, lastx); - return -1; - } - (*sp->fill)(buf, thisrun, pa, lastx); - SETVALUE(0); /* imaginary change for reference */ - SWAP(uint32*, sp->curruns, sp->refruns); - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOFG4: - NeedBits16( 13, BADG4 ); - BADG4: + EXPAND2D(EOFG4); + if (EOLcnt) + goto EOFG4; + if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ + { + TIFFErrorExtR(tif, module, + "Buffer overrun detected : %" TIFF_SSIZE_FORMAT + " bytes available, %d bits needed", + occ, lastx); + return -1; + } + (*sp->fill)(buf, thisrun, pa, lastx); + SETVALUE(0); /* imaginary change for reference */ + SWAP(uint32_t *, sp->curruns, sp->refruns); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOFG4: + NeedBits16(13, BADG4); + BADG4: #ifdef FAX3_DEBUG - if( GetBits(13) != 0x1001 ) - fputs( "Bad EOFB\n", stderr ); -#endif - ClrBits( 13 ); - if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ - { - TIFFErrorExt(tif->tif_clientdata, module, - "Buffer overrun detected : %d bytes available, %d bits needed", - (int)occ, lastx); - return -1; - } - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return ( sp->line ? 1 : -1); /* don't error on badly-terminated strips */ - } - UNCACHE_STATE(tif, sp); - return (1); + if (GetBits(13) != 0x1001) + fputs("Bad EOFB\n", stderr); +#endif + ClrBits(13); + if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ + { + TIFFErrorExtR(tif, module, + "Buffer overrun detected : %" TIFF_SSIZE_FORMAT + " bytes available, %d bits needed", + occ, lastx); + return -1; + } + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (sp->line ? 1 : -1); /* don't error on badly-terminated strips */ + } + UNCACHE_STATE(tif, sp); + return (1); } -#undef SWAP +#undef SWAP /* * Encode the requested amount of data. */ -static int -Fax4Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int Fax4Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "Fax4Encode"; - Fax3CodecState *sp = EncoderState(tif); - (void) s; - if (cc % sp->b.rowbytes) - { - TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written"); - return (0); - } - while (cc > 0) { - if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) - return (0); - _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); - bp += sp->b.rowbytes; - cc -= sp->b.rowbytes; - } - return (1); + static const char module[] = "Fax4Encode"; + Fax3CodecState *sp = EncoderState(tif); + (void)s; + if (cc % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) + { + if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) + return (0); + _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); + bp += sp->b.rowbytes; + cc -= sp->b.rowbytes; + } + return (1); } -static int -Fax4PostEncode(TIFF* tif) +static int Fax4PostEncode(TIFF *tif) { - Fax3CodecState *sp = EncoderState(tif); + Fax3CodecState *sp = EncoderState(tif); - /* terminate strip w/ EOFB */ - Fax3PutBits(tif, EOL, 12); - Fax3PutBits(tif, EOL, 12); - if (sp->bit != 8) - Fax3FlushBits(tif, sp); - return (1); + /* terminate strip w/ EOFB */ + Fax3PutBits(tif, EOL, 12); + Fax3PutBits(tif, EOL, 12); + if (sp->bit != 8) + Fax3FlushBits(tif, sp); + return (1); } -int -TIFFInitCCITTFax4(TIFF* tif, int scheme) +int TIFFInitCCITTFax4(TIFF *tif, int scheme) { - (void) scheme; - if (InitCCITTFax3(tif)) { /* reuse G3 support */ - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, fax4Fields, - TIFFArrayCount(fax4Fields))) { - TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax4", - "Merging CCITT Fax 4 codec-specific tags failed"); - return 0; - } + (void)scheme; + if (InitCCITTFax3(tif)) + { /* reuse G3 support */ + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, fax4Fields, TIFFArrayCount(fax4Fields))) + { + TIFFErrorExtR(tif, "TIFFInitCCITTFax4", + "Merging CCITT Fax 4 codec-specific tags failed"); + return 0; + } - tif->tif_decoderow = Fax4Decode; - tif->tif_decodestrip = Fax4Decode; - tif->tif_decodetile = Fax4Decode; - tif->tif_encoderow = Fax4Encode; - tif->tif_encodestrip = Fax4Encode; - tif->tif_encodetile = Fax4Encode; - tif->tif_postencode = Fax4PostEncode; - /* - * Suppress RTC at the end of each strip. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC); - } else - return (0); + tif->tif_decoderow = Fax4Decode; + tif->tif_decodestrip = Fax4Decode; + tif->tif_decodetile = Fax4Decode; + tif->tif_encoderow = Fax4Encode; + tif->tif_encodestrip = Fax4Encode; + tif->tif_encodetile = Fax4Encode; + tif->tif_postencode = Fax4PostEncode; + /* + * Suppress RTC at the end of each strip. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC); + } + else + return (0); } /* @@ -1610,95 +1645,91 @@ TIFFInitCCITTFax4(TIFF* tif, int scheme) /* * Decode the requested amount of RLE-encoded data. */ -static int -Fax3DecodeRLE(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); - int mode = sp->b.mode; - (void) s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - thisrun = sp->curruns; - while (occ > 0) { - a0 = 0; - RunLength = 0; - pa = thisrun; + DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); + int mode = sp->b.mode; + (void)s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + thisrun = sp->curruns; + while (occ > 0) + { + a0 = 0; + RunLength = 0; + pa = thisrun; #ifdef FAX3_DEBUG - printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %d\n", tif->tif_row); - fflush(stdout); + printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %" PRIu32 "\n", tif->tif_row); + fflush(stdout); #endif - EXPAND1D(EOFRLE); - (*sp->fill)(buf, thisrun, pa, lastx); - /* - * Cleanup at the end of the row. - */ - if (mode & FAXMODE_BYTEALIGN) { - int n = BitsAvail - (BitsAvail &~ 7); - ClrBits(n); - } else if (mode & FAXMODE_WORDALIGN) { - int n = BitsAvail - (BitsAvail &~ 15); - ClrBits(n); - if (BitsAvail == 0 && !isAligned(cp, uint16)) - cp++; - } - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOFRLE: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (-1); - } - UNCACHE_STATE(tif, sp); - return (1); + EXPAND1D(EOFRLE); + (*sp->fill)(buf, thisrun, pa, lastx); + /* + * Cleanup at the end of the row. + */ + if (mode & FAXMODE_BYTEALIGN) + { + int n = BitsAvail - (BitsAvail & ~7); + ClrBits(n); + } + else if (mode & FAXMODE_WORDALIGN) + { + int n = BitsAvail - (BitsAvail & ~15); + ClrBits(n); + if (BitsAvail == 0 && !isAligned(cp, uint16_t)) + cp++; + } + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOFRLE: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); } -int -TIFFInitCCITTRLE(TIFF* tif, int scheme) +int TIFFInitCCITTRLE(TIFF *tif, int scheme) { - (void) scheme; - if (InitCCITTFax3(tif)) { /* reuse G3 support */ - tif->tif_decoderow = Fax3DecodeRLE; - tif->tif_decodestrip = Fax3DecodeRLE; - tif->tif_decodetile = Fax3DecodeRLE; - /* - * Suppress RTC+EOLs when encoding and byte-align data. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, - FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN); - } else - return (0); + (void)scheme; + if (InitCCITTFax3(tif)) + { /* reuse G3 support */ + tif->tif_decoderow = Fax3DecodeRLE; + tif->tif_decodestrip = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; + /* + * Suppress RTC+EOLs when encoding and byte-align data. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, + FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_BYTEALIGN); + } + else + return (0); } -int -TIFFInitCCITTRLEW(TIFF* tif, int scheme) +int TIFFInitCCITTRLEW(TIFF *tif, int scheme) { - (void) scheme; - if (InitCCITTFax3(tif)) { /* reuse G3 support */ - tif->tif_decoderow = Fax3DecodeRLE; - tif->tif_decodestrip = Fax3DecodeRLE; - tif->tif_decodetile = Fax3DecodeRLE; - /* - * Suppress RTC+EOLs when encoding and word-align data. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, - FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN); - } else - return (0); + (void)scheme; + if (InitCCITTFax3(tif)) + { /* reuse G3 support */ + tif->tif_decoderow = Fax3DecodeRLE; + tif->tif_decodestrip = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; + /* + * Suppress RTC+EOLs when encoding and word-align data. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, + FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_WORDALIGN); + } + else + return (0); } #endif /* CCITT_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_fax3.h b/3rdparty/libtiff/tif_fax3.h index 701716cc18..e095009bba 100644 --- a/3rdparty/libtiff/tif_fax3.h +++ b/3rdparty/libtiff/tif_fax3.h @@ -2,28 +2,28 @@ * Copyright (c) 1990-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _FAX3_ -#define _FAX3_ +#define _FAX3_ /* * TIFF Library. * @@ -41,7 +41,7 @@ * The routine must have the type signature given below; * for example: * - * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) + * fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t lastx) * * where buf is place to set the bits, runs is the array of b&w run * lengths (white then black), erun is the last run in the array, and @@ -50,41 +50,47 @@ * data in the run array as needed (e.g. to append zero runs to bring * the count up to a nice multiple). */ -typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32); +typedef void (*TIFFFaxFillFunc)(unsigned char *, uint32_t *, uint32_t *, + uint32_t); /* * The default run filler; made external for other decoders. */ #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32); + extern void _TIFFFax3fillruns(unsigned char *, uint32_t *, uint32_t *, + uint32_t); #if defined(__cplusplus) } #endif - /* finite state machine codes */ -#define S_Null 0 -#define S_Pass 1 -#define S_Horiz 2 -#define S_V0 3 -#define S_VR 4 -#define S_VL 5 -#define S_Ext 6 -#define S_TermW 7 -#define S_TermB 8 -#define S_MakeUpW 9 -#define S_MakeUpB 10 -#define S_MakeUp 11 -#define S_EOL 12 +#define S_Null 0 +#define S_Pass 1 +#define S_Horiz 2 +#define S_V0 3 +#define S_VR 4 +#define S_VL 5 +#define S_Ext 6 +#define S_TermW 7 +#define S_TermB 8 +#define S_MakeUpW 9 +#define S_MakeUpB 10 +#define S_MakeUp 11 +#define S_EOL 12 -/* WARNING: do not change the layout of this structure as the HylaFAX software */ -/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 */ -typedef struct { /* state table entry */ - unsigned char State; /* see above */ - unsigned char Width; /* width of code in bits */ - uint32 Param; /* unsigned 32-bit run length in bits (holds on 16 bit actually, but cannot be changed. See above warning) */ +/* WARNING: do not change the layout of this structure as the HylaFAX software + */ +/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 + */ +typedef struct +{ /* state table entry */ + unsigned char State; /* see above */ + unsigned char Width; /* width of code in bits */ + uint32_t Param; /* unsigned 32-bit run length in bits (holds on 16 bit + actually, but cannot be changed. See above warning) */ } TIFFFaxTabEnt; extern const TIFFFaxTabEnt TIFFFaxMainTable[]; @@ -108,7 +114,7 @@ extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; */ #ifndef EndOfData -#define EndOfData() (cp >= ep) +#define EndOfData() (cp >= ep) #endif /* * Need <=8 or <=16 bits of input data. Unlike viewfax we @@ -134,121 +140,143 @@ extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; * otherwise we should get the right answer. */ #ifndef NeedBits8 -#define NeedBits8(n,eoflab) do { \ - if (BitsAvail < (n)) { \ - if (EndOfData()) { \ - if (BitsAvail == 0) /* no valid bits */ \ - goto eoflab; \ - BitsAvail = (n); /* pad with zeros */ \ - } else { \ - BitAcc |= ((uint32) bitmap[*cp++])<>= (n); \ -} while (0) +#define GetBits(n) (BitAcc & ((1 << (n)) - 1)) +#define ClrBits(n) \ + do \ + { \ + BitsAvail -= (n); \ + BitAcc >>= (n); \ + } while (0) #ifdef FAX3_DEBUG -static const char* StateNames[] = { - "Null ", - "Pass ", - "Horiz ", - "V0 ", - "VR ", - "VL ", - "Ext ", - "TermW ", - "TermB ", - "MakeUpW", - "MakeUpB", - "MakeUp ", - "EOL ", +static const char *StateNames[] = { + "Null ", "Pass ", "Horiz ", "V0 ", "VR ", "VL ", "Ext ", + "TermW ", "TermB ", "MakeUpW", "MakeUpB", "MakeUp ", "EOL ", }; #define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0') -#define LOOKUP8(wid,tab,eoflab) do { \ - int t; \ - NeedBits8(wid,eoflab); \ - TabEnt = tab + GetBits(wid); \ - printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ - StateNames[TabEnt->State], TabEnt->Param); \ - for (t = 0; t < TabEnt->Width; t++) \ - DEBUG_SHOW; \ - putchar('\n'); \ - fflush(stdout); \ - ClrBits(TabEnt->Width); \ -} while (0) -#define LOOKUP16(wid,tab,eoflab) do { \ - int t; \ - NeedBits16(wid,eoflab); \ - TabEnt = tab + GetBits(wid); \ - printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ - StateNames[TabEnt->State], TabEnt->Param); \ - for (t = 0; t < TabEnt->Width; t++) \ - DEBUG_SHOW; \ - putchar('\n'); \ - fflush(stdout); \ - ClrBits(TabEnt->Width); \ -} while (0) +#define LOOKUP8(wid, tab, eoflab) \ + do \ + { \ + int t; \ + NeedBits8(wid, eoflab); \ + TabEnt = tab + GetBits(wid); \ + printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \ + StateNames[TabEnt->State], TabEnt->Param); \ + for (t = 0; t < TabEnt->Width; t++) \ + DEBUG_SHOW; \ + putchar('\n'); \ + fflush(stdout); \ + ClrBits(TabEnt->Width); \ + } while (0) +#define LOOKUP16(wid, tab, eoflab) \ + do \ + { \ + int t; \ + NeedBits16(wid, eoflab); \ + TabEnt = tab + GetBits(wid); \ + printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \ + StateNames[TabEnt->State], TabEnt->Param); \ + for (t = 0; t < TabEnt->Width; t++) \ + DEBUG_SHOW; \ + putchar('\n'); \ + fflush(stdout); \ + ClrBits(TabEnt->Width); \ + } while (0) -#define SETVALUE(x) do { \ - *pa++ = RunLength + (x); \ - printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \ - a0 += x; \ - RunLength = 0; \ -} while (0) +#define SETVALUE(x) \ + do \ + { \ + *pa++ = RunLength + (x); \ + printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \ + a0 += x; \ + RunLength = 0; \ + } while (0) #else -#define LOOKUP8(wid,tab,eoflab) do { \ - NeedBits8(wid,eoflab); \ - TabEnt = tab + GetBits(wid); \ - ClrBits(TabEnt->Width); \ -} while (0) -#define LOOKUP16(wid,tab,eoflab) do { \ - NeedBits16(wid,eoflab); \ - TabEnt = tab + GetBits(wid); \ - ClrBits(TabEnt->Width); \ -} while (0) +#define LOOKUP8(wid, tab, eoflab) \ + do \ + { \ + NeedBits8(wid, eoflab); \ + TabEnt = tab + GetBits(wid); \ + ClrBits(TabEnt->Width); \ + } while (0) +#define LOOKUP16(wid, tab, eoflab) \ + do \ + { \ + NeedBits16(wid, eoflab); \ + TabEnt = tab + GetBits(wid); \ + ClrBits(TabEnt->Width); \ + } while (0) /* * Append a run to the run length array for the * current row and reset decoding state. */ -#define SETVALUE(x) do { \ - if (pa >= thisrun + sp->nruns) { \ - TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - *pa++ = RunLength + (x); \ - a0 += (x); \ - RunLength = 0; \ -} while (0) +#define SETVALUE(x) \ + do \ + { \ + if (pa >= thisrun + sp->nruns) \ + { \ + TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \ + sp->line, isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile \ + : tif->tif_curstrip); \ + return (-1); \ + } \ + *pa++ = RunLength + (x); \ + a0 += (x); \ + RunLength = 0; \ + } while (0) #endif /* @@ -261,51 +289,62 @@ static const char* StateNames[] = { * is non-zero then we still need to scan for the final flag * bit that is part of the EOL code. */ -#define SYNC_EOL(eoflab) do { \ - if (EOLcnt == 0) { \ - for (;;) { \ - NeedBits16(11,eoflab); \ - if (GetBits(11) == 0) \ - break; \ - ClrBits(1); \ - } \ - } \ - for (;;) { \ - NeedBits8(8,eoflab); \ - if (GetBits(8)) \ - break; \ - ClrBits(8); \ - } \ - while (GetBits(1) == 0) \ - ClrBits(1); \ - ClrBits(1); /* EOL bit */ \ - EOLcnt = 0; /* reset EOL counter/flag */ \ -} while (0) +#define SYNC_EOL(eoflab) \ + do \ + { \ + if (EOLcnt == 0) \ + { \ + for (;;) \ + { \ + NeedBits16(11, eoflab); \ + if (GetBits(11) == 0) \ + break; \ + ClrBits(1); \ + } \ + } \ + for (;;) \ + { \ + NeedBits8(8, eoflab); \ + if (GetBits(8)) \ + break; \ + ClrBits(8); \ + } \ + while (GetBits(1) == 0) \ + ClrBits(1); \ + ClrBits(1); /* EOL bit */ \ + EOLcnt = 0; /* reset EOL counter/flag */ \ + } while (0) /* * Cleanup the array of runs after decoding a row. * We adjust final runs to insure the user buffer is not * overwritten and/or undecoded area is white filled. */ -#define CLEANUP_RUNS() do { \ - if (RunLength) \ - SETVALUE(0); \ - if (a0 != lastx) { \ - badlength(a0, lastx); \ - while (a0 > lastx && pa > thisrun) \ - a0 -= *--pa; \ - if (a0 < lastx) { \ - if (a0 < 0) \ - a0 = 0; \ - if ((pa-thisrun)&1) \ - SETVALUE(0); \ - SETVALUE(lastx - a0); \ - } else if (a0 > lastx) { \ - SETVALUE(lastx); \ - SETVALUE(0); \ - } \ - } \ -} while (0) +#define CLEANUP_RUNS() \ + do \ + { \ + if (RunLength) \ + SETVALUE(0); \ + if (a0 != lastx) \ + { \ + badlength(a0, lastx); \ + while (a0 > lastx && pa > thisrun) \ + a0 -= *--pa; \ + if (a0 < lastx) \ + { \ + if (a0 < 0) \ + a0 = 0; \ + if ((pa - thisrun) & 1) \ + SETVALUE(0); \ + SETVALUE(lastx - a0); \ + } \ + else if (a0 > lastx) \ + { \ + SETVALUE(lastx); \ + SETVALUE(0); \ + } \ + } \ + } while (0) /* * Decode a line of 1D-encoded data. @@ -319,249 +358,291 @@ static const char* StateNames[] = { * the original code depended on the input data being zero-padded to * insure the decoder recognized an EOL before running out of data. */ -#define EXPAND1D(eoflab) do { \ - for (;;) { \ - for (;;) { \ - LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \ - switch (TabEnt->State) { \ - case S_EOL: \ - EOLcnt = 1; \ - goto done1d; \ - case S_TermW: \ - SETVALUE(TabEnt->Param); \ - goto doneWhite1d; \ - case S_MakeUpW: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - unexpected("WhiteTable", a0); \ - goto done1d; \ - } \ - } \ - doneWhite1d: \ - if (a0 >= lastx) \ - goto done1d; \ - for (;;) { \ - LOOKUP16(13, TIFFFaxBlackTable, eof1d); \ - switch (TabEnt->State) { \ - case S_EOL: \ - EOLcnt = 1; \ - goto done1d; \ - case S_TermB: \ - SETVALUE(TabEnt->Param); \ - goto doneBlack1d; \ - case S_MakeUpB: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - unexpected("BlackTable", a0); \ - goto done1d; \ - } \ - } \ - doneBlack1d: \ - if (a0 >= lastx) \ - goto done1d; \ - if( *(pa-1) == 0 && *(pa-2) == 0 ) \ - pa -= 2; \ - } \ -eof1d: \ - prematureEOF(a0); \ - CLEANUP_RUNS(); \ - goto eoflab; \ -done1d: \ - CLEANUP_RUNS(); \ -} while (0) +#define EXPAND1D(eoflab) \ + do \ + { \ + for (;;) \ + { \ + for (;;) \ + { \ + LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \ + switch (TabEnt->State) \ + { \ + case S_EOL: \ + EOLcnt = 1; \ + goto done1d; \ + case S_TermW: \ + SETVALUE(TabEnt->Param); \ + goto doneWhite1d; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("WhiteTable", a0); \ + goto done1d; \ + } \ + } \ + doneWhite1d: \ + if (a0 >= lastx) \ + goto done1d; \ + for (;;) \ + { \ + LOOKUP16(13, TIFFFaxBlackTable, eof1d); \ + switch (TabEnt->State) \ + { \ + case S_EOL: \ + EOLcnt = 1; \ + goto done1d; \ + case S_TermB: \ + SETVALUE(TabEnt->Param); \ + goto doneBlack1d; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("BlackTable", a0); \ + goto done1d; \ + } \ + } \ + doneBlack1d: \ + if (a0 >= lastx) \ + goto done1d; \ + if (*(pa - 1) == 0 && *(pa - 2) == 0) \ + pa -= 2; \ + } \ + eof1d: \ + prematureEOF(a0); \ + CLEANUP_RUNS(); \ + goto eoflab; \ + done1d: \ + CLEANUP_RUNS(); \ + } while (0) /* * Update the value of b1 using the array * of runs for the reference line. */ -#define CHECK_b1 do { \ - if (pa != thisrun) while (b1 <= a0 && b1 < lastx) { \ - if( pb + 1 >= sp->refruns + sp->nruns) { \ - TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - b1 += pb[0] + pb[1]; \ - pb += 2; \ - } \ -} while (0) +#define CHECK_b1 \ + do \ + { \ + if (pa != thisrun) \ + while (b1 <= a0 && b1 < lastx) \ + { \ + if (pb + 1 >= sp->refruns + sp->nruns) \ + { \ + TIFFErrorExtR( \ + tif, module, "Buffer overflow at line %u of %s %u", \ + sp->line, isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ + return (-1); \ + } \ + b1 += pb[0] + pb[1]; \ + pb += 2; \ + } \ + } while (0) /* * Expand a row of 2D-encoded data. */ -#define EXPAND2D(eoflab) do { \ - while (a0 < lastx) { \ - if (pa >= thisrun + sp->nruns) { \ - TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - LOOKUP8(7, TIFFFaxMainTable, eof2d); \ - switch (TabEnt->State) { \ - case S_Pass: \ - CHECK_b1; \ - if( pb + 1 >= sp->refruns + sp->nruns) { \ - TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - b1 += *pb++; \ - RunLength += b1 - a0; \ - a0 = b1; \ - b1 += *pb++; \ - break; \ - case S_Horiz: \ - if ((pa-thisrun)&1) { \ - for (;;) { /* black first */ \ - LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ - switch (TabEnt->State) { \ - case S_TermB: \ - SETVALUE(TabEnt->Param); \ - goto doneWhite2da; \ - case S_MakeUpB: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badBlack2d; \ - } \ - } \ - doneWhite2da:; \ - for (;;) { /* then white */ \ - LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ - switch (TabEnt->State) { \ - case S_TermW: \ - SETVALUE(TabEnt->Param); \ - goto doneBlack2da; \ - case S_MakeUpW: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badWhite2d; \ - } \ - } \ - doneBlack2da:; \ - } else { \ - for (;;) { /* white first */ \ - LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ - switch (TabEnt->State) { \ - case S_TermW: \ - SETVALUE(TabEnt->Param); \ - goto doneWhite2db; \ - case S_MakeUpW: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badWhite2d; \ - } \ - } \ - doneWhite2db:; \ - for (;;) { /* then black */ \ - LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ - switch (TabEnt->State) { \ - case S_TermB: \ - SETVALUE(TabEnt->Param); \ - goto doneBlack2db; \ - case S_MakeUpB: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badBlack2d; \ - } \ - } \ - doneBlack2db:; \ - } \ - CHECK_b1; \ - break; \ - case S_V0: \ - CHECK_b1; \ - SETVALUE(b1 - a0); \ - if( pb >= sp->refruns + sp->nruns) { \ - TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - b1 += *pb++; \ - break; \ - case S_VR: \ - CHECK_b1; \ - SETVALUE(b1 - a0 + TabEnt->Param); \ - if( pb >= sp->refruns + sp->nruns) { \ - TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - b1 += *pb++; \ - break; \ - case S_VL: \ - CHECK_b1; \ - if (b1 < (int) (a0 + TabEnt->Param)) { \ - unexpected("VL", a0); \ - goto eol2d; \ - } \ - SETVALUE(b1 - a0 - TabEnt->Param); \ - b1 -= *--pb; \ - break; \ - case S_Ext: \ - *pa++ = lastx - a0; \ - extension(a0); \ - goto eol2d; \ - case S_EOL: \ - *pa++ = lastx - a0; \ - NeedBits8(4,eof2d); \ - if (GetBits(4)) \ - unexpected("EOL", a0); \ - ClrBits(4); \ - EOLcnt = 1; \ - goto eol2d; \ - default: \ - badMain2d: \ - unexpected("MainTable", a0); \ - goto eol2d; \ - badBlack2d: \ - unexpected("BlackTable", a0); \ - goto eol2d; \ - badWhite2d: \ - unexpected("WhiteTable", a0); \ - goto eol2d; \ - eof2d: \ - prematureEOF(a0); \ - CLEANUP_RUNS(); \ - goto eoflab; \ - } \ - } \ - if (RunLength) { \ - if (RunLength + a0 < lastx) { \ - /* expect a final V0 */ \ - NeedBits8(1,eof2d); \ - if (!GetBits(1)) \ - goto badMain2d; \ - ClrBits(1); \ - } \ - SETVALUE(0); \ - } \ -eol2d: \ - CLEANUP_RUNS(); \ -} while (0) +#define EXPAND2D(eoflab) \ + do \ + { \ + while (a0 < lastx) \ + { \ + if (pa >= thisrun + sp->nruns) \ + { \ + TIFFErrorExtR( \ + tif, module, "Buffer overflow at line %u of %s %u", \ + sp->line, isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ + return (-1); \ + } \ + LOOKUP8(7, TIFFFaxMainTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_Pass: \ + CHECK_b1; \ + if (pb + 1 >= sp->refruns + sp->nruns) \ + { \ + TIFFErrorExtR(tif, module, \ + "Buffer overflow at line %u of %s %u", \ + sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile \ + : tif->tif_curstrip); \ + return (-1); \ + } \ + b1 += *pb++; \ + RunLength += b1 - a0; \ + a0 = b1; \ + b1 += *pb++; \ + break; \ + case S_Horiz: \ + if ((pa - thisrun) & 1) \ + { \ + for (;;) \ + { /* black first */ \ + LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_TermB: \ + SETVALUE(TabEnt->Param); \ + goto doneWhite2da; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badBlack2d; \ + } \ + } \ + doneWhite2da:; \ + for (;;) \ + { /* then white */ \ + LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_TermW: \ + SETVALUE(TabEnt->Param); \ + goto doneBlack2da; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badWhite2d; \ + } \ + } \ + doneBlack2da:; \ + } \ + else \ + { \ + for (;;) \ + { /* white first */ \ + LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_TermW: \ + SETVALUE(TabEnt->Param); \ + goto doneWhite2db; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badWhite2d; \ + } \ + } \ + doneWhite2db:; \ + for (;;) \ + { /* then black */ \ + LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_TermB: \ + SETVALUE(TabEnt->Param); \ + goto doneBlack2db; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badBlack2d; \ + } \ + } \ + doneBlack2db:; \ + } \ + CHECK_b1; \ + break; \ + case S_V0: \ + CHECK_b1; \ + SETVALUE(b1 - a0); \ + if (pb >= sp->refruns + sp->nruns) \ + { \ + TIFFErrorExtR(tif, module, \ + "Buffer overflow at line %u of %s %u", \ + sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile \ + : tif->tif_curstrip); \ + return (-1); \ + } \ + b1 += *pb++; \ + break; \ + case S_VR: \ + CHECK_b1; \ + SETVALUE(b1 - a0 + TabEnt->Param); \ + if (pb >= sp->refruns + sp->nruns) \ + { \ + TIFFErrorExtR(tif, module, \ + "Buffer overflow at line %u of %s %u", \ + sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile \ + : tif->tif_curstrip); \ + return (-1); \ + } \ + b1 += *pb++; \ + break; \ + case S_VL: \ + CHECK_b1; \ + if (b1 < (int)(a0 + TabEnt->Param)) \ + { \ + unexpected("VL", a0); \ + goto eol2d; \ + } \ + SETVALUE(b1 - a0 - TabEnt->Param); \ + b1 -= *--pb; \ + break; \ + case S_Ext: \ + *pa++ = lastx - a0; \ + extension(a0); \ + goto eol2d; \ + case S_EOL: \ + *pa++ = lastx - a0; \ + NeedBits8(4, eof2d); \ + if (GetBits(4)) \ + unexpected("EOL", a0); \ + ClrBits(4); \ + EOLcnt = 1; \ + goto eol2d; \ + default: \ + badMain2d: \ + unexpected("MainTable", a0); \ + goto eol2d; \ + badBlack2d: \ + unexpected("BlackTable", a0); \ + goto eol2d; \ + badWhite2d: \ + unexpected("WhiteTable", a0); \ + goto eol2d; \ + eof2d: \ + prematureEOF(a0); \ + CLEANUP_RUNS(); \ + goto eoflab; \ + } \ + } \ + if (RunLength) \ + { \ + if (RunLength + a0 < lastx) \ + { \ + /* expect a final V0 */ \ + NeedBits8(1, eof2d); \ + if (!GetBits(1)) \ + goto badMain2d; \ + ClrBits(1); \ + } \ + SETVALUE(0); \ + } \ + eol2d: \ + CLEANUP_RUNS(); \ + } while (0) #endif /* _FAX3_ */ -/* vim: set ts=8 sts=4 sw=4 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_flush.c b/3rdparty/libtiff/tif_flush.c index f7fa2072ab..ff9c1e247a 100644 --- a/3rdparty/libtiff/tif_flush.c +++ b/3rdparty/libtiff/tif_flush.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -27,30 +27,28 @@ */ #include "tiffiop.h" -int -TIFFFlush(TIFF* tif) +int TIFFFlush(TIFF *tif) { - if( tif->tif_mode == O_RDONLY ) + if (tif->tif_mode == O_RDONLY) return 1; if (!TIFFFlushData(tif)) return (0); - - /* In update (r+) mode we try to detect the case where - only the strip/tile map has been altered, and we try to - rewrite only that portion of the directory without + + /* In update (r+) mode we try to detect the case where + only the strip/tile map has been altered, and we try to + rewrite only that portion of the directory without making any other changes */ - - if( (tif->tif_flags & TIFF_DIRTYSTRIP) - && !(tif->tif_flags & TIFF_DIRTYDIRECT) - && tif->tif_mode == O_RDWR ) + + if ((tif->tif_flags & TIFF_DIRTYSTRIP) && + !(tif->tif_flags & TIFF_DIRTYDIRECT) && tif->tif_mode == O_RDWR) { - if( TIFFForceStrileArrayWriting(tif) ) + if (TIFFForceStrileArrayWriting(tif)) return 1; } - if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP)) - && !TIFFRewriteDirectory(tif)) + if ((tif->tif_flags & (TIFF_DIRTYDIRECT | TIFF_DIRTYSTRIP)) && + !TIFFRewriteDirectory(tif)) return (0); return (1); @@ -75,45 +73,43 @@ TIFFFlush(TIFF* tif) * * Returns 1 in case of success, 0 otherwise. */ -int TIFFForceStrileArrayWriting(TIFF* tif) +int TIFFForceStrileArrayWriting(TIFF *tif) { static const char module[] = "TIFFForceStrileArrayWriting"; const int isTiled = TIFFIsTiled(tif); if (tif->tif_mode == O_RDONLY) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "File opened in read-only mode"); + TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode"); return 0; } - if( tif->tif_diroff == 0 ) + if (tif->tif_diroff == 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Directory has not yet been written"); + TIFFErrorExtR(tif, module, "Directory has not yet been written"); return 0; } - if( (tif->tif_flags & TIFF_DIRTYDIRECT) != 0 ) + if ((tif->tif_flags & TIFF_DIRTYDIRECT) != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Directory has changes other than the strile arrays. " - "TIFFRewriteDirectory() should be called instead"); + TIFFErrorExtR(tif, module, + "Directory has changes other than the strile arrays. " + "TIFFRewriteDirectory() should be called instead"); return 0; } - if( !(tif->tif_flags & TIFF_DIRTYSTRIP) ) + if (!(tif->tif_flags & TIFF_DIRTYSTRIP)) { - if( !(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) ) + if (!(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && + tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Function not called together with " - "TIFFDeferStrileArrayWriting()"); + TIFFErrorExtR(tif, module, + "Function not called together with " + "TIFFDeferStrileArrayWriting()"); return 0; } @@ -121,18 +117,14 @@ int TIFFForceStrileArrayWriting(TIFF* tif) return 0; } - if( _TIFFRewriteField( tif, - isTiled ? TIFFTAG_TILEOFFSETS : - TIFFTAG_STRIPOFFSETS, - TIFF_LONG8, - tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripoffset_p ) - && _TIFFRewriteField( tif, - isTiled ? TIFFTAG_TILEBYTECOUNTS : - TIFFTAG_STRIPBYTECOUNTS, - TIFF_LONG8, - tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripbytecount_p ) ) + if (_TIFFRewriteField(tif, + isTiled ? TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS, + TIFF_LONG8, tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripoffset_p) && + _TIFFRewriteField( + tif, isTiled ? TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS, + TIFF_LONG8, tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripbytecount_p)) { tif->tif_flags &= ~TIFF_DIRTYSTRIP; tif->tif_flags &= ~TIFF_BEENWRITING; @@ -149,26 +141,17 @@ int TIFFForceStrileArrayWriting(TIFF* tif) * is not set, so that TIFFFlush() will proceed to write out the directory. * The documentation says returning 1 is an error indicator, but not having * been writing isn't exactly a an error. Hopefully this doesn't cause - * problems for other people. + * problems for other people. */ -int -TIFFFlushData(TIFF* tif) +int TIFFFlushData(TIFF *tif) { - if ((tif->tif_flags & TIFF_BEENWRITING) == 0) - return (1); - if (tif->tif_flags & TIFF_POSTENCODE) { - tif->tif_flags &= ~TIFF_POSTENCODE; - if (!(*tif->tif_postencode)(tif)) - return (0); - } - return (TIFFFlushData1(tif)); + if ((tif->tif_flags & TIFF_BEENWRITING) == 0) + return (1); + if (tif->tif_flags & TIFF_POSTENCODE) + { + tif->tif_flags &= ~TIFF_POSTENCODE; + if (!(*tif->tif_postencode)(tif)) + return (0); + } + return (TIFFFlushData1(tif)); } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_getimage.c b/3rdparty/libtiff/tif_getimage.c index 3460af744e..41f7dfd77e 100644 --- a/3rdparty/libtiff/tif_getimage.c +++ b/3rdparty/libtiff/tif_getimage.c @@ -2,23 +2,23 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -28,41 +28,50 @@ * Read and return a packed RGBA image. */ #include "tiffiop.h" -#include #include +#include -static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32); -static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); -static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32); -static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); -static int PickContigCase(TIFFRGBAImage*); -static int PickSeparateCase(TIFFRGBAImage*); +static int gtTileContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); +static int gtTileSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); +static int gtStripContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); +static int gtStripSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); +static int PickContigCase(TIFFRGBAImage *); +static int PickSeparateCase(TIFFRGBAImage *); -static int BuildMapUaToAa(TIFFRGBAImage* img); -static int BuildMapBitdepth16To8(TIFFRGBAImage* img); +static int BuildMapUaToAa(TIFFRGBAImage *img); +static int BuildMapBitdepth16To8(TIFFRGBAImage *img); static const char photoTag[] = "PhotometricInterpretation"; -/* +/* * Helper constants used in Orientation tag handling */ #define FLIP_VERTICALLY 0x01 #define FLIP_HORIZONTALLY 0x02 +#define EMSG_BUF_SIZE 1024 + /* * Color conversion constants. We will define display types here. */ static const TIFFDisplay display_sRGB = { - { /* XYZ -> luminance matrix */ - { 3.2410F, -1.5374F, -0.4986F }, - { -0.9692F, 1.8760F, 0.0416F }, - { 0.0556F, -0.2040F, 1.0570F } - }, - 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */ - 255, 255, 255, /* Pixel values for ref. white */ - 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */ - 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */ + {/* XYZ -> luminance matrix */ + {3.2410F, -1.5374F, -0.4986F}, + {-0.9692F, 1.8760F, 0.0416F}, + {0.0556F, -0.2040F, 1.0570F}}, + 100.0F, + 100.0F, + 100.0F, /* Light o/p for reference white */ + 255, + 255, + 255, /* Pixel values for ref. white */ + 1.0F, + 1.0F, + 1.0F, /* Residual light o/p for black pixel */ + 2.4F, + 2.4F, + 2.4F, /* Gamma values for the three guns */ }; /* @@ -71,443 +80,525 @@ static const TIFFDisplay display_sRGB = { * be handled. If 0 is returned, emsg contains the reason * why it is being rejected. */ -int -TIFFRGBAImageOK(TIFF* tif, char emsg[1024]) +int TIFFRGBAImageOK(TIFF *tif, char emsg[EMSG_BUF_SIZE]) { - TIFFDirectory* td = &tif->tif_dir; - uint16 photometric; - int colorchannels; + TIFFDirectory *td = &tif->tif_dir; + uint16_t photometric; + int colorchannels; - if (!tif->tif_decodestatus) { - sprintf(emsg, "Sorry, requested compression method is not configured"); - return (0); - } - switch (td->td_bitspersample) { - case 1: - case 2: - case 4: - case 8: - case 16: - break; - default: - sprintf(emsg, "Sorry, can not handle images with %d-bit samples", - td->td_bitspersample); - return (0); - } - if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) { - sprintf(emsg, "Sorry, can not handle images with IEEE floating-point samples"); + if (!tif->tif_decodestatus) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, requested compression method is not configured"); + return (0); + } + switch (td->td_bitspersample) + { + case 1: + case 2: + case 4: + case 8: + case 16: + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle images with %" PRIu16 + "-bit samples", + td->td_bitspersample); + return (0); + } + if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle images with IEEE floating-point samples"); + return (0); + } + colorchannels = td->td_samplesperpixel - td->td_extrasamples; + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) + { + switch (colorchannels) + { + case 1: + photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + photometric = PHOTOMETRIC_RGB; + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", + photoTag); return (0); } - colorchannels = td->td_samplesperpixel - td->td_extrasamples; - if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { - switch (colorchannels) { - case 1: - photometric = PHOTOMETRIC_MINISBLACK; - break; - case 3: - photometric = PHOTOMETRIC_RGB; - break; - default: - sprintf(emsg, "Missing needed %s tag", photoTag); - return (0); - } - } - switch (photometric) { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_PALETTE: - if (td->td_planarconfig == PLANARCONFIG_CONTIG - && td->td_samplesperpixel != 1 - && td->td_bitspersample < 8 ) { - sprintf(emsg, - "Sorry, can not handle contiguous data with %s=%d, " - "and %s=%d and Bits/Sample=%d", - photoTag, photometric, - "Samples/pixel", td->td_samplesperpixel, - td->td_bitspersample); - return (0); - } - /* - * We should likely validate that any extra samples are either - * to be ignored, or are alpha, and if alpha we should try to use - * them. But for now we won't bother with this. - */ - break; - case PHOTOMETRIC_YCBCR: - /* - * TODO: if at all meaningful and useful, make more complete - * support check here, or better still, refactor to let supporting - * code decide whether there is support and what meaningful - * error to return - */ - break; - case PHOTOMETRIC_RGB: - if (colorchannels < 3) { - sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", - "Color channels", colorchannels); - return (0); - } - break; - case PHOTOMETRIC_SEPARATED: - { - uint16 inkset; - TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); - if (inkset != INKSET_CMYK) { - sprintf(emsg, - "Sorry, can not handle separated image with %s=%d", - "InkSet", inkset); - return 0; - } - if (td->td_samplesperpixel < 4) { - sprintf(emsg, - "Sorry, can not handle separated image with %s=%d", - "Samples/pixel", td->td_samplesperpixel); - return 0; - } - break; - } - case PHOTOMETRIC_LOGL: - if (td->td_compression != COMPRESSION_SGILOG) { - sprintf(emsg, "Sorry, LogL data must have %s=%d", - "Compression", COMPRESSION_SGILOG); - return (0); - } - break; - case PHOTOMETRIC_LOGLUV: - if (td->td_compression != COMPRESSION_SGILOG && - td->td_compression != COMPRESSION_SGILOG24) { - sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", - "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); - return (0); - } - if (td->td_planarconfig != PLANARCONFIG_CONTIG) { - sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", - "Planarconfiguration", td->td_planarconfig); - return (0); - } - if ( td->td_samplesperpixel != 3 || colorchannels != 3 ) { - sprintf(emsg, - "Sorry, can not handle image with %s=%d, %s=%d", - "Samples/pixel", td->td_samplesperpixel, - "colorchannels", colorchannels); - return 0; - } - break; - case PHOTOMETRIC_CIELAB: - if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) { - sprintf(emsg, - "Sorry, can not handle image with %s=%d, %s=%d and %s=%d", - "Samples/pixel", td->td_samplesperpixel, - "colorchannels", colorchannels, - "Bits/sample", td->td_bitspersample); - return 0; - } - break; - default: - sprintf(emsg, "Sorry, can not handle image with %s=%d", - photoTag, photometric); - return (0); - } - return (1); + } + switch (photometric) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + td->td_samplesperpixel != 1 && td->td_bitspersample < 8) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle contiguous data with %s=%" PRIu16 + ", " + "and %s=%" PRIu16 " and Bits/Sample=%" PRIu16 "", + photoTag, photometric, "Samples/pixel", + td->td_samplesperpixel, td->td_bitspersample); + return (0); + } + /* + * We should likely validate that any extra samples are either + * to be ignored, or are alpha, and if alpha we should try to use + * them. But for now we won't bother with this. + */ + break; + case PHOTOMETRIC_YCBCR: + /* + * TODO: if at all meaningful and useful, make more complete + * support check here, or better still, refactor to let supporting + * code decide whether there is support and what meaningful + * error to return + */ + break; + case PHOTOMETRIC_RGB: + if (colorchannels < 3) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle RGB image with %s=%d", + "Color channels", colorchannels); + return (0); + } + break; + case PHOTOMETRIC_SEPARATED: + { + uint16_t inkset; + TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); + if (inkset != INKSET_CMYK) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle separated image with %s=%d", + "InkSet", inkset); + return 0; + } + if (td->td_samplesperpixel < 4) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle separated image with %s=%" PRIu16, + "Samples/pixel", td->td_samplesperpixel); + return 0; + } + break; + } + case PHOTOMETRIC_LOGL: + if (td->td_compression != COMPRESSION_SGILOG) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, LogL data must have %s=%d", "Compression", + COMPRESSION_SGILOG); + return (0); + } + break; + case PHOTOMETRIC_LOGLUV: + if (td->td_compression != COMPRESSION_SGILOG && + td->td_compression != COMPRESSION_SGILOG24) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, LogLuv data must have %s=%d or %d", + "Compression", COMPRESSION_SGILOG, + COMPRESSION_SGILOG24); + return (0); + } + if (td->td_planarconfig != PLANARCONFIG_CONTIG) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle LogLuv images with %s=%" PRIu16, + "Planarconfiguration", td->td_planarconfig); + return (0); + } + if (td->td_samplesperpixel != 3 || colorchannels != 3) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle image with %s=%" PRIu16 + ", %s=%d", + "Samples/pixel", td->td_samplesperpixel, + "colorchannels", colorchannels); + return 0; + } + break; + case PHOTOMETRIC_CIELAB: + if (td->td_samplesperpixel != 3 || colorchannels != 3 || + (td->td_bitspersample != 8 && td->td_bitspersample != 16)) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle image with %s=%" PRIu16 + ", %s=%d and %s=%" PRIu16, + "Samples/pixel", td->td_samplesperpixel, + "colorchannels", colorchannels, "Bits/sample", + td->td_bitspersample); + return 0; + } + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle image with %s=%" PRIu16, photoTag, + photometric); + return (0); + } + return (1); } -void -TIFFRGBAImageEnd(TIFFRGBAImage* img) +void TIFFRGBAImageEnd(TIFFRGBAImage *img) { - if (img->Map) { - _TIFFfree(img->Map); - img->Map = NULL; - } - if (img->BWmap) { - _TIFFfree(img->BWmap); - img->BWmap = NULL; - } - if (img->PALmap) { - _TIFFfree(img->PALmap); - img->PALmap = NULL; - } - if (img->ycbcr) { - _TIFFfree(img->ycbcr); - img->ycbcr = NULL; - } - if (img->cielab) { - _TIFFfree(img->cielab); - img->cielab = NULL; - } - if (img->UaToAa) { - _TIFFfree(img->UaToAa); - img->UaToAa = NULL; - } - if (img->Bitdepth16To8) { - _TIFFfree(img->Bitdepth16To8); - img->Bitdepth16To8 = NULL; - } + if (img->Map) + { + _TIFFfreeExt(img->tif, img->Map); + img->Map = NULL; + } + if (img->BWmap) + { + _TIFFfreeExt(img->tif, img->BWmap); + img->BWmap = NULL; + } + if (img->PALmap) + { + _TIFFfreeExt(img->tif, img->PALmap); + img->PALmap = NULL; + } + if (img->ycbcr) + { + _TIFFfreeExt(img->tif, img->ycbcr); + img->ycbcr = NULL; + } + if (img->cielab) + { + _TIFFfreeExt(img->tif, img->cielab); + img->cielab = NULL; + } + if (img->UaToAa) + { + _TIFFfreeExt(img->tif, img->UaToAa); + img->UaToAa = NULL; + } + if (img->Bitdepth16To8) + { + _TIFFfreeExt(img->tif, img->Bitdepth16To8); + img->Bitdepth16To8 = NULL; + } - if( img->redcmap ) { - _TIFFfree( img->redcmap ); - _TIFFfree( img->greencmap ); - _TIFFfree( img->bluecmap ); - img->redcmap = img->greencmap = img->bluecmap = NULL; - } + if (img->redcmap) + { + _TIFFfreeExt(img->tif, img->redcmap); + _TIFFfreeExt(img->tif, img->greencmap); + _TIFFfreeExt(img->tif, img->bluecmap); + img->redcmap = img->greencmap = img->bluecmap = NULL; + } } -static int -isCCITTCompression(TIFF* tif) +static int isCCITTCompression(TIFF *tif) { - uint16 compress; + uint16_t compress; TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); return (compress == COMPRESSION_CCITTFAX3 || - compress == COMPRESSION_CCITTFAX4 || - compress == COMPRESSION_CCITTRLE || - compress == COMPRESSION_CCITTRLEW); + compress == COMPRESSION_CCITTFAX4 || + compress == COMPRESSION_CCITTRLE || + compress == COMPRESSION_CCITTRLEW); } -int -TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) +int TIFFRGBAImageBegin(TIFFRGBAImage *img, TIFF *tif, int stop, + char emsg[EMSG_BUF_SIZE]) { - uint16* sampleinfo; - uint16 extrasamples; - uint16 planarconfig; - uint16 compress; - int colorchannels; - uint16 *red_orig, *green_orig, *blue_orig; - int n_color; - - if( !TIFFRGBAImageOK(tif, emsg) ) - return 0; + uint16_t *sampleinfo; + uint16_t extrasamples; + uint16_t planarconfig; + uint16_t compress; + int colorchannels; + uint16_t *red_orig, *green_orig, *blue_orig; + int n_color; - /* Initialize to normal values */ - img->row_offset = 0; - img->col_offset = 0; - img->redcmap = NULL; - img->greencmap = NULL; - img->bluecmap = NULL; - img->Map = NULL; - img->BWmap = NULL; - img->PALmap = NULL; - img->ycbcr = NULL; - img->cielab = NULL; - img->UaToAa = NULL; - img->Bitdepth16To8 = NULL; - img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ + if (!TIFFRGBAImageOK(tif, emsg)) + return 0; - img->tif = tif; - img->stoponerr = stop; - TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); - switch (img->bitspersample) { - case 1: - case 2: - case 4: - case 8: - case 16: - break; - default: - sprintf(emsg, "Sorry, can not handle images with %d-bit samples", - img->bitspersample); - goto fail_return; - } - img->alpha = 0; - TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); - TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, - &extrasamples, &sampleinfo); - if (extrasamples >= 1) - { - switch (sampleinfo[0]) { - case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */ - if (img->samplesperpixel > 3) /* correct info about alpha channel */ - img->alpha = EXTRASAMPLE_ASSOCALPHA; - break; - case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ - case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ - img->alpha = sampleinfo[0]; - break; - } - } + /* Initialize to normal values */ + img->row_offset = 0; + img->col_offset = 0; + img->redcmap = NULL; + img->greencmap = NULL; + img->bluecmap = NULL; + img->Map = NULL; + img->BWmap = NULL; + img->PALmap = NULL; + img->ycbcr = NULL; + img->cielab = NULL; + img->UaToAa = NULL; + img->Bitdepth16To8 = NULL; + img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ + + img->tif = tif; + img->stoponerr = stop; + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); + switch (img->bitspersample) + { + case 1: + case 2: + case 4: + case 8: + case 16: + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle images with %" PRIu16 + "-bit samples", + img->bitspersample); + goto fail_return; + } + img->alpha = 0; + TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); + TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, + &sampleinfo); + if (extrasamples >= 1) + { + switch (sampleinfo[0]) + { + case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without + */ + if (img->samplesperpixel > + 3) /* correct info about alpha channel */ + img->alpha = EXTRASAMPLE_ASSOCALPHA; + break; + case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ + case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ + img->alpha = sampleinfo[0]; + break; + } + } #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA - if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) - img->photometric = PHOTOMETRIC_MINISWHITE; + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) + img->photometric = PHOTOMETRIC_MINISWHITE; - if( extrasamples == 0 - && img->samplesperpixel == 4 - && img->photometric == PHOTOMETRIC_RGB ) - { - img->alpha = EXTRASAMPLE_ASSOCALPHA; - extrasamples = 1; - } + if (extrasamples == 0 && img->samplesperpixel == 4 && + img->photometric == PHOTOMETRIC_RGB) + { + img->alpha = EXTRASAMPLE_ASSOCALPHA; + extrasamples = 1; + } #endif - colorchannels = img->samplesperpixel - extrasamples; - TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress); - TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); - if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) { - switch (colorchannels) { - case 1: - if (isCCITTCompression(tif)) - img->photometric = PHOTOMETRIC_MINISWHITE; - else - img->photometric = PHOTOMETRIC_MINISBLACK; - break; - case 3: - img->photometric = PHOTOMETRIC_RGB; - break; - default: - sprintf(emsg, "Missing needed %s tag", photoTag); - goto fail_return; - } - } - switch (img->photometric) { - case PHOTOMETRIC_PALETTE: - if (!TIFFGetField(tif, TIFFTAG_COLORMAP, - &red_orig, &green_orig, &blue_orig)) { - sprintf(emsg, "Missing required \"Colormap\" tag"); - goto fail_return; - } + colorchannels = img->samplesperpixel - extrasamples; + TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress); + TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) + { + switch (colorchannels) + { + case 1: + if (isCCITTCompression(tif)) + img->photometric = PHOTOMETRIC_MINISWHITE; + else + img->photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + img->photometric = PHOTOMETRIC_RGB; + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", + photoTag); + goto fail_return; + } + } + switch (img->photometric) + { + case PHOTOMETRIC_PALETTE: + if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &red_orig, &green_orig, + &blue_orig)) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Missing required \"Colormap\" tag"); + goto fail_return; + } - /* copy the colormaps so we can modify them */ - n_color = (1U << img->bitspersample); - img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); - img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); - img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); - if( !img->redcmap || !img->greencmap || !img->bluecmap ) { - sprintf(emsg, "Out of memory for colormap copy"); - goto fail_return; - } + /* copy the colormaps so we can modify them */ + n_color = (1U << img->bitspersample); + img->redcmap = + (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color); + img->greencmap = + (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color); + img->bluecmap = + (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color); + if (!img->redcmap || !img->greencmap || !img->bluecmap) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Out of memory for colormap copy"); + goto fail_return; + } - _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 ); - _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 ); - _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 ); + _TIFFmemcpy(img->redcmap, red_orig, n_color * 2); + _TIFFmemcpy(img->greencmap, green_orig, n_color * 2); + _TIFFmemcpy(img->bluecmap, blue_orig, n_color * 2); - /* fall through... */ - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - if (planarconfig == PLANARCONFIG_CONTIG - && img->samplesperpixel != 1 - && img->bitspersample < 8 ) { - sprintf(emsg, - "Sorry, can not handle contiguous data with %s=%d, " - "and %s=%d and Bits/Sample=%d", - photoTag, img->photometric, - "Samples/pixel", img->samplesperpixel, - img->bitspersample); - goto fail_return; - } - break; - case PHOTOMETRIC_YCBCR: - /* It would probably be nice to have a reality check here. */ - if (planarconfig == PLANARCONFIG_CONTIG) - /* can rely on libjpeg to convert to RGB */ - /* XXX should restore current state on exit */ - switch (compress) { - case COMPRESSION_JPEG: - /* - * TODO: when complete tests verify complete desubsampling - * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in - * favor of tif_getimage.c native handling - */ - TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); - img->photometric = PHOTOMETRIC_RGB; - break; - default: - /* do nothing */; - break; - } - /* - * TODO: if at all meaningful and useful, make more complete - * support check here, or better still, refactor to let supporting - * code decide whether there is support and what meaningful - * error to return - */ - break; - case PHOTOMETRIC_RGB: - if (colorchannels < 3) { - sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", - "Color channels", colorchannels); - goto fail_return; - } - break; - case PHOTOMETRIC_SEPARATED: - { - uint16 inkset; - TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); - if (inkset != INKSET_CMYK) { - sprintf(emsg, "Sorry, can not handle separated image with %s=%d", - "InkSet", inkset); - goto fail_return; - } - if (img->samplesperpixel < 4) { - sprintf(emsg, "Sorry, can not handle separated image with %s=%d", - "Samples/pixel", img->samplesperpixel); - goto fail_return; - } - } - break; - case PHOTOMETRIC_LOGL: - if (compress != COMPRESSION_SGILOG) { - sprintf(emsg, "Sorry, LogL data must have %s=%d", - "Compression", COMPRESSION_SGILOG); - goto fail_return; - } - TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); - img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ - img->bitspersample = 8; - break; - case PHOTOMETRIC_LOGLUV: - if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) { - sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", - "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); - goto fail_return; - } - if (planarconfig != PLANARCONFIG_CONTIG) { - sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", - "Planarconfiguration", planarconfig); - return (0); - } - TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); - img->photometric = PHOTOMETRIC_RGB; /* little white lie */ - img->bitspersample = 8; - break; - case PHOTOMETRIC_CIELAB: - break; - default: - sprintf(emsg, "Sorry, can not handle image with %s=%d", - photoTag, img->photometric); - goto fail_return; - } - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); - TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); - img->isContig = - !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1); - if (img->isContig) { - if (!PickContigCase(img)) { - sprintf(emsg, "Sorry, can not handle image"); - goto fail_return; - } - } else { - if (!PickSeparateCase(img)) { - sprintf(emsg, "Sorry, can not handle image"); - goto fail_return; - } - } - return 1; + /* fall through... */ + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + if (planarconfig == PLANARCONFIG_CONTIG && + img->samplesperpixel != 1 && img->bitspersample < 8) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle contiguous data with %s=%" PRIu16 + ", " + "and %s=%" PRIu16 " and Bits/Sample=%" PRIu16, + photoTag, img->photometric, "Samples/pixel", + img->samplesperpixel, img->bitspersample); + goto fail_return; + } + break; + case PHOTOMETRIC_YCBCR: + /* It would probably be nice to have a reality check here. */ + if (planarconfig == PLANARCONFIG_CONTIG) + /* can rely on libjpeg to convert to RGB */ + /* XXX should restore current state on exit */ + switch (compress) + { + case COMPRESSION_JPEG: + /* + * TODO: when complete tests verify complete + * desubsampling and YCbCr handling, remove use of + * TIFFTAG_JPEGCOLORMODE in favor of tif_getimage.c + * native handling + */ + TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, + JPEGCOLORMODE_RGB); + img->photometric = PHOTOMETRIC_RGB; + break; + default: + /* do nothing */; + break; + } + /* + * TODO: if at all meaningful and useful, make more complete + * support check here, or better still, refactor to let supporting + * code decide whether there is support and what meaningful + * error to return + */ + break; + case PHOTOMETRIC_RGB: + if (colorchannels < 3) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle RGB image with %s=%d", + "Color channels", colorchannels); + goto fail_return; + } + break; + case PHOTOMETRIC_SEPARATED: + { + uint16_t inkset; + TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); + if (inkset != INKSET_CMYK) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle separated image with %s=%" PRIu16, + "InkSet", inkset); + goto fail_return; + } + if (img->samplesperpixel < 4) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle separated image with %s=%" PRIu16, + "Samples/pixel", img->samplesperpixel); + goto fail_return; + } + } + break; + case PHOTOMETRIC_LOGL: + if (compress != COMPRESSION_SGILOG) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, LogL data must have %s=%d", "Compression", + COMPRESSION_SGILOG); + goto fail_return; + } + TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); + img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ + img->bitspersample = 8; + break; + case PHOTOMETRIC_LOGLUV: + if (compress != COMPRESSION_SGILOG && + compress != COMPRESSION_SGILOG24) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, LogLuv data must have %s=%d or %d", + "Compression", COMPRESSION_SGILOG, + COMPRESSION_SGILOG24); + goto fail_return; + } + if (planarconfig != PLANARCONFIG_CONTIG) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle LogLuv images with %s=%" PRIu16, + "Planarconfiguration", planarconfig); + return (0); + } + TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); + img->photometric = PHOTOMETRIC_RGB; /* little white lie */ + img->bitspersample = 8; + break; + case PHOTOMETRIC_CIELAB: + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle image with %s=%" PRIu16, photoTag, + img->photometric); + goto fail_return; + } + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); + TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); + img->isContig = + !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1); + if (img->isContig) + { + if (!PickContigCase(img)) + { + snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image"); + goto fail_return; + } + } + else + { + if (!PickSeparateCase(img)) + { + snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image"); + goto fail_return; + } + } + return 1; - fail_return: - TIFFRGBAImageEnd( img ); - return 0; +fail_return: + TIFFRGBAImageEnd(img); + return 0; } -int -TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +int TIFFRGBAImageGet(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) { - if (img->get == NULL) { - TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup"); - return (0); - } - if (img->put.any == NULL) { - TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), - "No \"put\" routine setupl; probably can not handle image format"); - return (0); + if (img->get == NULL) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "No \"get\" routine setup"); + return (0); + } + if (img->put.any == NULL) + { + TIFFErrorExtR( + img->tif, TIFFFileName(img->tif), + "No \"put\" routine setupl; probably can not handle image format"); + return (0); } return (*img->get)(img, raster, w, h); } @@ -516,24 +607,25 @@ TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) * Read the specified image into an ABGR-format rastertaking in account * specified orientation. */ -int -TIFFReadRGBAImageOriented(TIFF* tif, - uint32 rwidth, uint32 rheight, uint32* raster, - int orientation, int stop) +int TIFFReadRGBAImageOriented(TIFF *tif, uint32_t rwidth, uint32_t rheight, + uint32_t *raster, int orientation, int stop) { - char emsg[1024] = ""; + char emsg[EMSG_BUF_SIZE] = ""; TIFFRGBAImage img; int ok; - if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) { - img.req_orientation = (uint16)orientation; - /* XXX verify rwidth and rheight against width and height */ - ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth, - rwidth, img.height); - TIFFRGBAImageEnd(&img); - } else { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); - ok = 0; + if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) + { + img.req_orientation = (uint16_t)orientation; + /* XXX verify rwidth and rheight against width and height */ + ok = TIFFRGBAImageGet(&img, raster + (rheight - img.height) * rwidth, + rwidth, img.height); + TIFFRGBAImageEnd(&img); + } + else + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); + ok = 0; } return (ok); } @@ -542,73 +634,72 @@ TIFFReadRGBAImageOriented(TIFF* tif, * Read the specified image into an ABGR-format raster. Use bottom left * origin for raster by default. */ -int -TIFFReadRGBAImage(TIFF* tif, - uint32 rwidth, uint32 rheight, uint32* raster, int stop) +int TIFFReadRGBAImage(TIFF *tif, uint32_t rwidth, uint32_t rheight, + uint32_t *raster, int stop) { - return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster, - ORIENTATION_BOTLEFT, stop); + return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster, + ORIENTATION_BOTLEFT, stop); } -static int -setorientation(TIFFRGBAImage* img) +static int setorientation(TIFFRGBAImage *img) { - switch (img->orientation) { - case ORIENTATION_TOPLEFT: - case ORIENTATION_LEFTTOP: - if (img->req_orientation == ORIENTATION_TOPRIGHT || - img->req_orientation == ORIENTATION_RIGHTTOP) - return FLIP_HORIZONTALLY; - else if (img->req_orientation == ORIENTATION_BOTRIGHT || - img->req_orientation == ORIENTATION_RIGHTBOT) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTLEFT || - img->req_orientation == ORIENTATION_LEFTBOT) - return FLIP_VERTICALLY; - else - return 0; - case ORIENTATION_TOPRIGHT: - case ORIENTATION_RIGHTTOP: - if (img->req_orientation == ORIENTATION_TOPLEFT || - img->req_orientation == ORIENTATION_LEFTTOP) - return FLIP_HORIZONTALLY; - else if (img->req_orientation == ORIENTATION_BOTRIGHT || - img->req_orientation == ORIENTATION_RIGHTBOT) - return FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTLEFT || - img->req_orientation == ORIENTATION_LEFTBOT) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else - return 0; - case ORIENTATION_BOTRIGHT: - case ORIENTATION_RIGHTBOT: - if (img->req_orientation == ORIENTATION_TOPLEFT || - img->req_orientation == ORIENTATION_LEFTTOP) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_TOPRIGHT || - img->req_orientation == ORIENTATION_RIGHTTOP) - return FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTLEFT || - img->req_orientation == ORIENTATION_LEFTBOT) - return FLIP_HORIZONTALLY; - else - return 0; - case ORIENTATION_BOTLEFT: - case ORIENTATION_LEFTBOT: - if (img->req_orientation == ORIENTATION_TOPLEFT || - img->req_orientation == ORIENTATION_LEFTTOP) - return FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_TOPRIGHT || - img->req_orientation == ORIENTATION_RIGHTTOP) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTRIGHT || - img->req_orientation == ORIENTATION_RIGHTBOT) - return FLIP_HORIZONTALLY; - else - return 0; - default: /* NOTREACHED */ - return 0; - } + switch (img->orientation) + { + case ORIENTATION_TOPLEFT: + case ORIENTATION_LEFTTOP: + if (img->req_orientation == ORIENTATION_TOPRIGHT || + img->req_orientation == ORIENTATION_RIGHTTOP) + return FLIP_HORIZONTALLY; + else if (img->req_orientation == ORIENTATION_BOTRIGHT || + img->req_orientation == ORIENTATION_RIGHTBOT) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTLEFT || + img->req_orientation == ORIENTATION_LEFTBOT) + return FLIP_VERTICALLY; + else + return 0; + case ORIENTATION_TOPRIGHT: + case ORIENTATION_RIGHTTOP: + if (img->req_orientation == ORIENTATION_TOPLEFT || + img->req_orientation == ORIENTATION_LEFTTOP) + return FLIP_HORIZONTALLY; + else if (img->req_orientation == ORIENTATION_BOTRIGHT || + img->req_orientation == ORIENTATION_RIGHTBOT) + return FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTLEFT || + img->req_orientation == ORIENTATION_LEFTBOT) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else + return 0; + case ORIENTATION_BOTRIGHT: + case ORIENTATION_RIGHTBOT: + if (img->req_orientation == ORIENTATION_TOPLEFT || + img->req_orientation == ORIENTATION_LEFTTOP) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_TOPRIGHT || + img->req_orientation == ORIENTATION_RIGHTTOP) + return FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTLEFT || + img->req_orientation == ORIENTATION_LEFTBOT) + return FLIP_HORIZONTALLY; + else + return 0; + case ORIENTATION_BOTLEFT: + case ORIENTATION_LEFTBOT: + if (img->req_orientation == ORIENTATION_TOPLEFT || + img->req_orientation == ORIENTATION_LEFTTOP) + return FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_TOPRIGHT || + img->req_orientation == ORIENTATION_RIGHTTOP) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTRIGHT || + img->req_orientation == ORIENTATION_RIGHTBOT) + return FLIP_HORIZONTALLY; + else + return 0; + default: /* NOTREACHED */ + return 0; + } } /* @@ -616,28 +707,29 @@ setorientation(TIFFRGBAImage* img) * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 - */ -static int -gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) + */ +static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) { - TIFF* tif = img->tif; + TIFF *tif = img->tif; tileContigRoutine put = img->put.contig; - uint32 col, row, y, rowstoread; + uint32_t col, row, y, rowstoread; tmsize_t pos; - uint32 tw, th; - unsigned char* buf = NULL; - int32 fromskew, toskew; - uint32 nrow; + uint32_t tw, th; + unsigned char *buf = NULL; + int32_t fromskew, toskew; + uint32_t nrow; int ret = 1, flip; - uint32 this_tw, tocol; - int32 this_toskew, leftmost_toskew; - int32 leftmost_fromskew; - uint32 leftmost_tw; + uint32_t this_tw, tocol; + int32_t this_toskew, leftmost_toskew; + int32_t leftmost_fromskew; + uint32_t leftmost_tw; tmsize_t bufsize; bufsize = TIFFTileSize(tif); - if (bufsize == 0) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); + if (bufsize == 0) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "No space for tile buffer"); return (0); } @@ -645,23 +737,29 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); flip = setorientation(img); - if (flip & FLIP_VERTICALLY) { - if ((tw + w) > INT_MAX) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); + if (flip & FLIP_VERTICALLY) + { + if ((tw + w) > INT_MAX) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", + "unsupported tile size (too wide)"); return (0); } y = h - 1; - toskew = -(int32)(tw + w); + toskew = -(int32_t)(tw + w); } - else { - if (tw > (INT_MAX + w)) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); + else + { + if (tw > (INT_MAX + w)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", + "unsupported tile size (too wide)"); return (0); } y = 0; - toskew = -(int32)(tw - w); + toskew = -(int32_t)(tw - w); } - + /* * Leftmost tile is clipped on left side if col_offset > 0. */ @@ -671,62 +769,69 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) for (row = 0; ret != 0 && row < h; row += nrow) { rowstoread = th - (row + img->row_offset) % th; - nrow = (row + rowstoread > h ? h - row : rowstoread); - fromskew = leftmost_fromskew; - this_tw = leftmost_tw; - this_toskew = leftmost_toskew; - tocol = 0; - col = img->col_offset; - while (tocol < w) + nrow = (row + rowstoread > h ? h - row : rowstoread); + fromskew = leftmost_fromskew; + this_tw = leftmost_tw; + this_toskew = leftmost_toskew; + tocol = 0; + col = img->col_offset; + while (tocol < w) { - if (_TIFFReadTileAndAllocBuffer(tif, (void**) &buf, bufsize, col, - row+img->row_offset, 0, 0)==(tmsize_t)(-1) && + if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, col, + row + img->row_offset, 0, + 0) == (tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; break; } - pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \ - ((tmsize_t) fromskew * img->samplesperpixel); - if (tocol + this_tw > w) - { - /* - * Rightmost tile is clipped on right side. - */ - fromskew = tw - (w - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; - } - (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, buf + pos); - tocol += this_tw; - col += this_tw; - /* - * After the leftmost tile, tiles are no longer clipped on left side. - */ - fromskew = 0; - this_tw = tw; - this_toskew = toskew; - } + pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + + ((tmsize_t)fromskew * img->samplesperpixel); + if (tocol + this_tw > w) + { + /* + * Rightmost tile is clipped on right side. + */ + fromskew = tw - (w - tocol); + this_tw = tw - fromskew; + this_toskew = toskew + fromskew; + } + tmsize_t roffset = (tmsize_t)y * w + tocol; + (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, + this_toskew, buf + pos); + tocol += this_tw; + col += this_tw; + /* + * After the leftmost tile, tiles are no longer clipped on left + * side. + */ + fromskew = 0; + this_tw = tw; + this_toskew = toskew; + } - y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); + y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); } - _TIFFfree(buf); + _TIFFfreeExt(img->tif, buf); - if (flip & FLIP_HORIZONTALLY) { - uint32 line; + if (flip & FLIP_HORIZONTALLY) + { + uint32_t line; - for (line = 0; line < h; line++) { - uint32 *left = raster + (line * w); - uint32 *right = left + w - 1; - - while ( left < right ) { - uint32 temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } + for (line = 0; line < h; line++) + { + uint32_t *left = raster + (line * w); + uint32_t *right = left + w - 1; + + while (left < right) + { + uint32_t temp = *left; + *left = *right; + *right = temp; + left++; + right--; + } + } } return (ret); @@ -737,188 +842,203 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) * SamplesPerPixel > 1 * PlanarConfiguration separated * We assume that all such images are RGB. - */ -static int -gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) + */ +static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) { - TIFF* tif = img->tif; - tileSeparateRoutine put = img->put.separate; - uint32 col, row, y, rowstoread; - tmsize_t pos; - uint32 tw, th; - unsigned char* buf = NULL; - unsigned char* p0 = NULL; - unsigned char* p1 = NULL; - unsigned char* p2 = NULL; - unsigned char* pa = NULL; - tmsize_t tilesize; - tmsize_t bufsize; - int32 fromskew, toskew; - int alpha = img->alpha; - uint32 nrow; - int ret = 1, flip; - uint16 colorchannels; - uint32 this_tw, tocol; - int32 this_toskew, leftmost_toskew; - int32 leftmost_fromskew; - uint32 leftmost_tw; + TIFF *tif = img->tif; + tileSeparateRoutine put = img->put.separate; + uint32_t col, row, y, rowstoread; + tmsize_t pos; + uint32_t tw, th; + unsigned char *buf = NULL; + unsigned char *p0 = NULL; + unsigned char *p1 = NULL; + unsigned char *p2 = NULL; + unsigned char *pa = NULL; + tmsize_t tilesize; + tmsize_t bufsize; + int32_t fromskew, toskew; + int alpha = img->alpha; + uint32_t nrow; + int ret = 1, flip; + uint16_t colorchannels; + uint32_t this_tw, tocol; + int32_t this_toskew, leftmost_toskew; + int32_t leftmost_fromskew; + uint32_t leftmost_tw; - tilesize = TIFFTileSize(tif); - bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate"); - if (bufsize == 0) { - return (0); - } + tilesize = TIFFTileSize(tif); + bufsize = + _TIFFMultiplySSize(tif, alpha ? 4 : 3, tilesize, "gtTileSeparate"); + if (bufsize == 0) + { + return (0); + } - TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); - TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) { - if ((tw + w) > INT_MAX) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); - return (0); - } - y = h - 1; - toskew = -(int32)(tw + w); - } - else { - if (tw > (INT_MAX + w)) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); - return (0); - } - y = 0; - toskew = -(int32)(tw - w); - } - - switch( img->photometric ) + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) + { + if ((tw + w) > INT_MAX) { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_PALETTE: + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", + "unsupported tile size (too wide)"); + return (0); + } + y = h - 1; + toskew = -(int32_t)(tw + w); + } + else + { + if (tw > (INT_MAX + w)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", + "unsupported tile size (too wide)"); + return (0); + } + y = 0; + toskew = -(int32_t)(tw - w); + } + + switch (img->photometric) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: colorchannels = 1; break; - default: + default: colorchannels = 3; break; + } + + /* + * Leftmost tile is clipped on left side if col_offset > 0. + */ + leftmost_fromskew = img->col_offset % tw; + leftmost_tw = tw - leftmost_fromskew; + leftmost_toskew = toskew + leftmost_fromskew; + for (row = 0; ret != 0 && row < h; row += nrow) + { + rowstoread = th - (row + img->row_offset) % th; + nrow = (row + rowstoread > h ? h - row : rowstoread); + fromskew = leftmost_fromskew; + this_tw = leftmost_tw; + this_toskew = leftmost_toskew; + tocol = 0; + col = img->col_offset; + while (tocol < w) + { + if (buf == NULL) + { + if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, + col, row + img->row_offset, 0, + 0) == (tmsize_t)(-1) && + (buf == NULL || img->stoponerr)) + { + ret = 0; + break; + } + p0 = buf; + if (colorchannels == 1) + { + p2 = p1 = p0; + pa = (alpha ? (p0 + 3 * tilesize) : NULL); + } + else + { + p1 = p0 + tilesize; + p2 = p1 + tilesize; + pa = (alpha ? (p2 + tilesize) : NULL); + } + } + else if (TIFFReadTile(tif, p0, col, row + img->row_offset, 0, 0) == + (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 && + TIFFReadTile(tif, p1, col, row + img->row_offset, 0, 1) == + (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 && + TIFFReadTile(tif, p2, col, row + img->row_offset, 0, 2) == + (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (alpha && + TIFFReadTile(tif, pa, col, row + img->row_offset, 0, + colorchannels) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + + pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + + ((tmsize_t)fromskew * img->samplesperpixel); + if (tocol + this_tw > w) + { + /* + * Rightmost tile is clipped on right side. + */ + fromskew = tw - (w - tocol); + this_tw = tw - fromskew; + this_toskew = toskew + fromskew; + } + tmsize_t roffset = (tmsize_t)y * w + tocol; + (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, + this_toskew, p0 + pos, p1 + pos, p2 + pos, + (alpha ? (pa + pos) : NULL)); + tocol += this_tw; + col += this_tw; + /* + * After the leftmost tile, tiles are no longer clipped on left + * side. + */ + fromskew = 0; + this_tw = tw; + this_toskew = toskew; } - /* - * Leftmost tile is clipped on left side if col_offset > 0. - */ - leftmost_fromskew = img->col_offset % tw; - leftmost_tw = tw - leftmost_fromskew; - leftmost_toskew = toskew + leftmost_fromskew; - for (row = 0; ret != 0 && row < h; row += nrow) - { - rowstoread = th - (row + img->row_offset) % th; - nrow = (row + rowstoread > h ? h - row : rowstoread); - fromskew = leftmost_fromskew; - this_tw = leftmost_tw; - this_toskew = leftmost_toskew; - tocol = 0; - col = img->col_offset; - while (tocol < w) - { - if( buf == NULL ) - { - if (_TIFFReadTileAndAllocBuffer( - tif, (void**) &buf, bufsize, col, - row+img->row_offset,0,0)==(tmsize_t)(-1) - && (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } - p0 = buf; - if( colorchannels == 1 ) - { - p2 = p1 = p0; - pa = (alpha?(p0+3*tilesize):NULL); - } - else - { - p1 = p0 + tilesize; - p2 = p1 + tilesize; - pa = (alpha?(p2+tilesize):NULL); - } - } - else if (TIFFReadTile(tif, p0, col, - row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 - && TIFFReadTile(tif, p1, col, - row+img->row_offset,0,1) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 - && TIFFReadTile(tif, p2, col, - row+img->row_offset,0,2) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (alpha - && TIFFReadTile(tif,pa,col, - row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } + y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + } - pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \ - ((tmsize_t) fromskew * img->samplesperpixel); - if (tocol + this_tw > w) - { - /* - * Rightmost tile is clipped on right side. - */ - fromskew = tw - (w - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; - } - (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, \ - p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); - tocol += this_tw; - col += this_tw; - /* - * After the leftmost tile, tiles are no longer clipped on left side. - */ - fromskew = 0; - this_tw = tw; - this_toskew = toskew; - } + if (flip & FLIP_HORIZONTALLY) + { + uint32_t line; - y += ((flip & FLIP_VERTICALLY) ?-(int32) nrow : (int32) nrow); - } + for (line = 0; line < h; line++) + { + uint32_t *left = raster + (line * w); + uint32_t *right = left + w - 1; - if (flip & FLIP_HORIZONTALLY) { - uint32 line; + while (left < right) + { + uint32_t temp = *left; + *left = *right; + *right = temp; + left++; + right--; + } + } + } - for (line = 0; line < h; line++) { - uint32 *left = raster + (line * w); - uint32 *right = left + w - 1; - - while ( left < right ) { - uint32 temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } - - _TIFFfree(buf); - return (ret); + _TIFFfreeExt(img->tif, buf); + return (ret); } /* @@ -926,98 +1046,110 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 - */ -static int -gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) + */ +static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) { - TIFF* tif = img->tif; - tileContigRoutine put = img->put.contig; - uint32 row, y, nrow, nrowsub, rowstoread; - tmsize_t pos; - unsigned char* buf = NULL; - uint32 rowsperstrip; - uint16 subsamplinghor,subsamplingver; - uint32 imagewidth = img->width; - tmsize_t scanline; - int32 fromskew, toskew; - int ret = 1, flip; - tmsize_t maxstripsize; + TIFF *tif = img->tif; + tileContigRoutine put = img->put.contig; + uint32_t row, y, nrow, nrowsub, rowstoread; + tmsize_t pos; + unsigned char *buf = NULL; + uint32_t rowsperstrip; + uint16_t subsamplinghor, subsamplingver; + uint32_t imagewidth = img->width; + tmsize_t scanline; + int32_t fromskew, toskew; + int ret = 1, flip; + tmsize_t maxstripsize; - TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver); - if( subsamplingver == 0 ) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling"); - return (0); - } - - maxstripsize = TIFFStripSize(tif); + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, + &subsamplingver); + if (subsamplingver == 0) + { + TIFFErrorExtR(tif, TIFFFileName(tif), + "Invalid vertical YCbCr subsampling"); + return (0); + } - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) { - if ( w > INT_MAX ) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Width overflow"); - return (0); - } - y = h - 1; - toskew = -(int32)(w + w); - } else { - y = 0; - toskew = -(int32)(w - w); - } + maxstripsize = TIFFStripSize(tif); - TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) + { + if (w > INT_MAX) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow"); + return (0); + } + y = h - 1; + toskew = -(int32_t)(w + w); + } + else + { + y = 0; + toskew = -(int32_t)(w - w); + } - scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); - for (row = 0; row < h; row += nrow) - { - uint32 temp; - rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; - nrow = (row + rowstoread > h ? h - row : rowstoread); - nrowsub = nrow; - if ((nrowsub%subsamplingver)!=0) - nrowsub+=subsamplingver-nrowsub%subsamplingver; - temp = (row + img->row_offset)%rowsperstrip + nrowsub; - if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) ) - { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripContig"); - return 0; - } - if (_TIFFReadEncodedStripAndAllocBuffer(tif, - TIFFComputeStrip(tif,row+img->row_offset, 0), - (void**)(&buf), - maxstripsize, - temp * scanline)==(tmsize_t)(-1) - && (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ - ((tmsize_t) img->col_offset * img->samplesperpixel); - (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos); - y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); - } + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += nrow) + { + uint32_t temp; + rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + nrow = (row + rowstoread > h ? h - row : rowstoread); + nrowsub = nrow; + if ((nrowsub % subsamplingver) != 0) + nrowsub += subsamplingver - nrowsub % subsamplingver; + temp = (row + img->row_offset) % rowsperstrip + nrowsub; + if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), + "Integer overflow in gtStripContig"); + return 0; + } + if (_TIFFReadEncodedStripAndAllocBuffer( + tif, TIFFComputeStrip(tif, row + img->row_offset, 0), + (void **)(&buf), maxstripsize, + temp * scanline) == (tmsize_t)(-1) && + (buf == NULL || img->stoponerr)) + { + ret = 0; + break; + } - if (flip & FLIP_HORIZONTALLY) { - uint32 line; + pos = ((row + img->row_offset) % rowsperstrip) * scanline + + ((tmsize_t)img->col_offset * img->samplesperpixel); + tmsize_t roffset = (tmsize_t)y * w; + (*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew, + buf + pos); + y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + } - for (line = 0; line < h; line++) { - uint32 *left = raster + (line * w); - uint32 *right = left + w - 1; + if (flip & FLIP_HORIZONTALLY) + { + uint32_t line; - while ( left < right ) { - uint32 temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } + for (line = 0; line < h; line++) + { + uint32_t *left = raster + (line * w); + uint32_t *right = left + w - 1; - _TIFFfree(buf); - return (ret); + while (left < right) + { + uint32_t temp = *left; + *left = *right; + *right = temp; + left++; + right--; + } + } + } + + _TIFFfreeExt(img->tif, buf); + return (ret); } /* @@ -1026,157 +1158,167 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) * PlanarConfiguration separated * We assume that all such images are RGB. */ -static int -gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) { - TIFF* tif = img->tif; - tileSeparateRoutine put = img->put.separate; - unsigned char *buf = NULL; - unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL; - uint32 row, y, nrow, rowstoread; - tmsize_t pos; - tmsize_t scanline; - uint32 rowsperstrip, offset_row; - uint32 imagewidth = img->width; - tmsize_t stripsize; - tmsize_t bufsize; - int32 fromskew, toskew; - int alpha = img->alpha; - int ret = 1, flip; - uint16 colorchannels; + TIFF *tif = img->tif; + tileSeparateRoutine put = img->put.separate; + unsigned char *buf = NULL; + unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL; + uint32_t row, y, nrow, rowstoread; + tmsize_t pos; + tmsize_t scanline; + uint32_t rowsperstrip, offset_row; + uint32_t imagewidth = img->width; + tmsize_t stripsize; + tmsize_t bufsize; + int32_t fromskew, toskew; + int alpha = img->alpha; + int ret = 1, flip; + uint16_t colorchannels; - stripsize = TIFFStripSize(tif); - bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate"); - if (bufsize == 0) { - return (0); - } + stripsize = TIFFStripSize(tif); + bufsize = + _TIFFMultiplySSize(tif, alpha ? 4 : 3, stripsize, "gtStripSeparate"); + if (bufsize == 0) + { + return (0); + } - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) { - if ( w > INT_MAX ) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Width overflow"); - return (0); - } - y = h - 1; - toskew = -(int32)(w + w); - } - else { - y = 0; - toskew = -(int32)(w - w); - } - - switch( img->photometric ) + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) + { + if (w > INT_MAX) { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_PALETTE: + TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow"); + return (0); + } + y = h - 1; + toskew = -(int32_t)(w + w); + } + else + { + y = 0; + toskew = -(int32_t)(w - w); + } + + switch (img->photometric) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: colorchannels = 1; break; - default: + default: colorchannels = 3; break; + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += nrow) + { + uint32_t temp; + rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + nrow = (row + rowstoread > h ? h - row : rowstoread); + offset_row = row + img->row_offset; + temp = (row + img->row_offset) % rowsperstrip + nrow; + if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), + "Integer overflow in gtStripSeparate"); + return 0; + } + if (buf == NULL) + { + if (_TIFFReadEncodedStripAndAllocBuffer( + tif, TIFFComputeStrip(tif, offset_row, 0), (void **)&buf, + bufsize, temp * scanline) == (tmsize_t)(-1) && + (buf == NULL || img->stoponerr)) + { + ret = 0; + break; + } + p0 = buf; + if (colorchannels == 1) + { + p2 = p1 = p0; + pa = (alpha ? (p0 + 3 * stripsize) : NULL); + } + else + { + p1 = p0 + stripsize; + p2 = p1 + stripsize; + pa = (alpha ? (p2 + stripsize) : NULL); + } + } + else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), + p0, temp * scanline) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 && + TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), p1, + temp * scanline) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 && + TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), p2, + temp * scanline) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (alpha) + { + if (TIFFReadEncodedStrip( + tif, TIFFComputeStrip(tif, offset_row, colorchannels), pa, + temp * scanline) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } } - TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); - for (row = 0; row < h; row += nrow) - { - uint32 temp; - rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; - nrow = (row + rowstoread > h ? h - row : rowstoread); - offset_row = row + img->row_offset; - temp = (row + img->row_offset)%rowsperstrip + nrow; - if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) ) - { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripSeparate"); - return 0; - } - if( buf == NULL ) - { - if (_TIFFReadEncodedStripAndAllocBuffer( - tif, TIFFComputeStrip(tif, offset_row, 0), - (void**) &buf, bufsize, - temp * scanline)==(tmsize_t)(-1) - && (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } - p0 = buf; - if( colorchannels == 1 ) - { - p2 = p1 = p0; - pa = (alpha?(p0+3*stripsize):NULL); - } - else - { - p1 = p0 + stripsize; - p2 = p1 + stripsize; - pa = (alpha?(p2+stripsize):NULL); - } - } - else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), - p0, temp * scanline)==(tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 - && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), - p1, temp * scanline) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 - && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), - p2, temp * scanline) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (alpha) - { - if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels), - pa, temp * scanline)==(tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - } + pos = ((row + img->row_offset) % rowsperstrip) * scanline + + ((tmsize_t)img->col_offset * img->samplesperpixel); + tmsize_t roffset = (tmsize_t)y * w; + (*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew, p0 + pos, + p1 + pos, p2 + pos, (alpha ? (pa + pos) : NULL)); + y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + } - pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ - ((tmsize_t) img->col_offset * img->samplesperpixel); - (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos, - p2 + pos, (alpha?(pa+pos):NULL)); - y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); - } + if (flip & FLIP_HORIZONTALLY) + { + uint32_t line; - if (flip & FLIP_HORIZONTALLY) { - uint32 line; + for (line = 0; line < h; line++) + { + uint32_t *left = raster + (line * w); + uint32_t *right = left + w - 1; - for (line = 0; line < h; line++) { - uint32 *left = raster + (line * w); - uint32 *right = left + w - 1; + while (left < right) + { + uint32_t temp = *left; + *left = *right; + *right = temp; + left++; + right--; + } + } + } - while ( left < right ) { - uint32 temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } - - _TIFFfree(buf); - return (ret); + _TIFFfreeExt(img->tif, buf); + return (ret); } /* @@ -1189,98 +1331,139 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) * PickSeparateCase analyze the parameters and select * the appropriate "get" and "put" routine to use. */ -#define REPEAT8(op) REPEAT4(op); REPEAT4(op) -#define REPEAT4(op) REPEAT2(op); REPEAT2(op) -#define REPEAT2(op) op; op -#define CASE8(x,op) \ - switch (x) { \ - case 7: op; /*-fallthrough*/ \ - case 6: op; /*-fallthrough*/ \ - case 5: op; /*-fallthrough*/ \ - case 4: op; /*-fallthrough*/ \ - case 3: op; /*-fallthrough*/ \ - case 2: op; /*-fallthrough*/ \ - case 1: op; \ +#define REPEAT8(op) \ + REPEAT4(op); \ + REPEAT4(op) +#define REPEAT4(op) \ + REPEAT2(op); \ + REPEAT2(op) +#define REPEAT2(op) \ + op; \ + op +#define CASE8(x, op) \ + switch (x) \ + { \ + case 7: \ + op; /*-fallthrough*/ \ + case 6: \ + op; /*-fallthrough*/ \ + case 5: \ + op; /*-fallthrough*/ \ + case 4: \ + op; /*-fallthrough*/ \ + case 3: \ + op; /*-fallthrough*/ \ + case 2: \ + op; /*-fallthrough*/ \ + case 1: \ + op; \ } -#define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; } -#define NOP +#define CASE4(x, op) \ + switch (x) \ + { \ + case 3: \ + op; /*-fallthrough*/ \ + case 2: \ + op; /*-fallthrough*/ \ + case 1: \ + op; \ + } +#define NOP -#define UNROLL8(w, op1, op2) { \ - uint32 _x; \ - for (_x = w; _x >= 8; _x -= 8) { \ - op1; \ - REPEAT8(op2); \ - } \ - if (_x > 0) { \ - op1; \ - CASE8(_x,op2); \ - } \ -} -#define UNROLL4(w, op1, op2) { \ - uint32 _x; \ - for (_x = w; _x >= 4; _x -= 4) { \ - op1; \ - REPEAT4(op2); \ - } \ - if (_x > 0) { \ - op1; \ - CASE4(_x,op2); \ - } \ -} -#define UNROLL2(w, op1, op2) { \ - uint32 _x; \ - for (_x = w; _x >= 2; _x -= 2) { \ - op1; \ - REPEAT2(op2); \ - } \ - if (_x) { \ - op1; \ - op2; \ - } \ -} - -#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; } -#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; } +#define UNROLL8(w, op1, op2) \ + { \ + uint32_t _x; \ + for (_x = w; _x >= 8; _x -= 8) \ + { \ + op1; \ + REPEAT8(op2); \ + } \ + if (_x > 0) \ + { \ + op1; \ + CASE8(_x, op2); \ + } \ + } +#define UNROLL4(w, op1, op2) \ + { \ + uint32_t _x; \ + for (_x = w; _x >= 4; _x -= 4) \ + { \ + op1; \ + REPEAT4(op2); \ + } \ + if (_x > 0) \ + { \ + op1; \ + CASE4(_x, op2); \ + } \ + } +#define UNROLL2(w, op1, op2) \ + { \ + uint32_t _x; \ + for (_x = w; _x >= 2; _x -= 2) \ + { \ + op1; \ + REPEAT2(op2); \ + } \ + if (_x) \ + { \ + op1; \ + op2; \ + } \ + } -#define A1 (((uint32)0xffL)<<24) -#define PACK(r,g,b) \ - ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1) -#define PACK4(r,g,b,a) \ - ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24)) -#define W2B(v) (((v)>>8)&0xff) +#define SKEW(r, g, b, skew) \ + { \ + r += skew; \ + g += skew; \ + b += skew; \ + } +#define SKEW4(r, g, b, a, skew) \ + { \ + r += skew; \ + g += skew; \ + b += skew; \ + a += skew; \ + } + +#define A1 (((uint32_t)0xffL) << 24) +#define PACK(r, g, b) \ + ((uint32_t)(r) | ((uint32_t)(g) << 8) | ((uint32_t)(b) << 16) | A1) +#define PACK4(r, g, b, a) \ + ((uint32_t)(r) | ((uint32_t)(g) << 8) | ((uint32_t)(b) << 16) | \ + ((uint32_t)(a) << 24)) +#define W2B(v) (((v) >> 8) & 0xff) /* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */ -#define PACKW(r,g,b) \ - ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1) -#define PACKW4(r,g,b,a) \ - ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24)) +#define PACKW(r, g, b) \ + ((uint32_t)W2B(r) | ((uint32_t)W2B(g) << 8) | ((uint32_t)W2B(b) << 16) | A1) +#define PACKW4(r, g, b, a) \ + ((uint32_t)W2B(r) | ((uint32_t)W2B(g) << 8) | ((uint32_t)W2B(b) << 16) | \ + ((uint32_t)W2B(a) << 24)) -#define DECLAREContigPutFunc(name) \ -static void name(\ - TIFFRGBAImage* img, \ - uint32* cp, \ - uint32 x, uint32 y, \ - uint32 w, uint32 h, \ - int32 fromskew, int32 toskew, \ - unsigned char* pp \ -) +#define DECLAREContigPutFunc(name) \ + static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \ + uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \ + unsigned char *pp) /* * 8-bit palette => colormap/RGB */ DECLAREContigPutFunc(put8bitcmaptile) { - uint32** PALmap = img->PALmap; + uint32_t **PALmap = img->PALmap; int samplesperpixel = img->samplesperpixel; - (void) y; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) + (void)y; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) { - *cp++ = PALmap[*pp][0]; + *cp++ = PALmap[*pp][0]; pp += samplesperpixel; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } } @@ -1289,15 +1472,17 @@ DECLAREContigPutFunc(put8bitcmaptile) */ DECLAREContigPutFunc(put4bitcmaptile) { - uint32** PALmap = img->PALmap; + uint32_t **PALmap = img->PALmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 2; - for( ; h > 0; --h) { - uint32* bw; - UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1306,15 +1491,17 @@ DECLAREContigPutFunc(put4bitcmaptile) */ DECLAREContigPutFunc(put2bitcmaptile) { - uint32** PALmap = img->PALmap; + uint32_t **PALmap = img->PALmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 4; - for( ; h > 0; --h) { - uint32* bw; - UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1323,15 +1510,17 @@ DECLAREContigPutFunc(put2bitcmaptile) */ DECLAREContigPutFunc(put1bitcmaptile) { - uint32** PALmap = img->PALmap; + uint32_t **PALmap = img->PALmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 8; - for( ; h > 0; --h) { - uint32* bw; - UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1341,17 +1530,18 @@ DECLAREContigPutFunc(put1bitcmaptile) DECLAREContigPutFunc(putgreytile) { int samplesperpixel = img->samplesperpixel; - uint32** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) y; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) + (void)y; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) { - *cp++ = BWmap[*pp][0]; + *cp++ = BWmap[*pp][0]; pp += samplesperpixel; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } } @@ -1361,17 +1551,18 @@ DECLAREContigPutFunc(putgreytile) DECLAREContigPutFunc(putagreytile) { int samplesperpixel = img->samplesperpixel; - uint32** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) y; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) + (void)y; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) { - *cp++ = BWmap[*pp][0] & ((uint32)*(pp+1) << 24 | ~A1); + *cp++ = BWmap[*pp][0] & ((uint32_t) * (pp + 1) << 24 | ~A1); pp += samplesperpixel; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } } @@ -1381,22 +1572,23 @@ DECLAREContigPutFunc(putagreytile) DECLAREContigPutFunc(put16bitbwtile) { int samplesperpixel = img->samplesperpixel; - uint32** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) y; - for( ; h > 0; --h) { - uint16 *wp = (uint16 *) pp; + (void)y; + for (; h > 0; --h) + { + uint16_t *wp = (uint16_t *)pp; - for (x = w; x > 0; --x) + for (x = w; x > 0; --x) { /* use high order byte of 16bit value */ - *cp++ = BWmap[*wp >> 8][0]; + *cp++ = BWmap[*wp >> 8][0]; pp += 2 * samplesperpixel; wp += samplesperpixel; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } } @@ -1405,15 +1597,17 @@ DECLAREContigPutFunc(put16bitbwtile) */ DECLAREContigPutFunc(put1bitbwtile) { - uint32** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 8; - for( ; h > 0; --h) { - uint32* bw; - UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1422,15 +1616,17 @@ DECLAREContigPutFunc(put1bitbwtile) */ DECLAREContigPutFunc(put2bitbwtile) { - uint32** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 4; - for( ; h > 0; --h) { - uint32* bw; - UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1439,15 +1635,17 @@ DECLAREContigPutFunc(put2bitbwtile) */ DECLAREContigPutFunc(put4bitbwtile) { - uint32** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 2; - for( ; h > 0; --h) { - uint32* bw; - UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1458,14 +1656,15 @@ DECLAREContigPutFunc(putRGBcontig8bittile) { int samplesperpixel = img->samplesperpixel; - (void) x; (void) y; + (void)x; + (void)y; fromskew *= samplesperpixel; - for( ; h > 0; --h) { - UNROLL8(w, NOP, - *cp++ = PACK(pp[0], pp[1], pp[2]); - pp += samplesperpixel); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + UNROLL8(w, NOP, *cp++ = PACK(pp[0], pp[1], pp[2]); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; } } @@ -1477,14 +1676,15 @@ DECLAREContigPutFunc(putRGBAAcontig8bittile) { int samplesperpixel = img->samplesperpixel; - (void) x; (void) y; + (void)x; + (void)y; fromskew *= samplesperpixel; - for( ; h > 0; --h) { - UNROLL8(w, NOP, - *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); - pp += samplesperpixel); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + UNROLL8(w, NOP, *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; } } @@ -1494,24 +1694,26 @@ DECLAREContigPutFunc(putRGBAAcontig8bittile) */ DECLAREContigPutFunc(putRGBUAcontig8bittile) { - int samplesperpixel = img->samplesperpixel; - (void) y; - fromskew *= samplesperpixel; - for( ; h > 0; --h) { - uint32 r, g, b, a; - uint8* m; - for (x = w; x > 0; --x) { - a = pp[3]; - m = img->UaToAa+((size_t) a<<8); - r = m[pp[0]]; - g = m[pp[1]]; - b = m[pp[2]]; - *cp++ = PACK4(r,g,b,a); - pp += samplesperpixel; - } - cp += toskew; - pp += fromskew; - } + int samplesperpixel = img->samplesperpixel; + (void)y; + fromskew *= samplesperpixel; + for (; h > 0; --h) + { + uint32_t r, g, b, a; + uint8_t *m; + for (x = w; x > 0; --x) + { + a = pp[3]; + m = img->UaToAa + ((size_t)a << 8); + r = m[pp[0]]; + g = m[pp[1]]; + b = m[pp[2]]; + *cp++ = PACK4(r, g, b, a); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } } /* @@ -1519,20 +1721,21 @@ DECLAREContigPutFunc(putRGBUAcontig8bittile) */ DECLAREContigPutFunc(putRGBcontig16bittile) { - int samplesperpixel = img->samplesperpixel; - uint16 *wp = (uint16 *)pp; - (void) y; - fromskew *= samplesperpixel; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) { - *cp++ = PACK(img->Bitdepth16To8[wp[0]], - img->Bitdepth16To8[wp[1]], - img->Bitdepth16To8[wp[2]]); - wp += samplesperpixel; - } - cp += toskew; - wp += fromskew; - } + int samplesperpixel = img->samplesperpixel; + uint16_t *wp = (uint16_t *)pp; + (void)y; + fromskew *= samplesperpixel; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + *cp++ = PACK(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]], + img->Bitdepth16To8[wp[2]]); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } } /* @@ -1541,21 +1744,21 @@ DECLAREContigPutFunc(putRGBcontig16bittile) */ DECLAREContigPutFunc(putRGBAAcontig16bittile) { - int samplesperpixel = img->samplesperpixel; - uint16 *wp = (uint16 *)pp; - (void) y; - fromskew *= samplesperpixel; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) { - *cp++ = PACK4(img->Bitdepth16To8[wp[0]], - img->Bitdepth16To8[wp[1]], - img->Bitdepth16To8[wp[2]], - img->Bitdepth16To8[wp[3]]); - wp += samplesperpixel; - } - cp += toskew; - wp += fromskew; - } + int samplesperpixel = img->samplesperpixel; + uint16_t *wp = (uint16_t *)pp; + (void)y; + fromskew *= samplesperpixel; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + *cp++ = PACK4(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]], + img->Bitdepth16To8[wp[2]], img->Bitdepth16To8[wp[3]]); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } } /* @@ -1564,25 +1767,27 @@ DECLAREContigPutFunc(putRGBAAcontig16bittile) */ DECLAREContigPutFunc(putRGBUAcontig16bittile) { - int samplesperpixel = img->samplesperpixel; - uint16 *wp = (uint16 *)pp; - (void) y; - fromskew *= samplesperpixel; - for( ; h > 0; --h) { - uint32 r,g,b,a; - uint8* m; - for (x = w; x > 0; --x) { - a = img->Bitdepth16To8[wp[3]]; - m = img->UaToAa+((size_t) a<<8); - r = m[img->Bitdepth16To8[wp[0]]]; - g = m[img->Bitdepth16To8[wp[1]]]; - b = m[img->Bitdepth16To8[wp[2]]]; - *cp++ = PACK4(r,g,b,a); - wp += samplesperpixel; - } - cp += toskew; - wp += fromskew; - } + int samplesperpixel = img->samplesperpixel; + uint16_t *wp = (uint16_t *)pp; + (void)y; + fromskew *= samplesperpixel; + for (; h > 0; --h) + { + uint32_t r, g, b, a; + uint8_t *m; + for (x = w; x > 0; --x) + { + a = img->Bitdepth16To8[wp[3]]; + m = img->UaToAa + ((size_t)a << 8); + r = m[img->Bitdepth16To8[wp[0]]]; + g = m[img->Bitdepth16To8[wp[1]]]; + b = m[img->Bitdepth16To8[wp[2]]]; + *cp++ = PACK4(r, g, b, a); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } } /* @@ -1593,20 +1798,18 @@ DECLAREContigPutFunc(putRGBUAcontig16bittile) DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) { int samplesperpixel = img->samplesperpixel; - uint16 r, g, b, k; + uint16_t r, g, b, k; - (void) x; (void) y; + (void)x; + (void)y; fromskew *= samplesperpixel; - for( ; h > 0; --h) { - UNROLL8(w, NOP, - k = 255 - pp[3]; - r = (k*(255-pp[0]))/255; - g = (k*(255-pp[1]))/255; - b = (k*(255-pp[2]))/255; - *cp++ = PACK(r, g, b); - pp += samplesperpixel); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + UNROLL8(w, NOP, k = 255 - pp[3]; r = (k * (255 - pp[0])) / 255; + g = (k * (255 - pp[1])) / 255; b = (k * (255 - pp[2])) / 255; + *cp++ = PACK(r, g, b); pp += samplesperpixel); + cp += toskew; + pp += fromskew; } } @@ -1618,45 +1821,47 @@ DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) { int samplesperpixel = img->samplesperpixel; - TIFFRGBValue* Map = img->Map; - uint16 r, g, b, k; + TIFFRGBValue *Map = img->Map; + uint16_t r, g, b, k; - (void) y; + (void)y; fromskew *= samplesperpixel; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) { - k = 255 - pp[3]; - r = (k*(255-pp[0]))/255; - g = (k*(255-pp[1]))/255; - b = (k*(255-pp[2]))/255; - *cp++ = PACK(Map[r], Map[g], Map[b]); - pp += samplesperpixel; - } - pp += fromskew; - cp += toskew; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + k = 255 - pp[3]; + r = (k * (255 - pp[0])) / 255; + g = (k * (255 - pp[1])) / 255; + b = (k * (255 - pp[2])) / 255; + *cp++ = PACK(Map[r], Map[g], Map[b]); + pp += samplesperpixel; + } + pp += fromskew; + cp += toskew; } } -#define DECLARESepPutFunc(name) \ -static void name(\ - TIFFRGBAImage* img,\ - uint32* cp,\ - uint32 x, uint32 y, \ - uint32 w, uint32 h,\ - int32 fromskew, int32 toskew,\ - unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\ -) +#define DECLARESepPutFunc(name) \ + static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \ + uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \ + unsigned char *r, unsigned char *g, unsigned char *b, \ + unsigned char *a) /* * 8-bit unpacked samples => RGB */ DECLARESepPutFunc(putRGBseparate8bittile) { - (void) img; (void) x; (void) y; (void) a; - for( ; h > 0; --h) { - UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); - SKEW(r, g, b, fromskew); - cp += toskew; + (void)img; + (void)x; + (void)y; + (void)a; + for (; h > 0; --h) + { + UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); + SKEW(r, g, b, fromskew); + cp += toskew; } } @@ -1665,12 +1870,15 @@ DECLARESepPutFunc(putRGBseparate8bittile) */ DECLARESepPutFunc(putRGBAAseparate8bittile) { - (void) img; (void) x; (void) y; - for( ; h > 0; --h) { - UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); - SKEW4(r, g, b, a, fromskew); - cp += toskew; - } + (void)img; + (void)x; + (void)y; + for (; h > 0; --h) + { + UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } } /* @@ -1678,19 +1886,22 @@ DECLARESepPutFunc(putRGBAAseparate8bittile) */ DECLARESepPutFunc(putCMYKseparate8bittile) { - (void) img; (void) y; - for( ; h > 0; --h) { - uint32 rv, gv, bv, kv; - for (x = w; x > 0; --x) { - kv = 255 - *a++; - rv = (kv*(255-*r++))/255; - gv = (kv*(255-*g++))/255; - bv = (kv*(255-*b++))/255; - *cp++ = PACK4(rv,gv,bv,255); - } - SKEW4(r, g, b, a, fromskew); - cp += toskew; - } + (void)img; + (void)y; + for (; h > 0; --h) + { + uint32_t rv, gv, bv, kv; + for (x = w; x > 0; --x) + { + kv = 255 - *a++; + rv = (kv * (255 - *r++)) / 255; + gv = (kv * (255 - *g++)) / 255; + bv = (kv * (255 - *b++)) / 255; + *cp++ = PACK4(rv, gv, bv, 255); + } + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } } /* @@ -1698,21 +1909,24 @@ DECLARESepPutFunc(putCMYKseparate8bittile) */ DECLARESepPutFunc(putRGBUAseparate8bittile) { - (void) img; (void) y; - for( ; h > 0; --h) { - uint32 rv, gv, bv, av; - uint8* m; - for (x = w; x > 0; --x) { - av = *a++; - m = img->UaToAa+((size_t) av<<8); - rv = m[*r++]; - gv = m[*g++]; - bv = m[*b++]; - *cp++ = PACK4(rv,gv,bv,av); - } - SKEW4(r, g, b, a, fromskew); - cp += toskew; - } + (void)img; + (void)y; + for (; h > 0; --h) + { + uint32_t rv, gv, bv, av; + uint8_t *m; + for (x = w; x > 0; --x) + { + av = *a++; + m = img->UaToAa + ((size_t)av << 8); + rv = m[*r++]; + gv = m[*g++]; + bv = m[*b++]; + *cp++ = PACK4(rv, gv, bv, av); + } + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } } /* @@ -1720,18 +1934,20 @@ DECLARESepPutFunc(putRGBUAseparate8bittile) */ DECLARESepPutFunc(putRGBseparate16bittile) { - uint16 *wr = (uint16*) r; - uint16 *wg = (uint16*) g; - uint16 *wb = (uint16*) b; - (void) img; (void) y; (void) a; - for( ; h > 0; --h) { - for (x = 0; x < w; x++) - *cp++ = PACK(img->Bitdepth16To8[*wr++], - img->Bitdepth16To8[*wg++], - img->Bitdepth16To8[*wb++]); - SKEW(wr, wg, wb, fromskew); - cp += toskew; - } + uint16_t *wr = (uint16_t *)r; + uint16_t *wg = (uint16_t *)g; + uint16_t *wb = (uint16_t *)b; + (void)img; + (void)y; + (void)a; + for (; h > 0; --h) + { + for (x = 0; x < w; x++) + *cp++ = PACK(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++], + img->Bitdepth16To8[*wb++]); + SKEW(wr, wg, wb, fromskew); + cp += toskew; + } } /* @@ -1739,20 +1955,20 @@ DECLARESepPutFunc(putRGBseparate16bittile) */ DECLARESepPutFunc(putRGBAAseparate16bittile) { - uint16 *wr = (uint16*) r; - uint16 *wg = (uint16*) g; - uint16 *wb = (uint16*) b; - uint16 *wa = (uint16*) a; - (void) img; (void) y; - for( ; h > 0; --h) { - for (x = 0; x < w; x++) - *cp++ = PACK4(img->Bitdepth16To8[*wr++], - img->Bitdepth16To8[*wg++], - img->Bitdepth16To8[*wb++], - img->Bitdepth16To8[*wa++]); - SKEW4(wr, wg, wb, wa, fromskew); - cp += toskew; - } + uint16_t *wr = (uint16_t *)r; + uint16_t *wg = (uint16_t *)g; + uint16_t *wb = (uint16_t *)b; + uint16_t *wa = (uint16_t *)a; + (void)img; + (void)y; + for (; h > 0; --h) + { + for (x = 0; x < w; x++) + *cp++ = PACK4(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++], + img->Bitdepth16To8[*wb++], img->Bitdepth16To8[*wa++]); + SKEW4(wr, wg, wb, wa, fromskew); + cp += toskew; + } } /* @@ -1760,168 +1976,123 @@ DECLARESepPutFunc(putRGBAAseparate16bittile) */ DECLARESepPutFunc(putRGBUAseparate16bittile) { - uint16 *wr = (uint16*) r; - uint16 *wg = (uint16*) g; - uint16 *wb = (uint16*) b; - uint16 *wa = (uint16*) a; - (void) img; (void) y; - for( ; h > 0; --h) { - uint32 r2,g2,b2,a2; - uint8* m; - for (x = w; x > 0; --x) { - a2 = img->Bitdepth16To8[*wa++]; - m = img->UaToAa+((size_t) a2<<8); - r2 = m[img->Bitdepth16To8[*wr++]]; - g2 = m[img->Bitdepth16To8[*wg++]]; - b2 = m[img->Bitdepth16To8[*wb++]]; - *cp++ = PACK4(r2,g2,b2,a2); - } - SKEW4(wr, wg, wb, wa, fromskew); - cp += toskew; - } + uint16_t *wr = (uint16_t *)r; + uint16_t *wg = (uint16_t *)g; + uint16_t *wb = (uint16_t *)b; + uint16_t *wa = (uint16_t *)a; + (void)img; + (void)y; + for (; h > 0; --h) + { + uint32_t r2, g2, b2, a2; + uint8_t *m; + for (x = w; x > 0; --x) + { + a2 = img->Bitdepth16To8[*wa++]; + m = img->UaToAa + ((size_t)a2 << 8); + r2 = m[img->Bitdepth16To8[*wr++]]; + g2 = m[img->Bitdepth16To8[*wg++]]; + b2 = m[img->Bitdepth16To8[*wb++]]; + *cp++ = PACK4(r2, g2, b2, a2); + } + SKEW4(wr, wg, wb, wa, fromskew); + cp += toskew; + } } /* * 8-bit packed CIE L*a*b 1976 samples => RGB */ -DECLAREContigPutFunc(putcontig8bitCIELab) +DECLAREContigPutFunc(putcontig8bitCIELab8) { - float X, Y, Z; - uint32 r, g, b; - (void) y; - fromskew *= 3; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) { - TIFFCIELabToXYZ(img->cielab, - (unsigned char)pp[0], - (signed char)pp[1], - (signed char)pp[2], - &X, &Y, &Z); - TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); - *cp++ = PACK(r, g, b); - pp += 3; - } - cp += toskew; - pp += fromskew; - } + float X, Y, Z; + uint32_t r, g, b; + (void)y; + fromskew *= 3; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + TIFFCIELabToXYZ(img->cielab, (unsigned char)pp[0], + (signed char)pp[1], (signed char)pp[2], &X, &Y, &Z); + TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); + *cp++ = PACK(r, g, b); + pp += 3; + } + cp += toskew; + pp += fromskew; + } +} + +/* + * 16-bit packed CIE L*a*b 1976 samples => RGB + */ +DECLAREContigPutFunc(putcontig8bitCIELab16) +{ + float X, Y, Z; + uint32_t r, g, b; + uint16_t *wp = (uint16_t *)pp; + (void)y; + fromskew *= 3; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + TIFFCIELab16ToXYZ(img->cielab, (uint16_t)wp[0], (int16_t)wp[1], + (int16_t)wp[2], &X, &Y, &Z); + TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); + *cp++ = PACK(r, g, b); + wp += 3; + } + cp += toskew; + wp += fromskew; + } } /* * YCbCr -> RGB conversion and packing routines. */ -#define YCbCrtoRGB(dst, Y) { \ - uint32 r, g, b; \ - TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ - dst = PACK(r, g, b); \ -} - -/* - * 8-bit packed YCbCr samples => RGB - * This function is generic for different sampling sizes, - * and can handle blocks sizes that aren't multiples of the - * sampling size. However, it is substantially less optimized - * than the specific sampling cases. It is used as a fallback - * for difficult blocks. - */ -#ifdef notdef -static void putcontig8bitYCbCrGenericTile( - TIFFRGBAImage* img, - uint32* cp, - uint32 x, uint32 y, - uint32 w, uint32 h, - int32 fromskew, int32 toskew, - unsigned char* pp, - int h_group, - int v_group ) - -{ - uint32* cp1 = cp+w+toskew; - uint32* cp2 = cp1+w+toskew; - uint32* cp3 = cp2+w+toskew; - int32 incr = 3*w+4*toskew; - int32 Cb, Cr; - int group_size = v_group * h_group + 2; - - (void) y; - fromskew = (fromskew * group_size) / h_group; - - for( yy = 0; yy < h; yy++ ) - { - unsigned char *pp_line; - int y_line_group = yy / v_group; - int y_remainder = yy - y_line_group * v_group; - - pp_line = pp + v_line_group * - - - for( xx = 0; xx < w; xx++ ) - { - Cb = pp - } +#define YCbCrtoRGB(dst, Y) \ + { \ + uint32_t r, g, b; \ + TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ + dst = PACK(r, g, b); \ } - for (; h >= 4; h -= 4) { - x = w>>2; - do { - Cb = pp[16]; - Cr = pp[17]; - - YCbCrtoRGB(cp [0], pp[ 0]); - YCbCrtoRGB(cp [1], pp[ 1]); - YCbCrtoRGB(cp [2], pp[ 2]); - YCbCrtoRGB(cp [3], pp[ 3]); - YCbCrtoRGB(cp1[0], pp[ 4]); - YCbCrtoRGB(cp1[1], pp[ 5]); - YCbCrtoRGB(cp1[2], pp[ 6]); - YCbCrtoRGB(cp1[3], pp[ 7]); - YCbCrtoRGB(cp2[0], pp[ 8]); - YCbCrtoRGB(cp2[1], pp[ 9]); - YCbCrtoRGB(cp2[2], pp[10]); - YCbCrtoRGB(cp2[3], pp[11]); - YCbCrtoRGB(cp3[0], pp[12]); - YCbCrtoRGB(cp3[1], pp[13]); - YCbCrtoRGB(cp3[2], pp[14]); - YCbCrtoRGB(cp3[3], pp[15]); - - cp += 4, cp1 += 4, cp2 += 4, cp3 += 4; - pp += 18; - } while (--x); - cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; - pp += fromskew; - } -} -#endif /* * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB */ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) { - uint32* cp1 = cp+w+toskew; - uint32* cp2 = cp1+w+toskew; - uint32* cp3 = cp2+w+toskew; - int32 incr = 3*w+4*toskew; + uint32_t *cp1 = cp + w + toskew; + uint32_t *cp2 = cp1 + w + toskew; + uint32_t *cp3 = cp2 + w + toskew; + int32_t incr = 3 * w + 4 * toskew; - (void) y; + (void)y; /* adjust fromskew */ - fromskew = (fromskew / 4) * (4*2+2); - if ((h & 3) == 0 && (w & 3) == 0) { - for (; h >= 4; h -= 4) { - x = w>>2; - do { - int32 Cb = pp[16]; - int32 Cr = pp[17]; + fromskew = (fromskew / 4) * (4 * 2 + 2); + if ((h & 3) == 0 && (w & 3) == 0) + { + for (; h >= 4; h -= 4) + { + x = w >> 2; + do + { + int32_t Cb = pp[16]; + int32_t Cr = pp[17]; - YCbCrtoRGB(cp [0], pp[ 0]); - YCbCrtoRGB(cp [1], pp[ 1]); - YCbCrtoRGB(cp [2], pp[ 2]); - YCbCrtoRGB(cp [3], pp[ 3]); - YCbCrtoRGB(cp1[0], pp[ 4]); - YCbCrtoRGB(cp1[1], pp[ 5]); - YCbCrtoRGB(cp1[2], pp[ 6]); - YCbCrtoRGB(cp1[3], pp[ 7]); - YCbCrtoRGB(cp2[0], pp[ 8]); - YCbCrtoRGB(cp2[1], pp[ 9]); + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp[2], pp[2]); + YCbCrtoRGB(cp[3], pp[3]); + YCbCrtoRGB(cp1[0], pp[4]); + YCbCrtoRGB(cp1[1], pp[5]); + YCbCrtoRGB(cp1[2], pp[6]); + YCbCrtoRGB(cp1[3], pp[7]); + YCbCrtoRGB(cp2[0], pp[8]); + YCbCrtoRGB(cp2[1], pp[9]); YCbCrtoRGB(cp2[2], pp[10]); YCbCrtoRGB(cp2[3], pp[11]); YCbCrtoRGB(cp3[0], pp[12]); @@ -1941,47 +2112,80 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) cp3 += incr; pp += fromskew; } - } else { - while (h > 0) { - for (x = w; x > 0;) { - int32 Cb = pp[16]; - int32 Cr = pp[17]; - switch (x) { - default: - switch (h) { - default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */ - case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */ - case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 3: - switch (h) { - default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */ - case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */ - case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 2: - switch (h) { - default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */ - case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */ - case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 1: - switch (h) { - default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */ - case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */ - case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } + else + { + while (h > 0) + { + for (x = w; x > 0;) + { + int32_t Cb = pp[16]; + int32_t Cr = pp[17]; + switch (x) + { + default: + switch (h) + { + default: + YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */ + case 3: + YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */ + case 2: + YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 3: + switch (h) + { + default: + YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */ + case 3: + YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */ + case 2: + YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 2: + switch (h) + { + default: + YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */ + case 3: + YCbCrtoRGB(cp2[1], pp[9]); /* FALLTHROUGH */ + case 2: + YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 1: + switch (h) + { + default: + YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */ + case 3: + YCbCrtoRGB(cp2[0], pp[8]); /* FALLTHROUGH */ + case 2: + YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ } - if (x < 4) { - cp += x; cp1 += x; cp2 += x; cp3 += x; + if (x < 4) + { + cp += x; + cp1 += x; + cp2 += x; + cp3 += x; x = 0; } - else { - cp += 4; cp1 += 4; cp2 += 4; cp3 += 4; + else + { + cp += 4; + cp1 += 4; + cp2 += 4; + cp3 += 4; x -= 4; } pp += 18; @@ -2003,27 +2207,30 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) { - uint32* cp1 = cp+w+toskew; - int32 incr = 2*toskew+w; + uint32_t *cp1 = cp + w + toskew; + int32_t incr = 2 * toskew + w; - (void) y; - fromskew = (fromskew / 4) * (4*2+2); - if ((w & 3) == 0 && (h & 1) == 0) { - for (; h >= 2; h -= 2) { - x = w>>2; - do { - int32 Cb = pp[8]; - int32 Cr = pp[9]; - - YCbCrtoRGB(cp [0], pp[0]); - YCbCrtoRGB(cp [1], pp[1]); - YCbCrtoRGB(cp [2], pp[2]); - YCbCrtoRGB(cp [3], pp[3]); + (void)y; + fromskew = (fromskew / 4) * (4 * 2 + 2); + if ((w & 3) == 0 && (h & 1) == 0) + { + for (; h >= 2; h -= 2) + { + x = w >> 2; + do + { + int32_t Cb = pp[8]; + int32_t Cr = pp[9]; + + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp[2], pp[2]); + YCbCrtoRGB(cp[3], pp[3]); YCbCrtoRGB(cp1[0], pp[4]); YCbCrtoRGB(cp1[1], pp[5]); YCbCrtoRGB(cp1[2], pp[6]); YCbCrtoRGB(cp1[3], pp[7]); - + cp += 4; cp1 += 4; pp += 10; @@ -2032,39 +2239,60 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) cp1 += incr; pp += fromskew; } - } else { - while (h > 0) { - for (x = w; x > 0;) { - int32 Cb = pp[8]; - int32 Cr = pp[9]; - switch (x) { - default: - switch (h) { - default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 3: - switch (h) { - default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 2: - switch (h) { - default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 1: - switch (h) { - default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } + else + { + while (h > 0) + { + for (x = w; x > 0;) + { + int32_t Cb = pp[8]; + int32_t Cr = pp[9]; + switch (x) + { + default: + switch (h) + { + default: + YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 3: + switch (h) + { + default: + YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 2: + switch (h) + { + default: + YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 1: + switch (h) + { + default: + YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ } - if (x < 4) { - cp += x; cp1 += x; + if (x < 4) + { + cp += x; + cp1 += x; x = 0; } - else { - cp += 4; cp1 += 4; + else + { + cp += 4; + cp1 += 4; x -= 4; } pp += 10; @@ -2084,44 +2312,50 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) { - (void) y; - fromskew = (fromskew / 4) * (4*1+2); - do { - x = w>>2; - while(x>0) { - int32 Cb = pp[4]; - int32 Cr = pp[5]; - - YCbCrtoRGB(cp [0], pp[0]); - YCbCrtoRGB(cp [1], pp[1]); - YCbCrtoRGB(cp [2], pp[2]); - YCbCrtoRGB(cp [3], pp[3]); - - cp += 4; - pp += 6; - x--; - } - - if( (w&3) != 0 ) + (void)y; + fromskew = (fromskew / 4) * (4 * 1 + 2); + do + { + x = w >> 2; + while (x > 0) { - int32 Cb = pp[4]; - int32 Cr = pp[5]; + int32_t Cb = pp[4]; + int32_t Cr = pp[5]; - switch( (w&3) ) { - case 3: YCbCrtoRGB(cp [2], pp[2]); /*-fallthrough*/ - case 2: YCbCrtoRGB(cp [1], pp[1]); /*-fallthrough*/ - case 1: YCbCrtoRGB(cp [0], pp[0]); /*-fallthrough*/ - case 0: break; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp[2], pp[2]); + YCbCrtoRGB(cp[3], pp[3]); + + cp += 4; + pp += 6; + x--; + } + + if ((w & 3) != 0) + { + int32_t Cb = pp[4]; + int32_t Cr = pp[5]; + + switch ((w & 3)) + { + case 3: + YCbCrtoRGB(cp[2], pp[2]); /*-fallthrough*/ + case 2: + YCbCrtoRGB(cp[1], pp[1]); /*-fallthrough*/ + case 1: + YCbCrtoRGB(cp[0], pp[0]); /*-fallthrough*/ + case 0: + break; } - cp += (w&3); + cp += (w & 3); pp += 6; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } while (--h); - } /* @@ -2129,57 +2363,63 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) { - uint32* cp2; - int32 incr = 2*toskew+w; - (void) y; - fromskew = (fromskew / 2) * (2*2+2); - cp2 = cp+w+toskew; - while (h>=2) { - x = w; - while (x>=2) { - uint32 Cb = pp[4]; - uint32 Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - YCbCrtoRGB(cp2[0], pp[2]); - YCbCrtoRGB(cp2[1], pp[3]); - cp += 2; - cp2 += 2; - pp += 6; - x -= 2; - } - if (x==1) { - uint32 Cb = pp[4]; - uint32 Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp2[0], pp[2]); - cp ++ ; - cp2 ++ ; - pp += 6; - } - cp += incr; - cp2 += incr; - pp += fromskew; - h-=2; - } - if (h==1) { - x = w; - while (x>=2) { - uint32 Cb = pp[4]; - uint32 Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - cp += 2; - cp2 += 2; - pp += 6; - x -= 2; - } - if (x==1) { - uint32 Cb = pp[4]; - uint32 Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - } - } + uint32_t *cp2; + int32_t incr = 2 * toskew + w; + (void)y; + fromskew = (fromskew / 2) * (2 * 2 + 2); + cp2 = cp + w + toskew; + while (h >= 2) + { + x = w; + while (x >= 2) + { + uint32_t Cb = pp[4]; + uint32_t Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp2[0], pp[2]); + YCbCrtoRGB(cp2[1], pp[3]); + cp += 2; + cp2 += 2; + pp += 6; + x -= 2; + } + if (x == 1) + { + uint32_t Cb = pp[4]; + uint32_t Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp2[0], pp[2]); + cp++; + cp2++; + pp += 6; + } + cp += incr; + cp2 += incr; + pp += fromskew; + h -= 2; + } + if (h == 1) + { + x = w; + while (x >= 2) + { + uint32_t Cb = pp[4]; + uint32_t Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + cp += 2; + cp2 += 2; + pp += 6; + x -= 2; + } + if (x == 1) + { + uint32_t Cb = pp[4]; + uint32_t Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + } + } } /* @@ -2187,36 +2427,38 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) { - (void) y; - fromskew = (fromskew / 2) * (2*1+2); - do { - x = w>>1; - while(x>0) { - int32 Cb = pp[2]; - int32 Cr = pp[3]; + (void)y; + fromskew = (fromskew / 2) * (2 * 1 + 2); + do + { + x = w >> 1; + while (x > 0) + { + int32_t Cb = pp[2]; + int32_t Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); - cp += 2; - pp += 4; - x --; - } + cp += 2; + pp += 4; + x--; + } - if( (w&1) != 0 ) - { - int32 Cb = pp[2]; - int32 Cr = pp[3]; + if ((w & 1) != 0) + { + int32_t Cb = pp[2]; + int32_t Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[0], pp[0]); - cp += 1; - pp += 4; - } + cp += 1; + pp += 4; + } - cp += toskew; - pp += fromskew; - } while (--h); + cp += toskew; + pp += fromskew; + } while (--h); } /* @@ -2224,37 +2466,41 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) { - uint32* cp2; - int32 incr = 2*toskew+w; - (void) y; - fromskew = (fromskew / 1) * (1 * 2 + 2); - cp2 = cp+w+toskew; - while (h>=2) { - x = w; - do { - uint32 Cb = pp[2]; - uint32 Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp2[0], pp[1]); - cp ++; - cp2 ++; - pp += 4; - } while (--x); - cp += incr; - cp2 += incr; - pp += fromskew; - h-=2; - } - if (h==1) { - x = w; - do { - uint32 Cb = pp[2]; - uint32 Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); - cp ++; - pp += 4; - } while (--x); - } + uint32_t *cp2; + int32_t incr = 2 * toskew + w; + (void)y; + fromskew = (fromskew / 1) * (1 * 2 + 2); + cp2 = cp + w + toskew; + while (h >= 2) + { + x = w; + do + { + uint32_t Cb = pp[2]; + uint32_t Cr = pp[3]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp2[0], pp[1]); + cp++; + cp2++; + pp += 4; + } while (--x); + cp += incr; + cp2 += incr; + pp += fromskew; + h -= 2; + } + if (h == 1) + { + x = w; + do + { + uint32_t Cb = pp[2]; + uint32_t Cr = pp[3]; + YCbCrtoRGB(cp[0], pp[0]); + cp++; + pp += 4; + } while (--x); + } } /* @@ -2262,21 +2508,23 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr11tile) { - (void) y; - fromskew = (fromskew / 1) * (1 * 1 + 2); - do { - x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ - do { - int32 Cb = pp[1]; - int32 Cr = pp[2]; + (void)y; + fromskew = (fromskew / 1) * (1 * 1 + 2); + do + { + x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ + do + { + int32_t Cb = pp[1]; + int32_t Cr = pp[2]; - YCbCrtoRGB(*cp++, pp[0]); + YCbCrtoRGB(*cp++, pp[0]); - pp += 3; - } while (--x); - cp += toskew; - pp += fromskew; - } while (--h); + pp += 3; + } while (--x); + cp += toskew; + pp += fromskew; + } while (--h); } /* @@ -2284,19 +2532,22 @@ DECLAREContigPutFunc(putcontig8bitYCbCr11tile) */ DECLARESepPutFunc(putseparate8bitYCbCr11tile) { - (void) y; - (void) a; - /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */ - for( ; h > 0; --h) { - x = w; - do { - uint32 dr, dg, db; - TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db); - *cp++ = PACK(dr,dg,db); - } while (--x); - SKEW(r, g, b, fromskew); - cp += toskew; - } + (void)y; + (void)a; + /* TODO: naming of input vars is still off, change obfuscating declaration + * inside define, or resolve obfuscation */ + for (; h > 0; --h) + { + x = w; + do + { + uint32_t dr, dg, db; + TIFFYCbCrtoRGB(img->ycbcr, *r++, *g++, *b++, &dr, &dg, &db); + *cp++ = PACK(dr, dg, db); + } while (--x); + SKEW(r, g, b, fromskew); + cp += toskew; + } } #undef YCbCrtoRGB @@ -2305,97 +2556,100 @@ static int isInRefBlackWhiteRange(float f) return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF; } -static int -initYCbCrConversion(TIFFRGBAImage* img) +static int initYCbCrConversion(TIFFRGBAImage *img) { - static const char module[] = "initYCbCrConversion"; + static const char module[] = "initYCbCrConversion"; - float *luma, *refBlackWhite; + float *luma, *refBlackWhite; - if (img->ycbcr == NULL) { - img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc( - TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)) - + 4*256*sizeof (TIFFRGBValue) - + 2*256*sizeof (int) - + 3*256*sizeof (int32) - ); - if (img->ycbcr == NULL) { - TIFFErrorExt(img->tif->tif_clientdata, module, - "No space for YCbCr->RGB conversion state"); - return (0); - } - } - - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); - TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, - &refBlackWhite); - - /* Do some validation to avoid later issues. Detect NaN for now */ - /* and also if lumaGreen is zero since we divide by it later */ - if( luma[0] != luma[0] || - luma[1] != luma[1] || - luma[1] == 0.0 || - luma[2] != luma[2] ) + if (img->ycbcr == NULL) + { + img->ycbcr = (TIFFYCbCrToRGB *)_TIFFmallocExt( + img->tif, TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)) + + 4 * 256 * sizeof(TIFFRGBValue) + + 2 * 256 * sizeof(int) + 3 * 256 * sizeof(int32_t)); + if (img->ycbcr == NULL) { - TIFFErrorExt(img->tif->tif_clientdata, module, - "Invalid values for YCbCrCoefficients tag"); + TIFFErrorExtR(img->tif, module, + "No space for YCbCr->RGB conversion state"); return (0); } + } - if( !isInRefBlackWhiteRange(refBlackWhite[0]) || - !isInRefBlackWhiteRange(refBlackWhite[1]) || - !isInRefBlackWhiteRange(refBlackWhite[2]) || - !isInRefBlackWhiteRange(refBlackWhite[3]) || - !isInRefBlackWhiteRange(refBlackWhite[4]) || - !isInRefBlackWhiteRange(refBlackWhite[5]) ) - { - TIFFErrorExt(img->tif->tif_clientdata, module, - "Invalid values for ReferenceBlackWhite tag"); - return (0); - } + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); + TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, + &refBlackWhite); - if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) - return(0); - return (1); + /* Do some validation to avoid later issues. Detect NaN for now */ + /* and also if lumaGreen is zero since we divide by it later */ + if (luma[0] != luma[0] || luma[1] != luma[1] || luma[1] == 0.0 || + luma[2] != luma[2]) + { + TIFFErrorExtR(img->tif, module, + "Invalid values for YCbCrCoefficients tag"); + return (0); + } + + if (!isInRefBlackWhiteRange(refBlackWhite[0]) || + !isInRefBlackWhiteRange(refBlackWhite[1]) || + !isInRefBlackWhiteRange(refBlackWhite[2]) || + !isInRefBlackWhiteRange(refBlackWhite[3]) || + !isInRefBlackWhiteRange(refBlackWhite[4]) || + !isInRefBlackWhiteRange(refBlackWhite[5])) + { + TIFFErrorExtR(img->tif, module, + "Invalid values for ReferenceBlackWhite tag"); + return (0); + } + + if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) + return (0); + return (1); } -static tileContigRoutine -initCIELabConversion(TIFFRGBAImage* img) +static tileContigRoutine initCIELabConversion(TIFFRGBAImage *img) { - static const char module[] = "initCIELabConversion"; + static const char module[] = "initCIELabConversion"; - float *whitePoint; - float refWhite[3]; + float *whitePoint; + float refWhite[3]; - TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); - if (whitePoint[1] == 0.0f ) { - TIFFErrorExt(img->tif->tif_clientdata, module, - "Invalid value for WhitePoint tag."); - return NULL; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); + if (whitePoint[1] == 0.0f) + { + TIFFErrorExtR(img->tif, module, "Invalid value for WhitePoint tag."); + return NULL; + } + + if (!img->cielab) + { + img->cielab = (TIFFCIELabToRGB *)_TIFFmallocExt( + img->tif, sizeof(TIFFCIELabToRGB)); + if (!img->cielab) + { + TIFFErrorExtR(img->tif, module, + "No space for CIE L*a*b*->RGB conversion state."); + return NULL; } + } - if (!img->cielab) { - img->cielab = (TIFFCIELabToRGB *) - _TIFFmalloc(sizeof(TIFFCIELabToRGB)); - if (!img->cielab) { - TIFFErrorExt(img->tif->tif_clientdata, module, - "No space for CIE L*a*b*->RGB conversion state."); - return NULL; - } - } + refWhite[1] = 100.0F; + refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; + refWhite[2] = + (1.0F - whitePoint[0] - whitePoint[1]) / whitePoint[1] * refWhite[1]; + if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) + { + TIFFErrorExtR(img->tif, module, + "Failed to initialize CIE L*a*b*->RGB conversion state."); + _TIFFfreeExt(img->tif, img->cielab); + return NULL; + } - refWhite[1] = 100.0F; - refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; - refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1]) - / whitePoint[1] * refWhite[1]; - if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) { - TIFFErrorExt(img->tif->tif_clientdata, module, - "Failed to initialize CIE L*a*b*->RGB conversion state."); - _TIFFfree(img->cielab); - return NULL; - } - - return putcontig8bitCIELab; + if (img->bitspersample == 8) + return putcontig8bitCIELab8; + else if (img->bitspersample == 16) + return putcontig8bitCIELab16; + return NULL; } /* @@ -2405,56 +2659,62 @@ initCIELabConversion(TIFFRGBAImage* img) * pixel values simply by indexing into the table with one * number. */ -static int -makebwmap(TIFFRGBAImage* img) +static int makebwmap(TIFFRGBAImage *img) { - TIFFRGBValue* Map = img->Map; + TIFFRGBValue *Map = img->Map; int bitspersample = img->bitspersample; int nsamples = 8 / bitspersample; int i; - uint32* p; + uint32_t *p; - if( nsamples == 0 ) + if (nsamples == 0) nsamples = 1; - img->BWmap = (uint32**) _TIFFmalloc( - 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); - if (img->BWmap == NULL) { - TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table"); - return (0); + img->BWmap = (uint32_t **)_TIFFmallocExt( + img->tif, + 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); + if (img->BWmap == NULL) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "No space for B&W mapping table"); + return (0); } - p = (uint32*)(img->BWmap + 256); - for (i = 0; i < 256; i++) { - TIFFRGBValue c; - img->BWmap[i] = p; - switch (bitspersample) { -#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c); - case 1: - GREY(i>>7); - GREY((i>>6)&1); - GREY((i>>5)&1); - GREY((i>>4)&1); - GREY((i>>3)&1); - GREY((i>>2)&1); - GREY((i>>1)&1); - GREY(i&1); - break; - case 2: - GREY(i>>6); - GREY((i>>4)&3); - GREY((i>>2)&3); - GREY(i&3); - break; - case 4: - GREY(i>>4); - GREY(i&0xf); - break; - case 8: - case 16: - GREY(i); - break; - } -#undef GREY + p = (uint32_t *)(img->BWmap + 256); + for (i = 0; i < 256; i++) + { + TIFFRGBValue c; + img->BWmap[i] = p; + switch (bitspersample) + { +#define GREY(x) \ + c = Map[x]; \ + *p++ = PACK(c, c, c); + case 1: + GREY(i >> 7); + GREY((i >> 6) & 1); + GREY((i >> 5) & 1); + GREY((i >> 4) & 1); + GREY((i >> 3) & 1); + GREY((i >> 2) & 1); + GREY((i >> 1) & 1); + GREY(i & 1); + break; + case 2: + GREY(i >> 6); + GREY((i >> 4) & 3); + GREY((i >> 2) & 3); + GREY(i & 3); + break; + case 4: + GREY(i >> 4); + GREY(i & 0xf); + break; + case 8: + case 16: + GREY(i); + break; + } +#undef GREY } return (1); } @@ -2463,75 +2723,79 @@ makebwmap(TIFFRGBAImage* img) * Construct a mapping table to convert from the range * of the data samples to [0,255] --for display. This * process also handles inverting B&W images when needed. - */ -static int -setupMap(TIFFRGBAImage* img) + */ +static int setupMap(TIFFRGBAImage *img) { - int32 x, range; + int32_t x, range; + + range = (int32_t)((1L << img->bitspersample) - 1); - range = (int32)((1L<bitspersample)-1); - /* treat 16 bit the same as eight bit */ - if( img->bitspersample == 16 ) - range = (int32) 255; + if (img->bitspersample == 16) + range = (int32_t)255; - img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue)); - if (img->Map == NULL) { - TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), - "No space for photometric conversion table"); - return (0); + img->Map = (TIFFRGBValue *)_TIFFmallocExt( + img->tif, (range + 1) * sizeof(TIFFRGBValue)); + if (img->Map == NULL) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "No space for photometric conversion table"); + return (0); } - if (img->photometric == PHOTOMETRIC_MINISWHITE) { - for (x = 0; x <= range; x++) - img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range); - } else { - for (x = 0; x <= range; x++) - img->Map[x] = (TIFFRGBValue) ((x * 255) / range); + if (img->photometric == PHOTOMETRIC_MINISWHITE) + { + for (x = 0; x <= range; x++) + img->Map[x] = (TIFFRGBValue)(((range - x) * 255) / range); + } + else + { + for (x = 0; x <= range; x++) + img->Map[x] = (TIFFRGBValue)((x * 255) / range); } if (img->bitspersample <= 16 && - (img->photometric == PHOTOMETRIC_MINISBLACK || - img->photometric == PHOTOMETRIC_MINISWHITE)) { - /* - * Use photometric mapping table to construct - * unpacking tables for samples <= 8 bits. - */ - if (!makebwmap(img)) - return (0); - /* no longer need Map, free it */ - _TIFFfree(img->Map); - img->Map = NULL; + (img->photometric == PHOTOMETRIC_MINISBLACK || + img->photometric == PHOTOMETRIC_MINISWHITE)) + { + /* + * Use photometric mapping table to construct + * unpacking tables for samples <= 8 bits. + */ + if (!makebwmap(img)) + return (0); + /* no longer need Map, free it */ + _TIFFfreeExt(img->tif, img->Map); + img->Map = NULL; } return (1); } -static int -checkcmap(TIFFRGBAImage* img) +static int checkcmap(TIFFRGBAImage *img) { - uint16* r = img->redcmap; - uint16* g = img->greencmap; - uint16* b = img->bluecmap; - long n = 1L<bitspersample; + uint16_t *r = img->redcmap; + uint16_t *g = img->greencmap; + uint16_t *b = img->bluecmap; + long n = 1L << img->bitspersample; while (n-- > 0) - if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) - return (16); + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); return (8); } -static void -cvtcmap(TIFFRGBAImage* img) +static void cvtcmap(TIFFRGBAImage *img) { - uint16* r = img->redcmap; - uint16* g = img->greencmap; - uint16* b = img->bluecmap; + uint16_t *r = img->redcmap; + uint16_t *g = img->greencmap; + uint16_t *b = img->bluecmap; long i; - for (i = (1L<bitspersample)-1; i >= 0; i--) { -#define CVT(x) ((uint16)((x)>>8)) - r[i] = CVT(r[i]); - g[i] = CVT(g[i]); - b[i] = CVT(b[i]); -#undef CVT + for (i = (1L << img->bitspersample) - 1; i >= 0; i--) + { +#define CVT(x) ((uint16_t)((x) >> 8)) + r[i] = CVT(r[i]); + g[i] = CVT(g[i]); + b[i] = CVT(b[i]); +#undef CVT } } @@ -2542,93 +2806,100 @@ cvtcmap(TIFFRGBAImage* img) * pixel values simply by indexing into the table with one * number. */ -static int -makecmap(TIFFRGBAImage* img) +static int makecmap(TIFFRGBAImage *img) { int bitspersample = img->bitspersample; int nsamples = 8 / bitspersample; - uint16* r = img->redcmap; - uint16* g = img->greencmap; - uint16* b = img->bluecmap; - uint32 *p; + uint16_t *r = img->redcmap; + uint16_t *g = img->greencmap; + uint16_t *b = img->bluecmap; + uint32_t *p; int i; - img->PALmap = (uint32**) _TIFFmalloc( - 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); - if (img->PALmap == NULL) { - TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table"); - return (0); - } - p = (uint32*)(img->PALmap + 256); - for (i = 0; i < 256; i++) { - TIFFRGBValue c; - img->PALmap[i] = p; -#define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff); - switch (bitspersample) { - case 1: - CMAP(i>>7); - CMAP((i>>6)&1); - CMAP((i>>5)&1); - CMAP((i>>4)&1); - CMAP((i>>3)&1); - CMAP((i>>2)&1); - CMAP((i>>1)&1); - CMAP(i&1); - break; - case 2: - CMAP(i>>6); - CMAP((i>>4)&3); - CMAP((i>>2)&3); - CMAP(i&3); - break; - case 4: - CMAP(i>>4); - CMAP(i&0xf); - break; - case 8: - CMAP(i); - break; - } + img->PALmap = (uint32_t **)_TIFFmallocExt( + img->tif, + 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); + if (img->PALmap == NULL) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "No space for Palette mapping table"); + return (0); + } + p = (uint32_t *)(img->PALmap + 256); + for (i = 0; i < 256; i++) + { + TIFFRGBValue c; + img->PALmap[i] = p; +#define CMAP(x) \ + c = (TIFFRGBValue)x; \ + *p++ = PACK(r[c] & 0xff, g[c] & 0xff, b[c] & 0xff); + switch (bitspersample) + { + case 1: + CMAP(i >> 7); + CMAP((i >> 6) & 1); + CMAP((i >> 5) & 1); + CMAP((i >> 4) & 1); + CMAP((i >> 3) & 1); + CMAP((i >> 2) & 1); + CMAP((i >> 1) & 1); + CMAP(i & 1); + break; + case 2: + CMAP(i >> 6); + CMAP((i >> 4) & 3); + CMAP((i >> 2) & 3); + CMAP(i & 3); + break; + case 4: + CMAP(i >> 4); + CMAP(i & 0xf); + break; + case 8: + CMAP(i); + break; + } #undef CMAP } return (1); } -/* +/* * Construct any mapping table used * by the associated put routine. */ -static int -buildMap(TIFFRGBAImage* img) +static int buildMap(TIFFRGBAImage *img) { - switch (img->photometric) { - case PHOTOMETRIC_RGB: - case PHOTOMETRIC_YCBCR: - case PHOTOMETRIC_SEPARATED: - if (img->bitspersample == 8) - break; - /* fall through... */ - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_MINISWHITE: - if (!setupMap(img)) - return (0); - break; - case PHOTOMETRIC_PALETTE: - /* - * Convert 16-bit colormap to 8-bit (unless it looks - * like an old-style 8-bit colormap). - */ - if (checkcmap(img) == 16) - cvtcmap(img); - else - TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap"); - /* - * Use mapping table and colormap to construct - * unpacking tables for samples < 8 bits. - */ - if (img->bitspersample <= 8 && !makecmap(img)) - return (0); - break; + switch (img->photometric) + { + case PHOTOMETRIC_RGB: + case PHOTOMETRIC_YCBCR: + case PHOTOMETRIC_SEPARATED: + if (img->bitspersample == 8) + break; + /* fall through... */ + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_MINISWHITE: + if (!setupMap(img)) + return (0); + break; + case PHOTOMETRIC_PALETTE: + /* + * Convert 16-bit colormap to 8-bit (unless it looks + * like an old-style 8-bit colormap). + */ + if (checkcmap(img) == 16) + cvtcmap(img); + else + TIFFWarningExtR(img->tif, TIFFFileName(img->tif), + "Assuming 8-bit colormap"); + /* + * Use mapping table and colormap to construct + * unpacking tables for samples < 8 bits. + */ + if (img->bitspersample <= 8 && !makecmap(img)) + return (0); + break; } return (1); } @@ -2636,153 +2907,162 @@ buildMap(TIFFRGBAImage* img) /* * Select the appropriate conversion routine for packed data. */ -static int -PickContigCase(TIFFRGBAImage* img) +static int PickContigCase(TIFFRGBAImage *img) { - img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig; - img->put.contig = NULL; - switch (img->photometric) { - case PHOTOMETRIC_RGB: - switch (img->bitspersample) { - case 8: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA && - img->samplesperpixel >= 4) - img->put.contig = putRGBAAcontig8bittile; - else if (img->alpha == EXTRASAMPLE_UNASSALPHA && - img->samplesperpixel >= 4) - { - if (BuildMapUaToAa(img)) - img->put.contig = putRGBUAcontig8bittile; - } - else if( img->samplesperpixel >= 3 ) - img->put.contig = putRGBcontig8bittile; - break; - case 16: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA && - img->samplesperpixel >=4 ) - { - if (BuildMapBitdepth16To8(img)) - img->put.contig = putRGBAAcontig16bittile; - } - else if (img->alpha == EXTRASAMPLE_UNASSALPHA && - img->samplesperpixel >=4 ) - { - if (BuildMapBitdepth16To8(img) && - BuildMapUaToAa(img)) - img->put.contig = putRGBUAcontig16bittile; - } - else if( img->samplesperpixel >=3 ) - { - if (BuildMapBitdepth16To8(img)) - img->put.contig = putRGBcontig16bittile; - } - break; - } - break; - case PHOTOMETRIC_SEPARATED: - if (img->samplesperpixel >=4 && buildMap(img)) { - if (img->bitspersample == 8) { - if (!img->Map) - img->put.contig = putRGBcontig8bitCMYKtile; - else - img->put.contig = putRGBcontig8bitCMYKMaptile; - } - } - break; - case PHOTOMETRIC_PALETTE: - if (buildMap(img)) { - switch (img->bitspersample) { - case 8: - img->put.contig = put8bitcmaptile; - break; - case 4: - img->put.contig = put4bitcmaptile; - break; - case 2: - img->put.contig = put2bitcmaptile; - break; - case 1: - img->put.contig = put1bitcmaptile; - break; - } - } - break; - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - if (buildMap(img)) { - switch (img->bitspersample) { - case 16: - img->put.contig = put16bitbwtile; - break; - case 8: - if (img->alpha && img->samplesperpixel == 2) - img->put.contig = putagreytile; - else - img->put.contig = putgreytile; - break; - case 4: - img->put.contig = put4bitbwtile; - break; - case 2: - img->put.contig = put2bitbwtile; - break; - case 1: - img->put.contig = put1bitbwtile; - break; - } - } - break; - case PHOTOMETRIC_YCBCR: - if ((img->bitspersample==8) && (img->samplesperpixel==3)) - { - if (initYCbCrConversion(img)!=0) - { - /* - * The 6.0 spec says that subsampling must be - * one of 1, 2, or 4, and that vertical subsampling - * must always be <= horizontal subsampling; so - * there are only a few possibilities and we just - * enumerate the cases. - * Joris: added support for the [1,2] case, nonetheless, to accommodate - * some OJPEG files - */ - uint16 SubsamplingHor; - uint16 SubsamplingVer; - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer); - switch ((SubsamplingHor<<4)|SubsamplingVer) { - case 0x44: - img->put.contig = putcontig8bitYCbCr44tile; - break; - case 0x42: - img->put.contig = putcontig8bitYCbCr42tile; - break; - case 0x41: - img->put.contig = putcontig8bitYCbCr41tile; - break; - case 0x22: - img->put.contig = putcontig8bitYCbCr22tile; - break; - case 0x21: - img->put.contig = putcontig8bitYCbCr21tile; - break; - case 0x12: - img->put.contig = putcontig8bitYCbCr12tile; - break; - case 0x11: - img->put.contig = putcontig8bitYCbCr11tile; - break; - } - } - } - break; - case PHOTOMETRIC_CIELAB: - if (img->samplesperpixel == 3 && buildMap(img)) { - if (img->bitspersample == 8) - img->put.contig = initCIELabConversion(img); - break; - } - } - return ((img->get!=NULL) && (img->put.contig!=NULL)); + img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig; + img->put.contig = NULL; + switch (img->photometric) + { + case PHOTOMETRIC_RGB: + switch (img->bitspersample) + { + case 8: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA && + img->samplesperpixel >= 4) + img->put.contig = putRGBAAcontig8bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA && + img->samplesperpixel >= 4) + { + if (BuildMapUaToAa(img)) + img->put.contig = putRGBUAcontig8bittile; + } + else if (img->samplesperpixel >= 3) + img->put.contig = putRGBcontig8bittile; + break; + case 16: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA && + img->samplesperpixel >= 4) + { + if (BuildMapBitdepth16To8(img)) + img->put.contig = putRGBAAcontig16bittile; + } + else if (img->alpha == EXTRASAMPLE_UNASSALPHA && + img->samplesperpixel >= 4) + { + if (BuildMapBitdepth16To8(img) && BuildMapUaToAa(img)) + img->put.contig = putRGBUAcontig16bittile; + } + else if (img->samplesperpixel >= 3) + { + if (BuildMapBitdepth16To8(img)) + img->put.contig = putRGBcontig16bittile; + } + break; + } + break; + case PHOTOMETRIC_SEPARATED: + if (img->samplesperpixel >= 4 && buildMap(img)) + { + if (img->bitspersample == 8) + { + if (!img->Map) + img->put.contig = putRGBcontig8bitCMYKtile; + else + img->put.contig = putRGBcontig8bitCMYKMaptile; + } + } + break; + case PHOTOMETRIC_PALETTE: + if (buildMap(img)) + { + switch (img->bitspersample) + { + case 8: + img->put.contig = put8bitcmaptile; + break; + case 4: + img->put.contig = put4bitcmaptile; + break; + case 2: + img->put.contig = put2bitcmaptile; + break; + case 1: + img->put.contig = put1bitcmaptile; + break; + } + } + break; + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + if (buildMap(img)) + { + switch (img->bitspersample) + { + case 16: + img->put.contig = put16bitbwtile; + break; + case 8: + if (img->alpha && img->samplesperpixel == 2) + img->put.contig = putagreytile; + else + img->put.contig = putgreytile; + break; + case 4: + img->put.contig = put4bitbwtile; + break; + case 2: + img->put.contig = put2bitbwtile; + break; + case 1: + img->put.contig = put1bitbwtile; + break; + } + } + break; + case PHOTOMETRIC_YCBCR: + if ((img->bitspersample == 8) && (img->samplesperpixel == 3)) + { + if (initYCbCrConversion(img) != 0) + { + /* + * The 6.0 spec says that subsampling must be + * one of 1, 2, or 4, and that vertical subsampling + * must always be <= horizontal subsampling; so + * there are only a few possibilities and we just + * enumerate the cases. + * Joris: added support for the [1,2] case, nonetheless, to + * accommodate some OJPEG files + */ + uint16_t SubsamplingHor; + uint16_t SubsamplingVer; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, + &SubsamplingHor, &SubsamplingVer); + switch ((SubsamplingHor << 4) | SubsamplingVer) + { + case 0x44: + img->put.contig = putcontig8bitYCbCr44tile; + break; + case 0x42: + img->put.contig = putcontig8bitYCbCr42tile; + break; + case 0x41: + img->put.contig = putcontig8bitYCbCr41tile; + break; + case 0x22: + img->put.contig = putcontig8bitYCbCr22tile; + break; + case 0x21: + img->put.contig = putcontig8bitYCbCr21tile; + break; + case 0x12: + img->put.contig = putcontig8bitYCbCr12tile; + break; + case 0x11: + img->put.contig = putcontig8bitYCbCr11tile; + break; + } + } + } + break; + case PHOTOMETRIC_CIELAB: + if (img->samplesperpixel == 3 && buildMap(img)) + { + if (img->bitspersample == 8 || img->bitspersample == 16) + img->put.contig = initCIELabConversion(img); + break; + } + } + return ((img->get != NULL) && (img->put.contig != NULL)); } /* @@ -2791,117 +3071,118 @@ PickContigCase(TIFFRGBAImage* img) * NB: we assume that unpacked single channel data is directed * to the "packed routines. */ -static int -PickSeparateCase(TIFFRGBAImage* img) +static int PickSeparateCase(TIFFRGBAImage *img) { - img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; - img->put.separate = NULL; - switch (img->photometric) { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - /* greyscale images processed pretty much as RGB by gtTileSeparate */ - case PHOTOMETRIC_RGB: - switch (img->bitspersample) { - case 8: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA) - img->put.separate = putRGBAAseparate8bittile; - else if (img->alpha == EXTRASAMPLE_UNASSALPHA) - { - if (BuildMapUaToAa(img)) - img->put.separate = putRGBUAseparate8bittile; - } - else - img->put.separate = putRGBseparate8bittile; - break; - case 16: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA) - { - if (BuildMapBitdepth16To8(img)) - img->put.separate = putRGBAAseparate16bittile; - } - else if (img->alpha == EXTRASAMPLE_UNASSALPHA) - { - if (BuildMapBitdepth16To8(img) && - BuildMapUaToAa(img)) - img->put.separate = putRGBUAseparate16bittile; - } - else - { - if (BuildMapBitdepth16To8(img)) - img->put.separate = putRGBseparate16bittile; - } - break; - } - break; - case PHOTOMETRIC_SEPARATED: - if (img->bitspersample == 8 && img->samplesperpixel == 4) - { - img->alpha = 1; // Not alpha, but seems like the only way to get 4th band - img->put.separate = putCMYKseparate8bittile; - } - break; - case PHOTOMETRIC_YCBCR: - if ((img->bitspersample==8) && (img->samplesperpixel==3)) - { - if (initYCbCrConversion(img)!=0) - { - uint16 hs, vs; - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); - switch ((hs<<4)|vs) { - case 0x11: - img->put.separate = putseparate8bitYCbCr11tile; - break; - /* TODO: add other cases here */ - } - } - } - break; - } - return ((img->get!=NULL) && (img->put.separate!=NULL)); + img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; + img->put.separate = NULL; + switch (img->photometric) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + /* greyscale images processed pretty much as RGB by gtTileSeparate + */ + case PHOTOMETRIC_RGB: + switch (img->bitspersample) + { + case 8: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + img->put.separate = putRGBAAseparate8bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapUaToAa(img)) + img->put.separate = putRGBUAseparate8bittile; + } + else + img->put.separate = putRGBseparate8bittile; + break; + case 16: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + { + if (BuildMapBitdepth16To8(img)) + img->put.separate = putRGBAAseparate16bittile; + } + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapBitdepth16To8(img) && BuildMapUaToAa(img)) + img->put.separate = putRGBUAseparate16bittile; + } + else + { + if (BuildMapBitdepth16To8(img)) + img->put.separate = putRGBseparate16bittile; + } + break; + } + break; + case PHOTOMETRIC_SEPARATED: + if (img->bitspersample == 8 && img->samplesperpixel == 4) + { + img->alpha = + 1; // Not alpha, but seems like the only way to get 4th band + img->put.separate = putCMYKseparate8bittile; + } + break; + case PHOTOMETRIC_YCBCR: + if ((img->bitspersample == 8) && (img->samplesperpixel == 3)) + { + if (initYCbCrConversion(img) != 0) + { + uint16_t hs, vs; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, + &hs, &vs); + switch ((hs << 4) | vs) + { + case 0x11: + img->put.separate = putseparate8bitYCbCr11tile; + break; + /* TODO: add other cases here */ + } + } + } + break; + } + return ((img->get != NULL) && (img->put.separate != NULL)); } -static int -BuildMapUaToAa(TIFFRGBAImage* img) +static int BuildMapUaToAa(TIFFRGBAImage *img) { - static const char module[]="BuildMapUaToAa"; - uint8* m; - uint16 na,nv; - assert(img->UaToAa==NULL); - img->UaToAa=_TIFFmalloc(65536); - if (img->UaToAa==NULL) - { - TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); - return(0); - } - m=img->UaToAa; - for (na=0; na<256; na++) - { - for (nv=0; nv<256; nv++) - *m++=(uint8)((nv*na+127)/255); - } - return(1); + static const char module[] = "BuildMapUaToAa"; + uint8_t *m; + uint16_t na, nv; + assert(img->UaToAa == NULL); + img->UaToAa = _TIFFmallocExt(img->tif, 65536); + if (img->UaToAa == NULL) + { + TIFFErrorExtR(img->tif, module, "Out of memory"); + return (0); + } + m = img->UaToAa; + for (na = 0; na < 256; na++) + { + for (nv = 0; nv < 256; nv++) + *m++ = (uint8_t)((nv * na + 127) / 255); + } + return (1); } -static int -BuildMapBitdepth16To8(TIFFRGBAImage* img) +static int BuildMapBitdepth16To8(TIFFRGBAImage *img) { - static const char module[]="BuildMapBitdepth16To8"; - uint8* m; - uint32 n; - assert(img->Bitdepth16To8==NULL); - img->Bitdepth16To8=_TIFFmalloc(65536); - if (img->Bitdepth16To8==NULL) - { - TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); - return(0); - } - m=img->Bitdepth16To8; - for (n=0; n<65536; n++) - *m++=(uint8)((n+128)/257); - return(1); + static const char module[] = "BuildMapBitdepth16To8"; + uint8_t *m; + uint32_t n; + assert(img->Bitdepth16To8 == NULL); + img->Bitdepth16To8 = _TIFFmallocExt(img->tif, 65536); + if (img->Bitdepth16To8 == NULL) + { + TIFFErrorExtR(img->tif, module, "Out of memory"); + return (0); + } + m = img->Bitdepth16To8; + for (n = 0; n < 65536; n++) + *m++ = (uint8_t)((n + 128) / 257); + return (1); } - /* * Read a whole strip off data from the file, and convert to RGBA form. * If this is the last strip, then it will only contain the portion of @@ -2909,56 +3190,59 @@ BuildMapBitdepth16To8(TIFFRGBAImage* img) * organized in bottom to top form. */ - -int -TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ) +int TIFFReadRGBAStrip(TIFF *tif, uint32_t row, uint32_t *raster) { - return TIFFReadRGBAStripExt(tif, row, raster, 0 ); + return TIFFReadRGBAStripExt(tif, row, raster, 0); } -int -TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error) +int TIFFReadRGBAStripExt(TIFF *tif, uint32_t row, uint32_t *raster, + int stop_on_error) { - char emsg[1024] = ""; + char emsg[EMSG_BUF_SIZE] = ""; TIFFRGBAImage img; - int ok; - uint32 rowsperstrip, rows_to_read; + int ok; + uint32_t rowsperstrip, rows_to_read; - if( TIFFIsTiled( tif ) ) + if (TIFFIsTiled(tif)) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), - "Can't use TIFFReadRGBAStrip() with tiled file."); - return (0); + TIFFErrorExtR(tif, TIFFFileName(tif), + "Can't use TIFFReadRGBAStrip() with tiled file."); + return (0); } - + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - if( (row % rowsperstrip) != 0 ) + if ((row % rowsperstrip) != 0) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), - "Row passed to TIFFReadRGBAStrip() must be first in a strip."); - return (0); + TIFFErrorExtR( + tif, TIFFFileName(tif), + "Row passed to TIFFReadRGBAStrip() must be first in a strip."); + return (0); } - if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { + if (TIFFRGBAImageOK(tif, emsg) && + TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) + { img.row_offset = row; img.col_offset = 0; - if( row + rowsperstrip > img.height ) + if (row + rowsperstrip > img.height) rows_to_read = img.height - row; else rows_to_read = rowsperstrip; - - ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read ); - - TIFFRGBAImageEnd(&img); - } else { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); - ok = 0; + + ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read); + + TIFFRGBAImageEnd(&img); } - + else + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); + ok = 0; + } + return (ok); } @@ -2968,54 +3252,53 @@ TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error) * and may include zeroed areas if the tile extends off the image. */ -int -TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster) +int TIFFReadRGBATile(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster) { - return TIFFReadRGBATileExt(tif, col, row, raster, 0 ); + return TIFFReadRGBATileExt(tif, col, row, raster, 0); } - -int -TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop_on_error ) +int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster, + int stop_on_error) { - char emsg[1024] = ""; + char emsg[EMSG_BUF_SIZE] = ""; TIFFRGBAImage img; - int ok; - uint32 tile_xsize, tile_ysize; - uint32 read_xsize, read_ysize; - uint32 i_row; + int ok; + uint32_t tile_xsize, tile_ysize; + uint32_t read_xsize, read_ysize; + uint32_t i_row; /* * Verify that our request is legal - on a tile file, and on a * tile boundary. */ - - if( !TIFFIsTiled( tif ) ) + + if (!TIFFIsTiled(tif)) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), - "Can't use TIFFReadRGBATile() with striped file."); - return (0); + TIFFErrorExtR(tif, TIFFFileName(tif), + "Can't use TIFFReadRGBATile() with striped file."); + return (0); } - + TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize); TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize); - if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 ) + if ((col % tile_xsize) != 0 || (row % tile_ysize) != 0) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), - "Row/col passed to TIFFReadRGBATile() must be top" - "left corner of a tile."); - return (0); + TIFFErrorExtR(tif, TIFFFileName(tif), + "Row/col passed to TIFFReadRGBATile() must be top" + "left corner of a tile."); + return (0); } /* * Setup the RGBA reader. */ - - if (!TIFFRGBAImageOK(tif, emsg) - || !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); - return( 0 ); + + if (!TIFFRGBAImageOK(tif, emsg) || + !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); + return (0); } /* @@ -3025,12 +3308,12 @@ TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop * a full tile configuration afterwards. */ - if( row + tile_ysize > img.height ) + if (row + tile_ysize > img.height) read_ysize = img.height - row; else read_ysize = tile_ysize; - - if( col + tile_xsize > img.width ) + + if (col + tile_xsize > img.width) read_xsize = img.width - col; else read_xsize = tile_xsize; @@ -3038,12 +3321,12 @@ TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop /* * Read the chunk of imagery. */ - + img.row_offset = row; img.col_offset = col; - ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize ); - + ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize); + TIFFRGBAImageEnd(&img); /* @@ -3051,33 +3334,27 @@ TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop * shifting the data around as if a full tile of data is being returned. * * This is all the more complicated because the image is organized in - * bottom to top format. + * bottom to top format. */ - if( read_xsize == tile_xsize && read_ysize == tile_ysize ) - return( ok ); + if (read_xsize == tile_xsize && read_ysize == tile_ysize) + return (ok); - for( i_row = 0; i_row < read_ysize; i_row++ ) { - memmove( raster + (tile_ysize - i_row - 1) * tile_xsize, - raster + (read_ysize - i_row - 1) * read_xsize, - read_xsize * sizeof(uint32) ); - _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize, - 0, sizeof(uint32) * (tile_xsize - read_xsize) ); + for (i_row = 0; i_row < read_ysize; i_row++) + { + memmove(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize, + raster + (size_t)(read_ysize - i_row - 1) * read_xsize, + read_xsize * sizeof(uint32_t)); + _TIFFmemset(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize + + read_xsize, + 0, sizeof(uint32_t) * (tile_xsize - read_xsize)); } - for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) { - _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize, - 0, sizeof(uint32) * tile_xsize ); + for (i_row = read_ysize; i_row < tile_ysize; i_row++) + { + _TIFFmemset(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize, 0, + sizeof(uint32_t) * tile_xsize); } return (ok); } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_hash_set.c b/3rdparty/libtiff/tif_hash_set.c new file mode 100644 index 0000000000..9792c63f47 --- /dev/null +++ b/3rdparty/libtiff/tif_hash_set.c @@ -0,0 +1,603 @@ +/********************************************************************** + * + * Name: tif_hash_set.c + * Purpose: Hash set functions. + * Author: Even Rouault, + * + ********************************************************************** + * Copyright (c) 2008-2009, Even Rouault + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************/ + +#include "tif_config.h" + +#include "tif_hash_set.h" + +#include +#include +#include +#include +#include + +/** List element structure. */ +typedef struct _TIFFList TIFFList; + +/** List element structure. */ +struct _TIFFList +{ + /*! Pointer to the data object. Should be allocated and freed by the + * caller. + * */ + void *pData; + /*! Pointer to the next element in list. NULL, if current element is the + * last one. + */ + struct _TIFFList *psNext; +}; + +struct _TIFFHashSet +{ + TIFFHashSetHashFunc fnHashFunc; + TIFFHashSetEqualFunc fnEqualFunc; + TIFFHashSetFreeEltFunc fnFreeEltFunc; + TIFFList **tabList; + int nSize; + int nIndiceAllocatedSize; + int nAllocatedSize; + TIFFList *psRecyclingList; + int nRecyclingListSize; + bool bRehash; +#ifdef HASH_DEBUG + int nCollisions; +#endif +}; + +static const int anPrimes[] = { + 53, 97, 193, 389, 769, 1543, 3079, + 6151, 12289, 24593, 49157, 98317, 196613, 393241, + 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, + 100663319, 201326611, 402653189, 805306457, 1610612741}; + +/************************************************************************/ +/* TIFFHashSetHashPointer() */ +/************************************************************************/ + +/** + * Hash function for an arbitrary pointer + * + * @param elt the arbitrary pointer to hash + * + * @return the hash value of the pointer + */ + +static unsigned long TIFFHashSetHashPointer(const void *elt) +{ + return (unsigned long)(uintptr_t)((void *)(elt)); +} + +/************************************************************************/ +/* TIFFHashSetEqualPointer() */ +/************************************************************************/ + +/** + * Equality function for arbitrary pointers + * + * @param elt1 the first arbitrary pointer to compare + * @param elt2 the second arbitrary pointer to compare + * + * @return true if the pointers are equal + */ + +static bool TIFFHashSetEqualPointer(const void *elt1, const void *elt2) +{ + return elt1 == elt2; +} + +/************************************************************************/ +/* TIFFHashSetNew() */ +/************************************************************************/ + +/** + * Creates a new hash set + * + * The hash function must return a hash value for the elements to insert. + * If fnHashFunc is NULL, TIFFHashSetHashPointer will be used. + * + * The equal function must return if two elements are equal. + * If fnEqualFunc is NULL, TIFFHashSetEqualPointer will be used. + * + * The free function is used to free elements inserted in the hash set, + * when the hash set is destroyed, when elements are removed or replaced. + * If fnFreeEltFunc is NULL, elements inserted into the hash set will not be + * freed. + * + * @param fnHashFunc hash function. May be NULL. + * @param fnEqualFunc equal function. May be NULL. + * @param fnFreeEltFunc element free function. May be NULL. + * + * @return a new hash set + */ + +TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc, + TIFFHashSetEqualFunc fnEqualFunc, + TIFFHashSetFreeEltFunc fnFreeEltFunc) +{ + TIFFHashSet *set = (TIFFHashSet *)malloc(sizeof(TIFFHashSet)); + if (set == NULL) + return NULL; + set->fnHashFunc = fnHashFunc ? fnHashFunc : TIFFHashSetHashPointer; + set->fnEqualFunc = fnEqualFunc ? fnEqualFunc : TIFFHashSetEqualPointer; + set->fnFreeEltFunc = fnFreeEltFunc; + set->nSize = 0; + set->tabList = (TIFFList **)(calloc(sizeof(TIFFList *), 53)); + if (set->tabList == NULL) + { + free(set); + return NULL; + } + set->nIndiceAllocatedSize = 0; + set->nAllocatedSize = 53; + set->psRecyclingList = NULL; + set->nRecyclingListSize = 0; + set->bRehash = false; +#ifdef HASH_DEBUG + set->nCollisions = 0; +#endif + return set; +} + +/************************************************************************/ +/* TIFFHashSetSize() */ +/************************************************************************/ + +/** + * Returns the number of elements inserted in the hash set + * + * Note: this is not the internal size of the hash set + * + * @param set the hash set + * + * @return the number of elements in the hash set + */ + +int TIFFHashSetSize(const TIFFHashSet *set) +{ + assert(set != NULL); + return set->nSize; +} + +/************************************************************************/ +/* TIFFHashSetGetNewListElt() */ +/************************************************************************/ + +static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set) +{ + if (set->psRecyclingList) + { + TIFFList *psRet = set->psRecyclingList; + psRet->pData = NULL; + set->nRecyclingListSize--; + set->psRecyclingList = psRet->psNext; + return psRet; + } + + return (TIFFList *)malloc(sizeof(TIFFList)); +} + +/************************************************************************/ +/* TIFFHashSetReturnListElt() */ +/************************************************************************/ + +static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList) +{ + if (set->nRecyclingListSize < 128) + { + psList->psNext = set->psRecyclingList; + set->psRecyclingList = psList; + set->nRecyclingListSize++; + } + else + { + free(psList); + } +} + +/************************************************************************/ +/* TIFFHashSetClearInternal() */ +/************************************************************************/ + +static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize) +{ + assert(set != NULL); + for (int i = 0; i < set->nAllocatedSize; i++) + { + TIFFList *cur = set->tabList[i]; + while (cur) + { + if (set->fnFreeEltFunc) + set->fnFreeEltFunc(cur->pData); + TIFFList *psNext = cur->psNext; + if (bFinalize) + free(cur); + else + TIFFHashSetReturnListElt(set, cur); + cur = psNext; + } + set->tabList[i] = NULL; + } + set->bRehash = false; +} + +/************************************************************************/ +/* TIFFListDestroy() */ +/************************************************************************/ + +/** + * Destroy a list. Caller responsible for freeing data objects contained in + * list elements. + * + * @param psList pointer to list head. + * + */ + +static void TIFFListDestroy(TIFFList *psList) +{ + TIFFList *psCurrent = psList; + + while (psCurrent) + { + TIFFList *const psNext = psCurrent->psNext; + free(psCurrent); + psCurrent = psNext; + } +} + +/************************************************************************/ +/* TIFFHashSetDestroy() */ +/************************************************************************/ + +/** + * Destroys an allocated hash set. + * + * This function also frees the elements if a free function was + * provided at the creation of the hash set. + * + * @param set the hash set + */ + +void TIFFHashSetDestroy(TIFFHashSet *set) +{ + if (set) + { + TIFFHashSetClearInternal(set, true); + free(set->tabList); + TIFFListDestroy(set->psRecyclingList); + free(set); + } +} + +#ifdef notused +/************************************************************************/ +/* TIFFHashSetClear() */ +/************************************************************************/ + +/** + * Clear all elements from a hash set. + * + * This function also frees the elements if a free function was + * provided at the creation of the hash set. + * + * @param set the hash set + */ + +void TIFFHashSetClear(TIFFHashSet *set) +{ + TIFFHashSetClearInternal(set, false); + set->nIndiceAllocatedSize = 0; + set->nAllocatedSize = 53; +#ifdef HASH_DEBUG + set->nCollisions = 0; +#endif + set->nSize = 0; +} + +/************************************************************************/ +/* TIFFHashSetForeach() */ +/************************************************************************/ + +/** + * Walk through the hash set and runs the provided function on all the + * elements + * + * This function is provided the user_data argument of TIFFHashSetForeach. + * It must return true to go on the walk through the hash set, or FALSE to + * make it stop. + * + * Note : the structure of the hash set must *NOT* be modified during the + * walk. + * + * @param set the hash set. + * @param fnIterFunc the function called on each element. + * @param user_data the user data provided to the function. + */ + +void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc, + void *user_data) +{ + assert(set != NULL); + if (!fnIterFunc) + return; + + for (int i = 0; i < set->nAllocatedSize; i++) + { + TIFFList *cur = set->tabList[i]; + while (cur) + { + if (!fnIterFunc(cur->pData, user_data)) + return; + + cur = cur->psNext; + } + } +} +#endif + +/************************************************************************/ +/* TIFFHashSetRehash() */ +/************************************************************************/ + +static bool TIFFHashSetRehash(TIFFHashSet *set) +{ + int nNewAllocatedSize = anPrimes[set->nIndiceAllocatedSize]; + TIFFList **newTabList = + (TIFFList **)(calloc(sizeof(TIFFList *), nNewAllocatedSize)); + if (newTabList == NULL) + return false; +#ifdef HASH_DEBUG + TIFFDebug("TIFFHASH", + "hashSet=%p, nSize=%d, nCollisions=%d, " + "fCollisionRate=%.02f", + set, set->nSize, set->nCollisions, + set->nCollisions * 100.0 / set->nSize); + set->nCollisions = 0; +#endif + for (int i = 0; i < set->nAllocatedSize; i++) + { + TIFFList *cur = set->tabList[i]; + while (cur) + { + const unsigned long nNewHashVal = + set->fnHashFunc(cur->pData) % nNewAllocatedSize; +#ifdef HASH_DEBUG + if (newTabList[nNewHashVal]) + set->nCollisions++; +#endif + TIFFList *psNext = cur->psNext; + cur->psNext = newTabList[nNewHashVal]; + newTabList[nNewHashVal] = cur; + cur = psNext; + } + } + free(set->tabList); + set->tabList = newTabList; + set->nAllocatedSize = nNewAllocatedSize; + set->bRehash = false; + return true; +} + +/************************************************************************/ +/* TIFFHashSetFindPtr() */ +/************************************************************************/ + +static void **TIFFHashSetFindPtr(TIFFHashSet *set, const void *elt) +{ + const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize; + TIFFList *cur = set->tabList[nHashVal]; + while (cur) + { + if (set->fnEqualFunc(cur->pData, elt)) + return &cur->pData; + cur = cur->psNext; + } + return NULL; +} + +/************************************************************************/ +/* TIFFHashSetInsert() */ +/************************************************************************/ + +/** + * Inserts an element into a hash set. + * + * If the element was already inserted in the hash set, the previous + * element is replaced by the new element. If a free function was provided, + * it is used to free the previously inserted element + * + * @param set the hash set + * @param elt the new element to insert in the hash set + * + * @return true if success. If false is returned, elt has not been inserted, + * but TIFFHashSetInsert() will have run the free function if provided. + */ + +bool TIFFHashSetInsert(TIFFHashSet *set, void *elt) +{ + assert(set != NULL); + void **pElt = TIFFHashSetFindPtr(set, elt); + if (pElt) + { + if (set->fnFreeEltFunc) + set->fnFreeEltFunc(*pElt); + + *pElt = elt; + return true; + } + + if (set->nSize >= 2 * set->nAllocatedSize / 3 || + (set->bRehash && set->nIndiceAllocatedSize > 0 && + set->nSize <= set->nAllocatedSize / 2)) + { + set->nIndiceAllocatedSize++; + if (!TIFFHashSetRehash(set)) + { + set->nIndiceAllocatedSize--; + if (set->fnFreeEltFunc) + set->fnFreeEltFunc(elt); + return false; + } + } + + const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize; +#ifdef HASH_DEBUG + if (set->tabList[nHashVal]) + set->nCollisions++; +#endif + + TIFFList *new_elt = TIFFHashSetGetNewListElt(set); + if (new_elt == NULL) + { + if (set->fnFreeEltFunc) + set->fnFreeEltFunc(elt); + return false; + } + new_elt->pData = elt; + new_elt->psNext = set->tabList[nHashVal]; + set->tabList[nHashVal] = new_elt; + set->nSize++; + + return true; +} + +/************************************************************************/ +/* TIFFHashSetLookup() */ +/************************************************************************/ + +/** + * Returns the element found in the hash set corresponding to the element to + * look up The element must not be modified. + * + * @param set the hash set + * @param elt the element to look up in the hash set + * + * @return the element found in the hash set or NULL + */ + +void *TIFFHashSetLookup(TIFFHashSet *set, const void *elt) +{ + assert(set != NULL); + void **pElt = TIFFHashSetFindPtr(set, elt); + if (pElt) + return *pElt; + + return NULL; +} + +/************************************************************************/ +/* TIFFHashSetRemoveInternal() */ +/************************************************************************/ + +static bool TIFFHashSetRemoveInternal(TIFFHashSet *set, const void *elt, + bool bDeferRehash) +{ + assert(set != NULL); + if (set->nIndiceAllocatedSize > 0 && set->nSize <= set->nAllocatedSize / 2) + { + set->nIndiceAllocatedSize--; + if (bDeferRehash) + set->bRehash = true; + else + { + if (!TIFFHashSetRehash(set)) + { + set->nIndiceAllocatedSize++; + return false; + } + } + } + + int nHashVal = (int)(set->fnHashFunc(elt) % set->nAllocatedSize); + TIFFList *cur = set->tabList[nHashVal]; + TIFFList *prev = NULL; + while (cur) + { + if (set->fnEqualFunc(cur->pData, elt)) + { + if (prev) + prev->psNext = cur->psNext; + else + set->tabList[nHashVal] = cur->psNext; + + if (set->fnFreeEltFunc) + set->fnFreeEltFunc(cur->pData); + + TIFFHashSetReturnListElt(set, cur); +#ifdef HASH_DEBUG + if (set->tabList[nHashVal]) + set->nCollisions--; +#endif + set->nSize--; + return true; + } + prev = cur; + cur = cur->psNext; + } + return false; +} + +/************************************************************************/ +/* TIFFHashSetRemove() */ +/************************************************************************/ + +/** + * Removes an element from a hash set + * + * @param set the hash set + * @param elt the new element to remove from the hash set + * + * @return true if the element was in the hash set + */ + +bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt) +{ + return TIFFHashSetRemoveInternal(set, elt, false); +} + +#ifdef notused +/************************************************************************/ +/* TIFFHashSetRemoveDeferRehash() */ +/************************************************************************/ + +/** + * Removes an element from a hash set. + * + * This will defer potential rehashing of the set to later calls to + * TIFFHashSetInsert() or TIFFHashSetRemove(). + * + * @param set the hash set + * @param elt the new element to remove from the hash set + * + * @return true if the element was in the hash set + */ + +bool TIFFHashSetRemoveDeferRehash(TIFFHashSet *set, const void *elt) +{ + return TIFFHashSetRemoveInternal(set, elt, true); +} +#endif diff --git a/3rdparty/libtiff/tif_hash_set.h b/3rdparty/libtiff/tif_hash_set.h new file mode 100644 index 0000000000..f60e2c675e --- /dev/null +++ b/3rdparty/libtiff/tif_hash_set.h @@ -0,0 +1,100 @@ +/********************************************************************** + * $Id$ + * + * Name: tif_hash_set.h + * Project: TIFF - Common Portability Library + * Purpose: Hash set functions. + * Author: Even Rouault, + * + ********************************************************************** + * Copyright (c) 2008-2009, Even Rouault + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************/ + +#ifndef TIFF_HASH_SET_H_INCLUDED +#define TIFF_HASH_SET_H_INCLUDED + +#include + +/** + * \file tif_hash_set.h + * + * Hash set implementation. + * + * An hash set is a data structure that holds elements that are unique + * according to a comparison function. Operations on the hash set, such as + * insertion, removal or lookup, are supposed to be fast if an efficient + * "hash" function is provided. + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Types */ + + /** Opaque type for a hash set */ + typedef struct _TIFFHashSet TIFFHashSet; + + /** TIFFHashSetHashFunc */ + typedef unsigned long (*TIFFHashSetHashFunc)(const void *elt); + + /** TIFFHashSetEqualFunc */ + typedef bool (*TIFFHashSetEqualFunc)(const void *elt1, const void *elt2); + + /** TIFFHashSetFreeEltFunc */ + typedef void (*TIFFHashSetFreeEltFunc)(void *elt); + + /* Functions */ + + TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc, + TIFFHashSetEqualFunc fnEqualFunc, + TIFFHashSetFreeEltFunc fnFreeEltFunc); + + void TIFFHashSetDestroy(TIFFHashSet *set); + + int TIFFHashSetSize(const TIFFHashSet *set); + +#ifdef notused + void TIFFHashSetClear(TIFFHashSet *set); + + /** TIFFHashSetIterEltFunc */ + typedef int (*TIFFHashSetIterEltFunc)(void *elt, void *user_data); + + void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc, + void *user_data); +#endif + + bool TIFFHashSetInsert(TIFFHashSet *set, void *elt); + + void *TIFFHashSetLookup(TIFFHashSet *set, const void *elt); + + bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt); + +#ifdef notused + bool TIFFHashSetRemoveDeferRehash(TIFFHashSet *set, const void *elt); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* TIFF_HASH_SET_H_INCLUDED */ diff --git a/3rdparty/libtiff/tif_jbig.c b/3rdparty/libtiff/tif_jbig.c index a3500e0b6f..7e455ad1ce 100644 --- a/3rdparty/libtiff/tif_jbig.c +++ b/3rdparty/libtiff/tif_jbig.c @@ -35,199 +35,197 @@ #ifdef JBIG_SUPPORT #include "jbig.h" -static int JBIGSetupDecode(TIFF* tif) +static int JBIGSetupDecode(TIFF *tif) { - if (TIFFNumberOfStrips(tif) != 1) - { - TIFFErrorExt(tif->tif_clientdata, "JBIG", "Multistrip images not supported in decoder"); - return 0; - } + if (TIFFNumberOfStrips(tif) != 1) + { + TIFFErrorExtR(tif, "JBIG", + "Multistrip images not supported in decoder"); + return 0; + } - return 1; + return 1; } -static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) +static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s) { - struct jbg_dec_state decoder; - int decodeStatus = 0; - unsigned char* pImage = NULL; - unsigned long decodedSize; - (void) s; + struct jbg_dec_state decoder; + int decodeStatus = 0; + unsigned char *pImage = NULL; + unsigned long decodedSize; + (void)s; - if (isFillOrder(tif, tif->tif_dir.td_fillorder)) - { - TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); - } + if (isFillOrder(tif, tif->tif_dir.td_fillorder)) + { + TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); + } - jbg_dec_init(&decoder); + jbg_dec_init(&decoder); #if defined(HAVE_JBG_NEWLEN) - jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); - /* - * I do not check the return status of jbg_newlen because even if this - * function fails it does not necessarily mean that decoding the image - * will fail. It is generally only needed for received fax images - * that do not contain the actual length of the image in the BIE - * header. I do not log when an error occurs because that will cause - * problems when converting JBIG encoded TIFF's to - * PostScript. As long as the actual image length is contained in the - * BIE header jbg_dec_in should succeed. - */ + jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); + /* + * I do not check the return status of jbg_newlen because even if this + * function fails it does not necessarily mean that decoding the image + * will fail. It is generally only needed for received fax images + * that do not contain the actual length of the image in the BIE + * header. I do not log when an error occurs because that will cause + * problems when converting JBIG encoded TIFF's to + * PostScript. As long as the actual image length is contained in the + * BIE header jbg_dec_in should succeed. + */ #endif /* HAVE_JBG_NEWLEN */ - decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawcp, - (size_t)tif->tif_rawcc, NULL); - if (JBG_EOK != decodeStatus) - { - /* - * XXX: JBG_EN constant was defined in pre-2.0 releases of the - * JBIG-KIT. Since the 2.0 the error reporting functions were - * changed. We will handle both cases here. - */ - TIFFErrorExt(tif->tif_clientdata, - "JBIG", "Error (%d) decoding: %s", - decodeStatus, + decodeStatus = jbg_dec_in(&decoder, (unsigned char *)tif->tif_rawcp, + (size_t)tif->tif_rawcc, NULL); + if (JBG_EOK != decodeStatus) + { + /* + * XXX: JBG_EN constant was defined in pre-2.0 releases of the + * JBIG-KIT. Since the 2.0 the error reporting functions were + * changed. We will handle both cases here. + */ + TIFFErrorExtR(tif, "JBIG", "Error (%d) decoding: %s", decodeStatus, #if defined(JBG_EN) - jbg_strerror(decodeStatus, JBG_EN) + jbg_strerror(decodeStatus, JBG_EN) #else - jbg_strerror(decodeStatus) + jbg_strerror(decodeStatus) #endif - ); - jbg_dec_free(&decoder); - return 0; - } + ); + jbg_dec_free(&decoder); + return 0; + } - decodedSize = jbg_dec_getsize(&decoder); - if( (tmsize_t)decodedSize < size ) - { - TIFFWarningExt(tif->tif_clientdata, "JBIG", - "Only decoded %lu bytes, whereas %lu requested", - decodedSize, (unsigned long)size); - } - else if( (tmsize_t)decodedSize > size ) - { - TIFFErrorExt(tif->tif_clientdata, "JBIG", - "Decoded %lu bytes, whereas %lu were requested", - decodedSize, (unsigned long)size); - jbg_dec_free(&decoder); - return 0; - } - pImage = jbg_dec_getimage(&decoder, 0); - _TIFFmemcpy(buffer, pImage, decodedSize); - jbg_dec_free(&decoder); + decodedSize = jbg_dec_getsize(&decoder); + if ((tmsize_t)decodedSize < size) + { + TIFFWarningExtR(tif, "JBIG", + "Only decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT + " requested", + decodedSize, size); + } + else if ((tmsize_t)decodedSize > size) + { + TIFFErrorExtR(tif, "JBIG", + "Decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT + " were requested", + decodedSize, size); + jbg_dec_free(&decoder); + return 0; + } + pImage = jbg_dec_getimage(&decoder, 0); + _TIFFmemcpy(buffer, pImage, decodedSize); + jbg_dec_free(&decoder); - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; + tif->tif_rawcp += tif->tif_rawcc; + tif->tif_rawcc = 0; - return 1; + return 1; } -static int JBIGSetupEncode(TIFF* tif) +static int JBIGSetupEncode(TIFF *tif) { - if (TIFFNumberOfStrips(tif) != 1) - { - TIFFErrorExt(tif->tif_clientdata, "JBIG", "Multistrip images not supported in encoder"); - return 0; - } + if (TIFFNumberOfStrips(tif) != 1) + { + TIFFErrorExtR(tif, "JBIG", + "Multistrip images not supported in encoder"); + return 0; + } - return 1; + return 1; } -static int JBIGCopyEncodedData(TIFF* tif, unsigned char* pp, size_t cc, uint16 s) +static int JBIGCopyEncodedData(TIFF *tif, unsigned char *pp, size_t cc, + uint16_t s) { - (void) s; - while (cc > 0) - { - tmsize_t n = (tmsize_t)cc; + (void)s; + while (cc > 0) + { + tmsize_t n = (tmsize_t)cc; - if (tif->tif_rawcc + n > tif->tif_rawdatasize) - { - n = tif->tif_rawdatasize - tif->tif_rawcc; - } + if (tif->tif_rawcc + n > tif->tif_rawdatasize) + { + n = tif->tif_rawdatasize - tif->tif_rawcc; + } - assert(n > 0); - _TIFFmemcpy(tif->tif_rawcp, pp, n); - tif->tif_rawcp += n; - tif->tif_rawcc += n; - pp += n; - cc -= (size_t)n; - if (tif->tif_rawcc >= tif->tif_rawdatasize && - !TIFFFlushData1(tif)) - { - return (-1); - } - } + assert(n > 0); + _TIFFmemcpy(tif->tif_rawcp, pp, n); + tif->tif_rawcp += n; + tif->tif_rawcc += n; + pp += n; + cc -= (size_t)n; + if (tif->tif_rawcc >= tif->tif_rawdatasize && !TIFFFlushData1(tif)) + { + return (-1); + } + } - return (1); + return (1); } -static void JBIGOutputBie(unsigned char* buffer, size_t len, void* userData) +static void JBIGOutputBie(unsigned char *buffer, size_t len, void *userData) { - TIFF* tif = (TIFF*)userData; + TIFF *tif = (TIFF *)userData; - if (isFillOrder(tif, tif->tif_dir.td_fillorder)) - { - TIFFReverseBits(buffer, (tmsize_t)len); - } + if (isFillOrder(tif, tif->tif_dir.td_fillorder)) + { + TIFFReverseBits(buffer, (tmsize_t)len); + } - JBIGCopyEncodedData(tif, buffer, len, 0); + JBIGCopyEncodedData(tif, buffer, len, 0); } -static int JBIGEncode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) +static int JBIGEncode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s) { - TIFFDirectory* dir = &tif->tif_dir; - struct jbg_enc_state encoder; + TIFFDirectory *dir = &tif->tif_dir; + struct jbg_enc_state encoder; - (void) size, (void) s; + (void)size, (void)s; - jbg_enc_init(&encoder, - dir->td_imagewidth, - dir->td_imagelength, - 1, - &buffer, - JBIGOutputBie, - tif); - /* - * jbg_enc_out does the "real" encoding. As data is encoded, - * JBIGOutputBie is called, which writes the data to the directory. - */ - jbg_enc_out(&encoder); - jbg_enc_free(&encoder); + jbg_enc_init(&encoder, dir->td_imagewidth, dir->td_imagelength, 1, &buffer, + JBIGOutputBie, tif); + /* + * jbg_enc_out does the "real" encoding. As data is encoded, + * JBIGOutputBie is called, which writes the data to the directory. + */ + jbg_enc_out(&encoder); + jbg_enc_free(&encoder); - return 1; + return 1; } -int TIFFInitJBIG(TIFF* tif, int scheme) +int TIFFInitJBIG(TIFF *tif, int scheme) { - (void)scheme; - assert(scheme == COMPRESSION_JBIG); + (void)scheme; + assert(scheme == COMPRESSION_JBIG); - /* - * These flags are set so the JBIG Codec can control when to reverse - * bits and when not to and to allow the jbig decoder and bit reverser - * to write to memory when necessary. - */ - tif->tif_flags |= TIFF_NOBITREV; - tif->tif_flags &= ~TIFF_MAPPED; + /* + * These flags are set so the JBIG Codec can control when to reverse + * bits and when not to and to allow the jbig decoder and bit reverser + * to write to memory when necessary. + */ + tif->tif_flags |= TIFF_NOBITREV; + tif->tif_flags &= ~TIFF_MAPPED; + /* We may have read from a previous IFD and thus set TIFF_BUFFERMMAP and + * cleared TIFF_MYBUFFER. It is necessary to restore them to their initial + * value to be consistent with the state of a non-memory mapped file. + */ + if (tif->tif_flags & TIFF_BUFFERMMAP) + { + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + tif->tif_flags &= ~TIFF_BUFFERMMAP; + tif->tif_flags |= TIFF_MYBUFFER; + } - /* Setup the function pointers for encode, decode, and cleanup. */ - tif->tif_setupdecode = JBIGSetupDecode; - tif->tif_decodestrip = JBIGDecode; + /* Setup the function pointers for encode, decode, and cleanup. */ + tif->tif_setupdecode = JBIGSetupDecode; + tif->tif_decodestrip = JBIGDecode; - tif->tif_setupencode = JBIGSetupEncode; - tif->tif_encodestrip = JBIGEncode; + tif->tif_setupencode = JBIGSetupEncode; + tif->tif_encodestrip = JBIGEncode; - return 1; + return 1; } #endif /* JBIG_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_jpeg.c b/3rdparty/libtiff/tif_jpeg.c index 6711137a92..250144f211 100644 --- a/3rdparty/libtiff/tif_jpeg.c +++ b/3rdparty/libtiff/tif_jpeg.c @@ -2,23 +2,23 @@ * Copyright (c) 1994-1997 Sam Leffler * Copyright (c) 1994-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -44,10 +44,34 @@ */ #include -int TIFFFillStrip(TIFF* tif, uint32 strip); -int TIFFFillTile(TIFF* tif, uint32 tile); -int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ); -int TIFFJPEGIsFullStripRequired_12(TIFF* tif); +/* Settings that are independent of libjpeg ABI. Used when reinitializing the */ +/* JPEGState from libjpegs 8 bit to libjpeg 12 bits, which have potentially */ +/* different ABI */ +typedef struct +{ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ + TIFFStripMethod defsparent; /* super-class method */ + TIFFTileMethod deftparent; /* super-class method */ + + /* pseudo-tag fields */ + void *jpegtables; /* JPEGTables tag value, or NULL */ + uint32_t jpegtables_length; /* number of bytes in same */ + int jpegquality; /* Compression quality level */ + int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ + int jpegtablesmode; /* What to put in JPEGTables */ + + int ycbcrsampling_fetched; + int max_allowed_scan_number; + int has_warned_about_progressive_mode; +} JPEGOtherSettings; + +int TIFFFillStrip(TIFF *tif, uint32_t strip); +int TIFFFillTile(TIFF *tif, uint32_t tile); +int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings, + int scheme, int is_encode); +int TIFFJPEGIsFullStripRequired_12(TIFF *tif); /* We undefine FAR to avoid conflict with JPEG definition */ @@ -62,7 +86,7 @@ int TIFFJPEGIsFullStripRequired_12(TIFF* tif); a conflicting typedef given the headers which are included. */ #if defined(__BORLANDC__) || defined(__MINGW32__) -# define XMD_H 1 +#define XMD_H 1 #endif /* @@ -80,24 +104,63 @@ int TIFFJPEGIsFullStripRequired_12(TIFF* tif); /* Define "boolean" as unsigned char, not int, per Windows custom. */ #if defined(__WIN32__) && !defined(__MINGW32__) -# ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ - typedef unsigned char boolean; -# endif -# define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ #endif -#include "jpeglib.h" #include "jerror.h" +#include "jpeglib.h" -/* +/* Do optional compile-time version check */ +#if defined(EXPECTED_JPEG_LIB_VERSION) && !defined(LIBJPEG_12_PATH) +#if EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION +#error EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION +#endif +#endif + +/* * Do we want to do special processing suitable for when JSAMPLE is a - * 16bit value? + * 16bit value? */ +/* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 2.2 which + * adds a dual-mode 8/12 bit API in the same library. + */ + +#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) +#define JPEG_DUAL_MODE_8_12 +/* Start by undefining BITS_IN_JSAMPLE which is always set to 8 in libjpeg-turbo + * >= 2.2 Cf + * https://github.com/libjpeg-turbo/libjpeg-turbo/commit/8b9bc4b9635a2a047fb23ebe70c9acd728d3f99b + */ +#undef BITS_IN_JSAMPLE +/* libjpeg-turbo >= 2.2 adds J12xxxx datatypes for the 12-bit mode. */ +#if defined(FROM_TIF_JPEG_12) +#define BITS_IN_JSAMPLE 12 +#define TIFF_JSAMPLE J12SAMPLE +#define TIFF_JSAMPARRAY J12SAMPARRAY +#define TIFF_JSAMPIMAGE J12SAMPIMAGE +#define TIFF_JSAMPROW J12SAMPROW +#else +#define BITS_IN_JSAMPLE 8 +#define TIFF_JSAMPLE JSAMPLE +#define TIFF_JSAMPARRAY JSAMPARRAY +#define TIFF_JSAMPIMAGE JSAMPIMAGE +#define TIFF_JSAMPROW JSAMPROW +#endif +#else +#define TIFF_JSAMPLE JSAMPLE +#define TIFF_JSAMPARRAY JSAMPARRAY +#define TIFF_JSAMPIMAGE JSAMPIMAGE +#define TIFF_JSAMPROW JSAMPROW +#endif + #if defined(JPEG_LIB_MK1) -# define JPEG_LIB_MK1_OR_12BIT 1 +#define JPEG_LIB_MK1_OR_12BIT 1 #elif BITS_IN_JSAMPLE == 12 -# define JPEG_LIB_MK1_OR_12BIT 1 +#define JPEG_LIB_MK1_OR_12BIT 1 #endif /* @@ -115,9 +178,9 @@ int TIFFJPEGIsFullStripRequired_12(TIFF* tif); * On some machines it may be worthwhile to use _setjmp or sigsetjmp * in place of plain setjmp. These macros will make it easier. */ -#define SETJMP(jbuf) setjmp(jbuf) -#define LONGJMP(jbuf,code) longjmp(jbuf,code) -#define JMP_BUF jmp_buf +#define SETJMP(jbuf) setjmp(jbuf) +#define LONGJMP(jbuf, code) longjmp(jbuf, code) +#define JMP_BUF jmp_buf typedef struct jpeg_destination_mgr jpeg_destination_mgr; typedef struct jpeg_source_mgr jpeg_source_mgr; @@ -136,68 +199,60 @@ typedef struct jpeg_error_mgr jpeg_error_mgr; * so we can safely cast JPEGState* -> jpeg_xxx_struct* * and vice versa! */ -typedef struct { - union { - struct jpeg_compress_struct c; - struct jpeg_decompress_struct d; - struct jpeg_common_struct comm; - } cinfo; /* NB: must be first */ - int cinfo_initialized; +typedef struct +{ + union + { + struct jpeg_compress_struct c; + struct jpeg_decompress_struct d; + struct jpeg_common_struct comm; + } cinfo; /* NB: must be first */ + int cinfo_initialized; - jpeg_error_mgr err; /* libjpeg error manager */ - JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ - - struct jpeg_progress_mgr progress; - /* - * The following two members could be a union, but - * they're small enough that it's not worth the effort. - */ - jpeg_destination_mgr dest; /* data dest for compression */ - jpeg_source_mgr src; /* data source for decompression */ - /* private state */ - TIFF* tif; /* back link needed by some code */ - uint16 photometric; /* copy of PhotometricInterpretation */ - uint16 h_sampling; /* luminance sampling factors */ - uint16 v_sampling; - tmsize_t bytesperline; /* decompressed bytes per scanline */ - /* pointers to intermediate buffers when processing downsampled data */ - JSAMPARRAY ds_buffer[MAX_COMPONENTS]; - int scancount; /* number of "scanlines" accumulated */ - int samplesperclump; + jpeg_error_mgr err; /* libjpeg error manager */ + JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ - TIFFStripMethod defsparent; /* super-class method */ - TIFFTileMethod deftparent; /* super-class method */ - /* pseudo-tag fields */ - void* jpegtables; /* JPEGTables tag value, or NULL */ - uint32 jpegtables_length; /* number of bytes in same */ - int jpegquality; /* Compression quality level */ - int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ - int jpegtablesmode; /* What to put in JPEGTables */ + struct jpeg_progress_mgr progress; + /* + * The following two members could be a union, but + * they're small enough that it's not worth the effort. + */ + jpeg_destination_mgr dest; /* data dest for compression */ + jpeg_source_mgr src; /* data source for decompression */ + /* private state */ + TIFF *tif; /* back link needed by some code */ + uint16_t photometric; /* copy of PhotometricInterpretation */ + uint16_t h_sampling; /* luminance sampling factors */ + uint16_t v_sampling; + tmsize_t bytesperline; /* decompressed bytes per scanline */ + /* pointers to intermediate buffers when processing downsampled data */ + TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS]; + int scancount; /* number of "scanlines" accumulated */ + int samplesperclump; - int ycbcrsampling_fetched; - int max_allowed_scan_number; + JPEGOtherSettings otherSettings; } JPEGState; -#define JState(tif) ((JPEGState*)(tif)->tif_data) +#define JState(tif) ((JPEGState *)(tif)->tif_data) -static int JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); -static int JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); -static int JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); -static int JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); -static int JPEGInitializeLibJPEG(TIFF * tif, int decode ); -static int DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int JPEGInitializeLibJPEG(TIFF *tif, int decode); +static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); -#define FIELD_JPEGTABLES (FIELD_CODEC+0) +#define FIELD_JPEGTABLES (FIELD_CODEC + 0) static const TIFFField jpegFields[] = { - { TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL }, - { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, - { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }, - { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL } -}; + {TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, + TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL}, + {TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, + {TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, + {TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}}; /* * libjpeg interface layer. @@ -213,16 +268,16 @@ static const TIFFField jpegFields[] = { * IJG routines from jerror.c). These are used for both * compression and decompression. */ -static void -TIFFjpeg_error_exit(j_common_ptr cinfo) +static void TIFFjpeg_error_exit(j_common_ptr cinfo) { - JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */ - char buffer[JMSG_LENGTH_MAX]; + JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ + char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message) (cinfo, buffer); - TIFFErrorExt(sp->tif->tif_clientdata, "JPEGLib", "%s", buffer); /* display the error message */ - jpeg_abort(cinfo); /* clean up libjpeg state */ - LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ + (*cinfo->err->format_message)(cinfo, buffer); + TIFFErrorExtR(sp->tif, "JPEGLib", "%s", + buffer); /* display the error message */ + jpeg_abort(cinfo); /* clean up libjpeg state */ + LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ } /* @@ -230,203 +285,216 @@ TIFFjpeg_error_exit(j_common_ptr cinfo) * since error_exit does its own thing and trace_level * is never set > 0. */ -static void -TIFFjpeg_output_message(j_common_ptr cinfo) +static void TIFFjpeg_output_message(j_common_ptr cinfo) { - char buffer[JMSG_LENGTH_MAX]; + char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message) (cinfo, buffer); - TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer); + (*cinfo->err->format_message)(cinfo, buffer); + TIFFWarningExtR(((JPEGState *)cinfo)->tif, "JPEGLib", "%s", buffer); } /* Avoid the risk of denial-of-service on crafted JPEGs with an insane */ /* number of scans. */ -/* See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */ -static void -TIFFjpeg_progress_monitor(j_common_ptr cinfo) +/* See + * http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + */ +static void TIFFjpeg_progress_monitor(j_common_ptr cinfo) { - JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */ + JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ if (cinfo->is_decompressor) { - const int scan_no = - ((j_decompress_ptr)cinfo)->input_scan_number; - if (scan_no >= sp->max_allowed_scan_number) + const int scan_no = ((j_decompress_ptr)cinfo)->input_scan_number; + if (scan_no >= sp->otherSettings.max_allowed_scan_number) { - TIFFErrorExt(((JPEGState *) cinfo)->tif->tif_clientdata, - "TIFFjpeg_progress_monitor", - "Scan number %d exceeds maximum scans (%d). This limit " - "can be raised through the LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER " - "environment variable.", - scan_no, sp->max_allowed_scan_number); + TIFFErrorExtR( + ((JPEGState *)cinfo)->tif, "TIFFjpeg_progress_monitor", + "Scan number %d exceeds maximum scans (%d). This limit " + "can be raised through the " + "LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER " + "environment variable.", + scan_no, sp->otherSettings.max_allowed_scan_number); - jpeg_abort(cinfo); /* clean up libjpeg state */ - LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ + jpeg_abort(cinfo); /* clean up libjpeg state */ + LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ } } } - /* * Interface routines. This layer of routines exists * primarily to limit side-effects from using setjmp. * Also, normal/error returns are converted into return * values per libtiff practice. */ -#define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op)) -#define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op),1)) +#define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op)) +#define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op), 1)) -static int -TIFFjpeg_create_compress(JPEGState* sp) +static int TIFFjpeg_create_compress(JPEGState *sp) { - /* initialize JPEG error handling */ - sp->cinfo.c.err = jpeg_std_error(&sp->err); - sp->err.error_exit = TIFFjpeg_error_exit; - sp->err.output_message = TIFFjpeg_output_message; + /* initialize JPEG error handling */ + sp->cinfo.c.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; - /* set client_data to avoid UMR warning from tools like Purify */ - sp->cinfo.c.client_data = NULL; + /* set client_data to avoid UMR warning from tools like Purify */ + sp->cinfo.c.client_data = NULL; - return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); + return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); } -static int -TIFFjpeg_create_decompress(JPEGState* sp) +static int TIFFjpeg_create_decompress(JPEGState *sp) { - /* initialize JPEG error handling */ - sp->cinfo.d.err = jpeg_std_error(&sp->err); - sp->err.error_exit = TIFFjpeg_error_exit; - sp->err.output_message = TIFFjpeg_output_message; + /* initialize JPEG error handling */ + sp->cinfo.d.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; - /* set client_data to avoid UMR warning from tools like Purify */ - sp->cinfo.d.client_data = NULL; + /* set client_data to avoid UMR warning from tools like Purify */ + sp->cinfo.d.client_data = NULL; - return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); + return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); } -static int -TIFFjpeg_set_defaults(JPEGState* sp) +static int TIFFjpeg_set_defaults(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); + return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); } -static int -TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace) +static int TIFFjpeg_set_colorspace(JPEGState *sp, J_COLOR_SPACE colorspace) { - return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); + return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); } -static int -TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline) +static int TIFFjpeg_set_quality(JPEGState *sp, int quality, + boolean force_baseline) { - return CALLVJPEG(sp, - jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); + return CALLVJPEG(sp, + jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); } -static int -TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress) +static int TIFFjpeg_suppress_tables(JPEGState *sp, boolean suppress) { - return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); + return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); } -static int -TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables) +static int TIFFjpeg_start_compress(JPEGState *sp, boolean write_all_tables) { - return CALLVJPEG(sp, - jpeg_start_compress(&sp->cinfo.c, write_all_tables)); + return CALLVJPEG(sp, jpeg_start_compress(&sp->cinfo.c, write_all_tables)); } -static int -TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines) +static int TIFFjpeg_write_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines, + int num_lines) { - return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c, - scanlines, (JDIMENSION) num_lines)); +#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 + return CALLJPEG(sp, -1, + (int)jpeg12_write_scanlines(&sp->cinfo.c, scanlines, + (JDIMENSION)num_lines)); +#else + return CALLJPEG(sp, -1, + (int)jpeg_write_scanlines(&sp->cinfo.c, scanlines, + (JDIMENSION)num_lines)); +#endif } -static int -TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines) +static int TIFFjpeg_write_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data, + int num_lines) { - return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c, - data, (JDIMENSION) num_lines)); +#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 + return CALLJPEG( + sp, -1, + (int)jpeg12_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines)); +#else + return CALLJPEG( + sp, -1, + (int)jpeg_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines)); +#endif } -static int -TIFFjpeg_finish_compress(JPEGState* sp) +static int TIFFjpeg_finish_compress(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); + return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); } -static int -TIFFjpeg_write_tables(JPEGState* sp) +static int TIFFjpeg_write_tables(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); + return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); } -static int -TIFFjpeg_read_header(JPEGState* sp, boolean require_image) +static int TIFFjpeg_read_header(JPEGState *sp, boolean require_image) { - return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); + return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); } -static int -TIFFjpeg_has_multiple_scans(JPEGState* sp) +static int TIFFjpeg_has_multiple_scans(JPEGState *sp) { - return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d)); + return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d)); } -static int -TIFFjpeg_start_decompress(JPEGState* sp) +static int TIFFjpeg_start_decompress(JPEGState *sp) { - const char* sz_max_allowed_scan_number; - /* progress monitor */ - sp->cinfo.d.progress = &sp->progress; - sp->progress.progress_monitor = TIFFjpeg_progress_monitor; - sp->max_allowed_scan_number = 100; - sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER"); - if( sz_max_allowed_scan_number ) - sp->max_allowed_scan_number = atoi(sz_max_allowed_scan_number); + const char *sz_max_allowed_scan_number; + /* progress monitor */ + sp->cinfo.d.progress = &sp->progress; + sp->progress.progress_monitor = TIFFjpeg_progress_monitor; + sp->otherSettings.max_allowed_scan_number = 100; + sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER"); + if (sz_max_allowed_scan_number) + sp->otherSettings.max_allowed_scan_number = + atoi(sz_max_allowed_scan_number); - return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); + return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); } -static int -TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines) +static int TIFFjpeg_read_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines, + int max_lines) { - return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d, - scanlines, (JDIMENSION) max_lines)); +#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 + return CALLJPEG(sp, -1, + (int)jpeg12_read_scanlines(&sp->cinfo.d, scanlines, + (JDIMENSION)max_lines)); +#else + return CALLJPEG(sp, -1, + (int)jpeg_read_scanlines(&sp->cinfo.d, scanlines, + (JDIMENSION)max_lines)); +#endif } -static int -TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines) +static int TIFFjpeg_read_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data, + int max_lines) { - return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d, - data, (JDIMENSION) max_lines)); +#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 + return CALLJPEG( + sp, -1, + (int)jpeg12_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines)); +#else + return CALLJPEG( + sp, -1, + (int)jpeg_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines)); +#endif } -static int -TIFFjpeg_finish_decompress(JPEGState* sp) +static int TIFFjpeg_finish_decompress(JPEGState *sp) { - return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d)); + return CALLJPEG(sp, -1, (int)jpeg_finish_decompress(&sp->cinfo.d)); } -static int -TIFFjpeg_abort(JPEGState* sp) +static int TIFFjpeg_abort(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); + return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); } -static int -TIFFjpeg_destroy(JPEGState* sp) +static int TIFFjpeg_destroy(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); + return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); } -static JSAMPARRAY -TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id, - JDIMENSION samplesperrow, JDIMENSION numrows) +static JSAMPARRAY TIFFjpeg_alloc_sarray(JPEGState *sp, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows) { - return CALLJPEG(sp, (JSAMPARRAY) NULL, - (*sp->cinfo.comm.mem->alloc_sarray) - (&sp->cinfo.comm, pool_id, samplesperrow, numrows)); + return CALLJPEG(sp, (JSAMPARRAY)NULL, + (*sp->cinfo.comm.mem->alloc_sarray)( + &sp->cinfo.comm, pool_id, samplesperrow, numrows)); } /* @@ -435,130 +503,128 @@ TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id, * libtiff output buffer. */ -static void -std_init_destination(j_compress_ptr cinfo) +static void std_init_destination(j_compress_ptr cinfo) { - JPEGState* sp = (JPEGState*) cinfo; - TIFF* tif = sp->tif; + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; - sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; + sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; } -static boolean -std_empty_output_buffer(j_compress_ptr cinfo) +static boolean std_empty_output_buffer(j_compress_ptr cinfo) { - JPEGState* sp = (JPEGState*) cinfo; - TIFF* tif = sp->tif; + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - /* the entire buffer has been filled */ - tif->tif_rawcc = tif->tif_rawdatasize; + /* the entire buffer has been filled */ + tif->tif_rawcc = tif->tif_rawdatasize; #ifdef IPPJ_HUFF - /* - * The Intel IPP performance library does not necessarily fill up - * the whole output buffer on each pass, so only dump out the parts - * that have been filled. - * http://trac.osgeo.org/gdal/wiki/JpegIPP - */ - if ( sp->dest.free_in_buffer >= 0 ) { - tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer; - } + /* + * The Intel IPP performance library does not necessarily fill up + * the whole output buffer on each pass, so only dump out the parts + * that have been filled. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if (sp->dest.free_in_buffer >= 0) + { + tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer; + } #endif - if( !TIFFFlushData1(tif) ) - return FALSE; - sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; - sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return FALSE; + sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; - return (TRUE); + return (TRUE); } -static void -std_term_destination(j_compress_ptr cinfo) +static void std_term_destination(j_compress_ptr cinfo) { - JPEGState* sp = (JPEGState*) cinfo; - TIFF* tif = sp->tif; + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - tif->tif_rawcp = (uint8*) sp->dest.next_output_byte; - tif->tif_rawcc = - tif->tif_rawdatasize - (tmsize_t) sp->dest.free_in_buffer; - /* NB: libtiff does the final buffer flush */ + tif->tif_rawcp = (uint8_t *)sp->dest.next_output_byte; + tif->tif_rawcc = tif->tif_rawdatasize - (tmsize_t)sp->dest.free_in_buffer; + /* NB: libtiff does the final buffer flush */ } -static void -TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif) +static void TIFFjpeg_data_dest(JPEGState *sp, TIFF *tif) { - (void) tif; - sp->cinfo.c.dest = &sp->dest; - sp->dest.init_destination = std_init_destination; - sp->dest.empty_output_buffer = std_empty_output_buffer; - sp->dest.term_destination = std_term_destination; + (void)tif; + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = std_init_destination; + sp->dest.empty_output_buffer = std_empty_output_buffer; + sp->dest.term_destination = std_term_destination; } /* * Alternate destination manager for outputting to JPEGTables field. */ -static void -tables_init_destination(j_compress_ptr cinfo) +static void tables_init_destination(j_compress_ptr cinfo) { - JPEGState* sp = (JPEGState*) cinfo; + JPEGState *sp = (JPEGState *)cinfo; - /* while building, jpegtables_length is allocated buffer size */ - sp->dest.next_output_byte = (JOCTET*) sp->jpegtables; - sp->dest.free_in_buffer = (size_t) sp->jpegtables_length; + /* while building, otherSettings.jpegtables_length is allocated buffer size + */ + sp->dest.next_output_byte = (JOCTET *)sp->otherSettings.jpegtables; + sp->dest.free_in_buffer = (size_t)sp->otherSettings.jpegtables_length; } -static boolean -tables_empty_output_buffer(j_compress_ptr cinfo) +static boolean tables_empty_output_buffer(j_compress_ptr cinfo) { - JPEGState* sp = (JPEGState*) cinfo; - void* newbuf; + JPEGState *sp = (JPEGState *)cinfo; + void *newbuf; - /* the entire buffer has been filled; enlarge it by 1000 bytes */ - newbuf = _TIFFrealloc((void*) sp->jpegtables, - (tmsize_t) (sp->jpegtables_length + 1000)); - if (newbuf == NULL) - ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); - sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length; - sp->dest.free_in_buffer = (size_t) 1000; - sp->jpegtables = newbuf; - sp->jpegtables_length += 1000; - return (TRUE); + /* the entire buffer has been filled; enlarge it by 1000 bytes */ + newbuf = + _TIFFreallocExt(sp->tif, (void *)sp->otherSettings.jpegtables, + (tmsize_t)(sp->otherSettings.jpegtables_length + 1000)); + if (newbuf == NULL) + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); + sp->dest.next_output_byte = + (JOCTET *)newbuf + sp->otherSettings.jpegtables_length; + sp->dest.free_in_buffer = (size_t)1000; + sp->otherSettings.jpegtables = newbuf; + sp->otherSettings.jpegtables_length += 1000; + return (TRUE); } -static void -tables_term_destination(j_compress_ptr cinfo) +static void tables_term_destination(j_compress_ptr cinfo) { - JPEGState* sp = (JPEGState*) cinfo; + JPEGState *sp = (JPEGState *)cinfo; - /* set tables length to number of bytes actually emitted */ - sp->jpegtables_length -= (uint32) sp->dest.free_in_buffer; + /* set tables length to number of bytes actually emitted */ + sp->otherSettings.jpegtables_length -= (uint32_t)sp->dest.free_in_buffer; } -static int -TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif) +static int TIFFjpeg_tables_dest(JPEGState *sp, TIFF *tif) { - (void) tif; - /* - * Allocate a working buffer for building tables. - * Initial size is 1000 bytes, which is usually adequate. - */ - if (sp->jpegtables) - _TIFFfree(sp->jpegtables); - sp->jpegtables_length = 1000; - sp->jpegtables = (void*) _TIFFmalloc((tmsize_t) sp->jpegtables_length); - if (sp->jpegtables == NULL) { - sp->jpegtables_length = 0; - TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables"); - return (0); - } - sp->cinfo.c.dest = &sp->dest; - sp->dest.init_destination = tables_init_destination; - sp->dest.empty_output_buffer = tables_empty_output_buffer; - sp->dest.term_destination = tables_term_destination; - return (1); + (void)tif; + /* + * Allocate a working buffer for building tables. + * Initial size is 1000 bytes, which is usually adequate. + */ + if (sp->otherSettings.jpegtables) + _TIFFfreeExt(tif, sp->otherSettings.jpegtables); + sp->otherSettings.jpegtables_length = 1000; + sp->otherSettings.jpegtables = (void *)_TIFFmallocExt( + tif, (tmsize_t)sp->otherSettings.jpegtables_length); + if (sp->otherSettings.jpegtables == NULL) + { + sp->otherSettings.jpegtables_length = 0; + TIFFErrorExtR(sp->tif, "TIFFjpeg_tables_dest", + "No space for JPEGTables"); + return (0); + } + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = tables_init_destination; + sp->dest.empty_output_buffer = tables_empty_output_buffer; + sp->dest.term_destination = tables_term_destination; + return (1); } /* @@ -566,86 +632,86 @@ TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif) * These routines supply compressed data to libjpeg. */ -static void -std_init_source(j_decompress_ptr cinfo) +static void std_init_source(j_decompress_ptr cinfo) { - JPEGState* sp = (JPEGState*) cinfo; - TIFF* tif = sp->tif; + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata; - sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; + sp->src.next_input_byte = (const JOCTET *)tif->tif_rawdata; + sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; } -static boolean -std_fill_input_buffer(j_decompress_ptr cinfo) +static boolean std_fill_input_buffer(j_decompress_ptr cinfo) { - JPEGState* sp = (JPEGState* ) cinfo; - static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI }; + JPEGState *sp = (JPEGState *)cinfo; + static const JOCTET dummy_EOI[2] = {0xFF, JPEG_EOI}; #ifdef IPPJ_HUFF - /* - * The Intel IPP performance library does not necessarily read the whole - * input buffer in one pass, so it is possible to get here with data - * yet to read. - * - * We just return without doing anything, until the entire buffer has - * been read. - * http://trac.osgeo.org/gdal/wiki/JpegIPP - */ - if( sp->src.bytes_in_buffer > 0 ) { - return (TRUE); - } + /* + * The Intel IPP performance library does not necessarily read the whole + * input buffer in one pass, so it is possible to get here with data + * yet to read. + * + * We just return without doing anything, until the entire buffer has + * been read. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if (sp->src.bytes_in_buffer > 0) + { + return (TRUE); + } #endif - /* - * Normally the whole strip/tile is read and so we don't need to do - * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have - * all the data, but the rawdata is refreshed between scanlines and - * we push this into the io machinery in JPEGDecode(). - * http://trac.osgeo.org/gdal/ticket/3894 - */ - - WARNMS(cinfo, JWRN_JPEG_EOF); - /* insert a fake EOI marker */ - sp->src.next_input_byte = dummy_EOI; - sp->src.bytes_in_buffer = 2; - return (TRUE); + /* + * Normally the whole strip/tile is read and so we don't need to do + * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have + * all the data, but the rawdata is refreshed between scanlines and + * we push this into the io machinery in JPEGDecode(). + * http://trac.osgeo.org/gdal/ticket/3894 + */ + + WARNMS(cinfo, JWRN_JPEG_EOF); + /* insert a fake EOI marker */ + sp->src.next_input_byte = dummy_EOI; + sp->src.bytes_in_buffer = 2; + return (TRUE); } -static void -std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +static void std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { - JPEGState* sp = (JPEGState*) cinfo; + JPEGState *sp = (JPEGState *)cinfo; - if (num_bytes > 0) { - if ((size_t)num_bytes > sp->src.bytes_in_buffer) { - /* oops, buffer overrun */ - (void) std_fill_input_buffer(cinfo); - } else { - sp->src.next_input_byte += (size_t) num_bytes; - sp->src.bytes_in_buffer -= (size_t) num_bytes; - } - } + if (num_bytes > 0) + { + if ((size_t)num_bytes > sp->src.bytes_in_buffer) + { + /* oops, buffer overrun */ + (void)std_fill_input_buffer(cinfo); + } + else + { + sp->src.next_input_byte += (size_t)num_bytes; + sp->src.bytes_in_buffer -= (size_t)num_bytes; + } + } } -static void -std_term_source(j_decompress_ptr cinfo) +static void std_term_source(j_decompress_ptr cinfo) { - /* No work necessary here */ - (void) cinfo; + /* No work necessary here */ + (void)cinfo; } -static void -TIFFjpeg_data_src(JPEGState* sp) +static void TIFFjpeg_data_src(JPEGState *sp) { - sp->cinfo.d.src = &sp->src; - sp->src.init_source = std_init_source; - sp->src.fill_input_buffer = std_fill_input_buffer; - sp->src.skip_input_data = std_skip_input_data; - sp->src.resync_to_restart = jpeg_resync_to_restart; - sp->src.term_source = std_term_source; - sp->src.bytes_in_buffer = 0; /* for safety */ - sp->src.next_input_byte = NULL; + sp->cinfo.d.src = &sp->src; + sp->src.init_source = std_init_source; + sp->src.fill_input_buffer = std_fill_input_buffer; + sp->src.skip_input_data = std_skip_input_data; + sp->src.resync_to_restart = jpeg_resync_to_restart; + sp->src.term_source = std_term_source; + sp->src.bytes_in_buffer = 0; /* for safety */ + sp->src.next_input_byte = NULL; } /* @@ -653,20 +719,18 @@ TIFFjpeg_data_src(JPEGState* sp) * We can share all the code except for the init routine. */ -static void -tables_init_source(j_decompress_ptr cinfo) +static void tables_init_source(j_decompress_ptr cinfo) { - JPEGState* sp = (JPEGState*) cinfo; + JPEGState *sp = (JPEGState *)cinfo; - sp->src.next_input_byte = (const JOCTET*) sp->jpegtables; - sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length; + sp->src.next_input_byte = (const JOCTET *)sp->otherSettings.jpegtables; + sp->src.bytes_in_buffer = (size_t)sp->otherSettings.jpegtables_length; } -static void -TIFFjpeg_tables_src(JPEGState* sp) +static void TIFFjpeg_tables_src(JPEGState *sp) { - TIFFjpeg_data_src(sp); - sp->src.init_source = tables_init_source; + TIFFjpeg_data_src(sp); + sp->src.init_source = tables_init_source; } /* @@ -676,32 +740,29 @@ TIFFjpeg_tables_src(JPEGState* sp) * when done with strip/tile. * This is also a handy place to compute samplesperclump, bytesperline. */ -static int -alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info, - int num_components) +static int alloc_downsampled_buffers(TIFF *tif, jpeg_component_info *comp_info, + int num_components) { - JPEGState* sp = JState(tif); - int ci; - jpeg_component_info* compptr; - JSAMPARRAY buf; - int samples_per_clump = 0; + JPEGState *sp = JState(tif); + int ci; + jpeg_component_info *compptr; + TIFF_JSAMPARRAY buf; + int samples_per_clump = 0; - for (ci = 0, compptr = comp_info; ci < num_components; - ci++, compptr++) { - samples_per_clump += compptr->h_samp_factor * - compptr->v_samp_factor; - buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE, - compptr->width_in_blocks * DCTSIZE, - (JDIMENSION) (compptr->v_samp_factor*DCTSIZE)); - if (buf == NULL) - return (0); - sp->ds_buffer[ci] = buf; - } - sp->samplesperclump = samples_per_clump; - return (1); + for (ci = 0, compptr = comp_info; ci < num_components; ci++, compptr++) + { + samples_per_clump += compptr->h_samp_factor * compptr->v_samp_factor; + buf = (TIFF_JSAMPARRAY)TIFFjpeg_alloc_sarray( + sp, JPOOL_IMAGE, compptr->width_in_blocks * DCTSIZE, + (JDIMENSION)(compptr->v_samp_factor * DCTSIZE)); + if (buf == NULL) + return (0); + sp->ds_buffer[ci] = buf; + } + sp->samplesperclump = samples_per_clump; + return (1); } - /* * JPEG Decoding. */ @@ -722,331 +783,367 @@ alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info, #define JPEG_MARKER_COM 0xFE struct JPEGFixupTagsSubsamplingData { - TIFF* tif; - void* buffer; - uint32 buffersize; - uint8* buffercurrentbyte; - uint32 bufferbytesleft; - uint64 fileoffset; - uint64 filebytesleft; - uint8 filepositioned; + TIFF *tif; + void *buffer; + uint32_t buffersize; + uint8_t *buffercurrentbyte; + uint32_t bufferbytesleft; + uint64_t fileoffset; + uint64_t filebytesleft; + uint8_t filepositioned; }; -static void JPEGFixupTagsSubsampling(TIFF* tif); -static int JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data); -static int JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result); -static int JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result); -static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength); +static void JPEGFixupTagsSubsampling(TIFF *tif); +static int +JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data); +static int +JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data, + uint8_t *result); +static int +JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data, + uint16_t *result); +static void +JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data, + uint16_t skiplength); #endif -static int -JPEGFixupTags(TIFF* tif) +static int JPEGFixupTags(TIFF *tif) { #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING - JPEGState* sp = JState(tif); - if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&& - (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& - (tif->tif_dir.td_samplesperpixel==3) && - !sp->ycbcrsampling_fetched) - JPEGFixupTagsSubsampling(tif); + JPEGState *sp = JState(tif); + if ((tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) && + (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) && + (tif->tif_dir.td_samplesperpixel == 3) && + !sp->otherSettings.ycbcrsampling_fetched) + JPEGFixupTagsSubsampling(tif); #endif - - return(1); + + return (1); } #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING -static void -JPEGFixupTagsSubsampling(TIFF* tif) +static void JPEGFixupTagsSubsampling(TIFF *tif) { - /* - * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in - * the TIFF tags, but still use non-default (2,2) values within the jpeg - * data stream itself. In order for TIFF applications to work properly - * - for instance to get the strip buffer size right - it is imperative - * that the subsampling be available before we start reading the image - * data normally. This function will attempt to analyze the first strip in - * order to get the sampling values from the jpeg data stream. - * - * Note that JPEGPreDeocode() will produce a fairly loud warning when the - * discovered sampling does not match the default sampling (2,2) or whatever - * was actually in the tiff tags. - * - * See the bug in bugzilla for details: - * - * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 - * - * Frank Warmerdam, July 2002 - * Joris Van Damme, May 2007 - */ - static const char module[] = "JPEGFixupTagsSubsampling"; - struct JPEGFixupTagsSubsamplingData m; - uint64 fileoffset = TIFFGetStrileOffset(tif, 0); + /* + * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in + * the TIFF tags, but still use non-default (2,2) values within the jpeg + * data stream itself. In order for TIFF applications to work properly + * - for instance to get the strip buffer size right - it is imperative + * that the subsampling be available before we start reading the image + * data normally. This function will attempt to analyze the first strip in + * order to get the sampling values from the jpeg data stream. + * + * Note that JPEGPreDeocode() will produce a fairly loud warning when the + * discovered sampling does not match the default sampling (2,2) or whatever + * was actually in the tiff tags. + * + * See the bug in bugzilla for details: + * + * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 + * + * Frank Warmerdam, July 2002 + * Joris Van Damme, May 2007 + */ + static const char module[] = "JPEGFixupTagsSubsampling"; + struct JPEGFixupTagsSubsamplingData m; + uint64_t fileoffset = TIFFGetStrileOffset(tif, 0); - if( fileoffset == 0 ) + if (fileoffset == 0) + { + /* Do not even try to check if the first strip/tile does not + yet exist, as occurs when GDAL has created a new NULL file + for instance. */ + return; + } + + m.tif = tif; + m.buffersize = 2048; + m.buffer = _TIFFmallocExt(tif, m.buffersize); + if (m.buffer == NULL) + { + TIFFWarningExtR(tif, module, + "Unable to allocate memory for auto-correcting of " + "subsampling values; auto-correcting skipped"); + return; + } + m.buffercurrentbyte = NULL; + m.bufferbytesleft = 0; + m.fileoffset = fileoffset; + m.filepositioned = 0; + m.filebytesleft = TIFFGetStrileByteCount(tif, 0); + if (!JPEGFixupTagsSubsamplingSec(&m)) + TIFFWarningExtR( + tif, module, + "Unable to auto-correct subsampling values, likely corrupt JPEG " + "compressed data in first strip/tile; auto-correcting skipped"); + _TIFFfreeExt(tif, m.buffer); +} + +static int +JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data) +{ + static const char module[] = "JPEGFixupTagsSubsamplingSec"; + uint8_t m; + while (1) + { + while (1) { - /* Do not even try to check if the first strip/tile does not - yet exist, as occurs when GDAL has created a new NULL file - for instance. */ - return; + if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) + return (0); + if (m == 255) + break; } - - m.tif=tif; - m.buffersize=2048; - m.buffer=_TIFFmalloc(m.buffersize); - if (m.buffer==NULL) - { - TIFFWarningExt(tif->tif_clientdata,module, - "Unable to allocate memory for auto-correcting of subsampling values; auto-correcting skipped"); - return; - } - m.buffercurrentbyte=NULL; - m.bufferbytesleft=0; - m.fileoffset=fileoffset; - m.filepositioned=0; - m.filebytesleft=TIFFGetStrileByteCount(tif, 0); - if (!JPEGFixupTagsSubsamplingSec(&m)) - TIFFWarningExt(tif->tif_clientdata,module, - "Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped"); - _TIFFfree(m.buffer); + while (1) + { + if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) + return (0); + if (m != 255) + break; + } + switch (m) + { + case JPEG_MARKER_SOI: + /* this type of marker has no data and should be skipped */ + break; + case JPEG_MARKER_COM: + case JPEG_MARKER_APP0: + case JPEG_MARKER_APP0 + 1: + case JPEG_MARKER_APP0 + 2: + case JPEG_MARKER_APP0 + 3: + case JPEG_MARKER_APP0 + 4: + case JPEG_MARKER_APP0 + 5: + case JPEG_MARKER_APP0 + 6: + case JPEG_MARKER_APP0 + 7: + case JPEG_MARKER_APP0 + 8: + case JPEG_MARKER_APP0 + 9: + case JPEG_MARKER_APP0 + 10: + case JPEG_MARKER_APP0 + 11: + case JPEG_MARKER_APP0 + 12: + case JPEG_MARKER_APP0 + 13: + case JPEG_MARKER_APP0 + 14: + case JPEG_MARKER_APP0 + 15: + case JPEG_MARKER_DQT: + case JPEG_MARKER_SOS: + case JPEG_MARKER_DHT: + case JPEG_MARKER_DRI: + /* this type of marker has data, but it has no use to us and + * should be skipped */ + { + uint16_t n; + if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) + return (0); + if (n < 2) + return (0); + n -= 2; + if (n > 0) + JPEGFixupTagsSubsamplingSkip(data, n); + } + break; + case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */ + case JPEG_MARKER_SOF1: /* Extended sequential Huffman */ + case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed + by TechNote, but that doesn't hurt + supporting it */ + case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */ + case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not + allowed by TechNote, but that doesn't + hurt supporting it */ + /* this marker contains the subsampling factors we're scanning + * for */ + { + uint16_t n; + uint16_t o; + uint8_t p; + uint8_t ph, pv; + if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) + return (0); + if (n != 8 + data->tif->tif_dir.td_samplesperpixel * 3) + return (0); + JPEGFixupTagsSubsamplingSkip(data, 7); + if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) + return (0); + ph = (p >> 4); + pv = (p & 15); + JPEGFixupTagsSubsamplingSkip(data, 1); + for (o = 1; o < data->tif->tif_dir.td_samplesperpixel; o++) + { + JPEGFixupTagsSubsamplingSkip(data, 1); + if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) + return (0); + if (p != 0x11) + { + TIFFWarningExtR(data->tif, module, + "Subsampling values inside JPEG " + "compressed data " + "have no TIFF equivalent, " + "auto-correction of TIFF " + "subsampling values failed"); + return (1); + } + JPEGFixupTagsSubsamplingSkip(data, 1); + } + if (((ph != 1) && (ph != 2) && (ph != 4)) || + ((pv != 1) && (pv != 2) && (pv != 4))) + { + TIFFWarningExtR(data->tif, module, + "Subsampling values inside JPEG " + "compressed data have no TIFF " + "equivalent, auto-correction of TIFF " + "subsampling values failed"); + return (1); + } + if ((ph != data->tif->tif_dir.td_ycbcrsubsampling[0]) || + (pv != data->tif->tif_dir.td_ycbcrsubsampling[1])) + { + TIFFWarningExtR( + data->tif, module, + "Auto-corrected former TIFF subsampling values " + "[%" PRIu16 ",%" PRIu16 + "] to match subsampling values inside JPEG " + "compressed data [%" PRIu8 ",%" PRIu8 "]", + data->tif->tif_dir.td_ycbcrsubsampling[0], + data->tif->tif_dir.td_ycbcrsubsampling[1], ph, pv); + data->tif->tif_dir.td_ycbcrsubsampling[0] = ph; + data->tif->tif_dir.td_ycbcrsubsampling[1] = pv; + } + } + return (1); + default: + return (0); + } + } } static int -JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data) +JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data, + uint8_t *result) { - static const char module[] = "JPEGFixupTagsSubsamplingSec"; - uint8 m; - while (1) - { - while (1) - { - if (!JPEGFixupTagsSubsamplingReadByte(data,&m)) - return(0); - if (m==255) - break; - } - while (1) - { - if (!JPEGFixupTagsSubsamplingReadByte(data,&m)) - return(0); - if (m!=255) - break; - } - switch (m) - { - case JPEG_MARKER_SOI: - /* this type of marker has no data and should be skipped */ - break; - case JPEG_MARKER_COM: - case JPEG_MARKER_APP0: - case JPEG_MARKER_APP0+1: - case JPEG_MARKER_APP0+2: - case JPEG_MARKER_APP0+3: - case JPEG_MARKER_APP0+4: - case JPEG_MARKER_APP0+5: - case JPEG_MARKER_APP0+6: - case JPEG_MARKER_APP0+7: - case JPEG_MARKER_APP0+8: - case JPEG_MARKER_APP0+9: - case JPEG_MARKER_APP0+10: - case JPEG_MARKER_APP0+11: - case JPEG_MARKER_APP0+12: - case JPEG_MARKER_APP0+13: - case JPEG_MARKER_APP0+14: - case JPEG_MARKER_APP0+15: - case JPEG_MARKER_DQT: - case JPEG_MARKER_SOS: - case JPEG_MARKER_DHT: - case JPEG_MARKER_DRI: - /* this type of marker has data, but it has no use to us and should be skipped */ - { - uint16 n; - if (!JPEGFixupTagsSubsamplingReadWord(data,&n)) - return(0); - if (n<2) - return(0); - n-=2; - if (n>0) - JPEGFixupTagsSubsamplingSkip(data,n); - } - break; - case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */ - case JPEG_MARKER_SOF1: /* Extended sequential Huffman */ - case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed by TechNote, but that doesn't hurt supporting it */ - case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */ - case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not allowed by TechNote, but that doesn't hurt supporting it */ - /* this marker contains the subsampling factors we're scanning for */ - { - uint16 n; - uint16 o; - uint8 p; - uint8 ph,pv; - if (!JPEGFixupTagsSubsamplingReadWord(data,&n)) - return(0); - if (n!=8+data->tif->tif_dir.td_samplesperpixel*3) - return(0); - JPEGFixupTagsSubsamplingSkip(data,7); - if (!JPEGFixupTagsSubsamplingReadByte(data,&p)) - return(0); - ph=(p>>4); - pv=(p&15); - JPEGFixupTagsSubsamplingSkip(data,1); - for (o=1; otif->tif_dir.td_samplesperpixel; o++) - { - JPEGFixupTagsSubsamplingSkip(data,1); - if (!JPEGFixupTagsSubsamplingReadByte(data,&p)) - return(0); - if (p!=0x11) - { - TIFFWarningExt(data->tif->tif_clientdata,module, - "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed"); - return(1); - } - JPEGFixupTagsSubsamplingSkip(data,1); - } - if (((ph!=1)&&(ph!=2)&&(ph!=4))||((pv!=1)&&(pv!=2)&&(pv!=4))) - { - TIFFWarningExt(data->tif->tif_clientdata,module, - "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed"); - return(1); - } - if ((ph!=data->tif->tif_dir.td_ycbcrsubsampling[0])||(pv!=data->tif->tif_dir.td_ycbcrsubsampling[1])) - { - TIFFWarningExt(data->tif->tif_clientdata,module, - "Auto-corrected former TIFF subsampling values [%d,%d] to match subsampling values inside JPEG compressed data [%d,%d]", - (int)data->tif->tif_dir.td_ycbcrsubsampling[0], - (int)data->tif->tif_dir.td_ycbcrsubsampling[1], - (int)ph,(int)pv); - data->tif->tif_dir.td_ycbcrsubsampling[0]=ph; - data->tif->tif_dir.td_ycbcrsubsampling[1]=pv; - } - } - return(1); - default: - return(0); - } - } + if (data->bufferbytesleft == 0) + { + uint32_t m; + if (data->filebytesleft == 0) + return (0); + if (!data->filepositioned) + { + if (TIFFSeekFile(data->tif, data->fileoffset, SEEK_SET) == + (toff_t)-1) + { + return 0; + } + data->filepositioned = 1; + } + m = data->buffersize; + if ((uint64_t)m > data->filebytesleft) + m = (uint32_t)data->filebytesleft; + assert(m < 0x80000000UL); + if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m) + return (0); + data->buffercurrentbyte = data->buffer; + data->bufferbytesleft = m; + data->fileoffset += m; + data->filebytesleft -= m; + } + *result = *data->buffercurrentbyte; + data->buffercurrentbyte++; + data->bufferbytesleft--; + return (1); } static int -JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result) +JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data, + uint16_t *result) { - if (data->bufferbytesleft==0) - { - uint32 m; - if (data->filebytesleft==0) - return(0); - if (!data->filepositioned) - { - if (TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET) == (toff_t)-1) - { - return 0; - } - data->filepositioned=1; - } - m=data->buffersize; - if ((uint64)m>data->filebytesleft) - m=(uint32)data->filebytesleft; - assert(m<0x80000000UL); - if (TIFFReadFile(data->tif,data->buffer,(tmsize_t)m)!=(tmsize_t)m) - return(0); - data->buffercurrentbyte=data->buffer; - data->bufferbytesleft=m; - data->fileoffset+=m; - data->filebytesleft-=m; - } - *result=*data->buffercurrentbyte; - data->buffercurrentbyte++; - data->bufferbytesleft--; - return(1); -} - -static int -JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result) -{ - uint8 ma; - uint8 mb; - if (!JPEGFixupTagsSubsamplingReadByte(data,&ma)) - return(0); - if (!JPEGFixupTagsSubsamplingReadByte(data,&mb)) - return(0); - *result=(ma<<8)|mb; - return(1); + uint8_t ma; + uint8_t mb; + if (!JPEGFixupTagsSubsamplingReadByte(data, &ma)) + return (0); + if (!JPEGFixupTagsSubsamplingReadByte(data, &mb)) + return (0); + *result = (ma << 8) | mb; + return (1); } static void -JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength) +JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data, + uint16_t skiplength) { - if ((uint32)skiplength<=data->bufferbytesleft) - { - data->buffercurrentbyte+=skiplength; - data->bufferbytesleft-=skiplength; - } - else - { - uint16 m; - m=(uint16)(skiplength-data->bufferbytesleft); - if (m<=data->filebytesleft) - { - data->bufferbytesleft=0; - data->fileoffset+=m; - data->filebytesleft-=m; - data->filepositioned=0; - } - else - { - data->bufferbytesleft=0; - data->filebytesleft=0; - } - } + if ((uint32_t)skiplength <= data->bufferbytesleft) + { + data->buffercurrentbyte += skiplength; + data->bufferbytesleft -= skiplength; + } + else + { + uint16_t m; + m = (uint16_t)(skiplength - data->bufferbytesleft); + if (m <= data->filebytesleft) + { + data->bufferbytesleft = 0; + data->fileoffset += m; + data->filebytesleft -= m; + data->filepositioned = 0; + } + else + { + data->bufferbytesleft = 0; + data->filebytesleft = 0; + } + } } #endif - -static int -JPEGSetupDecode(TIFF* tif) +static int JPEGSetupDecode(TIFF *tif) { - JPEGState* sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; -#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) - if( tif->tif_dir.td_bitspersample == 12 ) - return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 0 ); +#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) + if (tif->tif_dir.td_bitspersample == 12) + { + /* We pass a pointer to a copy of otherSettings, since */ + /* TIFFReInitJPEG_12() will clear sp */ + JPEGOtherSettings savedOtherSettings = sp->otherSettings; + return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 0); + } #endif - JPEGInitializeLibJPEG( tif, TRUE ); + JPEGInitializeLibJPEG(tif, TRUE); - assert(sp != NULL); - assert(sp->cinfo.comm.is_decompressor); + assert(sp != NULL); + assert(sp->cinfo.comm.is_decompressor); - /* Read JPEGTables if it is present */ - if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) { - TIFFjpeg_tables_src(sp); - if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) { - TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field"); - return (0); - } - } + /* Read JPEGTables if it is present */ + if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) + { + TIFFjpeg_tables_src(sp); + if (TIFFjpeg_read_header(sp, FALSE) != JPEG_HEADER_TABLES_ONLY) + { + TIFFErrorExtR(tif, "JPEGSetupDecode", "Bogus JPEGTables field"); + return (0); + } + } - /* Grab parameters that are same for all strips/tiles */ - sp->photometric = td->td_photometric; - switch (sp->photometric) { - case PHOTOMETRIC_YCBCR: - sp->h_sampling = td->td_ycbcrsubsampling[0]; - sp->v_sampling = td->td_ycbcrsubsampling[1]; - break; - default: - /* TIFF 6.0 forbids subsampling of all other color spaces */ - sp->h_sampling = 1; - sp->v_sampling = 1; - break; - } + /* Grab parameters that are same for all strips/tiles */ + sp->photometric = td->td_photometric; + switch (sp->photometric) + { + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + break; + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } - /* Set up for reading normal data */ - TIFFjpeg_data_src(sp); - tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ - return (1); + /* Set up for reading normal data */ + TIFFjpeg_data_src(sp); + tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ + return (1); } /* Returns 1 if the full strip should be read, even when doing scanline per */ @@ -1056,14 +1153,14 @@ JPEGSetupDecode(TIFF* tif) /* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */ /* tif->tif_rawcc members. */ /* Can be called independently of the usual setup/predecode/decode states */ -int TIFFJPEGIsFullStripRequired(TIFF* tif) +int TIFFJPEGIsFullStripRequired(TIFF *tif) { int ret; JPEGState state; -#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFJPEGIsFullStripRequired) - if( tif->tif_dir.td_bitspersample == 12 ) - return TIFFJPEGIsFullStripRequired_12( tif ); +#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) + if (tif->tif_dir.td_bitspersample == 12) + return TIFFJPEGIsFullStripRequired_12(tif); #endif memset(&state, 0, sizeof(JPEGState)); @@ -1088,233 +1185,271 @@ int TIFFJPEGIsFullStripRequired(TIFF* tif) /* * Set up for decoding a strip or tile. */ -/*ARGSUSED*/ static int -JPEGPreDecode(TIFF* tif, uint16 s) +/*ARGSUSED*/ static int JPEGPreDecode(TIFF *tif, uint16_t s) { - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGPreDecode"; - uint32 segment_width, segment_height; - int downsampled_output; - int ci; + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreDecode"; + uint32_t segment_width, segment_height; + int downsampled_output; + int ci; - assert(sp != NULL); - - if (sp->cinfo.comm.is_decompressor == 0) - { - tif->tif_setupdecode( tif ); - } - - assert(sp->cinfo.comm.is_decompressor); - /* - * Reset decoder state from any previous strip/tile, - * in case application didn't read the whole strip. - */ - if (!TIFFjpeg_abort(sp)) - return (0); - /* - * Read the header for this strip/tile. - */ - - if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) - return (0); + assert(sp != NULL); - tif->tif_rawcp = (uint8*) sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; + if (sp->cinfo.comm.is_decompressor == 0) + { + tif->tif_setupdecode(tif); + } - /* - * Check image parameters and set decompression parameters. - */ - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - sp->bytesperline = TIFFTileRowSize(tif); - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - sp->bytesperline = TIFFScanlineSize(tif); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { - /* - * For PC 2, scale down the expected strip/tile size - * to match a downsampled component - */ - segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); - segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); - } - if (sp->cinfo.d.image_width < segment_width || - sp->cinfo.d.image_height < segment_height) { - TIFFWarningExt(tif->tif_clientdata, module, - "Improper JPEG strip/tile size, " - "expected %dx%d, got %dx%d", - segment_width, segment_height, - sp->cinfo.d.image_width, - sp->cinfo.d.image_height); - } - if( sp->cinfo.d.image_width == segment_width && - sp->cinfo.d.image_height > segment_height && - tif->tif_row + segment_height == td->td_imagelength && - !isTiled(tif) ) { - /* Some files have a last strip, that should be truncated, */ - /* but their JPEG codestream has still the maximum strip */ - /* height. Warn about this as this is non compliant, but */ - /* we can safely recover from that. */ - TIFFWarningExt(tif->tif_clientdata, module, - "JPEG strip size exceeds expected dimensions," - " expected %dx%d, got %dx%d", - segment_width, segment_height, - sp->cinfo.d.image_width, sp->cinfo.d.image_height); - } - else if (sp->cinfo.d.image_width > segment_width || - sp->cinfo.d.image_height > segment_height) { - /* - * This case could be dangerous, if the strip or tile size has - * been reported as less than the amount of data jpeg will - * return, some potential security issues arise. Catch this - * case and error out. - */ - TIFFErrorExt(tif->tif_clientdata, module, - "JPEG strip/tile size exceeds expected dimensions," - " expected %dx%d, got %dx%d", - segment_width, segment_height, - sp->cinfo.d.image_width, sp->cinfo.d.image_height); - return (0); - } - if (sp->cinfo.d.num_components != - (td->td_planarconfig == PLANARCONFIG_CONTIG ? - td->td_samplesperpixel : 1)) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count"); - return (0); - } + assert(sp->cinfo.comm.is_decompressor); + /* + * Reset decoder state from any previous strip/tile, + * in case application didn't read the whole strip. + */ + if (!TIFFjpeg_abort(sp)) + return (0); + /* + * Read the header for this strip/tile. + */ + + if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) + return (0); + + tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + + /* + * Check image parameters and set decompression parameters. + */ + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) + { + /* + * For PC 2, scale down the expected strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); + } + if (sp->cinfo.d.image_width < segment_width || + sp->cinfo.d.image_height < segment_height) + { + TIFFWarningExtR(tif, module, + "Improper JPEG strip/tile size, " + "expected %" PRIu32 "x%" PRIu32 ", got %ux%u", + segment_width, segment_height, sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + } + if (sp->cinfo.d.image_width == segment_width && + sp->cinfo.d.image_height > segment_height && + tif->tif_row + segment_height == td->td_imagelength && !isTiled(tif)) + { + /* Some files have a last strip, that should be truncated, */ + /* but their JPEG codestream has still the maximum strip */ + /* height. Warn about this as this is non compliant, but */ + /* we can safely recover from that. */ + TIFFWarningExtR(tif, module, + "JPEG strip size exceeds expected dimensions," + " expected %" PRIu32 "x%" PRIu32 ", got %ux%u", + segment_width, segment_height, sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + } + else if (sp->cinfo.d.image_width > segment_width || + sp->cinfo.d.image_height > segment_height) + { + /* + * This case could be dangerous, if the strip or tile size has + * been reported as less than the amount of data jpeg will + * return, some potential security issues arise. Catch this + * case and error out. + */ + TIFFErrorExtR(tif, module, + "JPEG strip/tile size exceeds expected dimensions," + " expected %" PRIu32 "x%" PRIu32 ", got %ux%u", + segment_width, segment_height, sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + return (0); + } + if (sp->cinfo.d.num_components != + (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel + : 1)) + { + TIFFErrorExtR(tif, module, "Improper JPEG component count"); + return (0); + } #ifdef JPEG_LIB_MK1 - if (12 != td->td_bitspersample && 8 != td->td_bitspersample) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); - return (0); - } - sp->cinfo.d.data_precision = td->td_bitspersample; - sp->cinfo.d.bits_in_jsample = td->td_bitspersample; + if (12 != td->td_bitspersample && 8 != td->td_bitspersample) + { + TIFFErrorExtR(tif, module, "Improper JPEG data precision"); + return (0); + } + sp->cinfo.d.data_precision = td->td_bitspersample; + sp->cinfo.d.bits_in_jsample = td->td_bitspersample; #else - if (sp->cinfo.d.data_precision != td->td_bitspersample) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); - return (0); - } + if (sp->cinfo.d.data_precision != td->td_bitspersample) + { + TIFFErrorExtR(tif, module, "Improper JPEG data precision"); + return (0); + } #endif - /* In some cases, libjpeg needs to allocate a lot of memory */ - /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */ - if( TIFFjpeg_has_multiple_scans(sp) ) + if (sp->cinfo.d.progressive_mode && + !sp->otherSettings.has_warned_about_progressive_mode) + { + TIFFWarningExtR(tif, module, + "The JPEG strip/tile is encoded with progressive mode, " + "which is normally not legal for JPEG-in-TIFF.\n" + "libtiff should be able to decode it, but it might " + "cause compatibility issues with other readers"); + sp->otherSettings.has_warned_about_progressive_mode = TRUE; + } + + /* In some cases, libjpeg needs to allocate a lot of memory */ + /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + */ + if (TIFFjpeg_has_multiple_scans(sp)) + { + /* In this case libjpeg will need to allocate memory or backing */ + /* store for all coefficients */ + /* See call to jinit_d_coef_controller() from master_selection() */ + /* in libjpeg */ + + /* 1 MB for regular libjpeg usage */ + toff_t nRequiredMemory = 1024 * 1024; + + for (ci = 0; ci < sp->cinfo.d.num_components; ci++) { - /* In this case libjpeg will need to allocate memory or backing */ - /* store for all coefficients */ - /* See call to jinit_d_coef_controller() from master_selection() */ - /* in libjpeg */ - - /* 1 MB for regular libjpeg usage */ - toff_t nRequiredMemory = 1024 * 1024; - - for (ci = 0; ci < sp->cinfo.d.num_components; ci++) { - const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]); - if( compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0 ) - { - nRequiredMemory += (toff_t)( - ((compptr->width_in_blocks + compptr->h_samp_factor - 1) / compptr->h_samp_factor)) * - ((compptr->height_in_blocks + compptr->v_samp_factor - 1) / compptr->v_samp_factor) * - sizeof(JBLOCK); - } - } - - if( sp->cinfo.d.mem->max_memory_to_use > 0 && - nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) && - getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL ) + const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]); + if (compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Reading this image would require libjpeg to allocate " - "at least %u bytes. " - "This is disabled since above the %u threshold. " - "You may override this restriction by defining the " - "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, " - "or setting the JPEGMEM environment variable to a value greater " - "or equal to '%uM'", - (unsigned)(nRequiredMemory), - (unsigned)(sp->cinfo.d.mem->max_memory_to_use), - (unsigned)((nRequiredMemory + 1000000 - 1) / 1000000)); - return 0; + nRequiredMemory += + (toff_t)(((compptr->width_in_blocks + + compptr->h_samp_factor - 1) / + compptr->h_samp_factor)) * + ((compptr->height_in_blocks + compptr->v_samp_factor - 1) / + compptr->v_samp_factor) * + sizeof(JBLOCK); } } - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - /* Component 0 should have expected sampling factors */ - if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || - sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) { - TIFFErrorExt(tif->tif_clientdata, module, - "Improper JPEG sampling factors %d,%d\n" - "Apparently should be %d,%d.", - sp->cinfo.d.comp_info[0].h_samp_factor, - sp->cinfo.d.comp_info[0].v_samp_factor, - sp->h_sampling, sp->v_sampling); - return (0); - } - /* Rest should have sampling factors 1,1 */ - for (ci = 1; ci < sp->cinfo.d.num_components; ci++) { - if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || - sp->cinfo.d.comp_info[ci].v_samp_factor != 1) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors"); - return (0); - } - } - } else { - /* PC 2's single component should have sampling factors 1,1 */ - if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || - sp->cinfo.d.comp_info[0].v_samp_factor != 1) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors"); - return (0); - } - } - downsampled_output = FALSE; - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - sp->photometric == PHOTOMETRIC_YCBCR && - sp->jpegcolormode == JPEGCOLORMODE_RGB) { - /* Convert YCbCr to RGB */ - sp->cinfo.d.jpeg_color_space = JCS_YCbCr; - sp->cinfo.d.out_color_space = JCS_RGB; - } else { - /* Suppress colorspace handling */ - sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; - sp->cinfo.d.out_color_space = JCS_UNKNOWN; - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - (sp->h_sampling != 1 || sp->v_sampling != 1)) - downsampled_output = TRUE; - /* XXX what about up-sampling? */ - } - if (downsampled_output) { - /* Need to use raw-data interface to libjpeg */ - sp->cinfo.d.raw_data_out = TRUE; + if (sp->cinfo.d.mem->max_memory_to_use > 0 && + nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) && + getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL) + { + TIFFErrorExtR( + tif, module, + "Reading this image would require libjpeg to allocate " + "at least %" PRIu64 " bytes. " + "This is disabled since above the %ld threshold. " + "You may override this restriction by defining the " + "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, " + "or setting the JPEGMEM environment variable to a value " + "greater " + "or equal to '%" PRIu64 "M'", + nRequiredMemory, sp->cinfo.d.mem->max_memory_to_use, + (nRequiredMemory + 1000000u - 1u) / 1000000u); + return 0; + } + } + + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + /* Component 0 should have expected sampling factors */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || + sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) + { + TIFFErrorExtR(tif, module, + "Improper JPEG sampling factors %d,%d\n" + "Apparently should be %" PRIu16 ",%" PRIu16 ".", + sp->cinfo.d.comp_info[0].h_samp_factor, + sp->cinfo.d.comp_info[0].v_samp_factor, + sp->h_sampling, sp->v_sampling); + return (0); + } + /* Rest should have sampling factors 1,1 */ + for (ci = 1; ci < sp->cinfo.d.num_components; ci++) + { + if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || + sp->cinfo.d.comp_info[ci].v_samp_factor != 1) + { + TIFFErrorExtR(tif, module, "Improper JPEG sampling factors"); + return (0); + } + } + } + else + { + /* PC 2's single component should have sampling factors 1,1 */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || + sp->cinfo.d.comp_info[0].v_samp_factor != 1) + { + TIFFErrorExtR(tif, module, "Improper JPEG sampling factors"); + return (0); + } + } + downsampled_output = FALSE; + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + sp->photometric == PHOTOMETRIC_YCBCR && + sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) + { + /* Convert YCbCr to RGB */ + sp->cinfo.d.jpeg_color_space = JCS_YCbCr; + sp->cinfo.d.out_color_space = JCS_RGB; + } + else + { + /* Suppress colorspace handling */ + sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; + sp->cinfo.d.out_color_space = JCS_UNKNOWN; + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + (sp->h_sampling != 1 || sp->v_sampling != 1)) + downsampled_output = TRUE; + /* XXX what about up-sampling? */ + } + if (downsampled_output) + { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.d.raw_data_out = TRUE; #if JPEG_LIB_VERSION >= 70 - sp->cinfo.d.do_fancy_upsampling = FALSE; + sp->cinfo.d.do_fancy_upsampling = FALSE; #endif /* JPEG_LIB_VERSION >= 70 */ - tif->tif_decoderow = DecodeRowError; - tif->tif_decodestrip = JPEGDecodeRaw; - tif->tif_decodetile = JPEGDecodeRaw; - } else { - /* Use normal interface to libjpeg */ - sp->cinfo.d.raw_data_out = FALSE; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - } - /* Start JPEG decompressor */ - if (!TIFFjpeg_start_decompress(sp)) - return (0); - /* Allocate downsampled-data buffers if needed */ - if (downsampled_output) { - if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, - sp->cinfo.d.num_components)) - return (0); - sp->scancount = DCTSIZE; /* mark buffer empty */ - } - return (1); + tif->tif_decoderow = DecodeRowError; + tif->tif_decodestrip = JPEGDecodeRaw; + tif->tif_decodetile = JPEGDecodeRaw; + } + else + { + /* Use normal interface to libjpeg */ + sp->cinfo.d.raw_data_out = FALSE; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + } + /* Start JPEG decompressor */ + if (!TIFFjpeg_start_decompress(sp)) + return (0); + /* Allocate downsampled-data buffers if needed */ + if (downsampled_output) + { + if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, + sp->cinfo.d.num_components)) + return (0); + sp->scancount = DCTSIZE; /* mark buffer empty */ + } + return (1); } /* @@ -1322,177 +1457,179 @@ JPEGPreDecode(TIFF* tif, uint16 s) * "Standard" case: returned data is not downsampled. */ #if !JPEG_LIB_MK1_OR_12BIT -static int -JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - JPEGState *sp = JState(tif); - tmsize_t nrows; - (void) s; + JPEGState *sp = JState(tif); + tmsize_t nrows; + (void)s; - /* - ** Update available information, buffer may have been refilled - ** between decode requests - */ - sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp; - sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; + /* + ** Update available information, buffer may have been refilled + ** between decode requests + */ + sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; + sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; - if( sp->bytesperline == 0 ) - return 0; - - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "fractional scanline not read"); + if (sp->bytesperline == 0) + return 0; - if( nrows > (tmsize_t) sp->cinfo.d.image_height ) - nrows = sp->cinfo.d.image_height; + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read"); - /* data is expected to be read in multiples of a scanline */ - if (nrows) + if (nrows > (tmsize_t)sp->cinfo.d.image_height) + nrows = sp->cinfo.d.image_height; + + /* data is expected to be read in multiples of a scanline */ + if (nrows) + { + do { - do - { - /* - * In the libjpeg6b-9a 8bit case. We read directly into - * the TIFF buffer. - */ - JSAMPROW bufptr = (JSAMPROW)buf; + /* + * In the libjpeg6b-9a 8bit case. We read directly into + * the TIFF buffer. + */ + JSAMPROW bufptr = (JSAMPROW)buf; - if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1) - return (0); + if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1) + return (0); - ++tif->tif_row; - buf += sp->bytesperline; - cc -= sp->bytesperline; - } while (--nrows > 0); - } + ++tif->tif_row; + buf += sp->bytesperline; + cc -= sp->bytesperline; + } while (--nrows > 0); + } - /* Update information on consumed data */ - tif->tif_rawcp = (uint8*) sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; - - /* Close down the decompressor if we've finished the strip or tile. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height - || TIFFjpeg_finish_decompress(sp); + /* Update information on consumed data */ + tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + + /* Close down the decompressor if we've finished the strip or tile. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || + TIFFjpeg_finish_decompress(sp); } #endif /* !JPEG_LIB_MK1_OR_12BIT */ #if JPEG_LIB_MK1_OR_12BIT -/*ARGSUSED*/ static int -JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +/*ARGSUSED*/ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, + uint16_t s) { - JPEGState *sp = JState(tif); - tmsize_t nrows; - (void) s; + JPEGState *sp = JState(tif); + tmsize_t nrows; + (void)s; + + /* + ** Update available information, buffer may have been refilled + ** between decode requests + */ + sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; + sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; + + if (sp->bytesperline == 0) + return 0; + + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read"); + + if (nrows > (tmsize_t)sp->cinfo.d.image_height) + nrows = sp->cinfo.d.image_height; + + /* data is expected to be read in multiples of a scanline */ + if (nrows) + { + TIFF_JSAMPROW line_work_buf = NULL; /* - ** Update available information, buffer may have been refilled - ** between decode requests - */ - sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp; - sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; - - if( sp->bytesperline == 0 ) - return 0; - - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "fractional scanline not read"); - - if( nrows > (tmsize_t) sp->cinfo.d.image_height ) - nrows = sp->cinfo.d.image_height; - - /* data is expected to be read in multiples of a scanline */ - if (nrows) + * For 6B, only use temporary buffer for 12 bit imagery. + * For Mk1 always use it. + */ + if (sp->cinfo.d.data_precision == 12) { - JSAMPROW line_work_buf = NULL; - - /* - * For 6B, only use temporary buffer for 12 bit imagery. - * For Mk1 always use it. - */ - if( sp->cinfo.d.data_precision == 12 ) - { - line_work_buf = (JSAMPROW) - _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width - * sp->cinfo.d.num_components ); - } - - do - { - if( line_work_buf != NULL ) - { - /* - * In the MK1 case, we always read into a 16bit - * buffer, and then pack down to 12bit or 8bit. - * In 6B case we only read into 16 bit buffer - * for 12bit data, which we need to repack. - */ - if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) - return (0); - - if( sp->cinfo.d.data_precision == 12 ) - { - int value_pairs = (sp->cinfo.d.output_width - * sp->cinfo.d.num_components) / 2; - int iPair; - - for( iPair = 0; iPair < value_pairs; iPair++ ) - { - unsigned char *out_ptr = - ((unsigned char *) buf) + iPair * 3; - JSAMPLE *in_ptr = line_work_buf + iPair * 2; - - out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); - out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4) - | ((in_ptr[1] & 0xf00) >> 8)); - out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); - } - } - else if( sp->cinfo.d.data_precision == 8 ) - { - int value_count = (sp->cinfo.d.output_width - * sp->cinfo.d.num_components); - int iValue; - - for( iValue = 0; iValue < value_count; iValue++ ) - { - ((unsigned char *) buf)[iValue] = - line_work_buf[iValue] & 0xff; - } - } - } - - ++tif->tif_row; - buf += sp->bytesperline; - cc -= sp->bytesperline; - } while (--nrows > 0); - - if( line_work_buf != NULL ) - _TIFFfree( line_work_buf ); + line_work_buf = (TIFF_JSAMPROW)_TIFFmallocExt( + tif, sizeof(short) * sp->cinfo.d.output_width * + sp->cinfo.d.num_components); } - /* Update information on consumed data */ - tif->tif_rawcp = (uint8*) sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; - - /* Close down the decompressor if we've finished the strip or tile. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height - || TIFFjpeg_finish_decompress(sp); + do + { + if (line_work_buf != NULL) + { + /* + * In the MK1 case, we always read into a 16bit + * buffer, and then pack down to 12bit or 8bit. + * In 6B case we only read into 16 bit buffer + * for 12bit data, which we need to repack. + */ + if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) + return (0); + + if (sp->cinfo.d.data_precision == 12) + { + int value_pairs = (sp->cinfo.d.output_width * + sp->cinfo.d.num_components) / + 2; + int iPair; + + for (iPair = 0; iPair < value_pairs; iPair++) + { + unsigned char *out_ptr = + ((unsigned char *)buf) + iPair * 3; + TIFF_JSAMPLE *in_ptr = line_work_buf + iPair * 2; + + out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); + out_ptr[1] = + (unsigned char)(((in_ptr[0] & 0xf) << 4) | + ((in_ptr[1] & 0xf00) >> 8)); + out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); + } + } + else if (sp->cinfo.d.data_precision == 8) + { + int value_count = + (sp->cinfo.d.output_width * sp->cinfo.d.num_components); + int iValue; + + for (iValue = 0; iValue < value_count; iValue++) + { + ((unsigned char *)buf)[iValue] = + line_work_buf[iValue] & 0xff; + } + } + } + + ++tif->tif_row; + buf += sp->bytesperline; + cc -= sp->bytesperline; + } while (--nrows > 0); + + if (line_work_buf != NULL) + _TIFFfreeExt(tif, line_work_buf); + } + + /* Update information on consumed data */ + tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + + /* Close down the decompressor if we've finished the strip or tile. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || + TIFFjpeg_finish_decompress(sp); } #endif /* JPEG_LIB_MK1_OR_12BIT */ -/*ARGSUSED*/ static int -DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +/*ARGSUSED*/ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, + uint16_t s) { - (void) buf; - (void) cc; - (void) s; + (void)buf; + (void)cc; + (void)s; - TIFFErrorExt(tif->tif_clientdata, "TIFFReadScanline", - "scanline oriented access is not supported for downsampled JPEG compressed images, consider enabling TIFF_JPEGCOLORMODE as JPEGCOLORMODE_RGB." ); + TIFFErrorExtR( + tif, "TIFFReadScanline", + "scanline oriented access is not supported for downsampled JPEG " + "compressed images, consider enabling TIFFTAG_JPEGCOLORMODE as " + "JPEGCOLORMODE_RGB."); return 0; } @@ -1500,926 +1637,1079 @@ DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) * Decode a chunk of pixels. * Returned data is downsampled per sampling factors. */ -/*ARGSUSED*/ static int -JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +/*ARGSUSED*/ static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, + uint16_t s) { - JPEGState *sp = JState(tif); - tmsize_t nrows; - TIFFDirectory *td = &tif->tif_dir; - (void) s; + JPEGState *sp = JState(tif); + tmsize_t nrows; + TIFFDirectory *td = &tif->tif_dir; + (void)s; - nrows = sp->cinfo.d.image_height; - /* For last strip, limit number of rows to its truncated height */ - /* even if the codestream height is larger (which is not compliant, */ - /* but that we tolerate) */ - if( (uint32)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif) ) - nrows = td->td_imagelength - tif->tif_row; - - /* data is expected to be read in multiples of a scanline */ - if ( nrows != 0 ) { - - /* Cb,Cr both have sampling factors 1, so this is correct */ - JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; - int samples_per_clump = sp->samplesperclump; + nrows = sp->cinfo.d.image_height; + /* For last strip, limit number of rows to its truncated height */ + /* even if the codestream height is larger (which is not compliant, */ + /* but that we tolerate) */ + if ((uint32_t)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif)) + nrows = td->td_imagelength - tif->tif_row; #if defined(JPEG_LIB_MK1_OR_12BIT) - unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) * - sp->cinfo.d.output_width * - sp->cinfo.d.num_components); - if(tmpbuf==NULL) { - TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", - "Out of memory"); - return 0; - } + unsigned short *tmpbuf = NULL; #endif - do { - jpeg_component_info *compptr; - int ci, clumpoffset; + /* data is expected to be read in multiples of a scanline */ + if (nrows != 0) + { - if( cc < sp->bytesperline ) { - TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", - "application buffer not large enough for all data."); - return 0; - } + /* Cb,Cr both have sampling factors 1, so this is correct */ + JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; + int samples_per_clump = sp->samplesperclump; - /* Reload downsampled-data buffer if needed */ - if (sp->scancount >= DCTSIZE) { - int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - sp->scancount = 0; - } - /* - * Fastest way to unseparate data is to make one pass - * over the scanline for each row of each component. - */ - clumpoffset = 0; /* first sample in clump */ - for (ci = 0, compptr = sp->cinfo.d.comp_info; - ci < sp->cinfo.d.num_components; - ci++, compptr++) { - int hsamp = compptr->h_samp_factor; - int vsamp = compptr->v_samp_factor; - int ypos; - - for (ypos = 0; ypos < vsamp; ypos++) { - JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; - JDIMENSION nclump; #if defined(JPEG_LIB_MK1_OR_12BIT) - JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset; + tmpbuf = _TIFFmallocExt(tif, sizeof(unsigned short) * + sp->cinfo.d.output_width * + sp->cinfo.d.num_components); + if (tmpbuf == NULL) + { + TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory"); + return 0; + } +#endif + + do + { + jpeg_component_info *compptr; + int ci, clumpoffset; + + if (cc < sp->bytesperline) + { + TIFFErrorExtR( + tif, "JPEGDecodeRaw", + "application buffer not large enough for all data."); + goto error; + } + + /* Reload downsampled-data buffer if needed */ + if (sp->scancount >= DCTSIZE) + { + int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) + goto error; + sp->scancount = 0; + } + /* + * Fastest way to unseparate data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.d.comp_info; + ci < sp->cinfo.d.num_components; ci++, compptr++) + { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + int ypos; + + for (ypos = 0; ypos < vsamp; ypos++) + { + TIFF_JSAMPLE *inptr = + sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; + JDIMENSION nclump; +#if defined(JPEG_LIB_MK1_OR_12BIT) + TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)tmpbuf + clumpoffset; #else - JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset; - if (cc < (tmsize_t)(clumpoffset + (tmsize_t)samples_per_clump*(clumps_per_line-1) + hsamp)) { - TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", - "application buffer not large enough for all data, possible subsampling issue"); - return 0; - } + TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)buf + clumpoffset; + if (cc < (tmsize_t)(clumpoffset + + (tmsize_t)samples_per_clump * + (clumps_per_line - 1) + + hsamp)) + { + TIFFErrorExtR( + tif, "JPEGDecodeRaw", + "application buffer not large enough for all data, " + "possible subsampling issue"); + goto error; + } #endif - if (hsamp == 1) { - /* fast path for at least Cb and Cr */ - for (nclump = clumps_per_line; nclump-- > 0; ) { - outptr[0] = *inptr++; - outptr += samples_per_clump; - } - } else { - int xpos; + if (hsamp == 1) + { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0;) + { + outptr[0] = *inptr++; + outptr += samples_per_clump; + } + } + else + { + int xpos; - /* general case */ - for (nclump = clumps_per_line; nclump-- > 0; ) { - for (xpos = 0; xpos < hsamp; xpos++) - outptr[xpos] = *inptr++; - outptr += samples_per_clump; - } - } - clumpoffset += hsamp; - } - } + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0;) + { + for (xpos = 0; xpos < hsamp; xpos++) + outptr[xpos] = *inptr++; + outptr += samples_per_clump; + } + } + clumpoffset += hsamp; + } + } #if defined(JPEG_LIB_MK1_OR_12BIT) - { - if (sp->cinfo.d.data_precision == 8) - { - int i=0; - int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components; - for (i=0; icinfo.d.output_width - * sp->cinfo.d.num_components) / 2; - int iPair; - for( iPair = 0; iPair < value_pairs; iPair++ ) - { - unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3; - JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2); - out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); - out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4) - | ((in_ptr[1] & 0xf00) >> 8)); - out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); - } - } - } + { + if (sp->cinfo.d.data_precision == 8) + { + int i = 0; + int len = + sp->cinfo.d.output_width * sp->cinfo.d.num_components; + for (i = 0; i < len; i++) + { + ((unsigned char *)buf)[i] = tmpbuf[i] & 0xff; + } + } + else + { /* 12-bit */ + int value_pairs = (sp->cinfo.d.output_width * + sp->cinfo.d.num_components) / + 2; + int iPair; + for (iPair = 0; iPair < value_pairs; iPair++) + { + unsigned char *out_ptr = + ((unsigned char *)buf) + iPair * 3; + JSAMPLE *in_ptr = (JSAMPLE *)(tmpbuf + iPair * 2); + out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); + out_ptr[1] = + (unsigned char)(((in_ptr[0] & 0xf) << 4) | + ((in_ptr[1] & 0xf00) >> 8)); + out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); + } + } + } #endif - sp->scancount ++; - tif->tif_row += sp->v_sampling; + sp->scancount++; + tif->tif_row += sp->v_sampling; - buf += sp->bytesperline; - cc -= sp->bytesperline; + buf += sp->bytesperline; + cc -= sp->bytesperline; - nrows -= sp->v_sampling; - } while (nrows > 0); + nrows -= sp->v_sampling; + } while (nrows > 0); #if defined(JPEG_LIB_MK1_OR_12BIT) - _TIFFfree(tmpbuf); + _TIFFfreeExt(tif, tmpbuf); #endif + } - } + /* Close down the decompressor if done. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || + TIFFjpeg_finish_decompress(sp); - /* Close down the decompressor if done. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height - || TIFFjpeg_finish_decompress(sp); +error: +#if defined(JPEG_LIB_MK1_OR_12BIT) + _TIFFfreeExt(tif, tmpbuf); +#endif + return 0; } - /* * JPEG Encoding. */ -static void -unsuppress_quant_table (JPEGState* sp, int tblno) +static void unsuppress_quant_table(JPEGState *sp, int tblno) { - JQUANT_TBL* qtbl; + JQUANT_TBL *qtbl; - if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) - qtbl->sent_table = FALSE; + if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) + qtbl->sent_table = FALSE; } -static void -suppress_quant_table (JPEGState* sp, int tblno) +static void suppress_quant_table(JPEGState *sp, int tblno) { - JQUANT_TBL* qtbl; + JQUANT_TBL *qtbl; - if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) - qtbl->sent_table = TRUE; + if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) + qtbl->sent_table = TRUE; } -static void -unsuppress_huff_table (JPEGState* sp, int tblno) +static void unsuppress_huff_table(JPEGState *sp, int tblno) { - JHUFF_TBL* htbl; + JHUFF_TBL *htbl; - if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = FALSE; - if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = FALSE; + if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; + if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; } -static void -suppress_huff_table (JPEGState* sp, int tblno) +static void suppress_huff_table(JPEGState *sp, int tblno) { - JHUFF_TBL* htbl; + JHUFF_TBL *htbl; - if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = TRUE; - if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = TRUE; + if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = TRUE; + if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = TRUE; } -static int -prepare_JPEGTables(TIFF* tif) +static int prepare_JPEGTables(TIFF *tif) { - JPEGState* sp = JState(tif); + JPEGState *sp = JState(tif); - /* Initialize quant tables for current quality setting */ - if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) - return (0); - /* Mark only the tables we want for output */ - /* NB: chrominance tables are currently used only with YCbCr */ - if (!TIFFjpeg_suppress_tables(sp, TRUE)) - return (0); - if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) { - unsuppress_quant_table(sp, 0); - if (sp->photometric == PHOTOMETRIC_YCBCR) - unsuppress_quant_table(sp, 1); - } - if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) { - unsuppress_huff_table(sp, 0); - if (sp->photometric == PHOTOMETRIC_YCBCR) - unsuppress_huff_table(sp, 1); - } - /* Direct libjpeg output into jpegtables */ - if (!TIFFjpeg_tables_dest(sp, tif)) - return (0); - /* Emit tables-only datastream */ - if (!TIFFjpeg_write_tables(sp)) - return (0); + /* Initialize quant tables for current quality setting */ + if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) + return (0); + /* Mark only the tables we want for output */ + /* NB: chrominance tables are currently used only with YCbCr */ + if (!TIFFjpeg_suppress_tables(sp, TRUE)) + return (0); + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) + { + unsuppress_quant_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_quant_table(sp, 1); + } + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) + { + unsuppress_huff_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_huff_table(sp, 1); + } + /* Direct libjpeg output into otherSettings.jpegtables */ + if (!TIFFjpeg_tables_dest(sp, tif)) + return (0); + /* Emit tables-only datastream */ + if (!TIFFjpeg_write_tables(sp)) + return (0); - return (1); + return (1); } -static int -JPEGSetupEncode(TIFF* tif) +#if defined(JPEG_LIB_VERSION_MAJOR) && \ + (JPEG_LIB_VERSION_MAJOR > 9 || \ + (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4)) +/* This is a modified version of std_huff_tables() from jcparam.c + * in libjpeg-9d because it no longer initializes default Huffman + * tables in jpeg_set_defaults(). */ +static void TIFF_std_huff_tables(j_compress_ptr cinfo) { - JPEGState* sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGSetupEncode"; -#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) - if( tif->tif_dir.td_bitspersample == 12 ) - return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 1 ); + if (cinfo->dc_huff_tbl_ptrs[0] == NULL) + { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 0); + } + if (cinfo->ac_huff_tbl_ptrs[0] == NULL) + { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 0); + } + if (cinfo->dc_huff_tbl_ptrs[1] == NULL) + { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 1); + } + if (cinfo->ac_huff_tbl_ptrs[1] == NULL) + { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 1); + } +} #endif - JPEGInitializeLibJPEG( tif, FALSE ); +static int JPEGSetupEncode(TIFF *tif) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGSetupEncode"; - assert(sp != NULL); - assert(!sp->cinfo.comm.is_decompressor); +#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) + if (tif->tif_dir.td_bitspersample == 12) + { + /* We pass a pointer to a copy of otherSettings, since */ + /* TIFFReInitJPEG_12() will clear sp */ + JPEGOtherSettings savedOtherSettings = sp->otherSettings; + return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 1); + } +#endif - sp->photometric = td->td_photometric; + JPEGInitializeLibJPEG(tif, FALSE); - /* - * Initialize all JPEG parameters to default values. - * Note that jpeg_set_defaults needs legal values for - * in_color_space and input_components. - */ - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - sp->cinfo.c.input_components = td->td_samplesperpixel; - if (sp->photometric == PHOTOMETRIC_YCBCR) { - if (sp->jpegcolormode == JPEGCOLORMODE_RGB) { - sp->cinfo.c.in_color_space = JCS_RGB; - } else { - sp->cinfo.c.in_color_space = JCS_YCbCr; - } - } else { - if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1) - sp->cinfo.c.in_color_space = JCS_GRAYSCALE; - else if (td->td_photometric == PHOTOMETRIC_RGB && td->td_samplesperpixel == 3) - sp->cinfo.c.in_color_space = JCS_RGB; - else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4) - sp->cinfo.c.in_color_space = JCS_CMYK; - else - sp->cinfo.c.in_color_space = JCS_UNKNOWN; - } - } else { - sp->cinfo.c.input_components = 1; - sp->cinfo.c.in_color_space = JCS_UNKNOWN; - } - if (!TIFFjpeg_set_defaults(sp)) - return (0); - /* Set per-file parameters */ - switch (sp->photometric) { - case PHOTOMETRIC_YCBCR: - sp->h_sampling = td->td_ycbcrsubsampling[0]; - sp->v_sampling = td->td_ycbcrsubsampling[1]; - if( sp->h_sampling == 0 || sp->v_sampling == 0 ) + assert(sp != NULL); + assert(!sp->cinfo.comm.is_decompressor); + + sp->photometric = td->td_photometric; + + /* + * Initialize all JPEG parameters to default values. + * Note that jpeg_set_defaults needs legal values for + * in_color_space and input_components. + */ + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + sp->cinfo.c.input_components = td->td_samplesperpixel; + if (sp->photometric == PHOTOMETRIC_YCBCR) + { + if (sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) + { + sp->cinfo.c.in_color_space = JCS_RGB; + } + else + { + sp->cinfo.c.in_color_space = JCS_YCbCr; + } + } + else + { + if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || + td->td_photometric == PHOTOMETRIC_MINISBLACK) && + td->td_samplesperpixel == 1) + sp->cinfo.c.in_color_space = JCS_GRAYSCALE; + else if (td->td_photometric == PHOTOMETRIC_RGB && + td->td_samplesperpixel == 3) + sp->cinfo.c.in_color_space = JCS_RGB; + else if (td->td_photometric == PHOTOMETRIC_SEPARATED && + td->td_samplesperpixel == 4) + sp->cinfo.c.in_color_space = JCS_CMYK; + else + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + } + } + else + { + sp->cinfo.c.input_components = 1; + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + } + if (!TIFFjpeg_set_defaults(sp)) + return (0); + + /* mozjpeg by default enables progressive JPEG, which is illegal in + * JPEG-in-TIFF */ + /* So explicitly disable it. */ + if (sp->cinfo.c.num_scans != 0 && + (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0) + { + /* it has been found that mozjpeg could create corrupt strips/tiles */ + /* in non optimize_coding mode. */ + TIFFWarningExtR( + tif, module, + "mozjpeg library likely detected. Disable emission of " + "Huffman tables in JpegTables tag, and use optimize_coding " + "to avoid potential issues"); + sp->otherSettings.jpegtablesmode &= ~JPEGTABLESMODE_HUFF; + } + sp->cinfo.c.num_scans = 0; + sp->cinfo.c.scan_info = NULL; + + /* Set per-file parameters */ + switch (sp->photometric) + { + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + if (sp->h_sampling == 0 || sp->v_sampling == 0) + { + TIFFErrorExtR(tif, module, + "Invalig horizontal/vertical sampling value"); + return (0); + } + if (td->td_bitspersample > 16) + { + TIFFErrorExtR(tif, module, + "BitsPerSample %" PRIu16 " not allowed for JPEG", + td->td_bitspersample); + return (0); + } + + /* + * A ReferenceBlackWhite field *must* be present since the + * default value is inappropriate for YCbCr. Fill in the + * proper value if application didn't set it. + */ + { + float *ref; + if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Invalig horizontal/vertical sampling value"); - return (0); - } - if( td->td_bitspersample > 16 ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "BitsPerSample %d not allowed for JPEG", - td->td_bitspersample); - return (0); + float refbw[6]; + long top = 1L << td->td_bitspersample; + refbw[0] = 0; + refbw[1] = (float)(top - 1L); + refbw[2] = (float)(top >> 1); + refbw[3] = refbw[1]; + refbw[4] = refbw[2]; + refbw[5] = refbw[1]; + TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw); } + } + break; + case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ + case PHOTOMETRIC_MASK: + TIFFErrorExtR(tif, module, + "PhotometricInterpretation %" PRIu16 + " not allowed for JPEG", + sp->photometric); + return (0); + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } - /* - * A ReferenceBlackWhite field *must* be present since the - * default value is inappropriate for YCbCr. Fill in the - * proper value if application didn't set it. - */ - { - float *ref; - if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, - &ref)) { - float refbw[6]; - long top = 1L << td->td_bitspersample; - refbw[0] = 0; - refbw[1] = (float)(top-1L); - refbw[2] = (float)(top>>1); - refbw[3] = refbw[1]; - refbw[4] = refbw[2]; - refbw[5] = refbw[1]; - TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, - refbw); - } - } - break; - case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ - case PHOTOMETRIC_MASK: - TIFFErrorExt(tif->tif_clientdata, module, - "PhotometricInterpretation %d not allowed for JPEG", - (int) sp->photometric); - return (0); - default: - /* TIFF 6.0 forbids subsampling of all other color spaces */ - sp->h_sampling = 1; - sp->v_sampling = 1; - break; - } + /* Verify miscellaneous parameters */ - /* Verify miscellaneous parameters */ - - /* - * This would need work if libtiff ever supports different - * depths for different components, or if libjpeg ever supports - * run-time selection of depth. Neither is imminent. - */ + /* + * This would need work if libtiff ever supports different + * depths for different components, or if libjpeg ever supports + * run-time selection of depth. Neither is imminent. + */ #ifdef JPEG_LIB_MK1 - /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */ - if (td->td_bitspersample != 8 && td->td_bitspersample != 12) + /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */ + if (td->td_bitspersample != 8 && td->td_bitspersample != 12) #else - if (td->td_bitspersample != BITS_IN_JSAMPLE ) + if (td->td_bitspersample != BITS_IN_JSAMPLE) #endif - { - TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %d not allowed for JPEG", - (int) td->td_bitspersample); - return (0); - } - sp->cinfo.c.data_precision = td->td_bitspersample; + { + TIFFErrorExtR(tif, module, + "BitsPerSample %" PRIu16 " not allowed for JPEG", + td->td_bitspersample); + return (0); + } + sp->cinfo.c.data_precision = td->td_bitspersample; #ifdef JPEG_LIB_MK1 - sp->cinfo.c.bits_in_jsample = td->td_bitspersample; + sp->cinfo.c.bits_in_jsample = td->td_bitspersample; #endif - if (isTiled(tif)) { - if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "JPEG tile height must be multiple of %d", - sp->v_sampling * DCTSIZE); - return (0); - } - if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "JPEG tile width must be multiple of %d", - sp->h_sampling * DCTSIZE); - return (0); - } - } else { - if (td->td_rowsperstrip < td->td_imagelength && - (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "RowsPerStrip must be multiple of %d for JPEG", - sp->v_sampling * DCTSIZE); - return (0); - } - } + if (isTiled(tif)) + { + if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) + { + TIFFErrorExtR(tif, module, + "JPEG tile height must be multiple of %" PRIu32, + (uint32_t)(sp->v_sampling * DCTSIZE)); + return (0); + } + if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) + { + TIFFErrorExtR(tif, module, + "JPEG tile width must be multiple of %" PRIu32, + (uint32_t)(sp->h_sampling * DCTSIZE)); + return (0); + } + } + else + { + if (td->td_rowsperstrip < td->td_imagelength && + (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) + { + TIFFErrorExtR(tif, module, + "RowsPerStrip must be multiple of %" PRIu32 + " for JPEG", + (uint32_t)(sp->v_sampling * DCTSIZE)); + return (0); + } + } - /* Create a JPEGTables field if appropriate */ - if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) { - if( sp->jpegtables == NULL - || memcmp(sp->jpegtables,"\0\0\0\0\0\0\0\0\0",8) == 0 ) - { - if (!prepare_JPEGTables(tif)) - return (0); - /* Mark the field present */ - /* Can't use TIFFSetField since BEENWRITING is already set! */ - tif->tif_flags |= TIFF_DIRTYDIRECT; - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); - } - } else { - /* We do not support application-supplied JPEGTables, */ - /* so mark the field not present */ - TIFFClrFieldBit(tif, FIELD_JPEGTABLES); - } + /* Create a JPEGTables field if appropriate */ + if (sp->otherSettings.jpegtablesmode & + (JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF)) + { + if (sp->otherSettings.jpegtables == NULL || + memcmp(sp->otherSettings.jpegtables, "\0\0\0\0\0\0\0\0\0", 8) == 0) + { +#if defined(JPEG_LIB_VERSION_MAJOR) && \ + (JPEG_LIB_VERSION_MAJOR > 9 || \ + (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4)) + if ((sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0 && + (sp->cinfo.c.dc_huff_tbl_ptrs[0] == NULL || + sp->cinfo.c.dc_huff_tbl_ptrs[1] == NULL || + sp->cinfo.c.ac_huff_tbl_ptrs[0] == NULL || + sp->cinfo.c.ac_huff_tbl_ptrs[1] == NULL)) + { + /* libjpeg-9d no longer initializes default Huffman tables in */ + /* jpeg_set_defaults() */ + TIFF_std_huff_tables(&sp->cinfo.c); + } +#endif - /* Direct libjpeg output to libtiff's output buffer */ - TIFFjpeg_data_dest(sp, tif); + if (!prepare_JPEGTables(tif)) + return (0); + /* Mark the field present */ + /* Can't use TIFFSetField since BEENWRITING is already set! */ + tif->tif_flags |= TIFF_DIRTYDIRECT; + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + } + } + else + { + /* We do not support application-supplied JPEGTables, */ + /* so mark the field not present */ + TIFFClrFieldBit(tif, FIELD_JPEGTABLES); + } - return (1); + /* Direct libjpeg output to libtiff's output buffer */ + TIFFjpeg_data_dest(sp, tif); + + return (1); } /* * Set encoding state at the start of a strip or tile. */ -static int -JPEGPreEncode(TIFF* tif, uint16 s) +static int JPEGPreEncode(TIFF *tif, uint16_t s) { - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGPreEncode"; - uint32 segment_width, segment_height; - int downsampled_input; + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreEncode"; + uint32_t segment_width, segment_height; + int downsampled_input; - assert(sp != NULL); - - if (sp->cinfo.comm.is_decompressor == 1) - { - tif->tif_setupencode( tif ); - } - - assert(!sp->cinfo.comm.is_decompressor); - /* - * Set encoding parameters for this strip/tile. - */ - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - sp->bytesperline = TIFFTileRowSize(tif); - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - sp->bytesperline = TIFFScanlineSize(tif); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { - /* for PC 2, scale down the strip/tile size - * to match a downsampled component - */ - segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); - segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); - } - if (segment_width > 65535 || segment_height > 65535) { - TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG"); - return (0); - } - sp->cinfo.c.image_width = segment_width; - sp->cinfo.c.image_height = segment_height; - downsampled_input = FALSE; - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - sp->cinfo.c.input_components = td->td_samplesperpixel; - if (sp->photometric == PHOTOMETRIC_YCBCR) { - if (sp->jpegcolormode != JPEGCOLORMODE_RGB) { - if (sp->h_sampling != 1 || sp->v_sampling != 1) - downsampled_input = TRUE; - } - if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) - return (0); - /* - * Set Y sampling factors; - * we assume jpeg_set_colorspace() set the rest to 1 - */ - sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; - sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; - } else { - if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space)) - return (0); - /* jpeg_set_colorspace set all sampling factors to 1 */ - } - } else { - if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) - return (0); - sp->cinfo.c.comp_info[0].component_id = s; - /* jpeg_set_colorspace() set sampling factors to 1 */ - if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) { - sp->cinfo.c.comp_info[0].quant_tbl_no = 1; - sp->cinfo.c.comp_info[0].dc_tbl_no = 1; - sp->cinfo.c.comp_info[0].ac_tbl_no = 1; - } - } - /* ensure libjpeg won't write any extraneous markers */ - sp->cinfo.c.write_JFIF_header = FALSE; - sp->cinfo.c.write_Adobe_marker = FALSE; - /* set up table handling correctly */ - /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged */ - /* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT */ - /* mode, so we must manually suppress them. However TIFFjpeg_set_quality() */ - /* should really be called when dealing with files with directories with */ - /* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */ - if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) - return (0); - if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) { - suppress_quant_table(sp, 0); - suppress_quant_table(sp, 1); - } - else { - unsuppress_quant_table(sp, 0); - unsuppress_quant_table(sp, 1); - } - if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) - { - /* Explicit suppression is only needed if we did not go through the */ - /* prepare_JPEGTables() code path, which may be the case if updating */ - /* an existing file */ - suppress_huff_table(sp, 0); - suppress_huff_table(sp, 1); - sp->cinfo.c.optimize_coding = FALSE; - } - else - sp->cinfo.c.optimize_coding = TRUE; - if (downsampled_input) { - /* Need to use raw-data interface to libjpeg */ - sp->cinfo.c.raw_data_in = TRUE; - tif->tif_encoderow = JPEGEncodeRaw; - tif->tif_encodestrip = JPEGEncodeRaw; - tif->tif_encodetile = JPEGEncodeRaw; - } else { - /* Use normal interface to libjpeg */ - sp->cinfo.c.raw_data_in = FALSE; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - } - /* Start JPEG compressor */ - if (!TIFFjpeg_start_compress(sp, FALSE)) - return (0); - /* Allocate downsampled-data buffers if needed */ - if (downsampled_input) { - if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, - sp->cinfo.c.num_components)) - return (0); - } - sp->scancount = 0; + assert(sp != NULL); - return (1); + if (sp->cinfo.comm.is_decompressor == 1) + { + tif->tif_setupencode(tif); + } + + assert(!sp->cinfo.comm.is_decompressor); + /* + * Set encoding parameters for this strip/tile. + */ + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) + { + /* for PC 2, scale down the strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); + } + if (segment_width > 65535 || segment_height > 65535) + { + TIFFErrorExtR(tif, module, "Strip/tile too large for JPEG"); + return (0); + } + sp->cinfo.c.image_width = segment_width; + sp->cinfo.c.image_height = segment_height; + downsampled_input = FALSE; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + sp->cinfo.c.input_components = td->td_samplesperpixel; + if (sp->photometric == PHOTOMETRIC_YCBCR) + { + if (sp->otherSettings.jpegcolormode != JPEGCOLORMODE_RGB) + { + if (sp->h_sampling != 1 || sp->v_sampling != 1) + downsampled_input = TRUE; + } + if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) + return (0); + /* + * Set Y sampling factors; + * we assume jpeg_set_colorspace() set the rest to 1 + */ + sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; + sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; + } + else + { + if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space)) + return (0); + /* jpeg_set_colorspace set all sampling factors to 1 */ + } + } + else + { + if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) + return (0); + sp->cinfo.c.comp_info[0].component_id = s; + /* jpeg_set_colorspace() set sampling factors to 1 */ + if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) + { + sp->cinfo.c.comp_info[0].quant_tbl_no = 1; + sp->cinfo.c.comp_info[0].dc_tbl_no = 1; + sp->cinfo.c.comp_info[0].ac_tbl_no = 1; + } + } + /* ensure libjpeg won't write any extraneous markers */ + sp->cinfo.c.write_JFIF_header = FALSE; + sp->cinfo.c.write_Adobe_marker = FALSE; + /* set up table handling correctly */ + /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged + */ + /* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT + */ + /* mode, so we must manually suppress them. However TIFFjpeg_set_quality() + */ + /* should really be called when dealing with files with directories with */ + /* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */ + if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) + return (0); + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) + { + suppress_quant_table(sp, 0); + suppress_quant_table(sp, 1); + } + else + { + unsuppress_quant_table(sp, 0); + unsuppress_quant_table(sp, 1); + } + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) + { + /* Explicit suppression is only needed if we did not go through the */ + /* prepare_JPEGTables() code path, which may be the case if updating */ + /* an existing file */ + suppress_huff_table(sp, 0); + suppress_huff_table(sp, 1); + sp->cinfo.c.optimize_coding = FALSE; + } + else + sp->cinfo.c.optimize_coding = TRUE; + if (downsampled_input) + { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.c.raw_data_in = TRUE; + tif->tif_encoderow = JPEGEncodeRaw; + tif->tif_encodestrip = JPEGEncodeRaw; + tif->tif_encodetile = JPEGEncodeRaw; + } + else + { + /* Use normal interface to libjpeg */ + sp->cinfo.c.raw_data_in = FALSE; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + } + /* Start JPEG compressor */ + if (!TIFFjpeg_start_compress(sp, FALSE)) + return (0); + /* Allocate downsampled-data buffers if needed */ + if (downsampled_input) + { + if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, + sp->cinfo.c.num_components)) + return (0); + } + sp->scancount = 0; + + return (1); } /* * Encode a chunk of pixels. * "Standard" case: incoming data is not downsampled. */ -static int -JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - JPEGState *sp = JState(tif); - tmsize_t nrows; - JSAMPROW bufptr[1]; - short *line16 = NULL; - int line16_count = 0; + JPEGState *sp = JState(tif); + tmsize_t nrows; + TIFF_JSAMPROW bufptr[1]; + short *line16 = NULL; + int line16_count = 0; - (void) s; - assert(sp != NULL); - /* data is expected to be supplied in multiples of a scanline */ - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "fractional scanline discarded"); + (void)s; + assert(sp != NULL); + /* data is expected to be supplied in multiples of a scanline */ + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded"); - /* The last strip will be limited to image size */ - if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength ) - nrows = tif->tif_dir.td_imagelength - tif->tif_row; + /* The last strip will be limited to image size */ + if (!isTiled(tif) && tif->tif_row + nrows > tif->tif_dir.td_imagelength) + nrows = tif->tif_dir.td_imagelength - tif->tif_row; - if( sp->cinfo.c.data_precision == 12 ) + if (sp->cinfo.c.data_precision == 12) + { + line16_count = (int)((sp->bytesperline * 2) / 3); + line16 = (short *)_TIFFmallocExt(tif, sizeof(short) * line16_count); + if (!line16) { - line16_count = (int)((sp->bytesperline * 2) / 3); - line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count); - if (!line16) - { - TIFFErrorExt(tif->tif_clientdata, - "JPEGEncode", - "Failed to allocate memory"); + TIFFErrorExtR(tif, "JPEGEncode", "Failed to allocate memory"); - return 0; + return 0; + } + } + + while (nrows-- > 0) + { + + if (sp->cinfo.c.data_precision == 12) + { + + int value_pairs = line16_count / 2; + int iPair; + + bufptr[0] = (TIFF_JSAMPROW)line16; + + for (iPair = 0; iPair < value_pairs; iPair++) + { + unsigned char *in_ptr = ((unsigned char *)buf) + iPair * 3; + TIFF_JSAMPLE *out_ptr = (TIFF_JSAMPLE *)(line16 + iPair * 2); + + out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4); + out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2]; } } - - while (nrows-- > 0) { - - if( sp->cinfo.c.data_precision == 12 ) - { - - int value_pairs = line16_count / 2; - int iPair; - - bufptr[0] = (JSAMPROW) line16; - - for( iPair = 0; iPair < value_pairs; iPair++ ) - { - unsigned char *in_ptr = - ((unsigned char *) buf) + iPair * 3; - JSAMPLE *out_ptr = (JSAMPLE *) (line16 + iPair * 2); - - out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4); - out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2]; - } - } - else - { - bufptr[0] = (JSAMPROW) buf; - } - if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) - return (0); - if (nrows > 0) - tif->tif_row++; - buf += sp->bytesperline; - } - - if( sp->cinfo.c.data_precision == 12 ) + else { - _TIFFfree( line16 ); + bufptr[0] = (TIFF_JSAMPROW)buf; } - - return (1); + if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) + return (0); + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; + } + + if (sp->cinfo.c.data_precision == 12) + { + _TIFFfreeExt(tif, line16); + } + + return (1); } /* * Encode a chunk of pixels. * Incoming data is expected to be downsampled per sampling factors. */ -static int -JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - JPEGState *sp = JState(tif); - JSAMPLE* inptr; - JSAMPLE* outptr; - tmsize_t nrows; - JDIMENSION clumps_per_line, nclump; - int clumpoffset, ci, xpos, ypos; - jpeg_component_info* compptr; - int samples_per_clump = sp->samplesperclump; - tmsize_t bytesperclumpline; + JPEGState *sp = JState(tif); + TIFF_JSAMPLE *inptr; + TIFF_JSAMPLE *outptr; + tmsize_t nrows; + JDIMENSION clumps_per_line, nclump; + int clumpoffset, ci, xpos, ypos; + jpeg_component_info *compptr; + int samples_per_clump = sp->samplesperclump; + tmsize_t bytesperclumpline; - (void) s; - assert(sp != NULL); - /* data is expected to be supplied in multiples of a clumpline */ - /* a clumpline is equivalent to v_sampling desubsampled scanlines */ - /* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */ - bytesperclumpline = ((((tmsize_t)sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling) - *((tmsize_t)sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7) - /8; + (void)s; + assert(sp != NULL); + /* data is expected to be supplied in multiples of a clumpline */ + /* a clumpline is equivalent to v_sampling desubsampled scanlines */ + /* TODO: the following calculation of bytesperclumpline, should substitute + * calculation of sp->bytesperline, except that it is per v_sampling lines + */ + bytesperclumpline = + ((((tmsize_t)sp->cinfo.c.image_width + sp->h_sampling - 1) / + sp->h_sampling) * + ((tmsize_t)sp->h_sampling * sp->v_sampling + 2) * + sp->cinfo.c.data_precision + + 7) / + 8; - nrows = ( cc / bytesperclumpline ) * sp->v_sampling; - if (cc % bytesperclumpline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded"); + nrows = (cc / bytesperclumpline) * sp->v_sampling; + if (cc % bytesperclumpline) + TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded"); - /* Cb,Cr both have sampling factors 1, so this is correct */ - clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; + /* Cb,Cr both have sampling factors 1, so this is correct */ + clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; - while (nrows > 0) { - /* - * Fastest way to separate the data is to make one pass - * over the scanline for each row of each component. - */ - clumpoffset = 0; /* first sample in clump */ - for (ci = 0, compptr = sp->cinfo.c.comp_info; - ci < sp->cinfo.c.num_components; - ci++, compptr++) { - int hsamp = compptr->h_samp_factor; - int vsamp = compptr->v_samp_factor; - int padding = (int) (compptr->width_in_blocks * DCTSIZE - - clumps_per_line * hsamp); - for (ypos = 0; ypos < vsamp; ypos++) { - inptr = ((JSAMPLE*) buf) + clumpoffset; - outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; - if (hsamp == 1) { - /* fast path for at least Cb and Cr */ - for (nclump = clumps_per_line; nclump-- > 0; ) { - *outptr++ = inptr[0]; - inptr += samples_per_clump; - } - } else { - /* general case */ - for (nclump = clumps_per_line; nclump-- > 0; ) { - for (xpos = 0; xpos < hsamp; xpos++) - *outptr++ = inptr[xpos]; - inptr += samples_per_clump; - } - } - /* pad each scanline as needed */ - for (xpos = 0; xpos < padding; xpos++) { - *outptr = outptr[-1]; - outptr++; - } - clumpoffset += hsamp; - } - } - sp->scancount++; - if (sp->scancount >= DCTSIZE) { - int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - sp->scancount = 0; - } - tif->tif_row += sp->v_sampling; - buf += bytesperclumpline; - nrows -= sp->v_sampling; - } - return (1); + while (nrows > 0) + { + /* + * Fastest way to separate the data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; ci++, compptr++) + { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + int padding = (int)(compptr->width_in_blocks * DCTSIZE - + clumps_per_line * hsamp); + for (ypos = 0; ypos < vsamp; ypos++) + { + inptr = ((TIFF_JSAMPLE *)buf) + clumpoffset; + outptr = sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; + if (hsamp == 1) + { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0;) + { + *outptr++ = inptr[0]; + inptr += samples_per_clump; + } + } + else + { + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0;) + { + for (xpos = 0; xpos < hsamp; xpos++) + *outptr++ = inptr[xpos]; + inptr += samples_per_clump; + } + } + /* pad each scanline as needed */ + for (xpos = 0; xpos < padding; xpos++) + { + *outptr = outptr[-1]; + outptr++; + } + clumpoffset += hsamp; + } + } + sp->scancount++; + if (sp->scancount >= DCTSIZE) + { + int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + sp->scancount = 0; + } + tif->tif_row += sp->v_sampling; + buf += bytesperclumpline; + nrows -= sp->v_sampling; + } + return (1); } /* * Finish up at the end of a strip or tile. */ -static int -JPEGPostEncode(TIFF* tif) +static int JPEGPostEncode(TIFF *tif) { - JPEGState *sp = JState(tif); + JPEGState *sp = JState(tif); - if (sp->scancount > 0) { - /* - * Need to emit a partial bufferload of downsampled data. - * Pad the data vertically. - */ - int ci, ypos, n; - jpeg_component_info* compptr; + if (sp->scancount > 0) + { + /* + * Need to emit a partial bufferload of downsampled data. + * Pad the data vertically. + */ + int ci, ypos, n; + jpeg_component_info *compptr; - for (ci = 0, compptr = sp->cinfo.c.comp_info; - ci < sp->cinfo.c.num_components; - ci++, compptr++) { - int vsamp = compptr->v_samp_factor; - tmsize_t row_width = compptr->width_in_blocks * DCTSIZE - * sizeof(JSAMPLE); - for (ypos = sp->scancount * vsamp; - ypos < DCTSIZE * vsamp; ypos++) { - _TIFFmemcpy((void*)sp->ds_buffer[ci][ypos], - (void*)sp->ds_buffer[ci][ypos-1], - row_width); + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; ci++, compptr++) + { + int vsamp = compptr->v_samp_factor; + tmsize_t row_width = + compptr->width_in_blocks * DCTSIZE * sizeof(JSAMPLE); + for (ypos = sp->scancount * vsamp; ypos < DCTSIZE * vsamp; ypos++) + { + _TIFFmemcpy((void *)sp->ds_buffer[ci][ypos], + (void *)sp->ds_buffer[ci][ypos - 1], row_width); + } + } + n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + } - } - } - n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - } - - return (TIFFjpeg_finish_compress(JState(tif))); + return (TIFFjpeg_finish_compress(JState(tif))); } -static void -JPEGCleanup(TIFF* tif) +static void JPEGCleanup(TIFF *tif) { - JPEGState *sp = JState(tif); - - assert(sp != 0); + JPEGState *sp = JState(tif); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - tif->tif_tagmethods.printdir = sp->printdir; - if( sp->cinfo_initialized ) - TIFFjpeg_destroy(sp); /* release libjpeg resources */ - if (sp->jpegtables) /* tag value */ - _TIFFfree(sp->jpegtables); - _TIFFfree(tif->tif_data); /* release local state */ - tif->tif_data = NULL; + assert(sp != 0); - _TIFFSetDefaultCompressionState(tif); + tif->tif_tagmethods.vgetfield = sp->otherSettings.vgetparent; + tif->tif_tagmethods.vsetfield = sp->otherSettings.vsetparent; + tif->tif_tagmethods.printdir = sp->otherSettings.printdir; + if (sp->cinfo_initialized) + TIFFjpeg_destroy(sp); /* release libjpeg resources */ + if (sp->otherSettings.jpegtables) /* tag value */ + _TIFFfreeExt(tif, sp->otherSettings.jpegtables); + _TIFFfreeExt(tif, tif->tif_data); /* release local state */ + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); } -static void -JPEGResetUpsampled( TIFF* tif ) +static void JPEGResetUpsampled(TIFF *tif) { - JPEGState* sp = JState(tif); - TIFFDirectory* td = &tif->tif_dir; + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; - /* - * Mark whether returned data is up-sampled or not so TIFFStripSize - * and TIFFTileSize return values that reflect the true amount of - * data. - */ - tif->tif_flags &= ~TIFF_UPSAMPLED; - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - if (td->td_photometric == PHOTOMETRIC_YCBCR && - sp->jpegcolormode == JPEGCOLORMODE_RGB) { - tif->tif_flags |= TIFF_UPSAMPLED; - } else { + /* + * Mark whether returned data is up-sampled or not so TIFFStripSize + * and TIFFTileSize return values that reflect the true amount of + * data. + */ + tif->tif_flags &= ~TIFF_UPSAMPLED; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + if (td->td_photometric == PHOTOMETRIC_YCBCR && + sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) + { + tif->tif_flags |= TIFF_UPSAMPLED; + } + else + { #ifdef notdef - if (td->td_ycbcrsubsampling[0] != 1 || - td->td_ycbcrsubsampling[1] != 1) - ; /* XXX what about up-sampling? */ + if (td->td_ycbcrsubsampling[0] != 1 || + td->td_ycbcrsubsampling[1] != 1) + ; /* XXX what about up-sampling? */ #endif - } - } + } + } - /* - * Must recalculate cached tile size in case sampling state changed. - * Should we really be doing this now if image size isn't set? - */ - if( tif->tif_tilesize > 0 ) - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); - if( tif->tif_scanlinesize > 0 ) - tif->tif_scanlinesize = TIFFScanlineSize(tif); + /* + * Must recalculate cached tile size in case sampling state changed. + * Should we really be doing this now if image size isn't set? + */ + if (tif->tif_tilesize > 0) + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); + if (tif->tif_scanlinesize > 0) + tif->tif_scanlinesize = TIFFScanlineSize(tif); } -static int -JPEGVSetField(TIFF* tif, uint32 tag, va_list ap) +static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap) { - JPEGState* sp = JState(tif); - const TIFFField* fip; - uint32 v32; + JPEGState *sp = JState(tif); + const TIFFField *fip; + uint32_t v32; - assert(sp != NULL); + assert(sp != NULL); - switch (tag) { - case TIFFTAG_JPEGTABLES: - v32 = (uint32) va_arg(ap, uint32); - if (v32 == 0) { - /* XXX */ - return (0); - } - _TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*), v32); - sp->jpegtables_length = v32; - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); - break; - case TIFFTAG_JPEGQUALITY: - sp->jpegquality = (int) va_arg(ap, int); - return (1); /* pseudo tag */ - case TIFFTAG_JPEGCOLORMODE: - sp->jpegcolormode = (int) va_arg(ap, int); - JPEGResetUpsampled( tif ); - return (1); /* pseudo tag */ - case TIFFTAG_PHOTOMETRIC: - { - int ret_value = (*sp->vsetparent)(tif, tag, ap); - JPEGResetUpsampled( tif ); - return ret_value; - } - case TIFFTAG_JPEGTABLESMODE: - sp->jpegtablesmode = (int) va_arg(ap, int); - return (1); /* pseudo tag */ - case TIFFTAG_YCBCRSUBSAMPLING: - /* mark the fact that we have a real ycbcrsubsampling! */ - sp->ycbcrsampling_fetched = 1; - /* should we be recomputing upsampling info here? */ - return (*sp->vsetparent)(tif, tag, ap); - default: - return (*sp->vsetparent)(tif, tag, ap); - } + switch (tag) + { + case TIFFTAG_JPEGTABLES: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 == 0) + { + /* XXX */ + return (0); + } + _TIFFsetByteArrayExt(tif, &sp->otherSettings.jpegtables, + va_arg(ap, void *), v32); + sp->otherSettings.jpegtables_length = v32; + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + break; + case TIFFTAG_JPEGQUALITY: + sp->otherSettings.jpegquality = (int)va_arg(ap, int); + return (1); /* pseudo tag */ + case TIFFTAG_JPEGCOLORMODE: + sp->otherSettings.jpegcolormode = (int)va_arg(ap, int); + JPEGResetUpsampled(tif); + return (1); /* pseudo tag */ + case TIFFTAG_PHOTOMETRIC: + { + int ret_value = (*sp->otherSettings.vsetparent)(tif, tag, ap); + JPEGResetUpsampled(tif); + return ret_value; + } + case TIFFTAG_JPEGTABLESMODE: + sp->otherSettings.jpegtablesmode = (int)va_arg(ap, int); + return (1); /* pseudo tag */ + case TIFFTAG_YCBCRSUBSAMPLING: + /* mark the fact that we have a real ycbcrsubsampling! */ + sp->otherSettings.ycbcrsampling_fetched = 1; + /* should we be recomputing upsampling info here? */ + return (*sp->otherSettings.vsetparent)(tif, tag, ap); + default: + return (*sp->otherSettings.vsetparent)(tif, tag, ap); + } - if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) { - TIFFSetFieldBit(tif, fip->field_bit); - } else { - return (0); - } + if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) + { + TIFFSetFieldBit(tif, fip->field_bit); + } + else + { + return (0); + } - tif->tif_flags |= TIFF_DIRTYDIRECT; - return (1); + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); } -static int -JPEGVGetField(TIFF* tif, uint32 tag, va_list ap) +static int JPEGVGetField(TIFF *tif, uint32_t tag, va_list ap) { - JPEGState* sp = JState(tif); + JPEGState *sp = JState(tif); - assert(sp != NULL); + assert(sp != NULL); - switch (tag) { - case TIFFTAG_JPEGTABLES: - *va_arg(ap, uint32*) = sp->jpegtables_length; - *va_arg(ap, const void**) = sp->jpegtables; - break; - case TIFFTAG_JPEGQUALITY: - *va_arg(ap, int*) = sp->jpegquality; - break; - case TIFFTAG_JPEGCOLORMODE: - *va_arg(ap, int*) = sp->jpegcolormode; - break; - case TIFFTAG_JPEGTABLESMODE: - *va_arg(ap, int*) = sp->jpegtablesmode; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); + switch (tag) + { + case TIFFTAG_JPEGTABLES: + *va_arg(ap, uint32_t *) = sp->otherSettings.jpegtables_length; + *va_arg(ap, const void **) = sp->otherSettings.jpegtables; + break; + case TIFFTAG_JPEGQUALITY: + *va_arg(ap, int *) = sp->otherSettings.jpegquality; + break; + case TIFFTAG_JPEGCOLORMODE: + *va_arg(ap, int *) = sp->otherSettings.jpegcolormode; + break; + case TIFFTAG_JPEGTABLESMODE: + *va_arg(ap, int *) = sp->otherSettings.jpegtablesmode; + break; + default: + return (*sp->otherSettings.vgetparent)(tif, tag, ap); + } + return (1); } -static void -JPEGPrintDir(TIFF* tif, FILE* fd, long flags) +static void JPEGPrintDir(TIFF *tif, FILE *fd, long flags) { - JPEGState* sp = JState(tif); + JPEGState *sp = JState(tif); - assert(sp != NULL); - (void) flags; + assert(sp != NULL); + (void)flags; - if( sp != NULL ) { - if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) - fprintf(fd, " JPEG Tables: (%lu bytes)\n", - (unsigned long) sp->jpegtables_length); - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); - } + if (sp != NULL) + { + if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) + fprintf(fd, " JPEG Tables: (%" PRIu32 " bytes)\n", + sp->otherSettings.jpegtables_length); + if (sp->otherSettings.printdir) + (*sp->otherSettings.printdir)(tif, fd, flags); + } } -static uint32 -JPEGDefaultStripSize(TIFF* tif, uint32 s) +static uint32_t JPEGDefaultStripSize(TIFF *tif, uint32_t s) { - JPEGState* sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; - s = (*sp->defsparent)(tif, s); - if (s < td->td_imagelength) - s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE); - return (s); + s = (*sp->otherSettings.defsparent)(tif, s); + if (s < td->td_imagelength) + s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE); + return (s); } -static void -JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) +static void JPEGDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) { - JPEGState* sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; - (*sp->deftparent)(tif, tw, th); - *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); - *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); + (*sp->otherSettings.deftparent)(tif, tw, th); + *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); + *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); } /* * The JPEG library initialized used to be done in TIFFInitJPEG(), but * now that we allow a TIFF file to be opened in update mode it is necessary * to have some way of deciding whether compression or decompression is - * desired other than looking at tif->tif_mode. We accomplish this by + * desired other than looking at tif->tif_mode. We accomplish this by * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry. - * If so, we assume decompression is desired. + * If so, we assume decompression is desired. * * This is tricky, because TIFFInitJPEG() is called while the directory is * being read, and generally speaking the BYTECOUNTS tag won't have been read * at that point. So we try to defer jpeg library initialization till we * do have that tag ... basically any access that might require the compressor - * or decompressor that occurs after the reading of the directory. + * or decompressor that occurs after the reading of the directory. * * In an ideal world compressors or decompressors would be setup * at the point where a single tile or strip was accessed (for read or write) @@ -2429,16 +2719,16 @@ JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) * NFW, Feb 3rd, 2003. */ -static int JPEGInitializeLibJPEG( TIFF * tif, int decompress ) +static int JPEGInitializeLibJPEG(TIFF *tif, int decompress) { - JPEGState* sp = JState(tif); + JPEGState *sp = JState(tif); - if(sp->cinfo_initialized) + if (sp->cinfo_initialized) { - if( !decompress && sp->cinfo.comm.is_decompressor ) - TIFFjpeg_destroy( sp ); - else if( decompress && !sp->cinfo.comm.is_decompressor ) - TIFFjpeg_destroy( sp ); + if (!decompress && sp->cinfo.comm.is_decompressor) + TIFFjpeg_destroy(sp); + else if (decompress && !sp->cinfo.comm.is_decompressor) + TIFFjpeg_destroy(sp); else return 1; @@ -2448,29 +2738,36 @@ static int JPEGInitializeLibJPEG( TIFF * tif, int decompress ) /* * Initialize libjpeg. */ - if ( decompress ) { + if (decompress) + { if (!TIFFjpeg_create_decompress(sp)) return (0); - } else { + } + else + { if (!TIFFjpeg_create_compress(sp)) return (0); #ifndef TIFF_JPEG_MAX_MEMORY_TO_USE #define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024) #endif /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */ - /* store implementation, so better not set max_memory_to_use ourselves. */ + /* store implementation, so better not set max_memory_to_use ourselves. + */ /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */ - if( sp->cinfo.c.mem->max_memory_to_use > 0 ) + if (sp->cinfo.c.mem->max_memory_to_use > 0) { /* This is to address bug related in ticket GDAL #1795. */ if (getenv("JPEGMEM") == NULL) { - /* Increase the max memory usable. This helps when creating files */ + /* Increase the max memory usable. This helps when creating + * files */ /* with "big" tile, without using libjpeg temporary files. */ /* For example a 512x512 tile with 3 bands */ /* requires 1.5 MB which is above libjpeg 1MB default */ - if( sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE ) - sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE; + if (sp->cinfo.c.mem->max_memory_to_use < + TIFF_JPEG_MAX_MEMORY_TO_USE) + sp->cinfo.c.mem->max_memory_to_use = + TIFF_JPEG_MAX_MEMORY_TO_USE; } } } @@ -2480,124 +2777,124 @@ static int JPEGInitializeLibJPEG( TIFF * tif, int decompress ) return 1; } -int -TIFFInitJPEG(TIFF* tif, int scheme) +/* Common to tif_jpeg.c and tif_jpeg_12.c */ +static void TIFFInitJPEGCommon(TIFF *tif) { - JPEGState* sp; + JPEGState *sp; - (void)scheme; - assert(scheme == COMPRESSION_JPEG); + sp = JState(tif); + sp->tif = tif; /* back link */ - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) { - TIFFErrorExt(tif->tif_clientdata, - "TIFFInitJPEG", - "Merging JPEG codec-specific tags failed"); - return 0; - } + /* Default values for codec-specific fields */ + sp->otherSettings.jpegtables = NULL; + sp->otherSettings.jpegtables_length = 0; + sp->otherSettings.jpegquality = 75; /* Default IJG quality */ + sp->otherSettings.jpegcolormode = JPEGCOLORMODE_RAW; + sp->otherSettings.jpegtablesmode = + JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; + sp->otherSettings.ycbcrsampling_fetched = 0; - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8*) _TIFFmalloc(sizeof (JPEGState)); + tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ + tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ + tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ - if (tif->tif_data == NULL) { - TIFFErrorExt(tif->tif_clientdata, - "TIFFInitJPEG", "No space for JPEG state block"); - return 0; - } - _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); + /* + * Install codec methods. + */ + tif->tif_fixuptags = JPEGFixupTags; + tif->tif_setupdecode = JPEGSetupDecode; + tif->tif_predecode = JPEGPreDecode; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + tif->tif_setupencode = JPEGSetupEncode; + tif->tif_preencode = JPEGPreEncode; + tif->tif_postencode = JPEGPostEncode; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + tif->tif_cleanup = JPEGCleanup; - sp = JState(tif); - sp->tif = tif; /* back link */ + tif->tif_defstripsize = JPEGDefaultStripSize; + tif->tif_deftilesize = JPEGDefaultTileSize; + tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ + sp->cinfo_initialized = FALSE; +} - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ - sp->printdir = tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ +int TIFFInitJPEG(TIFF *tif, int scheme) +{ + JPEGState *sp; - /* Default values for codec-specific fields */ - sp->jpegtables = NULL; - sp->jpegtables_length = 0; - sp->jpegquality = 75; /* Default IJG quality */ - sp->jpegcolormode = JPEGCOLORMODE_RAW; - sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; - sp->ycbcrsampling_fetched = 0; + (void)scheme; + assert(scheme == COMPRESSION_JPEG); - /* - * Install codec methods. - */ - tif->tif_fixuptags = JPEGFixupTags; - tif->tif_setupdecode = JPEGSetupDecode; - tif->tif_predecode = JPEGPreDecode; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - tif->tif_setupencode = JPEGSetupEncode; - tif->tif_preencode = JPEGPreEncode; - tif->tif_postencode = JPEGPostEncode; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - tif->tif_cleanup = JPEGCleanup; - sp->defsparent = tif->tif_defstripsize; - tif->tif_defstripsize = JPEGDefaultStripSize; - sp->deftparent = tif->tif_deftilesize; - tif->tif_deftilesize = JPEGDefaultTileSize; - tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) + { + TIFFErrorExtR(tif, "TIFFInitJPEG", + "Merging JPEG codec-specific tags failed"); + return 0; + } - sp->cinfo_initialized = FALSE; + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(JPEGState)); - /* - ** Create a JPEGTables field if no directory has yet been created. - ** We do this just to ensure that sufficient space is reserved for - ** the JPEGTables field. It will be properly created the right - ** size later. - */ - if( tif->tif_diroff == 0 ) - { + if (tif->tif_data == NULL) + { + TIFFErrorExtR(tif, "TIFFInitJPEG", "No space for JPEG state block"); + return 0; + } + _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); + + sp = JState(tif); + /* + * Override parent get/set field methods. + */ + sp->otherSettings.vgetparent = tif->tif_tagmethods.vgetfield; + sp->otherSettings.vsetparent = tif->tif_tagmethods.vsetfield; + sp->otherSettings.printdir = tif->tif_tagmethods.printdir; + + sp->otherSettings.defsparent = tif->tif_defstripsize; + sp->otherSettings.deftparent = tif->tif_deftilesize; + + TIFFInitJPEGCommon(tif); + + /* + ** Create a JPEGTables field if no directory has yet been created. + ** We do this just to ensure that sufficient space is reserved for + ** the JPEGTables field. It will be properly created the right + ** size later. + */ + if (tif->tif_diroff == 0) + { #define SIZE_OF_JPEGTABLES 2000 -/* -The following line assumes incorrectly that all JPEG-in-TIFF files will have -a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be written -when the JPEG data is placed with TIFFWriteRawStrip. The field bit should be -set, anyway, later when actual JPEGTABLES header is generated, so removing it -here hopefully is harmless. - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); -*/ - sp->jpegtables_length = SIZE_OF_JPEGTABLES; - sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length); - if (sp->jpegtables) - { - _TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES); - } - else - { - TIFFErrorExt(tif->tif_clientdata, - "TIFFInitJPEG", - "Failed to allocate memory for JPEG tables"); - return 0; - } -#undef SIZE_OF_JPEGTABLES + /* + The following line assumes incorrectly that all JPEG-in-TIFF files will + have a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags + to be written when the JPEG data is placed with TIFFWriteRawStrip. The + field bit should be set, anyway, later when actual JPEGTABLES header is + generated, so removing it here hopefully is harmless. + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + */ + sp->otherSettings.jpegtables_length = SIZE_OF_JPEGTABLES; + sp->otherSettings.jpegtables = + (void *)_TIFFmallocExt(tif, sp->otherSettings.jpegtables_length); + if (sp->otherSettings.jpegtables) + { + _TIFFmemset(sp->otherSettings.jpegtables, 0, SIZE_OF_JPEGTABLES); } - - return 1; + else + { + TIFFErrorExtR(tif, "TIFFInitJPEG", + "Failed to allocate memory for JPEG tables"); + return 0; + } +#undef SIZE_OF_JPEGTABLES + } + return 1; } #endif /* JPEG_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_jpeg_12.c b/3rdparty/libtiff/tif_jpeg_12.c index b458c25899..406e1cfc31 100644 --- a/3rdparty/libtiff/tif_jpeg_12.c +++ b/3rdparty/libtiff/tif_jpeg_12.c @@ -1,69 +1,63 @@ #include "tiffiop.h" +#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) +#define JPEG_DUAL_MODE_8_12 +#endif + #if defined(JPEG_DUAL_MODE_8_12) -# define TIFFInitJPEG TIFFInitJPEG_12 -# define TIFFJPEGIsFullStripRequired TIFFJPEGIsFullStripRequired_12 +#define FROM_TIF_JPEG_12 -int -TIFFInitJPEG_12(TIFF* tif, int scheme); +#ifdef TIFFInitJPEG +#undef TIFFInitJPEG +#endif +#define TIFFInitJPEG TIFFInitJPEG_12 -# include LIBJPEG_12_PATH +#ifdef TIFFJPEGIsFullStripRequired +#undef TIFFJPEGIsFullStripRequired +#endif +#define TIFFJPEGIsFullStripRequired TIFFJPEGIsFullStripRequired_12 -# include "tif_jpeg.c" +int TIFFInitJPEG_12(TIFF *tif, int scheme); -int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ) +#if !defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) +#include LIBJPEG_12_PATH +#endif +#include "tif_jpeg.c" + +int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings, + int scheme, int is_encode) { - JPEGState* sp; + JPEGState *sp; + uint8_t *new_tif_data; + (void)scheme; assert(scheme == COMPRESSION_JPEG); + new_tif_data = + (uint8_t *)_TIFFreallocExt(tif, tif->tif_data, sizeof(JPEGState)); + + if (new_tif_data == NULL) + { + TIFFErrorExtR(tif, "TIFFReInitJPEG_12", + "No space for JPEG state block"); + return 0; + } + + tif->tif_data = new_tif_data; + _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); + + TIFFInitJPEGCommon(tif); + sp = JState(tif); - sp->tif = tif; /* back link */ + sp->otherSettings = *otherSettings; - /* - * Override parent get/set field methods. - */ - tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ - tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ - tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ - - /* - * Install codec methods. - */ - tif->tif_fixuptags = JPEGFixupTags; - tif->tif_setupdecode = JPEGSetupDecode; - tif->tif_predecode = JPEGPreDecode; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - tif->tif_setupencode = JPEGSetupEncode; - tif->tif_preencode = JPEGPreEncode; - tif->tif_postencode = JPEGPostEncode; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - tif->tif_cleanup = JPEGCleanup; - tif->tif_defstripsize = JPEGDefaultStripSize; - tif->tif_deftilesize = JPEGDefaultTileSize; - tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ - - sp->cinfo_initialized = FALSE; - - if( is_encode ) + if (is_encode) return JPEGSetupEncode(tif); else return JPEGSetupDecode(tif); } #endif /* defined(JPEG_DUAL_MODE_8_12) */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_lerc.c b/3rdparty/libtiff/tif_lerc.c new file mode 100644 index 0000000000..4f357a6011 --- /dev/null +++ b/3rdparty/libtiff/tif_lerc.c @@ -0,0 +1,1206 @@ +/* + * Copyright (c) 2018, Even Rouault + * Author: + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef LERC_SUPPORT +/* + * TIFF Library. + * + * LERC Compression Support + * + */ + +#include "Lerc_c_api.h" +#include "zlib.h" +#ifdef ZSTD_SUPPORT +#include "zstd.h" +#endif + +#if LIBDEFLATE_SUPPORT +#include "libdeflate.h" +#endif +#define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12 + +#include + +#define LSTATE_INIT_DECODE 0x01 +#define LSTATE_INIT_ENCODE 0x02 + +#ifndef LERC_AT_LEAST_VERSION +#define LERC_AT_LEAST_VERSION(maj, min, patch) 0 +#endif + +/* + * State block for each open TIFF file using LERC compression/decompression. + */ +typedef struct +{ + double maxzerror; /* max z error */ + int lerc_version; + int additional_compression; + int zstd_compress_level; /* zstd */ + int zipquality; /* deflate */ + int state; /* state flags */ + + uint32_t segment_width; + uint32_t segment_height; + + unsigned int uncompressed_size; + unsigned int uncompressed_alloc; + uint8_t *uncompressed_buffer; + unsigned int uncompressed_offset; + + unsigned int mask_size; + uint8_t *mask_buffer; + + unsigned int compressed_size; + void *compressed_buffer; + +#if LIBDEFLATE_SUPPORT + struct libdeflate_decompressor *libdeflate_dec; + struct libdeflate_compressor *libdeflate_enc; +#endif + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +} LERCState; + +#define LState(tif) ((LERCState *)(tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) + +static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); + +static int LERCFixupTags(TIFF *tif) +{ + (void)tif; + return 1; +} + +static int LERCSetupDecode(TIFF *tif) +{ + LERCState *sp = DecoderState(tif); + + assert(sp != NULL); + + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) + { + sp->state = 0; + } + + sp->state |= LSTATE_INIT_DECODE; + return 1; +} + +static int GetLercDataType(TIFF *tif) +{ + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "GetLercDataType"; + + if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 8) + { + return 0; + } + + if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 8) + { + return 1; + } + + if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 16) + { + return 2; + } + + if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 16) + { + return 3; + } + + if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 32) + { + return 4; + } + + if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 32) + { + return 5; + } + + if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && + td->td_bitspersample == 32) + { + return 6; + } + + if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && + td->td_bitspersample == 64) + { + return 7; + } + + TIFFErrorExtR( + tif, module, + "Unsupported combination of SampleFormat and td_bitspersample"); + return -1; +} + +static int SetupUncompressedBuffer(TIFF *tif, LERCState *sp, const char *module) +{ + TIFFDirectory *td = &tif->tif_dir; + uint64_t new_size_64; + uint64_t new_alloc_64; + unsigned int new_size; + unsigned int new_alloc; + + sp->uncompressed_offset = 0; + + if (isTiled(tif)) + { + sp->segment_width = td->td_tilewidth; + sp->segment_height = td->td_tilelength; + } + else + { + sp->segment_width = td->td_imagewidth; + sp->segment_height = td->td_imagelength - tif->tif_row; + if (sp->segment_height > td->td_rowsperstrip) + sp->segment_height = td->td_rowsperstrip; + } + + new_size_64 = (uint64_t)sp->segment_width * sp->segment_height * + (td->td_bitspersample / 8); + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + new_size_64 *= td->td_samplesperpixel; + } + + new_size = (unsigned int)new_size_64; + sp->uncompressed_size = new_size; + + /* add some margin as we are going to use it also to store deflate/zstd + * compressed data */ + new_alloc_64 = 100 + new_size_64 + new_size_64 / 3; +#ifdef ZSTD_SUPPORT + { + size_t zstd_max = ZSTD_compressBound((size_t)new_size_64); + if (new_alloc_64 < zstd_max) + { + new_alloc_64 = zstd_max; + } + } +#endif + new_alloc = (unsigned int)new_alloc_64; + if (new_alloc != new_alloc_64) + { + TIFFErrorExtR(tif, module, "Too large uncompressed strip/tile"); + _TIFFfreeExt(tif, sp->uncompressed_buffer); + sp->uncompressed_buffer = 0; + sp->uncompressed_alloc = 0; + return 0; + } + + if (sp->uncompressed_alloc < new_alloc) + { + _TIFFfreeExt(tif, sp->uncompressed_buffer); + sp->uncompressed_buffer = _TIFFmallocExt(tif, new_alloc); + if (!sp->uncompressed_buffer) + { + TIFFErrorExtR(tif, module, "Cannot allocate buffer"); + _TIFFfreeExt(tif, sp->uncompressed_buffer); + sp->uncompressed_buffer = 0; + sp->uncompressed_alloc = 0; + return 0; + } + sp->uncompressed_alloc = new_alloc; + } + + if ((td->td_planarconfig == PLANARCONFIG_CONTIG && + td->td_extrasamples > 0 && + td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && + GetLercDataType(tif) == 1) || + (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && + (td->td_planarconfig == PLANARCONFIG_SEPARATE || + td->td_samplesperpixel == 1) && + (td->td_bitspersample == 32 || td->td_bitspersample == 64))) + { + unsigned int mask_size = sp->segment_width * sp->segment_height; + if (sp->mask_size < mask_size) + { + void *mask_buffer = + _TIFFreallocExt(tif, sp->mask_buffer, mask_size); + if (mask_buffer == NULL) + { + TIFFErrorExtR(tif, module, "Cannot allocate buffer"); + sp->mask_size = 0; + _TIFFfreeExt(tif, sp->uncompressed_buffer); + sp->uncompressed_buffer = 0; + sp->uncompressed_alloc = 0; + return 0; + } + sp->mask_buffer = (uint8_t *)mask_buffer; + sp->mask_size = mask_size; + } + } + + return 1; +} + +/* + * Setup state for decoding a strip. + */ +static int LERCPreDecode(TIFF *tif, uint16_t s) +{ + static const char module[] = "LERCPreDecode"; + lerc_status lerc_ret; + TIFFDirectory *td = &tif->tif_dir; + LERCState *sp = DecoderState(tif); + int lerc_data_type; + unsigned int infoArray[8]; + unsigned nomask_bands = td->td_samplesperpixel; + int ndims; + int use_mask = 0; + uint8_t *lerc_data = tif->tif_rawcp; + unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc; + + (void)s; + assert(sp != NULL); + if (sp->state != LSTATE_INIT_DECODE) + tif->tif_setupdecode(tif); + + lerc_data_type = GetLercDataType(tif); + if (lerc_data_type < 0) + return 0; + + if (!SetupUncompressedBuffer(tif, sp, module)) + return 0; + + if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE) + { + if (sp->compressed_size < sp->uncompressed_alloc) + { + _TIFFfreeExt(tif, sp->compressed_buffer); + sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc); + if (!sp->compressed_buffer) + { + sp->compressed_size = 0; + return 0; + } + sp->compressed_size = sp->uncompressed_alloc; + } + } + + if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE) + { +#if LIBDEFLATE_SUPPORT + enum libdeflate_result res; + size_t lerc_data_sizet = 0; + if (sp->libdeflate_dec == NULL) + { + sp->libdeflate_dec = libdeflate_alloc_decompressor(); + if (sp->libdeflate_dec == NULL) + { + TIFFErrorExtR(tif, module, "Cannot allocate decompressor"); + return 0; + } + } + + res = libdeflate_zlib_decompress( + sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc, + sp->compressed_buffer, sp->compressed_size, &lerc_data_sizet); + if (res != LIBDEFLATE_SUCCESS) + { + TIFFErrorExtR(tif, module, "Decoding error at scanline %lu", + (unsigned long)tif->tif_row); + return 0; + } + assert(lerc_data_sizet == (unsigned int)lerc_data_sizet); + lerc_data = sp->compressed_buffer; + lerc_data_size = (unsigned int)lerc_data_sizet; +#else + z_stream strm; + int zlib_ret; + + memset(&strm, 0, sizeof(strm)); + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; + zlib_ret = inflateInit(&strm); + if (zlib_ret != Z_OK) + { + TIFFErrorExtR(tif, module, "inflateInit() failed"); + inflateEnd(&strm); + return 0; + } + + strm.avail_in = (uInt)tif->tif_rawcc; + strm.next_in = tif->tif_rawcp; + strm.avail_out = sp->compressed_size; + strm.next_out = sp->compressed_buffer; + zlib_ret = inflate(&strm, Z_FINISH); + if (zlib_ret != Z_STREAM_END && zlib_ret != Z_OK) + { + TIFFErrorExtR(tif, module, "inflate() failed"); + inflateEnd(&strm); + return 0; + } + lerc_data = sp->compressed_buffer; + lerc_data_size = sp->compressed_size - strm.avail_out; + inflateEnd(&strm); +#endif + } + else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD) + { +#ifdef ZSTD_SUPPORT + size_t zstd_ret; + + zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size, + tif->tif_rawcp, tif->tif_rawcc); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + + lerc_data = sp->compressed_buffer; + lerc_data_size = (unsigned int)zstd_ret; +#else + TIFFErrorExtR(tif, module, "ZSTD support missing"); + return 0; +#endif + } + else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE) + { + TIFFErrorExtR(tif, module, "Unhandled additional compression"); + return 0; + } + + lerc_ret = + lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 8, 0); + if (lerc_ret != 0) + { + TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed"); + return 0; + } + + /* If the configuration is compatible of a LERC mask, and that the */ + /* LERC info has dim == samplesperpixel - 1, then there is a LERC */ + /* mask. */ + if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 && + td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && + GetLercDataType(tif) == 1 && + infoArray[2] == td->td_samplesperpixel - 1U) + { + use_mask = 1; + nomask_bands--; + } + else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && + (td->td_planarconfig == PLANARCONFIG_SEPARATE || + td->td_samplesperpixel == 1) && + (td->td_bitspersample == 32 || td->td_bitspersample == 64)) + { + use_mask = 1; + } + + ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1; + + /* Info returned in infoArray is { version, dataType, nDim, nCols, + nRows, nBands, nValidPixels, blobSize } */ + if (infoArray[0] != (unsigned)sp->lerc_version) + { + TIFFWarningExtR(tif, module, + "Unexpected version number: %d. Expected: %d", + infoArray[0], sp->lerc_version); + } + if (infoArray[1] != (unsigned)lerc_data_type) + { + TIFFErrorExtR(tif, module, "Unexpected dataType: %d. Expected: %d", + infoArray[1], lerc_data_type); + return 0; + } + if (infoArray[2] != (unsigned)ndims) + { + TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: %d", + infoArray[2], ndims); + return 0; + } + if (infoArray[3] != sp->segment_width) + { + TIFFErrorExtR(tif, module, "Unexpected nCols: %d. Expected: %du", + infoArray[3], sp->segment_width); + return 0; + } + if (infoArray[4] != sp->segment_height) + { + TIFFErrorExtR(tif, module, "Unexpected nRows: %d. Expected: %u", + infoArray[4], sp->segment_height); + return 0; + } + if (infoArray[5] != 1) + { + TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d", + infoArray[5], 1); + return 0; + } + if (infoArray[7] != lerc_data_size) + { + TIFFErrorExtR(tif, module, "Unexpected blobSize: %d. Expected: %u", + infoArray[7], lerc_data_size); + return 0; + } + + lerc_ret = lerc_decode(lerc_data, lerc_data_size, +#if LERC_AT_LEAST_VERSION(3, 0, 0) + use_mask ? 1 : 0, +#endif + use_mask ? sp->mask_buffer : NULL, ndims, + sp->segment_width, sp->segment_height, 1, + lerc_data_type, sp->uncompressed_buffer); + if (lerc_ret != 0) + { + TIFFErrorExtR(tif, module, "lerc_decode() failed"); + return 0; + } + + /* Interleave alpha mask with other samples. */ + if (use_mask && GetLercDataType(tif) == 1) + { + unsigned src_stride = + (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); + unsigned dst_stride = + td->td_samplesperpixel * (td->td_bitspersample / 8); + unsigned i = sp->segment_width * sp->segment_height; + /* Operate from end to begin to be able to move in place */ + while (i > 0 && i > nomask_bands) + { + i--; + sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel - + 1] = 255 * sp->mask_buffer[i]; + memcpy(sp->uncompressed_buffer + i * dst_stride, + sp->uncompressed_buffer + i * src_stride, src_stride); + } + /* First pixels must use memmove due to overlapping areas */ + while (i > 0) + { + i--; + sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel - + 1] = 255 * sp->mask_buffer[i]; + memmove(sp->uncompressed_buffer + i * dst_stride, + sp->uncompressed_buffer + i * src_stride, src_stride); + } + } + else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP) + { + const unsigned nb_pixels = sp->segment_width * sp->segment_height; + unsigned i; +#if WORDS_BIGENDIAN + const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0}; +#else + const unsigned char nan_bytes[] = {0, 0, 0xc0, 0x7f}; +#endif + float nan_float32; + memcpy(&nan_float32, nan_bytes, 4); + + if (td->td_bitspersample == 32) + { + for (i = 0; i < nb_pixels; i++) + { + if (sp->mask_buffer[i] == 0) + ((float *)sp->uncompressed_buffer)[i] = nan_float32; + } + } + else + { + const double nan_float64 = nan_float32; + for (i = 0; i < nb_pixels; i++) + { + if (sp->mask_buffer[i] == 0) + ((double *)sp->uncompressed_buffer)[i] = nan_float64; + } + } + } + + return 1; +} + +/* + * Decode a strip, tile or scanline. + */ +static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) +{ + static const char module[] = "LERCDecode"; + LERCState *sp = DecoderState(tif); + + (void)s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + if (sp->uncompressed_buffer == 0) + { + TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated"); + return 0; + } + + if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ > + sp->uncompressed_size) + { + TIFFErrorExtR(tif, module, "Too many bytes read"); + return 0; + } + + memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, occ); + sp->uncompressed_offset += (unsigned)occ; + + return 1; +} + +static int LERCSetupEncode(TIFF *tif) +{ + LERCState *sp = EncoderState(tif); + + assert(sp != NULL); + if (sp->state & LSTATE_INIT_DECODE) + { + sp->state = 0; + } + + sp->state |= LSTATE_INIT_ENCODE; + + return 1; +} + +/* + * Reset encoding state at the start of a strip. + */ +static int LERCPreEncode(TIFF *tif, uint16_t s) +{ + static const char module[] = "LERCPreEncode"; + LERCState *sp = EncoderState(tif); + int lerc_data_type; + + (void)s; + assert(sp != NULL); + if (sp->state != LSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); + + lerc_data_type = GetLercDataType(tif); + if (lerc_data_type < 0) + return 0; + + if (!SetupUncompressedBuffer(tif, sp, module)) + return 0; + + return 1; +} + +/* + * Encode a chunk of pixels. + */ +static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) +{ + static const char module[] = "LERCEncode"; + LERCState *sp = EncoderState(tif); + + (void)s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); + + if ((uint64_t)sp->uncompressed_offset + (uint64_t)cc > + sp->uncompressed_size) + { + TIFFErrorExtR(tif, module, "Too many bytes written"); + return 0; + } + + memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc); + sp->uncompressed_offset += (unsigned)cc; + + return 1; +} + +/* + * Finish off an encoded strip by flushing it. + */ +static int LERCPostEncode(TIFF *tif) +{ + lerc_status lerc_ret; + static const char module[] = "LERCPostEncode"; + LERCState *sp = EncoderState(tif); + unsigned int numBytes = 0; + unsigned int numBytesWritten = 0; + TIFFDirectory *td = &tif->tif_dir; + int use_mask = 0; + unsigned dst_nbands = td->td_samplesperpixel; + + if (sp->uncompressed_offset != sp->uncompressed_size) + { + TIFFErrorExtR(tif, module, "Unexpected number of bytes in the buffer"); + return 0; + } + + /* Extract alpha mask (if containing only 0 and 255 values, */ + /* and compact array of regular bands */ + if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 && + td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && + GetLercDataType(tif) == 1) + { + const unsigned dst_stride = + (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); + const unsigned src_stride = + td->td_samplesperpixel * (td->td_bitspersample / 8); + unsigned i = 0; + const unsigned nb_pixels = sp->segment_width * sp->segment_height; + + use_mask = 1; + for (i = 0; i < nb_pixels; i++) + { + int v = sp->uncompressed_buffer[i * src_stride + + td->td_samplesperpixel - 1]; + if (v != 0 && v != 255) + { + use_mask = 0; + break; + } + } + + if (use_mask) + { + dst_nbands--; + /* First pixels must use memmove due to overlapping areas */ + for (i = 0; i < dst_nbands && i < nb_pixels; i++) + { + memmove(sp->uncompressed_buffer + i * dst_stride, + sp->uncompressed_buffer + i * src_stride, dst_stride); + sp->mask_buffer[i] = + sp->uncompressed_buffer[i * src_stride + + td->td_samplesperpixel - 1]; + } + for (; i < nb_pixels; i++) + { + memcpy(sp->uncompressed_buffer + i * dst_stride, + sp->uncompressed_buffer + i * src_stride, dst_stride); + sp->mask_buffer[i] = + sp->uncompressed_buffer[i * src_stride + + td->td_samplesperpixel - 1]; + } + } + } + else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && + (td->td_planarconfig == PLANARCONFIG_SEPARATE || + dst_nbands == 1) && + (td->td_bitspersample == 32 || td->td_bitspersample == 64)) + { + /* Check for NaN values */ + unsigned i; + const unsigned nb_pixels = sp->segment_width * sp->segment_height; + if (td->td_bitspersample == 32) + { + for (i = 0; i < nb_pixels; i++) + { + const float val = ((float *)sp->uncompressed_buffer)[i]; + if (val != val) + { + use_mask = 1; + break; + } + } + } + else + { + for (i = 0; i < nb_pixels; i++) + { + const double val = ((double *)sp->uncompressed_buffer)[i]; + if (val != val) + { + use_mask = 1; + break; + } + } + } + + if (use_mask) + { + if (td->td_bitspersample == 32) + { + for (i = 0; i < nb_pixels; i++) + { + const float val = ((float *)sp->uncompressed_buffer)[i]; + sp->mask_buffer[i] = (val == val) ? 255 : 0; + } + } + else + { + for (i = 0; i < nb_pixels; i++) + { + const double val = ((double *)sp->uncompressed_buffer)[i]; + sp->mask_buffer[i] = (val == val) ? 255 : 0; + } + } + } + } + +#if 0 + lerc_ret = lerc_computeCompressedSize( + sp->uncompressed_buffer, + sp->lerc_version, + GetLercDataType(tif), + td->td_planarconfig == PLANARCONFIG_CONTIG ? + dst_nbands : 1, + sp->segment_width, + sp->segment_height, + 1, + use_mask ? sp->mask_buffer : NULL, + sp->maxzerror, + &numBytes); + if( lerc_ret != 0 ) + { + TIFFErrorExtR(tif, module, + "lerc_computeCompressedSize() failed"); + return 0; + } +#else + numBytes = sp->uncompressed_alloc; +#endif + + if (sp->compressed_size < numBytes) + { + _TIFFfreeExt(tif, sp->compressed_buffer); + sp->compressed_buffer = _TIFFmallocExt(tif, numBytes); + if (!sp->compressed_buffer) + { + sp->compressed_size = 0; + return 0; + } + sp->compressed_size = numBytes; + } + + lerc_ret = lerc_encodeForVersion( + sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif), + td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1, + sp->segment_width, sp->segment_height, 1, +#if LERC_AT_LEAST_VERSION(3, 0, 0) + use_mask ? 1 : 0, +#endif + use_mask ? sp->mask_buffer : NULL, sp->maxzerror, sp->compressed_buffer, + sp->compressed_size, &numBytesWritten); + if (lerc_ret != 0) + { + TIFFErrorExtR(tif, module, "lerc_encode() failed"); + return 0; + } + assert(numBytesWritten < numBytes); + + if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE) + { +#if LIBDEFLATE_SUPPORT + if (sp->libdeflate_enc == NULL) + { + /* To get results as good as zlib, we ask for an extra */ + /* level of compression */ + sp->libdeflate_enc = libdeflate_alloc_compressor( + sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 + : sp->zipquality >= 6 && sp->zipquality <= 9 + ? sp->zipquality + 1 + : sp->zipquality); + if (sp->libdeflate_enc == NULL) + { + TIFFErrorExtR(tif, module, "Cannot allocate compressor"); + return 0; + } + } + + /* Should not happen normally */ + if (libdeflate_zlib_compress_bound( + sp->libdeflate_enc, numBytesWritten) > sp->uncompressed_alloc) + { + TIFFErrorExtR(tif, module, + "Output buffer for libdeflate too small"); + return 0; + } + + tif->tif_rawcc = libdeflate_zlib_compress( + sp->libdeflate_enc, sp->compressed_buffer, numBytesWritten, + sp->uncompressed_buffer, sp->uncompressed_alloc); + + if (tif->tif_rawcc == 0) + { + TIFFErrorExtR(tif, module, "Encoder error at scanline %lu", + (unsigned long)tif->tif_row); + return 0; + } +#else + z_stream strm; + int zlib_ret; + int cappedQuality = sp->zipquality; + if (cappedQuality > Z_BEST_COMPRESSION) + cappedQuality = Z_BEST_COMPRESSION; + + memset(&strm, 0, sizeof(strm)); + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; + zlib_ret = deflateInit(&strm, cappedQuality); + if (zlib_ret != Z_OK) + { + TIFFErrorExtR(tif, module, "deflateInit() failed"); + return 0; + } + + strm.avail_in = numBytesWritten; + strm.next_in = sp->compressed_buffer; + strm.avail_out = sp->uncompressed_alloc; + strm.next_out = sp->uncompressed_buffer; + zlib_ret = deflate(&strm, Z_FINISH); + if (zlib_ret == Z_STREAM_END) + { + tif->tif_rawcc = sp->uncompressed_alloc - strm.avail_out; + } + deflateEnd(&strm); + if (zlib_ret != Z_STREAM_END) + { + TIFFErrorExtR(tif, module, "deflate() failed"); + return 0; + } +#endif + { + int ret; + uint8_t *tif_rawdata_backup = tif->tif_rawdata; + tif->tif_rawdata = sp->uncompressed_buffer; + ret = TIFFFlushData1(tif); + tif->tif_rawdata = tif_rawdata_backup; + if (!ret) + { + return 0; + } + } + } + else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD) + { +#ifdef ZSTD_SUPPORT + size_t zstd_ret = ZSTD_compress( + sp->uncompressed_buffer, sp->uncompressed_alloc, + sp->compressed_buffer, numBytesWritten, sp->zstd_compress_level); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_compress(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + + { + int ret; + uint8_t *tif_rawdata_backup = tif->tif_rawdata; + tif->tif_rawdata = sp->uncompressed_buffer; + tif->tif_rawcc = zstd_ret; + ret = TIFFFlushData1(tif); + tif->tif_rawdata = tif_rawdata_backup; + if (!ret) + { + return 0; + } + } +#else + TIFFErrorExtR(tif, module, "ZSTD support missing"); + return 0; +#endif + } + else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE) + { + TIFFErrorExtR(tif, module, "Unhandled additional compression"); + return 0; + } + else + { + int ret; + uint8_t *tif_rawdata_backup = tif->tif_rawdata; + tif->tif_rawdata = sp->compressed_buffer; + tif->tif_rawcc = numBytesWritten; + ret = TIFFFlushData1(tif); + tif->tif_rawdata = tif_rawdata_backup; + if (!ret) + return 0; + } + + return 1; +} + +static void LERCCleanup(TIFF *tif) +{ + LERCState *sp = LState(tif); + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + _TIFFfreeExt(tif, sp->uncompressed_buffer); + _TIFFfreeExt(tif, sp->compressed_buffer); + _TIFFfreeExt(tif, sp->mask_buffer); + +#if LIBDEFLATE_SUPPORT + if (sp->libdeflate_dec) + libdeflate_free_decompressor(sp->libdeflate_dec); + if (sp->libdeflate_enc) + libdeflate_free_compressor(sp->libdeflate_enc); +#endif + + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static const TIFFField LERCFields[] = { + {TIFFTAG_LERC_PARAMETERS, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG, 0, + TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, FALSE, TRUE, + "LercParameters", NULL}, + {TIFFTAG_LERC_MAXZERROR, 0, 0, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "LercMaximumError", + NULL}, + {TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "LercVersion", NULL}, + {TIFFTAG_LERC_ADD_COMPRESSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, + "LercAdditionalCompression", NULL}, + {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, + "ZSTD zstd_compress_level", NULL}, + {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, +}; + +static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...) +{ + LERCState *sp = LState(tif); + int ret; + va_list ap; + va_start(ap, tag); + ret = (*sp->vsetparent)(tif, tag, ap); + va_end(ap); + return ret; +} + +static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap) +{ + static const char module[] = "LERCVSetField"; + LERCState *sp = LState(tif); + + switch (tag) + { + case TIFFTAG_LERC_PARAMETERS: + { + uint32_t count = va_arg(ap, int); + int *params = va_arg(ap, int *); + if (count < 2) + { + TIFFErrorExtR(tif, module, + "Invalid count for LercParameters: %u", count); + return 0; + } + sp->lerc_version = params[0]; + sp->additional_compression = params[1]; + return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count, + params); + } + case TIFFTAG_LERC_MAXZERROR: + sp->maxzerror = va_arg(ap, double); + return 1; + case TIFFTAG_LERC_VERSION: + { + int params[2] = {0, 0}; + int version = va_arg(ap, int); + if (version != LERC_VERSION_2_4) + { + TIFFErrorExtR(tif, module, "Invalid value for LercVersion: %d", + version); + return 0; + } + sp->lerc_version = version; + params[0] = sp->lerc_version; + params[1] = sp->additional_compression; + return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params); + } + case TIFFTAG_LERC_ADD_COMPRESSION: + { + int params[2] = {0, 0}; + int additional_compression = va_arg(ap, int); +#ifndef ZSTD_SUPPORT + if (additional_compression == LERC_ADD_COMPRESSION_ZSTD) + { + TIFFErrorExtR(tif, module, + "LERC_ZSTD requested, but ZSTD not available"); + return 0; + } +#endif + if (additional_compression != LERC_ADD_COMPRESSION_NONE && + additional_compression != LERC_ADD_COMPRESSION_DEFLATE && + additional_compression != LERC_ADD_COMPRESSION_ZSTD) + { + TIFFErrorExtR(tif, module, + "Invalid value for LercAdditionalCompression: %d", + additional_compression); + return 0; + } + sp->additional_compression = additional_compression; + params[0] = sp->lerc_version; + params[1] = sp->additional_compression; + return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params); + } +#ifdef ZSTD_SUPPORT + case TIFFTAG_ZSTD_LEVEL: + { + sp->zstd_compress_level = (int)va_arg(ap, int); + if (sp->zstd_compress_level <= 0 || + sp->zstd_compress_level > ZSTD_maxCLevel()) + { + TIFFWarningExtR(tif, module, + "ZSTD_LEVEL should be between 1 and %d", + ZSTD_maxCLevel()); + } + return 1; + } +#endif + case TIFFTAG_ZIPQUALITY: + { + sp->zipquality = (int)va_arg(ap, int); + if (sp->zipquality < Z_DEFAULT_COMPRESSION || + sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL) + { + TIFFErrorExtR( + tif, module, + "Invalid ZipQuality value. Should be in [-1,%d] range", + LIBDEFLATE_MAX_COMPRESSION_LEVEL); + return 0; + } + +#if LIBDEFLATE_SUPPORT + if (sp->libdeflate_enc) + { + libdeflate_free_compressor(sp->libdeflate_enc); + sp->libdeflate_enc = NULL; + } +#endif + + return (1); + } + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ +} + +static int LERCVGetField(TIFF *tif, uint32_t tag, va_list ap) +{ + LERCState *sp = LState(tif); + + switch (tag) + { + case TIFFTAG_LERC_MAXZERROR: + *va_arg(ap, double *) = sp->maxzerror; + break; + case TIFFTAG_LERC_VERSION: + *va_arg(ap, int *) = sp->lerc_version; + break; + case TIFFTAG_LERC_ADD_COMPRESSION: + *va_arg(ap, int *) = sp->additional_compression; + break; + case TIFFTAG_ZSTD_LEVEL: + *va_arg(ap, int *) = sp->zstd_compress_level; + break; + case TIFFTAG_ZIPQUALITY: + *va_arg(ap, int *) = sp->zipquality; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; +} + +int TIFFInitLERC(TIFF *tif, int scheme) +{ + static const char module[] = "TIFFInitLERC"; + LERCState *sp; + + (void)scheme; + assert(scheme == COMPRESSION_LERC); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields))) + { + TIFFErrorExtR(tif, module, "Merging LERC codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */ + + /* + * Install codec methods. + */ + tif->tif_fixuptags = LERCFixupTags; + tif->tif_setupdecode = LERCSetupDecode; + tif->tif_predecode = LERCPreDecode; + tif->tif_decoderow = LERCDecode; + tif->tif_decodestrip = LERCDecode; + tif->tif_decodetile = LERCDecode; + tif->tif_setupencode = LERCSetupEncode; + tif->tif_preencode = LERCPreEncode; + tif->tif_postencode = LERCPostEncode; + tif->tif_encoderow = LERCEncode; + tif->tif_encodestrip = LERCEncode; + tif->tif_encodetile = LERCEncode; + tif->tif_cleanup = LERCCleanup; + + /* Default values for codec-specific fields */ + TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4); + TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE); + sp->maxzerror = 0.0; + sp->zstd_compress_level = 9; /* default comp. level */ + sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; + + return 1; +bad: + TIFFErrorExtR(tif, module, "No space for LERC state block"); + return 0; +} +#endif /* LERC_SUPPORT */ diff --git a/3rdparty/libtiff/tif_luv.c b/3rdparty/libtiff/tif_luv.c index 3bd02e88e4..021756d5d6 100644 --- a/3rdparty/libtiff/tif_luv.c +++ b/3rdparty/libtiff/tif_luv.c @@ -2,23 +2,23 @@ * Copyright (c) 1997 Greg Ward Larson * Copyright (c) 1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any * advertising or publicity relating to the software without the specific, * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -34,7 +34,7 @@ * LogLuv image support uses the TIFF library to store 16 or 10-bit * log luminance values with 8 bits each of u and v or a 14-bit index. * - * The codec can take as input and produce as output 32-bit IEEE float values + * The codec can take as input and produce as output 32-bit IEEE float values * as well as 16-bit integer values. A 16-bit luminance is interpreted * as a sign bit followed by a 15-bit integer that is converted * to and from a linear magnitude using the transformation: @@ -145,9 +145,9 @@ * quantization errors into noise. */ +#include #include #include -#include /* * State block for each open TIFF @@ -155,22 +155,23 @@ */ typedef struct logLuvState LogLuvState; -struct logLuvState { - int encoder_state; /* 1 if encoder correctly initialized */ - int user_datafmt; /* user data format */ - int encode_meth; /* encoding method */ - int pixel_size; /* bytes per pixel */ +struct logLuvState +{ + int encoder_state; /* 1 if encoder correctly initialized */ + int user_datafmt; /* user data format */ + int encode_meth; /* encoding method */ + int pixel_size; /* bytes per pixel */ - uint8* tbuf; /* translation buffer */ - tmsize_t tbuflen; /* buffer length */ - void (*tfunc)(LogLuvState*, uint8*, tmsize_t); + uint8_t *tbuf; /* translation buffer */ + tmsize_t tbuflen; /* buffer length */ + void (*tfunc)(LogLuvState *, uint8_t *, tmsize_t); - TIFFVSetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVSetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ }; -#define DecoderState(tif) ((LogLuvState*) (tif)->tif_data) -#define EncoderState(tif) ((LogLuvState*) (tif)->tif_data) +#define DecoderState(tif) ((LogLuvState *)(tif)->tif_data) +#define EncoderState(tif) ((LogLuvState *)(tif)->tif_data) #define SGILOGDATAFMT_UNKNOWN -1 @@ -179,214 +180,207 @@ struct logLuvState { /* * Decode a string of 16-bit gray pixels. */ -static int -LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "LogL16Decode"; - LogLuvState* sp = DecoderState(tif); - int shft; - tmsize_t i; - tmsize_t npixels; - unsigned char* bp; - int16* tp; - int16 b; - tmsize_t cc; - int rc; + static const char module[] = "LogL16Decode"; + LogLuvState *sp = DecoderState(tif); + int shft; + tmsize_t i; + tmsize_t npixels; + unsigned char *bp; + int16_t *tp; + int16_t b; + tmsize_t cc; + int rc; - (void)s; - assert(s == 0); - assert(sp != NULL); + (void)s; + assert(s == 0); + assert(sp != NULL); - npixels = occ / sp->pixel_size; + npixels = occ / sp->pixel_size; - if (sp->user_datafmt == SGILOGDATAFMT_16BIT) - tp = (int16*) op; - else { - if(sp->tbuflen < npixels) { - TIFFErrorExt(tif->tif_clientdata, module, - "Translation buffer too short"); - return (0); - } - tp = (int16*) sp->tbuf; - } - _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); + if (sp->user_datafmt == SGILOGDATAFMT_16BIT) + tp = (int16_t *)op; + else + { + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + tp = (int16_t *)sp->tbuf; + } + _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0])); - bp = (unsigned char*) tif->tif_rawcp; - cc = tif->tif_rawcc; - /* get each byte string */ - for (shft = 8; shft >= 0; shft -=8) { - for (i = 0; i < npixels && cc > 0; ) { - if (*bp >= 128) { /* run */ - if( cc < 2 ) - break; - rc = *bp++ + (2-128); - b = (int16)(*bp++ << shft); - cc -= 2; - while (rc-- && i < npixels) - tp[i++] |= b; - } else { /* non-run */ - rc = *bp++; /* nul is noop */ - while (--cc && rc-- && i < npixels) - tp[i++] |= (int16)*bp++ << shft; - } - } - if (i != npixels) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at row %lu (short %I64d pixels)", - (unsigned long) tif->tif_row, - (unsigned __int64) (npixels - i)); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at row %lu (short %llu pixels)", - (unsigned long) tif->tif_row, - (unsigned long long) (npixels - i)); -#endif - tif->tif_rawcp = (uint8*) bp; - tif->tif_rawcc = cc; - return (0); - } - } - (*sp->tfunc)(sp, op, npixels); - tif->tif_rawcp = (uint8*) bp; - tif->tif_rawcc = cc; - return (1); + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + /* get each byte string */ + for (shft = 8; shft >= 0; shft -= 8) + { + for (i = 0; i < npixels && cc > 0;) + { + if (*bp >= 128) + { /* run */ + if (cc < 2) + break; + rc = *bp++ + (2 - 128); + b = (int16_t)(*bp++ << shft); + cc -= 2; + while (rc-- && i < npixels) + tp[i++] |= b; + } + else + { /* non-run */ + rc = *bp++; /* nul is noop */ + while (--cc && rc-- && i < npixels) + tp[i++] |= (int16_t)*bp++ << shft; + } + } + if (i != npixels) + { + TIFFErrorExtR(tif, module, + "Not enough data at row %" PRIu32 + " (short %" TIFF_SSIZE_FORMAT " pixels)", + tif->tif_row, npixels - i); + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (0); + } + } + (*sp->tfunc)(sp, op, npixels); + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (1); } /* * Decode a string of 24-bit pixels. */ -static int -LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "LogLuvDecode24"; - LogLuvState* sp = DecoderState(tif); - tmsize_t cc; - tmsize_t i; - tmsize_t npixels; - unsigned char* bp; - uint32* tp; + static const char module[] = "LogLuvDecode24"; + LogLuvState *sp = DecoderState(tif); + tmsize_t cc; + tmsize_t i; + tmsize_t npixels; + unsigned char *bp; + uint32_t *tp; - (void)s; - assert(s == 0); - assert(sp != NULL); + (void)s; + assert(s == 0); + assert(sp != NULL); - npixels = occ / sp->pixel_size; + npixels = occ / sp->pixel_size; - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32 *)op; - else { - if(sp->tbuflen < npixels) { - TIFFErrorExt(tif->tif_clientdata, module, - "Translation buffer too short"); - return (0); - } - tp = (uint32 *) sp->tbuf; - } - /* copy to array of uint32 */ - bp = (unsigned char*) tif->tif_rawcp; - cc = tif->tif_rawcc; - for (i = 0; i < npixels && cc >= 3; i++) { - tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; - bp += 3; - cc -= 3; - } - tif->tif_rawcp = (uint8*) bp; - tif->tif_rawcc = cc; - if (i != npixels) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at row %lu (short %I64d pixels)", - (unsigned long) tif->tif_row, - (unsigned __int64) (npixels - i)); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at row %lu (short %llu pixels)", - (unsigned long) tif->tif_row, - (unsigned long long) (npixels - i)); -#endif - return (0); - } - (*sp->tfunc)(sp, op, npixels); - return (1); + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32_t *)op; + else + { + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + tp = (uint32_t *)sp->tbuf; + } + /* copy to array of uint32_t */ + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + for (i = 0; i < npixels && cc >= 3; i++) + { + tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; + bp += 3; + cc -= 3; + } + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + if (i != npixels) + { + TIFFErrorExtR(tif, module, + "Not enough data at row %" PRIu32 + " (short %" TIFF_SSIZE_FORMAT " pixels)", + tif->tif_row, npixels - i); + return (0); + } + (*sp->tfunc)(sp, op, npixels); + return (1); } /* * Decode a string of 32-bit pixels. */ -static int -LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "LogLuvDecode32"; - LogLuvState* sp; - int shft; - tmsize_t i; - tmsize_t npixels; - unsigned char* bp; - uint32* tp; - uint32 b; - tmsize_t cc; - int rc; + static const char module[] = "LogLuvDecode32"; + LogLuvState *sp; + int shft; + tmsize_t i; + tmsize_t npixels; + unsigned char *bp; + uint32_t *tp; + uint32_t b; + tmsize_t cc; + int rc; - (void)s; - assert(s == 0); - sp = DecoderState(tif); - assert(sp != NULL); + (void)s; + assert(s == 0); + sp = DecoderState(tif); + assert(sp != NULL); - npixels = occ / sp->pixel_size; + npixels = occ / sp->pixel_size; - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32*) op; - else { - if(sp->tbuflen < npixels) { - TIFFErrorExt(tif->tif_clientdata, module, - "Translation buffer too short"); - return (0); - } - tp = (uint32*) sp->tbuf; - } - _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32_t *)op; + else + { + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + tp = (uint32_t *)sp->tbuf; + } + _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0])); - bp = (unsigned char*) tif->tif_rawcp; - cc = tif->tif_rawcc; - /* get each byte string */ - for (shft = 24; shft >= 0; shft -=8) { - for (i = 0; i < npixels && cc > 0; ) { - if (*bp >= 128) { /* run */ - if( cc < 2 ) - break; - rc = *bp++ + (2-128); - b = (uint32)*bp++ << shft; - cc -= 2; - while (rc-- && i < npixels) - tp[i++] |= b; - } else { /* non-run */ - rc = *bp++; /* nul is noop */ - while (--cc && rc-- && i < npixels) - tp[i++] |= (uint32)*bp++ << shft; - } - } - if (i != npixels) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at row %lu (short %I64d pixels)", - (unsigned long) tif->tif_row, - (unsigned __int64) (npixels - i)); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at row %lu (short %llu pixels)", - (unsigned long) tif->tif_row, - (unsigned long long) (npixels - i)); -#endif - tif->tif_rawcp = (uint8*) bp; - tif->tif_rawcc = cc; - return (0); - } - } - (*sp->tfunc)(sp, op, npixels); - tif->tif_rawcp = (uint8*) bp; - tif->tif_rawcc = cc; - return (1); + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + /* get each byte string */ + for (shft = 24; shft >= 0; shft -= 8) + { + for (i = 0; i < npixels && cc > 0;) + { + if (*bp >= 128) + { /* run */ + if (cc < 2) + break; + rc = *bp++ + (2 - 128); + b = (uint32_t)*bp++ << shft; + cc -= 2; + while (rc-- && i < npixels) + tp[i++] |= b; + } + else + { /* non-run */ + rc = *bp++; /* nul is noop */ + while (--cc && rc-- && i < npixels) + tp[i++] |= (uint32_t)*bp++ << shft; + } + } + if (i != npixels) + { + TIFFErrorExtR(tif, module, + "Not enough data at row %" PRIu32 + " (short %" TIFF_SSIZE_FORMAT " pixels)", + tif->tif_row, npixels - i); + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (0); + } + } + (*sp->tfunc)(sp, op, npixels); + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (1); } /* @@ -394,20 +388,20 @@ LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) * maintain synchrony with the encode algorithm, which * is row by row. */ -static int -LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int LogLuvDecodeStrip(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowlen = TIFFScanlineSize(tif); + tmsize_t rowlen = TIFFScanlineSize(tif); - if (rowlen == 0) - return 0; + if (rowlen == 0) + return 0; - assert(cc%rowlen == 0); - while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); + assert(cc % rowlen == 0); + while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) + { + bp += rowlen; + cc -= rowlen; + } + return (cc == 0); } /* @@ -415,314 +409,342 @@ LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) * maintain synchrony with the encode algorithm, which * is row by row. */ -static int -LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int LogLuvDecodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowlen = TIFFTileRowSize(tif); + tmsize_t rowlen = TIFFTileRowSize(tif); - if (rowlen == 0) - return 0; + if (rowlen == 0) + return 0; - assert(cc%rowlen == 0); - while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); + assert(cc % rowlen == 0); + while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) + { + bp += rowlen; + cc -= rowlen; + } + return (cc == 0); } /* * Encode a row of 16-bit pixels. */ -static int -LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int LogL16Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "LogL16Encode"; - LogLuvState* sp = EncoderState(tif); - int shft; - tmsize_t i; - tmsize_t j; - tmsize_t npixels; - uint8* op; - int16* tp; - int16 b; - tmsize_t occ; - int rc=0, mask; - tmsize_t beg; + static const char module[] = "LogL16Encode"; + LogLuvState *sp = EncoderState(tif); + int shft; + tmsize_t i; + tmsize_t j; + tmsize_t npixels; + uint8_t *op; + int16_t *tp; + int16_t b; + tmsize_t occ; + int rc = 0, mask; + tmsize_t beg; - (void)s; - assert(s == 0); - assert(sp != NULL); - npixels = cc / sp->pixel_size; + (void)s; + assert(s == 0); + assert(sp != NULL); + npixels = cc / sp->pixel_size; - if (sp->user_datafmt == SGILOGDATAFMT_16BIT) - tp = (int16*) bp; - else { - tp = (int16*) sp->tbuf; - if(sp->tbuflen < npixels) { - TIFFErrorExt(tif->tif_clientdata, module, - "Translation buffer too short"); - return (0); - } - (*sp->tfunc)(sp, bp, npixels); - } - /* compress each byte string */ - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (shft = 8; shft >= 0; shft -=8) { - for (i = 0; i < npixels; i += rc) { - if (occ < 4) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - mask = 0xff << shft; /* find next run */ - for (beg = i; beg < npixels; beg += rc) { - b = (int16) (tp[beg] & mask); - rc = 1; - while (rc < 127+2 && beg+rc < npixels && - (tp[beg+rc] & mask) == b) - rc++; - if (rc >= MINRUN) - break; /* long enough */ - } - if (beg-i > 1 && beg-i < MINRUN) { - b = (int16) (tp[i] & mask);/*check short run */ - j = i+1; - while ((tp[j++] & mask) == b) - if (j == beg) { - *op++ = (uint8)(128-2+j-i); - *op++ = (uint8)(b >> shft); - occ -= 2; - i = beg; - break; - } - } - while (i < beg) { /* write out non-run */ - if ((j = beg-i) > 127) j = 127; - if (occ < j+3) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - *op++ = (uint8) j; occ--; - while (j--) { - *op++ = (uint8) (tp[i++] >> shft & 0xff); - occ--; - } - } - if (rc >= MINRUN) { /* write out run */ - *op++ = (uint8) (128-2+rc); - *op++ = (uint8) (tp[beg] >> shft & 0xff); - occ -= 2; - } else - rc = 0; - } - } - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (sp->user_datafmt == SGILOGDATAFMT_16BIT) + tp = (int16_t *)bp; + else + { + tp = (int16_t *)sp->tbuf; + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + (*sp->tfunc)(sp, bp, npixels); + } + /* compress each byte string */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (shft = 8; shft >= 0; shft -= 8) + { + for (i = 0; i < npixels; i += rc) + { + if (occ < 4) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + mask = 0xff << shft; /* find next run */ + for (beg = i; beg < npixels; beg += rc) + { + b = (int16_t)(tp[beg] & mask); + rc = 1; + while (rc < 127 + 2 && beg + rc < npixels && + (tp[beg + rc] & mask) == b) + rc++; + if (rc >= MINRUN) + break; /* long enough */ + } + if (beg - i > 1 && beg - i < MINRUN) + { + b = (int16_t)(tp[i] & mask); /*check short run */ + j = i + 1; + while ((tp[j++] & mask) == b) + if (j == beg) + { + *op++ = (uint8_t)(128 - 2 + j - i); + *op++ = (uint8_t)(b >> shft); + occ -= 2; + i = beg; + break; + } + } + while (i < beg) + { /* write out non-run */ + if ((j = beg - i) > 127) + j = 127; + if (occ < j + 3) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = (uint8_t)j; + occ--; + while (j--) + { + *op++ = (uint8_t)(tp[i++] >> shft & 0xff); + occ--; + } + } + if (rc >= MINRUN) + { /* write out run */ + *op++ = (uint8_t)(128 - 2 + rc); + *op++ = (uint8_t)(tp[beg] >> shft & 0xff); + occ -= 2; + } + else + rc = 0; + } + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; - return (1); + return (1); } /* * Encode a row of 24-bit pixels. */ -static int -LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int LogLuvEncode24(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "LogLuvEncode24"; - LogLuvState* sp = EncoderState(tif); - tmsize_t i; - tmsize_t npixels; - tmsize_t occ; - uint8* op; - uint32* tp; + static const char module[] = "LogLuvEncode24"; + LogLuvState *sp = EncoderState(tif); + tmsize_t i; + tmsize_t npixels; + tmsize_t occ; + uint8_t *op; + uint32_t *tp; - (void)s; - assert(s == 0); - assert(sp != NULL); - npixels = cc / sp->pixel_size; + (void)s; + assert(s == 0); + assert(sp != NULL); + npixels = cc / sp->pixel_size; - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32*) bp; - else { - tp = (uint32*) sp->tbuf; - if(sp->tbuflen < npixels) { - TIFFErrorExt(tif->tif_clientdata, module, - "Translation buffer too short"); - return (0); - } - (*sp->tfunc)(sp, bp, npixels); - } - /* write out encoded pixels */ - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (i = npixels; i--; ) { - if (occ < 3) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - *op++ = (uint8)(*tp >> 16); - *op++ = (uint8)(*tp >> 8 & 0xff); - *op++ = (uint8)(*tp++ & 0xff); - occ -= 3; - } - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32_t *)bp; + else + { + tp = (uint32_t *)sp->tbuf; + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + (*sp->tfunc)(sp, bp, npixels); + } + /* write out encoded pixels */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (i = npixels; i--;) + { + if (occ < 3) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = (uint8_t)(*tp >> 16); + *op++ = (uint8_t)(*tp >> 8 & 0xff); + *op++ = (uint8_t)(*tp++ & 0xff); + occ -= 3; + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; - return (1); + return (1); } /* * Encode a row of 32-bit pixels. */ -static int -LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int LogLuvEncode32(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "LogLuvEncode32"; - LogLuvState* sp = EncoderState(tif); - int shft; - tmsize_t i; - tmsize_t j; - tmsize_t npixels; - uint8* op; - uint32* tp; - uint32 b; - tmsize_t occ; - int rc=0, mask; - tmsize_t beg; + static const char module[] = "LogLuvEncode32"; + LogLuvState *sp = EncoderState(tif); + int shft; + tmsize_t i; + tmsize_t j; + tmsize_t npixels; + uint8_t *op; + uint32_t *tp; + uint32_t b; + tmsize_t occ; + int rc = 0; + tmsize_t beg; - (void)s; - assert(s == 0); - assert(sp != NULL); + (void)s; + assert(s == 0); + assert(sp != NULL); - npixels = cc / sp->pixel_size; + npixels = cc / sp->pixel_size; - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32*) bp; - else { - tp = (uint32*) sp->tbuf; - if(sp->tbuflen < npixels) { - TIFFErrorExt(tif->tif_clientdata, module, - "Translation buffer too short"); - return (0); - } - (*sp->tfunc)(sp, bp, npixels); - } - /* compress each byte string */ - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (shft = 24; shft >= 0; shft -=8) { - for (i = 0; i < npixels; i += rc) { - if (occ < 4) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - mask = 0xff << shft; /* find next run */ - for (beg = i; beg < npixels; beg += rc) { - b = tp[beg] & mask; - rc = 1; - while (rc < 127+2 && beg+rc < npixels && - (tp[beg+rc] & mask) == b) - rc++; - if (rc >= MINRUN) - break; /* long enough */ - } - if (beg-i > 1 && beg-i < MINRUN) { - b = tp[i] & mask; /* check short run */ - j = i+1; - while ((tp[j++] & mask) == b) - if (j == beg) { - *op++ = (uint8)(128-2+j-i); - *op++ = (uint8)(b >> shft); - occ -= 2; - i = beg; - break; - } - } - while (i < beg) { /* write out non-run */ - if ((j = beg-i) > 127) j = 127; - if (occ < j+3) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - *op++ = (uint8) j; occ--; - while (j--) { - *op++ = (uint8)(tp[i++] >> shft & 0xff); - occ--; - } - } - if (rc >= MINRUN) { /* write out run */ - *op++ = (uint8) (128-2+rc); - *op++ = (uint8)(tp[beg] >> shft & 0xff); - occ -= 2; - } else - rc = 0; - } - } - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32_t *)bp; + else + { + tp = (uint32_t *)sp->tbuf; + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + (*sp->tfunc)(sp, bp, npixels); + } + /* compress each byte string */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (shft = 24; shft >= 0; shft -= 8) + { + const uint32_t mask = 0xffU << shft; /* find next run */ + for (i = 0; i < npixels; i += rc) + { + if (occ < 4) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + for (beg = i; beg < npixels; beg += rc) + { + b = tp[beg] & mask; + rc = 1; + while (rc < 127 + 2 && beg + rc < npixels && + (tp[beg + rc] & mask) == b) + rc++; + if (rc >= MINRUN) + break; /* long enough */ + } + if (beg - i > 1 && beg - i < MINRUN) + { + b = tp[i] & mask; /* check short run */ + j = i + 1; + while ((tp[j++] & mask) == b) + if (j == beg) + { + *op++ = (uint8_t)(128 - 2 + j - i); + *op++ = (uint8_t)(b >> shft); + occ -= 2; + i = beg; + break; + } + } + while (i < beg) + { /* write out non-run */ + if ((j = beg - i) > 127) + j = 127; + if (occ < j + 3) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = (uint8_t)j; + occ--; + while (j--) + { + *op++ = (uint8_t)(tp[i++] >> shft & 0xff); + occ--; + } + } + if (rc >= MINRUN) + { /* write out run */ + *op++ = (uint8_t)(128 - 2 + rc); + *op++ = (uint8_t)(tp[beg] >> shft & 0xff); + occ -= 2; + } + else + rc = 0; + } + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; - return (1); + return (1); } /* * Encode a strip of pixels. We break it into rows to * avoid encoding runs across row boundaries. */ -static int -LogLuvEncodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int LogLuvEncodeStrip(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowlen = TIFFScanlineSize(tif); + tmsize_t rowlen = TIFFScanlineSize(tif); - if (rowlen == 0) - return 0; + if (rowlen == 0) + return 0; - assert(cc%rowlen == 0); - while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); + assert(cc % rowlen == 0); + while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) + { + bp += rowlen; + cc -= rowlen; + } + return (cc == 0); } /* * Encode a tile of pixels. We break it into rows to * avoid encoding runs across row boundaries. */ -static int -LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int LogLuvEncodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowlen = TIFFTileRowSize(tif); + tmsize_t rowlen = TIFFTileRowSize(tif); - if (rowlen == 0) - return 0; + if (rowlen == 0) + return 0; - assert(cc%rowlen == 0); - while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); + assert(cc % rowlen == 0); + while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) + { + bp += rowlen; + cc -= rowlen; + } + return (cc == 0); } /* @@ -732,190 +754,192 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) #include "uvcode.h" #ifndef UVSCALE -#define U_NEU 0.210526316 -#define V_NEU 0.473684211 -#define UVSCALE 410. +#define U_NEU 0.210526316 +#define V_NEU 0.473684211 +#define UVSCALE 410. #endif -#ifndef M_LN2 -#define M_LN2 0.69314718055994530942 +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 #endif #ifndef M_PI -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif #undef log2 /* Conflict with C'99 function */ -#define log2(x) ((1./M_LN2)*log(x)) -#undef exp2 /* Conflict with C'99 function */ -#define exp2(x) exp(M_LN2*(x)) +#define log2(x) ((1. / M_LN2) * log(x)) +#undef exp2 /* Conflict with C'99 function */ +#define exp2(x) exp(M_LN2 *(x)) static int tiff_itrunc(double x, int m) { - if( m == SGILOGENCODE_NODITHER ) + if (m == SGILOGENCODE_NODITHER) return (int)x; /* Silence CoverityScan warning about bad crypto function */ /* coverity[dont_call] */ - return (int)(x + rand()*(1./RAND_MAX) - .5); + return (int)(x + rand() * (1. / RAND_MAX) - .5); } #if !LOGLUV_PUBLIC static #endif -double -LogL16toY(int p16) /* compute luminance from 16-bit LogL */ + double + LogL16toY(int p16) /* compute luminance from 16-bit LogL */ { - int Le = p16 & 0x7fff; - double Y; + int Le = p16 & 0x7fff; + double Y; - if (!Le) - return (0.); - Y = exp(M_LN2/256.*(Le+.5) - M_LN2*64.); - return (!(p16 & 0x8000) ? Y : -Y); + if (!Le) + return (0.); + Y = exp(M_LN2 / 256. * (Le + .5) - M_LN2 * 64.); + return (!(p16 & 0x8000) ? Y : -Y); } #if !LOGLUV_PUBLIC static #endif -int -LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ + int + LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ { - if (Y >= 1.8371976e19) - return (0x7fff); - if (Y <= -1.8371976e19) - return (0xffff); - if (Y > 5.4136769e-20) - return tiff_itrunc(256.*(log2(Y) + 64.), em); - if (Y < -5.4136769e-20) - return (~0x7fff | tiff_itrunc(256.*(log2(-Y) + 64.), em)); - return (0); + if (Y >= 1.8371976e19) + return (0x7fff); + if (Y <= -1.8371976e19) + return (0xffff); + if (Y > 5.4136769e-20) + return tiff_itrunc(256. * (log2(Y) + 64.), em); + if (Y < -5.4136769e-20) + return (~0x7fff | tiff_itrunc(256. * (log2(-Y) + 64.), em)); + return (0); } -static void -L16toY(LogLuvState* sp, uint8* op, tmsize_t n) +static void L16toY(LogLuvState *sp, uint8_t *op, tmsize_t n) { - int16* l16 = (int16*) sp->tbuf; - float* yp = (float*) op; + int16_t *l16 = (int16_t *)sp->tbuf; + float *yp = (float *)op; - while (n-- > 0) - *yp++ = (float)LogL16toY(*l16++); + while (n-- > 0) + *yp++ = (float)LogL16toY(*l16++); } -static void -L16toGry(LogLuvState* sp, uint8* op, tmsize_t n) +static void L16toGry(LogLuvState *sp, uint8_t *op, tmsize_t n) { - int16* l16 = (int16*) sp->tbuf; - uint8* gp = (uint8*) op; + int16_t *l16 = (int16_t *)sp->tbuf; + uint8_t *gp = (uint8_t *)op; - while (n-- > 0) { - double Y = LogL16toY(*l16++); - *gp++ = (uint8) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y))); - } + while (n-- > 0) + { + double Y = LogL16toY(*l16++); + *gp++ = (uint8_t)((Y <= 0.) ? 0 + : (Y >= 1.) ? 255 + : (int)(256. * sqrt(Y))); + } } -static void -L16fromY(LogLuvState* sp, uint8* op, tmsize_t n) +static void L16fromY(LogLuvState *sp, uint8_t *op, tmsize_t n) { - int16* l16 = (int16*) sp->tbuf; - float* yp = (float*) op; + int16_t *l16 = (int16_t *)sp->tbuf; + float *yp = (float *)op; - while (n-- > 0) - *l16++ = (int16) (LogL16fromY(*yp++, sp->encode_meth)); + while (n-- > 0) + *l16++ = (int16_t)(LogL16fromY(*yp++, sp->encode_meth)); } #if !LOGLUV_PUBLIC static #endif -void -XYZtoRGB24(float xyz[3], uint8 rgb[3]) + void + XYZtoRGB24(float *xyz, uint8_t *rgb) { - double r, g, b; - /* assume CCIR-709 primaries */ - r = 2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2]; - g = -1.022*xyz[0] + 1.978*xyz[1] + 0.044*xyz[2]; - b = 0.061*xyz[0] + -0.224*xyz[1] + 1.163*xyz[2]; - /* assume 2.0 gamma for speed */ - /* could use integer sqrt approx., but this is probably faster */ - rgb[0] = (uint8)((r<=0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r))); - rgb[1] = (uint8)((g<=0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g))); - rgb[2] = (uint8)((b<=0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b))); + double r, g, b; + /* assume CCIR-709 primaries */ + r = 2.690 * xyz[0] + -1.276 * xyz[1] + -0.414 * xyz[2]; + g = -1.022 * xyz[0] + 1.978 * xyz[1] + 0.044 * xyz[2]; + b = 0.061 * xyz[0] + -0.224 * xyz[1] + 1.163 * xyz[2]; + /* assume 2.0 gamma for speed */ + /* could use integer sqrt approx., but this is probably faster */ + rgb[0] = (uint8_t)((r <= 0.) ? 0 : (r >= 1.) ? 255 : (int)(256. * sqrt(r))); + rgb[1] = (uint8_t)((g <= 0.) ? 0 : (g >= 1.) ? 255 : (int)(256. * sqrt(g))); + rgb[2] = (uint8_t)((b <= 0.) ? 0 : (b >= 1.) ? 255 : (int)(256. * sqrt(b))); } #if !LOGLUV_PUBLIC static #endif -double -LogL10toY(int p10) /* compute luminance from 10-bit LogL */ + double + LogL10toY(int p10) /* compute luminance from 10-bit LogL */ { - if (p10 == 0) - return (0.); - return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.)); + if (p10 == 0) + return (0.); + return (exp(M_LN2 / 64. * (p10 + .5) - M_LN2 * 12.)); } #if !LOGLUV_PUBLIC static #endif -int -LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */ + int + LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */ { - if (Y >= 15.742) - return (0x3ff); - else if (Y <= .00024283) - return (0); - else - return tiff_itrunc(64.*(log2(Y) + 12.), em); + if (Y >= 15.742) + return (0x3ff); + else if (Y <= .00024283) + return (0); + else + return tiff_itrunc(64. * (log2(Y) + 12.), em); } -#define NANGLES 100 -#define uv2ang(u, v) ( (NANGLES*.499999999/M_PI) \ - * atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES ) +#define NANGLES 100 +#define uv2ang(u, v) \ + ((NANGLES * .499999999 / M_PI) * atan2((v)-V_NEU, (u)-U_NEU) + .5 * NANGLES) -static int -oog_encode(double u, double v) /* encode out-of-gamut chroma */ +static int oog_encode(double u, double v) /* encode out-of-gamut chroma */ { - static int oog_table[NANGLES]; - static int initialized = 0; - register int i; + static int oog_table[NANGLES]; + static int initialized = 0; + register int i; - if (!initialized) { /* set up perimeter table */ - double eps[NANGLES], ua, va, ang, epsa; - int ui, vi, ustep; - for (i = NANGLES; i--; ) - eps[i] = 2.; - for (vi = UV_NVS; vi--; ) { - va = UV_VSTART + (vi+.5)*UV_SQSIZ; - ustep = uv_row[vi].nus-1; - if (vi == UV_NVS-1 || vi == 0 || ustep <= 0) - ustep = 1; - for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) { - ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; - ang = uv2ang(ua, va); - i = (int) ang; - epsa = fabs(ang - (i+.5)); - if (epsa < eps[i]) { - oog_table[i] = uv_row[vi].ncum + ui; - eps[i] = epsa; - } - } - } - for (i = NANGLES; i--; ) /* fill any holes */ - if (eps[i] > 1.5) { - int i1, i2; - for (i1 = 1; i1 < NANGLES/2; i1++) - if (eps[(i+i1)%NANGLES] < 1.5) - break; - for (i2 = 1; i2 < NANGLES/2; i2++) - if (eps[(i+NANGLES-i2)%NANGLES] < 1.5) - break; - if (i1 < i2) - oog_table[i] = - oog_table[(i+i1)%NANGLES]; - else - oog_table[i] = - oog_table[(i+NANGLES-i2)%NANGLES]; - } - initialized = 1; - } - i = (int) uv2ang(u, v); /* look up hue angle */ - return (oog_table[i]); + if (!initialized) + { /* set up perimeter table */ + double eps[NANGLES], ua, va, ang, epsa; + int ui, vi, ustep; + for (i = NANGLES; i--;) + eps[i] = 2.; + for (vi = UV_NVS; vi--;) + { + va = UV_VSTART + (vi + .5) * UV_SQSIZ; + ustep = uv_row[vi].nus - 1; + if (vi == UV_NVS - 1 || vi == 0 || ustep <= 0) + ustep = 1; + for (ui = uv_row[vi].nus - 1; ui >= 0; ui -= ustep) + { + ua = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ; + ang = uv2ang(ua, va); + i = (int)ang; + epsa = fabs(ang - (i + .5)); + if (epsa < eps[i]) + { + oog_table[i] = uv_row[vi].ncum + ui; + eps[i] = epsa; + } + } + } + for (i = NANGLES; i--;) /* fill any holes */ + if (eps[i] > 1.5) + { + int i1, i2; + for (i1 = 1; i1 < NANGLES / 2; i1++) + if (eps[(i + i1) % NANGLES] < 1.5) + break; + for (i2 = 1; i2 < NANGLES / 2; i2++) + if (eps[(i + NANGLES - i2) % NANGLES] < 1.5) + break; + if (i1 < i2) + oog_table[i] = oog_table[(i + i1) % NANGLES]; + else + oog_table[i] = oog_table[(i + NANGLES - i2) % NANGLES]; + } + initialized = 1; + } + i = (int)uv2ang(u, v); /* look up hue angle */ + return (oog_table[i]); } #undef uv2ang @@ -924,847 +948,891 @@ oog_encode(double u, double v) /* encode out-of-gamut chroma */ #if !LOGLUV_PUBLIC static #endif -int -uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ + int + uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ { - register int vi, ui; + register int vi, ui; - if (v < UV_VSTART) - return oog_encode(u, v); - vi = tiff_itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em); - if (vi >= UV_NVS) - return oog_encode(u, v); - if (u < uv_row[vi].ustart) - return oog_encode(u, v); - ui = tiff_itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em); - if (ui >= uv_row[vi].nus) - return oog_encode(u, v); + /* check for NaN */ + if (u != u || v != v) + { + u = U_NEU; + v = V_NEU; + } - return (uv_row[vi].ncum + ui); + if (v < UV_VSTART) + return oog_encode(u, v); + vi = tiff_itrunc((v - UV_VSTART) * (1. / UV_SQSIZ), em); + if (vi >= UV_NVS) + return oog_encode(u, v); + if (u < uv_row[vi].ustart) + return oog_encode(u, v); + ui = tiff_itrunc((u - uv_row[vi].ustart) * (1. / UV_SQSIZ), em); + if (ui >= uv_row[vi].nus) + return oog_encode(u, v); + + return (uv_row[vi].ncum + ui); } #if !LOGLUV_PUBLIC static #endif -int -uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ + int + uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ { - int upper, lower; - register int ui, vi; + int upper, lower; + register int ui, vi; - if (c < 0 || c >= UV_NDIVS) - return (-1); - lower = 0; /* binary search */ - upper = UV_NVS; - while (upper - lower > 1) { - vi = (lower + upper) >> 1; - ui = c - uv_row[vi].ncum; - if (ui > 0) - lower = vi; - else if (ui < 0) - upper = vi; - else { - lower = vi; - break; - } - } - vi = lower; - ui = c - uv_row[vi].ncum; - *up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; - *vp = UV_VSTART + (vi+.5)*UV_SQSIZ; - return (0); -} - -#if !LOGLUV_PUBLIC -static -#endif -void -LogLuv24toXYZ(uint32 p, float XYZ[3]) -{ - int Ce; - double L, u, v, s, x, y; - /* decode luminance */ - L = LogL10toY(p>>14 & 0x3ff); - if (L <= 0.) { - XYZ[0] = XYZ[1] = XYZ[2] = 0.; - return; - } - /* decode color */ - Ce = p & 0x3fff; - if (uv_decode(&u, &v, Ce) < 0) { - u = U_NEU; v = V_NEU; - } - s = 1./(6.*u - 16.*v + 12.); - x = 9.*u * s; - y = 4.*v * s; - /* convert to XYZ */ - XYZ[0] = (float)(x/y * L); - XYZ[1] = (float)L; - XYZ[2] = (float)((1.-x-y)/y * L); -} - -#if !LOGLUV_PUBLIC -static -#endif -uint32 -LogLuv24fromXYZ(float XYZ[3], int em) -{ - int Le, Ce; - double u, v, s; - /* encode luminance */ - Le = LogL10fromY(XYZ[1], em); - /* encode color */ - s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; - if (!Le || s <= 0.) { - u = U_NEU; - v = V_NEU; - } else { - u = 4.*XYZ[0] / s; - v = 9.*XYZ[1] / s; - } - Ce = uv_encode(u, v, em); - if (Ce < 0) /* never happens */ - Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); - /* combine encodings */ - return (Le << 14 | Ce); -} - -static void -Luv24toXYZ(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - float* xyz = (float*) op; - - while (n-- > 0) { - LogLuv24toXYZ(*luv, xyz); - xyz += 3; - luv++; - } -} - -static void -Luv24toLuv48(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - int16* luv3 = (int16*) op; - - while (n-- > 0) { - double u, v; - - *luv3++ = (int16)((*luv >> 12 & 0xffd) + 13314); - if (uv_decode(&u, &v, *luv&0x3fff) < 0) { - u = U_NEU; - v = V_NEU; - } - *luv3++ = (int16)(u * (1L<<15)); - *luv3++ = (int16)(v * (1L<<15)); - luv++; - } -} - -static void -Luv24toRGB(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - uint8* rgb = (uint8*) op; - - while (n-- > 0) { - float xyz[3]; - - LogLuv24toXYZ(*luv++, xyz); - XYZtoRGB24(xyz, rgb); - rgb += 3; - } -} - -static void -Luv24fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - float* xyz = (float*) op; - - while (n-- > 0) { - *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth); - xyz += 3; - } -} - -static void -Luv24fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - int16* luv3 = (int16*) op; - - while (n-- > 0) { - int Le, Ce; - - if (luv3[0] <= 0) - Le = 0; - else if (luv3[0] >= (1<<12)+3314) - Le = (1<<10) - 1; - else if (sp->encode_meth == SGILOGENCODE_NODITHER) - Le = (luv3[0]-3314) >> 2; - else - Le = tiff_itrunc(.25*(luv3[0]-3314.), sp->encode_meth); - - Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15), - sp->encode_meth); - if (Ce < 0) /* never happens */ - Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); - *luv++ = (uint32)Le << 14 | Ce; - luv3 += 3; - } -} - -#if !LOGLUV_PUBLIC -static -#endif -void -LogLuv32toXYZ(uint32 p, float XYZ[3]) -{ - double L, u, v, s, x, y; - /* decode luminance */ - L = LogL16toY((int)p >> 16); - if (L <= 0.) { - XYZ[0] = XYZ[1] = XYZ[2] = 0.; - return; - } - /* decode color */ - u = 1./UVSCALE * ((p>>8 & 0xff) + .5); - v = 1./UVSCALE * ((p & 0xff) + .5); - s = 1./(6.*u - 16.*v + 12.); - x = 9.*u * s; - y = 4.*v * s; - /* convert to XYZ */ - XYZ[0] = (float)(x/y * L); - XYZ[1] = (float)L; - XYZ[2] = (float)((1.-x-y)/y * L); -} - -#if !LOGLUV_PUBLIC -static -#endif -uint32 -LogLuv32fromXYZ(float XYZ[3], int em) -{ - unsigned int Le, ue, ve; - double u, v, s; - /* encode luminance */ - Le = (unsigned int)LogL16fromY(XYZ[1], em); - /* encode color */ - s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; - if (!Le || s <= 0.) { - u = U_NEU; - v = V_NEU; - } else { - u = 4.*XYZ[0] / s; - v = 9.*XYZ[1] / s; - } - if (u <= 0.) ue = 0; - else ue = tiff_itrunc(UVSCALE*u, em); - if (ue > 255) ue = 255; - if (v <= 0.) ve = 0; - else ve = tiff_itrunc(UVSCALE*v, em); - if (ve > 255) ve = 255; - /* combine encodings */ - return (Le << 16 | ue << 8 | ve); -} - -static void -Luv32toXYZ(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - float* xyz = (float*) op; - - while (n-- > 0) { - LogLuv32toXYZ(*luv++, xyz); - xyz += 3; - } -} - -static void -Luv32toLuv48(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - int16* luv3 = (int16*) op; - - while (n-- > 0) { - double u, v; - - *luv3++ = (int16)(*luv >> 16); - u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5); - v = 1./UVSCALE * ((*luv & 0xff) + .5); - *luv3++ = (int16)(u * (1L<<15)); - *luv3++ = (int16)(v * (1L<<15)); - luv++; - } -} - -static void -Luv32toRGB(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - uint8* rgb = (uint8*) op; - - while (n-- > 0) { - float xyz[3]; - - LogLuv32toXYZ(*luv++, xyz); - XYZtoRGB24(xyz, rgb); - rgb += 3; - } -} - -static void -Luv32fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - float* xyz = (float*) op; - - while (n-- > 0) { - *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth); - xyz += 3; - } -} - -static void -Luv32fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n) -{ - uint32* luv = (uint32*) sp->tbuf; - int16* luv3 = (int16*) op; - - if (sp->encode_meth == SGILOGENCODE_NODITHER) { - while (n-- > 0) { - *luv++ = (uint32)luv3[0] << 16 | - (luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) | - (luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff); - luv3 += 3; - } - return; - } - while (n-- > 0) { - *luv++ = (uint32)luv3[0] << 16 | - (tiff_itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) | - (tiff_itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff); - luv3 += 3; - } -} - -static void -_logLuvNop(LogLuvState* sp, uint8* op, tmsize_t n) -{ - (void) sp; (void) op; (void) n; -} - -static int -LogL16GuessDataFmt(TIFFDirectory *td) -{ -#define PACK(s,b,f) (((b)<<6)|((s)<<3)|(f)) - switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) { - case PACK(1, 32, SAMPLEFORMAT_IEEEFP): - return (SGILOGDATAFMT_FLOAT); - case PACK(1, 16, SAMPLEFORMAT_VOID): - case PACK(1, 16, SAMPLEFORMAT_INT): - case PACK(1, 16, SAMPLEFORMAT_UINT): - return (SGILOGDATAFMT_16BIT); - case PACK(1, 8, SAMPLEFORMAT_VOID): - case PACK(1, 8, SAMPLEFORMAT_UINT): - return (SGILOGDATAFMT_8BIT); - } -#undef PACK - return (SGILOGDATAFMT_UNKNOWN); -} - -static tmsize_t -multiply_ms(tmsize_t m1, tmsize_t m2) -{ - return _TIFFMultiplySSize(NULL, m1, m2, NULL); -} - -static int -LogL16InitState(TIFF* tif) -{ - static const char module[] = "LogL16InitState"; - TIFFDirectory *td = &tif->tif_dir; - LogLuvState* sp = DecoderState(tif); - - assert(sp != NULL); - assert(td->td_photometric == PHOTOMETRIC_LOGL); - - if( td->td_samplesperpixel != 1 ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Sorry, can not handle LogL image with %s=%d", - "Samples/pixel", td->td_samplesperpixel); - return 0; - } - - /* for some reason, we can't do this in TIFFInitLogL16 */ - if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) - sp->user_datafmt = LogL16GuessDataFmt(td); - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->pixel_size = sizeof (float); - break; - case SGILOGDATAFMT_16BIT: - sp->pixel_size = sizeof (int16); - break; - case SGILOGDATAFMT_8BIT: - sp->pixel_size = sizeof (uint8); - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "No support for converting user data format to LogL"); - return (0); - } - if( isTiled(tif) ) - sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); - else if( td->td_rowsperstrip < td->td_imagelength ) - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + if (c < 0 || c >= UV_NDIVS) + return (-1); + lower = 0; /* binary search */ + upper = UV_NVS; + while (upper - lower > 1) + { + vi = (lower + upper) >> 1; + ui = c - uv_row[vi].ncum; + if (ui > 0) + lower = vi; + else if (ui < 0) + upper = vi; else - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); - if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 || - (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer"); - return (0); - } - return (1); -} - -static int -LogLuvGuessDataFmt(TIFFDirectory *td) -{ - int guess; - - /* - * If the user didn't tell us their datafmt, - * take our best guess from the bitspersample. - */ -#define PACK(a,b) (((a)<<3)|(b)) - switch (PACK(td->td_bitspersample, td->td_sampleformat)) { - case PACK(32, SAMPLEFORMAT_IEEEFP): - guess = SGILOGDATAFMT_FLOAT; - break; - case PACK(32, SAMPLEFORMAT_VOID): - case PACK(32, SAMPLEFORMAT_UINT): - case PACK(32, SAMPLEFORMAT_INT): - guess = SGILOGDATAFMT_RAW; - break; - case PACK(16, SAMPLEFORMAT_VOID): - case PACK(16, SAMPLEFORMAT_INT): - case PACK(16, SAMPLEFORMAT_UINT): - guess = SGILOGDATAFMT_16BIT; - break; - case PACK( 8, SAMPLEFORMAT_VOID): - case PACK( 8, SAMPLEFORMAT_UINT): - guess = SGILOGDATAFMT_8BIT; - break; - default: - guess = SGILOGDATAFMT_UNKNOWN; - break; -#undef PACK - } - /* - * Double-check samples per pixel. - */ - switch (td->td_samplesperpixel) { - case 1: - if (guess != SGILOGDATAFMT_RAW) - guess = SGILOGDATAFMT_UNKNOWN; - break; - case 3: - if (guess == SGILOGDATAFMT_RAW) - guess = SGILOGDATAFMT_UNKNOWN; - break; - default: - guess = SGILOGDATAFMT_UNKNOWN; - break; - } - return (guess); -} - -static int -LogLuvInitState(TIFF* tif) -{ - static const char module[] = "LogLuvInitState"; - TIFFDirectory* td = &tif->tif_dir; - LogLuvState* sp = DecoderState(tif); - - assert(sp != NULL); - assert(td->td_photometric == PHOTOMETRIC_LOGLUV); - - /* for some reason, we can't do this in TIFFInitLogLuv */ - if (td->td_planarconfig != PLANARCONFIG_CONTIG) { - TIFFErrorExt(tif->tif_clientdata, module, - "SGILog compression cannot handle non-contiguous data"); - return (0); - } - if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) - sp->user_datafmt = LogLuvGuessDataFmt(td); - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->pixel_size = 3*sizeof (float); - break; - case SGILOGDATAFMT_16BIT: - sp->pixel_size = 3*sizeof (int16); - break; - case SGILOGDATAFMT_RAW: - sp->pixel_size = sizeof (uint32); - break; - case SGILOGDATAFMT_8BIT: - sp->pixel_size = 3*sizeof (uint8); - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "No support for converting user data format to LogLuv"); - return (0); - } - if( isTiled(tif) ) - sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); - else if( td->td_rowsperstrip < td->td_imagelength ) - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); - else - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); - if (multiply_ms(sp->tbuflen, sizeof (uint32)) == 0 || - (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer"); - return (0); - } - return (1); -} - -static int -LogLuvFixupTags(TIFF* tif) -{ - (void) tif; - return (1); -} - -static int -LogLuvSetupDecode(TIFF* tif) -{ - static const char module[] = "LogLuvSetupDecode"; - LogLuvState* sp = DecoderState(tif); - TIFFDirectory* td = &tif->tif_dir; - - tif->tif_postdecode = _TIFFNoPostDecode; - switch (td->td_photometric) { - case PHOTOMETRIC_LOGLUV: - if (!LogLuvInitState(tif)) - break; - if (td->td_compression == COMPRESSION_SGILOG24) { - tif->tif_decoderow = LogLuvDecode24; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv24toXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv24toLuv48; - break; - case SGILOGDATAFMT_8BIT: - sp->tfunc = Luv24toRGB; - break; - } - } else { - tif->tif_decoderow = LogLuvDecode32; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv32toXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv32toLuv48; - break; - case SGILOGDATAFMT_8BIT: - sp->tfunc = Luv32toRGB; - break; - } - } - return (1); - case PHOTOMETRIC_LOGL: - if (!LogL16InitState(tif)) - break; - tif->tif_decoderow = LogL16Decode; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = L16toY; - break; - case SGILOGDATAFMT_8BIT: - sp->tfunc = L16toGry; - break; - } - return (1); - default: - TIFFErrorExt(tif->tif_clientdata, module, - "Inappropriate photometric interpretation %d for SGILog compression; %s", - td->td_photometric, "must be either LogLUV or LogL"); - break; - } - return (0); -} - -static int -LogLuvSetupEncode(TIFF* tif) -{ - static const char module[] = "LogLuvSetupEncode"; - LogLuvState* sp = EncoderState(tif); - TIFFDirectory* td = &tif->tif_dir; - - switch (td->td_photometric) { - case PHOTOMETRIC_LOGLUV: - if (!LogLuvInitState(tif)) - return (0); - if (td->td_compression == COMPRESSION_SGILOG24) { - tif->tif_encoderow = LogLuvEncode24; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv24fromXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv24fromLuv48; - break; - case SGILOGDATAFMT_RAW: - break; - default: - goto notsupported; - } - } else { - tif->tif_encoderow = LogLuvEncode32; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv32fromXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv32fromLuv48; - break; - case SGILOGDATAFMT_RAW: - break; - default: - goto notsupported; - } - } - break; - case PHOTOMETRIC_LOGL: - if (!LogL16InitState(tif)) - return (0); - tif->tif_encoderow = LogL16Encode; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = L16fromY; - break; - case SGILOGDATAFMT_16BIT: - break; - default: - goto notsupported; - } - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "Inappropriate photometric interpretation %d for SGILog compression; %s", - td->td_photometric, "must be either LogLUV or LogL"); - return (0); - } - sp->encoder_state = 1; - return (1); -notsupported: - TIFFErrorExt(tif->tif_clientdata, module, - "SGILog compression supported only for %s, or raw data", - td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv"); - return (0); -} - -static void -LogLuvClose(TIFF* tif) -{ - LogLuvState* sp = (LogLuvState*) tif->tif_data; - TIFFDirectory *td = &tif->tif_dir; - - assert(sp != 0); - /* - * For consistency, we always want to write out the same - * bitspersample and sampleformat for our TIFF file, - * regardless of the data format being used by the application. - * Since this routine is called after tags have been set but - * before they have been recorded in the file, we reset them here. - * Note: this is really a nasty approach. See PixarLogClose - */ - if( sp->encoder_state ) { - /* See PixarLogClose. Might avoid issues with tags whose size depends - * on those below, but not completely sure this is enough. */ - td->td_samplesperpixel = - (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; - td->td_bitspersample = 16; - td->td_sampleformat = SAMPLEFORMAT_INT; + lower = vi; + break; } + } + vi = lower; + ui = c - uv_row[vi].ncum; + *up = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ; + *vp = UV_VSTART + (vi + .5) * UV_SQSIZ; + return (0); } -static void -LogLuvCleanup(TIFF* tif) +#if !LOGLUV_PUBLIC +static +#endif + void + LogLuv24toXYZ(uint32_t p, float *XYZ) { - LogLuvState* sp = (LogLuvState *)tif->tif_data; - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->tbuf) - _TIFFfree(sp->tbuf); - _TIFFfree(sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); + int Ce; + double L, u, v, s, x, y; + /* decode luminance */ + L = LogL10toY(p >> 14 & 0x3ff); + if (L <= 0.) + { + XYZ[0] = XYZ[1] = XYZ[2] = 0.; + return; + } + /* decode color */ + Ce = p & 0x3fff; + if (uv_decode(&u, &v, Ce) < 0) + { + u = U_NEU; + v = V_NEU; + } + s = 1. / (6. * u - 16. * v + 12.); + x = 9. * u * s; + y = 4. * v * s; + /* convert to XYZ */ + XYZ[0] = (float)(x / y * L); + XYZ[1] = (float)L; + XYZ[2] = (float)((1. - x - y) / y * L); } -static int -LogLuvVSetField(TIFF* tif, uint32 tag, va_list ap) +#if !LOGLUV_PUBLIC +static +#endif + uint32_t + LogLuv24fromXYZ(float *XYZ, int em) { - static const char module[] = "LogLuvVSetField"; - LogLuvState* sp = DecoderState(tif); - int bps, fmt; - - switch (tag) { - case TIFFTAG_SGILOGDATAFMT: - sp->user_datafmt = (int) va_arg(ap, int); - /* - * Tweak the TIFF header so that the rest of libtiff knows what - * size of data will be passed between app and library, and - * assume that the app knows what it is doing and is not - * confused by these header manipulations... - */ - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - bps = 32; - fmt = SAMPLEFORMAT_IEEEFP; - break; - case SGILOGDATAFMT_16BIT: - bps = 16; - fmt = SAMPLEFORMAT_INT; - break; - case SGILOGDATAFMT_RAW: - bps = 32; - fmt = SAMPLEFORMAT_UINT; - TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); - break; - case SGILOGDATAFMT_8BIT: - bps = 8; - fmt = SAMPLEFORMAT_UINT; - break; - default: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Unknown data format %d for LogLuv compression", - sp->user_datafmt); - return (0); - } - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt); - /* - * Must recalculate sizes should bits/sample change. - */ - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t) -1; - tif->tif_scanlinesize = TIFFScanlineSize(tif); - return (1); - case TIFFTAG_SGILOGENCODE: - sp->encode_meth = (int) va_arg(ap, int); - if (sp->encode_meth != SGILOGENCODE_NODITHER && - sp->encode_meth != SGILOGENCODE_RANDITHER) { - TIFFErrorExt(tif->tif_clientdata, module, - "Unknown encoding %d for LogLuv compression", - sp->encode_meth); - return (0); - } - return (1); - default: - return (*sp->vsetparent)(tif, tag, ap); - } + int Le, Ce; + double u, v, s; + /* encode luminance */ + Le = LogL10fromY(XYZ[1], em); + /* encode color */ + s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2]; + if (!Le || s <= 0.) + { + u = U_NEU; + v = V_NEU; + } + else + { + u = 4. * XYZ[0] / s; + v = 9. * XYZ[1] / s; + } + Ce = uv_encode(u, v, em); + if (Ce < 0) /* never happens */ + Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); + /* combine encodings */ + return (Le << 14 | Ce); } -static int -LogLuvVGetField(TIFF* tif, uint32 tag, va_list ap) +static void Luv24toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) { - LogLuvState *sp = (LogLuvState *)tif->tif_data; + uint32_t *luv = (uint32_t *)sp->tbuf; + float *xyz = (float *)op; - switch (tag) { - case TIFFTAG_SGILOGDATAFMT: - *va_arg(ap, int*) = sp->user_datafmt; - return (1); - default: - return (*sp->vgetparent)(tif, tag, ap); - } + while (n-- > 0) + { + LogLuv24toXYZ(*luv, xyz); + xyz += 3; + luv++; + } +} + +static void Luv24toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + uint32_t *luv = (uint32_t *)sp->tbuf; + int16_t *luv3 = (int16_t *)op; + + while (n-- > 0) + { + double u, v; + + *luv3++ = (int16_t)((*luv >> 12 & 0xffd) + 13314); + if (uv_decode(&u, &v, *luv & 0x3fff) < 0) + { + u = U_NEU; + v = V_NEU; + } + *luv3++ = (int16_t)(u * (1L << 15)); + *luv3++ = (int16_t)(v * (1L << 15)); + luv++; + } +} + +static void Luv24toRGB(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + uint32_t *luv = (uint32_t *)sp->tbuf; + uint8_t *rgb = (uint8_t *)op; + + while (n-- > 0) + { + float xyz[3]; + + LogLuv24toXYZ(*luv++, xyz); + XYZtoRGB24(xyz, rgb); + rgb += 3; + } +} + +static void Luv24fromXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + uint32_t *luv = (uint32_t *)sp->tbuf; + float *xyz = (float *)op; + + while (n-- > 0) + { + *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth); + xyz += 3; + } +} + +static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + uint32_t *luv = (uint32_t *)sp->tbuf; + int16_t *luv3 = (int16_t *)op; + + while (n-- > 0) + { + int Le, Ce; + + if (luv3[0] <= 0) + Le = 0; + else if (luv3[0] >= (1 << 12) + 3314) + Le = (1 << 10) - 1; + else if (sp->encode_meth == SGILOGENCODE_NODITHER) + Le = (luv3[0] - 3314) >> 2; + else + Le = tiff_itrunc(.25 * (luv3[0] - 3314.), sp->encode_meth); + + Ce = uv_encode((luv3[1] + .5) / (1 << 15), (luv3[2] + .5) / (1 << 15), + sp->encode_meth); + if (Ce < 0) /* never happens */ + Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); + *luv++ = (uint32_t)Le << 14 | Ce; + luv3 += 3; + } +} + +#if !LOGLUV_PUBLIC +static +#endif + void + LogLuv32toXYZ(uint32_t p, float *XYZ) +{ + double L, u, v, s, x, y; + /* decode luminance */ + L = LogL16toY((int)p >> 16); + if (L <= 0.) + { + XYZ[0] = XYZ[1] = XYZ[2] = 0.; + return; + } + /* decode color */ + u = 1. / UVSCALE * ((p >> 8 & 0xff) + .5); + v = 1. / UVSCALE * ((p & 0xff) + .5); + s = 1. / (6. * u - 16. * v + 12.); + x = 9. * u * s; + y = 4. * v * s; + /* convert to XYZ */ + XYZ[0] = (float)(x / y * L); + XYZ[1] = (float)L; + XYZ[2] = (float)((1. - x - y) / y * L); +} + +#if !LOGLUV_PUBLIC +static +#endif + uint32_t + LogLuv32fromXYZ(float *XYZ, int em) +{ + unsigned int Le, ue, ve; + double u, v, s; + /* encode luminance */ + Le = (unsigned int)LogL16fromY(XYZ[1], em); + /* encode color */ + s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2]; + if (!Le || s <= 0.) + { + u = U_NEU; + v = V_NEU; + } + else + { + u = 4. * XYZ[0] / s; + v = 9. * XYZ[1] / s; + } + if (u <= 0.) + ue = 0; + else + ue = tiff_itrunc(UVSCALE * u, em); + if (ue > 255) + ue = 255; + if (v <= 0.) + ve = 0; + else + ve = tiff_itrunc(UVSCALE * v, em); + if (ve > 255) + ve = 255; + /* combine encodings */ + return (Le << 16 | ue << 8 | ve); +} + +static void Luv32toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + uint32_t *luv = (uint32_t *)sp->tbuf; + float *xyz = (float *)op; + + while (n-- > 0) + { + LogLuv32toXYZ(*luv++, xyz); + xyz += 3; + } +} + +static void Luv32toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + uint32_t *luv = (uint32_t *)sp->tbuf; + int16_t *luv3 = (int16_t *)op; + + while (n-- > 0) + { + double u, v; + + *luv3++ = (int16_t)(*luv >> 16); + u = 1. / UVSCALE * ((*luv >> 8 & 0xff) + .5); + v = 1. / UVSCALE * ((*luv & 0xff) + .5); + *luv3++ = (int16_t)(u * (1L << 15)); + *luv3++ = (int16_t)(v * (1L << 15)); + luv++; + } +} + +static void Luv32toRGB(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + uint32_t *luv = (uint32_t *)sp->tbuf; + uint8_t *rgb = (uint8_t *)op; + + while (n-- > 0) + { + float xyz[3]; + + LogLuv32toXYZ(*luv++, xyz); + XYZtoRGB24(xyz, rgb); + rgb += 3; + } +} + +static void Luv32fromXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + uint32_t *luv = (uint32_t *)sp->tbuf; + float *xyz = (float *)op; + + while (n-- > 0) + { + *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth); + xyz += 3; + } +} + +static void Luv32fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + uint32_t *luv = (uint32_t *)sp->tbuf; + int16_t *luv3 = (int16_t *)op; + + if (sp->encode_meth == SGILOGENCODE_NODITHER) + { + while (n-- > 0) + { + *luv++ = (uint32_t)luv3[0] << 16 | + (luv3[1] * (uint32_t)(UVSCALE + .5) >> 7 & 0xff00) | + (luv3[2] * (uint32_t)(UVSCALE + .5) >> 15 & 0xff); + luv3 += 3; + } + return; + } + while (n-- > 0) + { + *luv++ = + (uint32_t)luv3[0] << 16 | + (tiff_itrunc(luv3[1] * (UVSCALE / (1 << 15)), sp->encode_meth) + << 8 & + 0xff00) | + (tiff_itrunc(luv3[2] * (UVSCALE / (1 << 15)), sp->encode_meth) & + 0xff); + luv3 += 3; + } +} + +static void _logLuvNop(LogLuvState *sp, uint8_t *op, tmsize_t n) +{ + (void)sp; + (void)op; + (void)n; +} + +static int LogL16GuessDataFmt(TIFFDirectory *td) +{ +#define PACK(s, b, f) (((b) << 6) | ((s) << 3) | (f)) + switch ( + PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) + { + case PACK(1, 32, SAMPLEFORMAT_IEEEFP): + return (SGILOGDATAFMT_FLOAT); + case PACK(1, 16, SAMPLEFORMAT_VOID): + case PACK(1, 16, SAMPLEFORMAT_INT): + case PACK(1, 16, SAMPLEFORMAT_UINT): + return (SGILOGDATAFMT_16BIT); + case PACK(1, 8, SAMPLEFORMAT_VOID): + case PACK(1, 8, SAMPLEFORMAT_UINT): + return (SGILOGDATAFMT_8BIT); + } +#undef PACK + return (SGILOGDATAFMT_UNKNOWN); +} + +static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) +{ + return _TIFFMultiplySSize(NULL, m1, m2, NULL); +} + +static int LogL16InitState(TIFF *tif) +{ + static const char module[] = "LogL16InitState"; + TIFFDirectory *td = &tif->tif_dir; + LogLuvState *sp = DecoderState(tif); + + assert(sp != NULL); + assert(td->td_photometric == PHOTOMETRIC_LOGL); + + if (td->td_samplesperpixel != 1) + { + TIFFErrorExtR(tif, module, + "Sorry, can not handle LogL image with %s=%" PRIu16, + "Samples/pixel", td->td_samplesperpixel); + return 0; + } + + /* for some reason, we can't do this in TIFFInitLogL16 */ + if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) + sp->user_datafmt = LogL16GuessDataFmt(td); + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->pixel_size = sizeof(float); + break; + case SGILOGDATAFMT_16BIT: + sp->pixel_size = sizeof(int16_t); + break; + case SGILOGDATAFMT_8BIT: + sp->pixel_size = sizeof(uint8_t); + break; + default: + TIFFErrorExtR(tif, module, + "No support for converting user data format to LogL"); + return (0); + } + if (isTiled(tif)) + sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); + else if (td->td_rowsperstrip < td->td_imagelength) + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + else + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); + if (multiply_ms(sp->tbuflen, sizeof(int16_t)) == 0 || + (sp->tbuf = (uint8_t *)_TIFFmallocExt( + tif, sp->tbuflen * sizeof(int16_t))) == NULL) + { + TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); + return (0); + } + return (1); +} + +static int LogLuvGuessDataFmt(TIFFDirectory *td) +{ + int guess; + + /* + * If the user didn't tell us their datafmt, + * take our best guess from the bitspersample. + */ +#define PACK(a, b) (((a) << 3) | (b)) + switch (PACK(td->td_bitspersample, td->td_sampleformat)) + { + case PACK(32, SAMPLEFORMAT_IEEEFP): + guess = SGILOGDATAFMT_FLOAT; + break; + case PACK(32, SAMPLEFORMAT_VOID): + case PACK(32, SAMPLEFORMAT_UINT): + case PACK(32, SAMPLEFORMAT_INT): + guess = SGILOGDATAFMT_RAW; + break; + case PACK(16, SAMPLEFORMAT_VOID): + case PACK(16, SAMPLEFORMAT_INT): + case PACK(16, SAMPLEFORMAT_UINT): + guess = SGILOGDATAFMT_16BIT; + break; + case PACK(8, SAMPLEFORMAT_VOID): + case PACK(8, SAMPLEFORMAT_UINT): + guess = SGILOGDATAFMT_8BIT; + break; + default: + guess = SGILOGDATAFMT_UNKNOWN; + break; +#undef PACK + } + /* + * Double-check samples per pixel. + */ + switch (td->td_samplesperpixel) + { + case 1: + if (guess != SGILOGDATAFMT_RAW) + guess = SGILOGDATAFMT_UNKNOWN; + break; + case 3: + if (guess == SGILOGDATAFMT_RAW) + guess = SGILOGDATAFMT_UNKNOWN; + break; + default: + guess = SGILOGDATAFMT_UNKNOWN; + break; + } + return (guess); +} + +static int LogLuvInitState(TIFF *tif) +{ + static const char module[] = "LogLuvInitState"; + TIFFDirectory *td = &tif->tif_dir; + LogLuvState *sp = DecoderState(tif); + + assert(sp != NULL); + assert(td->td_photometric == PHOTOMETRIC_LOGLUV); + + /* for some reason, we can't do this in TIFFInitLogLuv */ + if (td->td_planarconfig != PLANARCONFIG_CONTIG) + { + TIFFErrorExtR(tif, module, + "SGILog compression cannot handle non-contiguous data"); + return (0); + } + if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) + sp->user_datafmt = LogLuvGuessDataFmt(td); + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->pixel_size = 3 * sizeof(float); + break; + case SGILOGDATAFMT_16BIT: + sp->pixel_size = 3 * sizeof(int16_t); + break; + case SGILOGDATAFMT_RAW: + sp->pixel_size = sizeof(uint32_t); + break; + case SGILOGDATAFMT_8BIT: + sp->pixel_size = 3 * sizeof(uint8_t); + break; + default: + TIFFErrorExtR( + tif, module, + "No support for converting user data format to LogLuv"); + return (0); + } + if (isTiled(tif)) + sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); + else if (td->td_rowsperstrip < td->td_imagelength) + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + else + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); + if (multiply_ms(sp->tbuflen, sizeof(uint32_t)) == 0 || + (sp->tbuf = (uint8_t *)_TIFFmallocExt( + tif, sp->tbuflen * sizeof(uint32_t))) == NULL) + { + TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); + return (0); + } + return (1); +} + +static int LogLuvFixupTags(TIFF *tif) +{ + (void)tif; + return (1); +} + +static int LogLuvSetupDecode(TIFF *tif) +{ + static const char module[] = "LogLuvSetupDecode"; + LogLuvState *sp = DecoderState(tif); + TIFFDirectory *td = &tif->tif_dir; + + tif->tif_postdecode = _TIFFNoPostDecode; + switch (td->td_photometric) + { + case PHOTOMETRIC_LOGLUV: + if (!LogLuvInitState(tif)) + break; + if (td->td_compression == COMPRESSION_SGILOG24) + { + tif->tif_decoderow = LogLuvDecode24; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv24toXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv24toLuv48; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = Luv24toRGB; + break; + } + } + else + { + tif->tif_decoderow = LogLuvDecode32; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv32toXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv32toLuv48; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = Luv32toRGB; + break; + } + } + return (1); + case PHOTOMETRIC_LOGL: + if (!LogL16InitState(tif)) + break; + tif->tif_decoderow = LogL16Decode; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = L16toY; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = L16toGry; + break; + } + return (1); + default: + TIFFErrorExtR(tif, module, + "Inappropriate photometric interpretation %" PRIu16 + " for SGILog compression; %s", + td->td_photometric, "must be either LogLUV or LogL"); + break; + } + return (0); +} + +static int LogLuvSetupEncode(TIFF *tif) +{ + static const char module[] = "LogLuvSetupEncode"; + LogLuvState *sp = EncoderState(tif); + TIFFDirectory *td = &tif->tif_dir; + + switch (td->td_photometric) + { + case PHOTOMETRIC_LOGLUV: + if (!LogLuvInitState(tif)) + return (0); + if (td->td_compression == COMPRESSION_SGILOG24) + { + tif->tif_encoderow = LogLuvEncode24; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv24fromXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv24fromLuv48; + break; + case SGILOGDATAFMT_RAW: + break; + default: + goto notsupported; + } + } + else + { + tif->tif_encoderow = LogLuvEncode32; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv32fromXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv32fromLuv48; + break; + case SGILOGDATAFMT_RAW: + break; + default: + goto notsupported; + } + } + break; + case PHOTOMETRIC_LOGL: + if (!LogL16InitState(tif)) + return (0); + tif->tif_encoderow = LogL16Encode; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = L16fromY; + break; + case SGILOGDATAFMT_16BIT: + break; + default: + goto notsupported; + } + break; + default: + TIFFErrorExtR(tif, module, + "Inappropriate photometric interpretation %" PRIu16 + " for SGILog compression; %s", + td->td_photometric, "must be either LogLUV or LogL"); + return (0); + } + sp->encoder_state = 1; + return (1); +notsupported: + TIFFErrorExtR(tif, module, + "SGILog compression supported only for %s, or raw data", + td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv"); + return (0); +} + +static void LogLuvClose(TIFF *tif) +{ + LogLuvState *sp = (LogLuvState *)tif->tif_data; + TIFFDirectory *td = &tif->tif_dir; + + assert(sp != 0); + /* + * For consistency, we always want to write out the same + * bitspersample and sampleformat for our TIFF file, + * regardless of the data format being used by the application. + * Since this routine is called after tags have been set but + * before they have been recorded in the file, we reset them here. + * Note: this is really a nasty approach. See PixarLogClose + */ + if (sp->encoder_state) + { + /* See PixarLogClose. Might avoid issues with tags whose size depends + * on those below, but not completely sure this is enough. */ + td->td_samplesperpixel = + (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; + td->td_bitspersample = 16; + td->td_sampleformat = SAMPLEFORMAT_INT; + } +} + +static void LogLuvCleanup(TIFF *tif) +{ + LogLuvState *sp = (LogLuvState *)tif->tif_data; + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->tbuf) + _TIFFfreeExt(tif, sp->tbuf); + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static int LogLuvVSetField(TIFF *tif, uint32_t tag, va_list ap) +{ + static const char module[] = "LogLuvVSetField"; + LogLuvState *sp = DecoderState(tif); + int bps, fmt; + + switch (tag) + { + case TIFFTAG_SGILOGDATAFMT: + sp->user_datafmt = (int)va_arg(ap, int); + /* + * Tweak the TIFF header so that the rest of libtiff knows what + * size of data will be passed between app and library, and + * assume that the app knows what it is doing and is not + * confused by these header manipulations... + */ + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + bps = 32; + fmt = SAMPLEFORMAT_IEEEFP; + break; + case SGILOGDATAFMT_16BIT: + bps = 16; + fmt = SAMPLEFORMAT_INT; + break; + case SGILOGDATAFMT_RAW: + bps = 32; + fmt = SAMPLEFORMAT_UINT; + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); + break; + case SGILOGDATAFMT_8BIT: + bps = 8; + fmt = SAMPLEFORMAT_UINT; + break; + default: + TIFFErrorExtR( + tif, tif->tif_name, + "Unknown data format %d for LogLuv compression", + sp->user_datafmt); + return (0); + } + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt); + /* + * Must recalculate sizes should bits/sample change. + */ + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1; + tif->tif_scanlinesize = TIFFScanlineSize(tif); + return (1); + case TIFFTAG_SGILOGENCODE: + sp->encode_meth = (int)va_arg(ap, int); + if (sp->encode_meth != SGILOGENCODE_NODITHER && + sp->encode_meth != SGILOGENCODE_RANDITHER) + { + TIFFErrorExtR(tif, module, + "Unknown encoding %d for LogLuv compression", + sp->encode_meth); + return (0); + } + return (1); + default: + return (*sp->vsetparent)(tif, tag, ap); + } +} + +static int LogLuvVGetField(TIFF *tif, uint32_t tag, va_list ap) +{ + LogLuvState *sp = (LogLuvState *)tif->tif_data; + + switch (tag) + { + case TIFFTAG_SGILOGDATAFMT: + *va_arg(ap, int *) = sp->user_datafmt; + return (1); + default: + return (*sp->vgetparent)(tif, tag, ap); + } } static const TIFFField LogLuvFields[] = { - { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL}, - { TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL} -}; + {TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL}, + {TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL}}; -int -TIFFInitSGILog(TIFF* tif, int scheme) +int TIFFInitSGILog(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitSGILog"; - LogLuvState* sp; + static const char module[] = "TIFFInitSGILog"; + LogLuvState *sp; - assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG); + assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG); - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, LogLuvFields, - TIFFArrayCount(LogLuvFields))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Merging SGILog codec-specific tags failed"); - return 0; - } + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, LogLuvFields, TIFFArrayCount(LogLuvFields))) + { + TIFFErrorExtR(tif, module, "Merging SGILog codec-specific tags failed"); + return 0; + } - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LogLuvState)); - if (tif->tif_data == NULL) - goto bad; - sp = (LogLuvState*) tif->tif_data; - _TIFFmemset((void*)sp, 0, sizeof (*sp)); - sp->user_datafmt = SGILOGDATAFMT_UNKNOWN; - sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ? - SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER; - sp->tfunc = _logLuvNop; + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LogLuvState)); + if (tif->tif_data == NULL) + goto bad; + sp = (LogLuvState *)tif->tif_data; + _TIFFmemset((void *)sp, 0, sizeof(*sp)); + sp->user_datafmt = SGILOGDATAFMT_UNKNOWN; + sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ? SGILOGENCODE_RANDITHER + : SGILOGENCODE_NODITHER; + sp->tfunc = _logLuvNop; - /* - * Install codec methods. - * NB: tif_decoderow & tif_encoderow are filled - * in at setup time. - */ - tif->tif_fixuptags = LogLuvFixupTags; - tif->tif_setupdecode = LogLuvSetupDecode; - tif->tif_decodestrip = LogLuvDecodeStrip; - tif->tif_decodetile = LogLuvDecodeTile; - tif->tif_setupencode = LogLuvSetupEncode; - tif->tif_encodestrip = LogLuvEncodeStrip; - tif->tif_encodetile = LogLuvEncodeTile; - tif->tif_close = LogLuvClose; - tif->tif_cleanup = LogLuvCleanup; + /* + * Install codec methods. + * NB: tif_decoderow & tif_encoderow are filled + * in at setup time. + */ + tif->tif_fixuptags = LogLuvFixupTags; + tif->tif_setupdecode = LogLuvSetupDecode; + tif->tif_decodestrip = LogLuvDecodeStrip; + tif->tif_decodetile = LogLuvDecodeTile; + tif->tif_setupencode = LogLuvSetupEncode; + tif->tif_encodestrip = LogLuvEncodeStrip; + tif->tif_encodetile = LogLuvEncodeTile; + tif->tif_close = LogLuvClose; + tif->tif_cleanup = LogLuvCleanup; - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = LogLuvVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = LogLuvVSetField; /* hook for codec tags */ + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = LogLuvVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = LogLuvVSetField; /* hook for codec tags */ - return (1); + return (1); bad: - TIFFErrorExt(tif->tif_clientdata, module, - "%s: No space for LogLuv state block", tif->tif_name); - return (0); + TIFFErrorExtR(tif, module, "%s: No space for LogLuv state block", + tif->tif_name); + return (0); } #endif /* LOGLUV_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_lzma.c b/3rdparty/libtiff/tif_lzma.c index e150bd635d..4cfd5e8821 100644 --- a/3rdparty/libtiff/tif_lzma.c +++ b/3rdparty/libtiff/tif_lzma.c @@ -33,471 +33,488 @@ * The codec is derived from ZLIB codec (tif_zip.c). */ -#include "tif_predict.h" #include "lzma.h" +#include "tif_predict.h" #include /* * State block for each open TIFF file using LZMA2 compression/decompression. */ -typedef struct { - TIFFPredictorState predict; - lzma_stream stream; - lzma_filter filters[LZMA_FILTERS_MAX + 1]; - lzma_options_delta opt_delta; /* delta filter options */ - lzma_options_lzma opt_lzma; /* LZMA2 filter options */ - int preset; /* compression level */ - lzma_check check; /* type of the integrity check */ - int state; /* state flags */ +typedef struct +{ + TIFFPredictorState predict; + lzma_stream stream; + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + lzma_options_delta opt_delta; /* delta filter options */ + lzma_options_lzma opt_lzma; /* LZMA2 filter options */ + int preset; /* compression level */ + lzma_check check; /* type of the integrity check */ + int state; /* state flags */ #define LSTATE_INIT_DECODE 0x01 #define LSTATE_INIT_ENCODE 0x02 - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } LZMAState; -#define LState(tif) ((LZMAState*) (tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) +#define LState(tif) ((LZMAState *)(tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) -static int LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); -static int LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); +static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -static const char * -LZMAStrerror(lzma_ret ret) +static const char *LZMAStrerror(lzma_ret ret) { - switch (ret) { - case LZMA_OK: - return "operation completed successfully"; - case LZMA_STREAM_END: - return "end of stream was reached"; - case LZMA_NO_CHECK: - return "input stream has no integrity check"; - case LZMA_UNSUPPORTED_CHECK: - return "cannot calculate the integrity check"; - case LZMA_GET_CHECK: - return "integrity check type is now available"; - case LZMA_MEM_ERROR: - return "cannot allocate memory"; - case LZMA_MEMLIMIT_ERROR: - return "memory usage limit was reached"; - case LZMA_FORMAT_ERROR: - return "file format not recognized"; - case LZMA_OPTIONS_ERROR: - return "invalid or unsupported options"; - case LZMA_DATA_ERROR: - return "data is corrupt"; - case LZMA_BUF_ERROR: - return "no progress is possible (stream is truncated or corrupt)"; - case LZMA_PROG_ERROR: - return "programming error"; - default: - return "unidentified liblzma error"; - } + switch (ret) + { + case LZMA_OK: + return "operation completed successfully"; + case LZMA_STREAM_END: + return "end of stream was reached"; + case LZMA_NO_CHECK: + return "input stream has no integrity check"; + case LZMA_UNSUPPORTED_CHECK: + return "cannot calculate the integrity check"; + case LZMA_GET_CHECK: + return "integrity check type is now available"; + case LZMA_MEM_ERROR: + return "cannot allocate memory"; + case LZMA_MEMLIMIT_ERROR: + return "memory usage limit was reached"; + case LZMA_FORMAT_ERROR: + return "file format not recognized"; + case LZMA_OPTIONS_ERROR: + return "invalid or unsupported options"; + case LZMA_DATA_ERROR: + return "data is corrupt"; + case LZMA_BUF_ERROR: + return "no progress is possible (stream is truncated or corrupt)"; + case LZMA_PROG_ERROR: + return "programming error"; + default: + return "unidentified liblzma error"; + } } -static int -LZMAFixupTags(TIFF* tif) +static int LZMAFixupTags(TIFF *tif) { - (void) tif; - return 1; + (void)tif; + return 1; } -static int -LZMASetupDecode(TIFF* tif) +static int LZMASetupDecode(TIFF *tif) { - LZMAState* sp = DecoderState(tif); + LZMAState *sp = DecoderState(tif); - assert(sp != NULL); - - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) { - lzma_end(&sp->stream); - sp->state = 0; - } + assert(sp != NULL); - sp->state |= LSTATE_INIT_DECODE; - return 1; + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) + { + lzma_end(&sp->stream); + sp->state = 0; + } + + sp->state |= LSTATE_INIT_DECODE; + return 1; } /* * Setup state for decoding a strip. */ -static int -LZMAPreDecode(TIFF* tif, uint16 s) +static int LZMAPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "LZMAPreDecode"; - LZMAState* sp = DecoderState(tif); - lzma_ret ret; + static const char module[] = "LZMAPreDecode"; + LZMAState *sp = DecoderState(tif); + lzma_ret ret; - (void) s; - assert(sp != NULL); + (void)s; + assert(sp != NULL); - if( (sp->state & LSTATE_INIT_DECODE) == 0 ) - tif->tif_setupdecode(tif); + if ((sp->state & LSTATE_INIT_DECODE) == 0) + tif->tif_setupdecode(tif); - sp->stream.next_in = tif->tif_rawdata; - sp->stream.avail_in = (size_t) tif->tif_rawcc; - if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) { - TIFFErrorExt(tif->tif_clientdata, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } + sp->stream.next_in = tif->tif_rawdata; + sp->stream.avail_in = (size_t)tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) + { + TIFFErrorExtR(tif, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } - /* - * Disable memory limit when decoding. UINT64_MAX is a flag to disable - * the limit, we are passing (uint64_t)-1 which should be the same. - */ - ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0); - if (ret != LZMA_OK) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error initializing the stream decoder, %s", - LZMAStrerror(ret)); - return 0; - } - return 1; + /* + * Disable memory limit when decoding. UINT64_MAX is a flag to disable + * the limit, we are passing (uint64_t)-1 which should be the same. + */ + ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0); + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, "Error initializing the stream decoder, %s", + LZMAStrerror(ret)); + return 0; + } + return 1; } -static int -LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "LZMADecode"; - LZMAState* sp = DecoderState(tif); + static const char module[] = "LZMADecode"; + LZMAState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); + (void)s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); - sp->stream.next_in = tif->tif_rawcp; - sp->stream.avail_in = (size_t) tif->tif_rawcc; + sp->stream.next_in = tif->tif_rawcp; + sp->stream.avail_in = (size_t)tif->tif_rawcc; - sp->stream.next_out = op; - sp->stream.avail_out = (size_t) occ; - if ((tmsize_t)sp->stream.avail_out != occ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } + sp->stream.next_out = op; + sp->stream.avail_out = (size_t)occ; + if ((tmsize_t)sp->stream.avail_out != occ) + { + TIFFErrorExtR(tif, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } - do { - /* - * Save the current stream state to properly recover from the - * decoding errors later. - */ - const uint8_t *next_in = sp->stream.next_in; - size_t avail_in = sp->stream.avail_in; + do + { + /* + * Save the current stream state to properly recover from the + * decoding errors later. + */ + const uint8_t *next_in = sp->stream.next_in; + size_t avail_in = sp->stream.avail_in; - lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); - if (ret == LZMA_STREAM_END) - break; - if (ret == LZMA_MEMLIMIT_ERROR) { - lzma_ret r = lzma_stream_decoder(&sp->stream, - lzma_memusage(&sp->stream), 0); - if (r != LZMA_OK) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error initializing the stream decoder, %s", - LZMAStrerror(r)); - break; - } - sp->stream.next_in = next_in; - sp->stream.avail_in = avail_in; - continue; - } - if (ret != LZMA_OK) { - TIFFErrorExt(tif->tif_clientdata, module, - "Decoding error at scanline %lu, %s", - (unsigned long) tif->tif_row, LZMAStrerror(ret)); - break; - } - } while (sp->stream.avail_out > 0); - if (sp->stream.avail_out != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %lu (short %lu bytes)", - (unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out); - return 0; - } + lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); + if (ret == LZMA_STREAM_END) + break; + if (ret == LZMA_MEMLIMIT_ERROR) + { + lzma_ret r = + lzma_stream_decoder(&sp->stream, lzma_memusage(&sp->stream), 0); + if (r != LZMA_OK) + { + TIFFErrorExtR(tif, module, + "Error initializing the stream decoder, %s", + LZMAStrerror(r)); + break; + } + sp->stream.next_in = next_in; + sp->stream.avail_in = avail_in; + continue; + } + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, + "Decoding error at scanline %" PRIu32 ", %s", + tif->tif_row, LZMAStrerror(ret)); + break; + } + } while (sp->stream.avail_out > 0); + if (sp->stream.avail_out != 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %" PRIu32 + " (short %" TIFF_SIZE_FORMAT " bytes)", + tif->tif_row, sp->stream.avail_out); + return 0; + } - tif->tif_rawcp = (uint8 *)sp->stream.next_in; /* cast away const */ - tif->tif_rawcc = sp->stream.avail_in; - - return 1; + tif->tif_rawcp = (uint8_t *)sp->stream.next_in; /* cast away const */ + tif->tif_rawcc = sp->stream.avail_in; + + return 1; } -static int -LZMASetupEncode(TIFF* tif) +static int LZMASetupEncode(TIFF *tif) { - LZMAState* sp = EncoderState(tif); + LZMAState *sp = EncoderState(tif); - assert(sp != NULL); - if (sp->state & LSTATE_INIT_DECODE) { - lzma_end(&sp->stream); - sp->state = 0; - } + assert(sp != NULL); + if (sp->state & LSTATE_INIT_DECODE) + { + lzma_end(&sp->stream); + sp->state = 0; + } - sp->state |= LSTATE_INIT_ENCODE; - return 1; + sp->state |= LSTATE_INIT_ENCODE; + return 1; } /* * Reset encoding state at the start of a strip. */ -static int -LZMAPreEncode(TIFF* tif, uint16 s) +static int LZMAPreEncode(TIFF *tif, uint16_t s) { - static const char module[] = "LZMAPreEncode"; - LZMAState *sp = EncoderState(tif); - lzma_ret ret; + static const char module[] = "LZMAPreEncode"; + LZMAState *sp = EncoderState(tif); + lzma_ret ret; - (void) s; - assert(sp != NULL); - if( sp->state != LSTATE_INIT_ENCODE ) - tif->tif_setupencode(tif); + (void)s; + assert(sp != NULL); + if (sp->state != LSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (size_t)tif->tif_rawdatasize; - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { - TIFFErrorExt(tif->tif_clientdata, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - ret = lzma_stream_encoder(&sp->stream, sp->filters, sp->check); - if (ret != LZMA_OK) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error in lzma_stream_encoder(): %s", LZMAStrerror(ret)); - return 0; - } - return 1; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (size_t)tif->tif_rawdatasize; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + TIFFErrorExtR(tif, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + ret = lzma_stream_encoder(&sp->stream, sp->filters, sp->check); + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, "Error in lzma_stream_encoder(): %s", + LZMAStrerror(ret)); + return 0; + } + return 1; } /* * Encode a chunk of pixels. */ -static int -LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "LZMAEncode"; - LZMAState *sp = EncoderState(tif); + static const char module[] = "LZMAEncode"; + LZMAState *sp = EncoderState(tif); - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); - (void) s; - sp->stream.next_in = bp; - sp->stream.avail_in = (size_t) cc; - if ((tmsize_t)sp->stream.avail_in != cc) { - TIFFErrorExt(tif->tif_clientdata, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - do { - lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); - if (ret != LZMA_OK) { - TIFFErrorExt(tif->tif_clientdata, module, - "Encoding error at scanline %lu, %s", - (unsigned long) tif->tif_row, LZMAStrerror(ret)); - return 0; - } - if (sp->stream.avail_out == 0) { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in LZMAPreEncode */ - } - } while (sp->stream.avail_in > 0); - return 1; + (void)s; + sp->stream.next_in = bp; + sp->stream.avail_in = (size_t)cc; + if ((tmsize_t)sp->stream.avail_in != cc) + { + TIFFErrorExtR(tif, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + do + { + lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, + "Encoding error at scanline %" PRIu32 ", %s", + tif->tif_row, LZMAStrerror(ret)); + return 0; + } + if (sp->stream.avail_out == 0) + { + tif->tif_rawcc = tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (size_t) + tif->tif_rawdatasize; /* this is a safe typecast, as check + is made already in LZMAPreEncode */ + } + } while (sp->stream.avail_in > 0); + return 1; } /* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ -static int -LZMAPostEncode(TIFF* tif) +static int LZMAPostEncode(TIFF *tif) { - static const char module[] = "LZMAPostEncode"; - LZMAState *sp = EncoderState(tif); - lzma_ret ret; + static const char module[] = "LZMAPostEncode"; + LZMAState *sp = EncoderState(tif); + lzma_ret ret; - sp->stream.avail_in = 0; - do { - ret = lzma_code(&sp->stream, LZMA_FINISH); - switch (ret) { - case LZMA_STREAM_END: - case LZMA_OK: - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { - tif->tif_rawcc = - tif->tif_rawdatasize - sp->stream.avail_out; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ - } - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, "Liblzma error: %s", - LZMAStrerror(ret)); - return 0; - } - } while (ret != LZMA_STREAM_END); - return 1; + sp->stream.avail_in = 0; + do + { + ret = lzma_code(&sp->stream, LZMA_FINISH); + switch (ret) + { + case LZMA_STREAM_END: + case LZMA_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (size_t) + tif->tif_rawdatasize; /* this is a safe typecast, as + check is made already in + ZIPPreEncode */ + } + break; + default: + TIFFErrorExtR(tif, module, "Liblzma error: %s", + LZMAStrerror(ret)); + return 0; + } + } while (ret != LZMA_STREAM_END); + return 1; } -static void -LZMACleanup(TIFF* tif) +static void LZMACleanup(TIFF *tif) { - LZMAState* sp = LState(tif); + LZMAState *sp = LState(tif); - assert(sp != 0); + assert(sp != 0); - (void)TIFFPredictorCleanup(tif); + (void)TIFFPredictorCleanup(tif); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; - if (sp->state) { - lzma_end(&sp->stream); - sp->state = 0; - } - _TIFFfree(sp); - tif->tif_data = NULL; + if (sp->state) + { + lzma_end(&sp->stream); + sp->state = 0; + } + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -static int -LZMAVSetField(TIFF* tif, uint32 tag, va_list ap) +static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "LZMAVSetField"; - LZMAState* sp = LState(tif); + static const char module[] = "LZMAVSetField"; + LZMAState *sp = LState(tif); - switch (tag) { - case TIFFTAG_LZMAPRESET: - sp->preset = (int) va_arg(ap, int); - lzma_lzma_preset(&sp->opt_lzma, sp->preset); - if (sp->state & LSTATE_INIT_ENCODE) { - lzma_ret ret = lzma_stream_encoder(&sp->stream, - sp->filters, - sp->check); - if (ret != LZMA_OK) { - TIFFErrorExt(tif->tif_clientdata, module, - "Liblzma error: %s", - LZMAStrerror(ret)); - } - } - return 1; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ + switch (tag) + { + case TIFFTAG_LZMAPRESET: + sp->preset = (int)va_arg(ap, int); + lzma_lzma_preset(&sp->opt_lzma, sp->preset); + if (sp->state & LSTATE_INIT_ENCODE) + { + lzma_ret ret = + lzma_stream_encoder(&sp->stream, sp->filters, sp->check); + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, "Liblzma error: %s", + LZMAStrerror(ret)); + } + } + return 1; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ } -static int -LZMAVGetField(TIFF* tif, uint32 tag, va_list ap) +static int LZMAVGetField(TIFF *tif, uint32_t tag, va_list ap) { - LZMAState* sp = LState(tif); + LZMAState *sp = LState(tif); - switch (tag) { - case TIFFTAG_LZMAPRESET: - *va_arg(ap, int*) = sp->preset; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; + switch (tag) + { + case TIFFTAG_LZMAPRESET: + *va_arg(ap, int *) = sp->preset; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; } static const TIFFField lzmaFields[] = { - { TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "LZMA2 Compression Preset", NULL }, + {TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, + "LZMA2 Compression Preset", NULL}, }; -int -TIFFInitLZMA(TIFF* tif, int scheme) +int TIFFInitLZMA(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitLZMA"; - LZMAState* sp; - lzma_stream tmp_stream = LZMA_STREAM_INIT; + static const char module[] = "TIFFInitLZMA"; + LZMAState *sp; + lzma_stream tmp_stream = LZMA_STREAM_INIT; - (void)scheme; - assert( scheme == COMPRESSION_LZMA ); + (void)scheme; + assert(scheme == COMPRESSION_LZMA); - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Merging LZMA2 codec-specific tags failed"); - return 0; - } + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) + { + TIFFErrorExtR(tif, module, "Merging LZMA2 codec-specific tags failed"); + return 0; + } - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZMAState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream)); + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZMAState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream)); - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */ + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */ - /* Default values for codec-specific fields */ - sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */ - sp->check = LZMA_CHECK_NONE; - sp->state = 0; + /* Default values for codec-specific fields */ + sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */ + sp->check = LZMA_CHECK_NONE; + sp->state = 0; - /* Data filters. So far we are using delta and LZMA2 filters only. */ - sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE; - /* - * The sample size in bytes seems to be reasonable distance for delta - * filter. - */ - sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ? - 1 : tif->tif_dir.td_bitspersample / 8; - sp->filters[0].id = LZMA_FILTER_DELTA; - sp->filters[0].options = &sp->opt_delta; + /* Data filters. So far we are using delta and LZMA2 filters only. */ + sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE; + /* + * The sample size in bytes seems to be reasonable distance for delta + * filter. + */ + sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) + ? 1 + : tif->tif_dir.td_bitspersample / 8; + sp->filters[0].id = LZMA_FILTER_DELTA; + sp->filters[0].options = &sp->opt_delta; - lzma_lzma_preset(&sp->opt_lzma, sp->preset); - sp->filters[1].id = LZMA_FILTER_LZMA2; - sp->filters[1].options = &sp->opt_lzma; + lzma_lzma_preset(&sp->opt_lzma, sp->preset); + sp->filters[1].id = LZMA_FILTER_LZMA2; + sp->filters[1].options = &sp->opt_lzma; - sp->filters[2].id = LZMA_VLI_UNKNOWN; - sp->filters[2].options = NULL; + sp->filters[2].id = LZMA_VLI_UNKNOWN; + sp->filters[2].options = NULL; - /* - * Install codec methods. - */ - tif->tif_fixuptags = LZMAFixupTags; - tif->tif_setupdecode = LZMASetupDecode; - tif->tif_predecode = LZMAPreDecode; - tif->tif_decoderow = LZMADecode; - tif->tif_decodestrip = LZMADecode; - tif->tif_decodetile = LZMADecode; - tif->tif_setupencode = LZMASetupEncode; - tif->tif_preencode = LZMAPreEncode; - tif->tif_postencode = LZMAPostEncode; - tif->tif_encoderow = LZMAEncode; - tif->tif_encodestrip = LZMAEncode; - tif->tif_encodetile = LZMAEncode; - tif->tif_cleanup = LZMACleanup; - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - return 1; + /* + * Install codec methods. + */ + tif->tif_fixuptags = LZMAFixupTags; + tif->tif_setupdecode = LZMASetupDecode; + tif->tif_predecode = LZMAPreDecode; + tif->tif_decoderow = LZMADecode; + tif->tif_decodestrip = LZMADecode; + tif->tif_decodetile = LZMADecode; + tif->tif_setupencode = LZMASetupEncode; + tif->tif_preencode = LZMAPreEncode; + tif->tif_postencode = LZMAPostEncode; + tif->tif_encoderow = LZMAEncode; + tif->tif_encodestrip = LZMAEncode; + tif->tif_encodetile = LZMAEncode; + tif->tif_cleanup = LZMACleanup; + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + return 1; bad: - TIFFErrorExt(tif->tif_clientdata, module, - "No space for LZMA2 state block"); - return 0; + TIFFErrorExtR(tif, module, "No space for LZMA2 state block"); + return 0; } #endif /* LZMA_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/3rdparty/libtiff/tif_lzw.c b/3rdparty/libtiff/tif_lzw.c index d92d0fd354..d631fa1049 100644 --- a/3rdparty/libtiff/tif_lzw.c +++ b/3rdparty/libtiff/tif_lzw.c @@ -1,31 +1,32 @@ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * Copyright (c) 2022 Even Rouault * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "tiffiop.h" #ifdef LZW_SUPPORT /* - * TIFF Library. + * TIFF Library. * Rev 5.0 Lempel-Ziv & Welch Compression Support * * This code is derived from the compress program whose code is @@ -36,7 +37,13 @@ */ #include "tif_predict.h" +#include #include +#include + +/* Select the plausible largest natural integer type for the architecture */ +#define SIZEOF_WORDTYPE SIZEOF_SIZE_T +typedef size_t WordType; /* * NB: The 5.0 spec describes a different algorithm than Aldus @@ -51,34 +58,27 @@ * * Future revisions to the TIFF spec are expected to "clarify this issue". */ -#define LZW_COMPAT /* include backwards compatibility code */ -/* - * Each strip of data is supposed to be terminated by a CODE_EOI. - * If the following #define is included, the decoder will also - * check for end-of-strip w/o seeing this code. This makes the - * library more robust, but also slower. - */ -#define LZW_CHECKEOS /* include checks for strips w/o EOI code */ +#define LZW_COMPAT /* include backwards compatibility code */ -#define MAXCODE(n) ((1L<<(n))-1) +#define MAXCODE(n) ((1L << (n)) - 1) /* * The TIFF spec specifies that encoded bit * strings range from 9 to 12 bits. */ -#define BITS_MIN 9 /* start with 9 bits */ -#define BITS_MAX 12 /* max of 12 bit strings */ +#define BITS_MIN 9 /* start with 9 bits */ +#define BITS_MAX 12 /* max of 12 bit strings */ /* predefined codes */ -#define CODE_CLEAR 256 /* code to clear string table */ -#define CODE_EOI 257 /* end-of-information code */ -#define CODE_FIRST 258 /* first free code entry */ -#define CODE_MAX MAXCODE(BITS_MAX) -#define HSIZE 9001L /* 91% occupancy */ -#define HSHIFT (13-8) +#define CODE_CLEAR 256 /* code to clear string table */ +#define CODE_EOI 257 /* end-of-information code */ +#define CODE_FIRST 258 /* first free code entry */ +#define CODE_MAX MAXCODE(BITS_MAX) +#define HSIZE 9001L /* 91% occupancy */ +#define HSHIFT (13 - 8) #ifdef LZW_COMPAT /* NB: +1024 is for compatibility with old files */ -#define CSIZE (MAXCODE(BITS_MAX)+1024L) +#define CSIZE (MAXCODE(BITS_MAX) + 1024L) #else -#define CSIZE (MAXCODE(BITS_MAX)+1L) +#define CSIZE (MAXCODE(BITS_MAX) + 1L) #endif /* @@ -86,722 +86,936 @@ * compression/decompression. Note that the predictor * state block must be first in this data structure. */ -typedef struct { - TIFFPredictorState predict; /* predictor super class */ +typedef struct +{ + TIFFPredictorState predict; /* predictor super class */ - unsigned short nbits; /* # of bits/code */ - unsigned short maxcode; /* maximum code for lzw_nbits */ - unsigned short free_ent; /* next free entry in hash table */ - unsigned long nextdata; /* next bits of i/o */ - long nextbits; /* # of valid bits in lzw_nextdata */ + unsigned short nbits; /* # of bits/code */ + unsigned short maxcode; /* maximum code for lzw_nbits */ + unsigned short free_ent; /* next free entry in hash table */ + WordType nextdata; /* next bits of i/o */ + long nextbits; /* # of valid bits in lzw_nextdata */ - int rw_mode; /* preserve rw_mode from init */ + int rw_mode; /* preserve rw_mode from init */ } LZWBaseState; -#define lzw_nbits base.nbits -#define lzw_maxcode base.maxcode -#define lzw_free_ent base.free_ent -#define lzw_nextdata base.nextdata -#define lzw_nextbits base.nextbits +#define lzw_nbits base.nbits +#define lzw_maxcode base.maxcode +#define lzw_free_ent base.free_ent +#define lzw_nextdata base.nextdata +#define lzw_nextbits base.nextbits /* * Encoding-specific state. */ -typedef uint16 hcode_t; /* codes fit in 16 bits */ -typedef struct { - long hash; - hcode_t code; +typedef uint16_t hcode_t; /* codes fit in 16 bits */ +typedef struct +{ + long hash; + hcode_t code; } hash_t; /* * Decoding-specific state. */ -typedef struct code_ent { - struct code_ent *next; - unsigned short length; /* string len, including this token */ - unsigned char value; /* data value */ - unsigned char firstchar; /* first token of string */ +typedef struct code_ent +{ + struct code_ent *next; + unsigned short length; /* string len, including this token */ + /* firstchar should be placed immediately before value in this structure */ + unsigned char firstchar; /* first token of string */ + unsigned char value; /* data value */ + bool repeated; } code_t; -typedef int (*decodeFunc)(TIFF*, uint8*, tmsize_t, uint16); +typedef int (*decodeFunc)(TIFF *, uint8_t *, tmsize_t, uint16_t); -typedef struct { - LZWBaseState base; +typedef struct +{ + LZWBaseState base; - /* Decoding specific data */ - long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ - long dec_restart; /* restart count */ -#ifdef LZW_CHECKEOS - uint64 dec_bitsleft; /* available bits in raw data */ - tmsize_t old_tif_rawcc; /* value of tif_rawcc at the end of the previous TIFLZWDecode() call */ -#endif - decodeFunc dec_decode; /* regular or backwards compatible */ - code_t* dec_codep; /* current recognized code */ - code_t* dec_oldcodep; /* previously recognized code */ - code_t* dec_free_entp; /* next free entry */ - code_t* dec_maxcodep; /* max available entry */ - code_t* dec_codetab; /* kept separate for small machines */ + /* Decoding specific data */ + long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ + tmsize_t dec_restart; /* restart count */ + uint64_t dec_bitsleft; /* available bits in raw data */ + tmsize_t old_tif_rawcc; /* value of tif_rawcc at the end of the previous + TIFLZWDecode() call */ + decodeFunc dec_decode; /* regular or backwards compatible */ + code_t *dec_codep; /* current recognized code */ + code_t *dec_oldcodep; /* previously recognized code */ + code_t *dec_free_entp; /* next free entry */ + code_t *dec_maxcodep; /* max available entry */ + code_t *dec_codetab; /* kept separate for small machines */ + int read_error; /* whether a read error has occurred, and which should cause + further reads in the same strip/tile to be aborted */ - /* Encoding specific data */ - int enc_oldcode; /* last code encountered */ - long enc_checkpoint; /* point at which to clear table */ -#define CHECK_GAP 10000 /* enc_ratio check interval */ - long enc_ratio; /* current compression ratio */ - long enc_incount; /* (input) data bytes encoded */ - long enc_outcount; /* encoded (output) bytes */ - uint8* enc_rawlimit; /* bound on tif_rawdata buffer */ - hash_t* enc_hashtab; /* kept separate for small machines */ + /* Encoding specific data */ + int enc_oldcode; /* last code encountered */ + tmsize_t enc_checkpoint; /* point at which to clear table */ +#define CHECK_GAP 10000 /* enc_ratio check interval */ + tmsize_t enc_ratio; /* current compression ratio */ + tmsize_t enc_incount; /* (input) data bytes encoded */ + tmsize_t enc_outcount; /* encoded (output) bytes */ + uint8_t *enc_rawlimit; /* bound on tif_rawdata buffer */ + hash_t *enc_hashtab; /* kept separate for small machines */ } LZWCodecState; -#define LZWState(tif) ((LZWBaseState*) (tif)->tif_data) -#define DecoderState(tif) ((LZWCodecState*) LZWState(tif)) -#define EncoderState(tif) ((LZWCodecState*) LZWState(tif)) +#define LZWState(tif) ((LZWBaseState *)(tif)->tif_data) +#define DecoderState(tif) ((LZWCodecState *)LZWState(tif)) +#define EncoderState(tif) ((LZWCodecState *)LZWState(tif)) -static int LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); +static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s); #ifdef LZW_COMPAT -static int LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); +static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s); #endif -static void cl_hash(LZWCodecState*); +static void cl_hash(LZWCodecState *); /* * LZW Decoder. */ -#ifdef LZW_CHECKEOS -/* - * This check shouldn't be necessary because each - * strip is suppose to be terminated with CODE_EOI. - */ -#define NextCode(_tif, _sp, _bp, _code, _get) { \ - if ((_sp)->dec_bitsleft < (uint64)nbits) { \ - TIFFWarningExt(_tif->tif_clientdata, module, \ - "LZWDecode: Strip %d not terminated with EOI code", \ - _tif->tif_curstrip); \ - _code = CODE_EOI; \ - } else { \ - _get(_sp,_bp,_code); \ - (_sp)->dec_bitsleft -= nbits; \ - } \ -} -#else -#define NextCode(tif, sp, bp, code, get) get(sp, bp, code) -#endif - -static int -LZWFixupTags(TIFF* tif) +static int LZWFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } -static int -LZWSetupDecode(TIFF* tif) +static int LZWSetupDecode(TIFF *tif) { - static const char module[] = "LZWSetupDecode"; - LZWCodecState* sp = DecoderState(tif); - int code; + static const char module[] = "LZWSetupDecode"; + LZWCodecState *sp = DecoderState(tif); + int code; - if( sp == NULL ) - { - /* - * Allocate state block so tag methods have storage to record - * values. - */ - tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZWCodecState)); - if (tif->tif_data == NULL) - { - TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW state block"); - return (0); - } + if (sp == NULL) + { + /* + * Allocate state block so tag methods have storage to record + * values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState)); + if (tif->tif_data == NULL) + { + TIFFErrorExtR(tif, module, "No space for LZW state block"); + return (0); + } - sp = DecoderState(tif); - sp->dec_codetab = NULL; - sp->dec_decode = NULL; + sp = DecoderState(tif); + sp->dec_codetab = NULL; + sp->dec_decode = NULL; - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - } + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + } - if (sp->dec_codetab == NULL) { - sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t)); - if (sp->dec_codetab == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, - "No space for LZW code table"); - return (0); - } - /* - * Pre-load the table. - */ - code = 255; - do { - sp->dec_codetab[code].value = (unsigned char)code; - sp->dec_codetab[code].firstchar = (unsigned char)code; - sp->dec_codetab[code].length = 1; - sp->dec_codetab[code].next = NULL; - } while (code--); - /* - * Zero-out the unused entries - */ - /* Silence false positive */ - /* coverity[overrun-buffer-arg] */ - _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0, - (CODE_FIRST - CODE_CLEAR) * sizeof (code_t)); - } - return (1); + if (sp->dec_codetab == NULL) + { + sp->dec_codetab = (code_t *)_TIFFmallocExt(tif, CSIZE * sizeof(code_t)); + if (sp->dec_codetab == NULL) + { + TIFFErrorExtR(tif, module, "No space for LZW code table"); + return (0); + } + /* + * Pre-load the table. + */ + code = 255; + do + { + sp->dec_codetab[code].firstchar = (unsigned char)code; + sp->dec_codetab[code].value = (unsigned char)code; + sp->dec_codetab[code].repeated = true; + sp->dec_codetab[code].length = 1; + sp->dec_codetab[code].next = NULL; + } while (code--); + /* + * Zero-out the unused entries */ + /* Silence false positive */ + /* coverity[overrun-buffer-arg] */ + memset(&sp->dec_codetab[CODE_CLEAR], 0, + (CODE_FIRST - CODE_CLEAR) * sizeof(code_t)); + } + return (1); } /* * Setup state for decoding a strip. */ -static int -LZWPreDecode(TIFF* tif, uint16 s) +static int LZWPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "LZWPreDecode"; - LZWCodecState *sp = DecoderState(tif); + static const char module[] = "LZWPreDecode"; + LZWCodecState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); - if( sp->dec_codetab == NULL ) - { - tif->tif_setupdecode( tif ); - if( sp->dec_codetab == NULL ) - return (0); - } + (void)s; + assert(sp != NULL); + if (sp->dec_codetab == NULL) + { + tif->tif_setupdecode(tif); + if (sp->dec_codetab == NULL) + return (0); + } - /* - * Check for old bit-reversed codes. - */ - if (tif->tif_rawcc >= 2 && - tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { + /* + * Check for old bit-reversed codes. + */ + if (tif->tif_rawcc >= 2 && tif->tif_rawdata[0] == 0 && + (tif->tif_rawdata[1] & 0x1)) + { #ifdef LZW_COMPAT - if (!sp->dec_decode) { - TIFFWarningExt(tif->tif_clientdata, module, - "Old-style LZW codes, convert file"); - /* - * Override default decoding methods with - * ones that deal with the old coding. - * Otherwise the predictor versions set - * above will call the compatibility routines - * through the dec_decode method. - */ - tif->tif_decoderow = LZWDecodeCompat; - tif->tif_decodestrip = LZWDecodeCompat; - tif->tif_decodetile = LZWDecodeCompat; - /* - * If doing horizontal differencing, must - * re-setup the predictor logic since we - * switched the basic decoder methods... - */ - (*tif->tif_setupdecode)(tif); - sp->dec_decode = LZWDecodeCompat; - } - sp->lzw_maxcode = MAXCODE(BITS_MIN); -#else /* !LZW_COMPAT */ - if (!sp->dec_decode) { - TIFFErrorExt(tif->tif_clientdata, module, - "Old-style LZW codes not supported"); - sp->dec_decode = LZWDecode; - } - return (0); -#endif/* !LZW_COMPAT */ - } else { - sp->lzw_maxcode = MAXCODE(BITS_MIN)-1; - sp->dec_decode = LZWDecode; - } - sp->lzw_nbits = BITS_MIN; - sp->lzw_nextbits = 0; - sp->lzw_nextdata = 0; + if (!sp->dec_decode) + { + TIFFWarningExtR(tif, module, "Old-style LZW codes, convert file"); + /* + * Override default decoding methods with + * ones that deal with the old coding. + * Otherwise the predictor versions set + * above will call the compatibility routines + * through the dec_decode method. + */ + tif->tif_decoderow = LZWDecodeCompat; + tif->tif_decodestrip = LZWDecodeCompat; + tif->tif_decodetile = LZWDecodeCompat; + /* + * If doing horizontal differencing, must + * re-setup the predictor logic since we + * switched the basic decoder methods... + */ + (*tif->tif_setupdecode)(tif); + sp->dec_decode = LZWDecodeCompat; + } + sp->lzw_maxcode = MAXCODE(BITS_MIN); +#else /* !LZW_COMPAT */ + if (!sp->dec_decode) + { + TIFFErrorExtR(tif, module, "Old-style LZW codes not supported"); + sp->dec_decode = LZWDecode; + } + return (0); +#endif /* !LZW_COMPAT */ + } + else + { + sp->lzw_maxcode = MAXCODE(BITS_MIN) - 1; + sp->dec_decode = LZWDecode; + } + sp->lzw_nbits = BITS_MIN; + sp->lzw_nextbits = 0; + sp->lzw_nextdata = 0; - sp->dec_restart = 0; - sp->dec_nbitsmask = MAXCODE(BITS_MIN); -#ifdef LZW_CHECKEOS - sp->dec_bitsleft = 0; - sp->old_tif_rawcc = 0; -#endif - sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; - /* - * Zero entries that are not yet filled in. We do - * this to guard against bogus input data that causes - * us to index into undefined entries. If you can - * come up with a way to safely bounds-check input codes - * while decoding then you can remove this operation. - */ - _TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t)); - sp->dec_oldcodep = &sp->dec_codetab[-1]; - sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1]; - return (1); + sp->dec_restart = 0; + sp->dec_nbitsmask = MAXCODE(BITS_MIN); + sp->dec_bitsleft = 0; + sp->old_tif_rawcc = 0; + sp->dec_free_entp = sp->dec_codetab - 1; // + CODE_FIRST; + /* + * Zero entries that are not yet filled in. We do + * this to guard against bogus input data that causes + * us to index into undefined entries. If you can + * come up with a way to safely bounds-check input codes + * while decoding then you can remove this operation. + */ + sp->dec_oldcodep = &sp->dec_codetab[0]; + sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask - 1]; + sp->read_error = 0; + return (1); } /* * Decode a "hunk of data". */ -#define GetNextCode(sp, bp, code) { \ - nextdata = (nextdata<<8) | *(bp)++; \ - nextbits += 8; \ - if (nextbits < nbits) { \ - nextdata = (nextdata<<8) | *(bp)++; \ - nextbits += 8; \ - } \ - code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask); \ - nextbits -= nbits; \ -} -static void -codeLoop(TIFF* tif, const char* module) -{ - TIFFErrorExt(tif->tif_clientdata, module, - "Bogus encoding, loop in the code table; scanline %d", - tif->tif_row); -} - -static int -LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) -{ - static const char module[] = "LZWDecode"; - LZWCodecState *sp = DecoderState(tif); - char *op = (char*) op0; - long occ = (long) occ0; - char *tp; - unsigned char *bp; - hcode_t code; - int len; - long nbits, nextbits, nbitsmask; - unsigned long nextdata; - code_t *codep, *free_entp, *maxcodep, *oldcodep; - - (void) s; - assert(sp != NULL); - assert(sp->dec_codetab != NULL); - - /* - Fail if value does not fit in long. - */ - if ((tmsize_t) occ != occ0) - return (0); - /* - * Restart interrupted output operation. - */ - if (sp->dec_restart) { - long residue; - - codep = sp->dec_codep; - residue = codep->length - sp->dec_restart; - if (residue > occ) { - /* - * Residue from previous decode is sufficient - * to satisfy decode request. Skip to the - * start of the decoded string, place decoded - * values in the output buffer, and return. - */ - sp->dec_restart += occ; - do { - codep = codep->next; - } while (--residue > occ && codep); - if (codep) { - tp = op + occ; - do { - *--tp = codep->value; - codep = codep->next; - } while (--occ && codep); - } - return (1); - } - /* - * Residue satisfies only part of the decode request. - */ - op += residue; - occ -= residue; - tp = op; - do { - int t; - --tp; - t = codep->value; - codep = codep->next; - *tp = (char)t; - } while (--residue && codep); - sp->dec_restart = 0; - } - - bp = (unsigned char *)tif->tif_rawcp; -#ifdef LZW_CHECKEOS - sp->dec_bitsleft += (((uint64)tif->tif_rawcc - sp->old_tif_rawcc) << 3); -#endif - nbits = sp->lzw_nbits; - nextdata = sp->lzw_nextdata; - nextbits = sp->lzw_nextbits; - nbitsmask = sp->dec_nbitsmask; - oldcodep = sp->dec_oldcodep; - free_entp = sp->dec_free_entp; - maxcodep = sp->dec_maxcodep; - - while (occ > 0) { - NextCode(tif, sp, bp, code, GetNextCode); - if (code == CODE_EOI) - break; - if (code == CODE_CLEAR) { - do { - free_entp = sp->dec_codetab + CODE_FIRST; - _TIFFmemset(free_entp, 0, - (CSIZE - CODE_FIRST) * sizeof (code_t)); - nbits = BITS_MIN; - nbitsmask = MAXCODE(BITS_MIN); - maxcodep = sp->dec_codetab + nbitsmask-1; - NextCode(tif, sp, bp, code, GetNextCode); - } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ - if (code == CODE_EOI) - break; - if (code > CODE_CLEAR) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecode: Corrupted LZW table at scanline %d", - tif->tif_row); - return (0); - } - *op++ = (char)code; - occ--; - oldcodep = sp->dec_codetab + code; - continue; - } - codep = sp->dec_codetab + code; - - /* - * Add the new entry to the code table. - */ - if (free_entp < &sp->dec_codetab[0] || - free_entp >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, module, - "Corrupted LZW table at scanline %d", - tif->tif_row); - return (0); - } - - free_entp->next = oldcodep; - if (free_entp->next < &sp->dec_codetab[0] || - free_entp->next >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, module, - "Corrupted LZW table at scanline %d", - tif->tif_row); - return (0); - } - free_entp->firstchar = free_entp->next->firstchar; - free_entp->length = free_entp->next->length+1; - free_entp->value = (codep < free_entp) ? - codep->firstchar : free_entp->firstchar; - if (++free_entp > maxcodep) { - if (++nbits > BITS_MAX) /* should not happen */ - nbits = BITS_MAX; - nbitsmask = MAXCODE(nbits); - maxcodep = sp->dec_codetab + nbitsmask-1; - } - oldcodep = codep; - if (code >= 256) { - /* - * Code maps to a string, copy string - * value to output (written in reverse). - */ - if(codep->length == 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Wrong length of decoded string: " - "data probably corrupted at scanline %d", - tif->tif_row); - return (0); - } - if (codep->length > occ) { - /* - * String is too long for decode buffer, - * locate portion that will fit, copy to - * the decode buffer, and setup restart - * logic for the next decoding call. - */ - sp->dec_codep = codep; - do { - codep = codep->next; - } while (codep && codep->length > occ); - if (codep) { - sp->dec_restart = (long)occ; - tp = op + occ; - do { - *--tp = codep->value; - codep = codep->next; - } while (--occ && codep); - if (codep) - codeLoop(tif, module); - } - break; - } - len = codep->length; - tp = op + len; - do { - int t; - --tp; - t = codep->value; - codep = codep->next; - *tp = (char)t; - } while (codep && tp > op); - if (codep) { - codeLoop(tif, module); - break; - } - assert(occ >= len); - op += len; - occ -= len; - } else { - *op++ = (char)code; - occ--; - } - } - - tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp ); - tif->tif_rawcp = (uint8*) bp; -#ifdef LZW_CHECKEOS - sp->old_tif_rawcc = tif->tif_rawcc; -#endif - sp->lzw_nbits = (unsigned short) nbits; - sp->lzw_nextdata = nextdata; - sp->lzw_nextbits = nextbits; - sp->dec_nbitsmask = nbitsmask; - sp->dec_oldcodep = oldcodep; - sp->dec_free_entp = free_entp; - sp->dec_maxcodep = maxcodep; - - if (occ > 0) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %d (short %I64d bytes)", - tif->tif_row, (unsigned __int64) occ); +/* Get the next 32 or 64-bit from the input data */ +#ifdef WORDS_BIGENDIAN +#define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)) +#elif SIZEOF_WORDTYPE == 8 +#if defined(__GNUC__) && defined(__x86_64__) +#define GetNextData(nextdata, bp) \ + nextdata = __builtin_bswap64(*(uint64_t *)(bp)) +#elif defined(_M_X64) +#define GetNextData(nextdata, bp) nextdata = _byteswap_uint64(*(uint64_t *)(bp)) +#elif defined(__GNUC__) +#define GetNextData(nextdata, bp) \ + memcpy(&nextdata, bp, sizeof(nextdata)); \ + nextdata = __builtin_bswap64(nextdata) #else - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %d (short %llu bytes)", - tif->tif_row, (unsigned long long) occ); +#define GetNextData(nextdata, bp) \ + nextdata = (((uint64_t)bp[0]) << 56) | (((uint64_t)bp[1]) << 48) | \ + (((uint64_t)bp[2]) << 40) | (((uint64_t)bp[3]) << 32) | \ + (((uint64_t)bp[4]) << 24) | (((uint64_t)bp[5]) << 16) | \ + (((uint64_t)bp[6]) << 8) | (((uint64_t)bp[7])) #endif - return (0); - } - return (1); +#elif SIZEOF_WORDTYPE == 4 +#if defined(__GNUC__) && defined(__i386__) +#define GetNextData(nextdata, bp) \ + nextdata = __builtin_bswap32(*(uint32_t *)(bp)) +#elif defined(_M_X86) +#define GetNextData(nextdata, bp) \ + nextdata = _byteswap_ulong(*(unsigned long *)(bp)) +#elif defined(__GNUC__) +#define GetNextData(nextdata, bp) \ + memcpy(&nextdata, bp, sizeof(nextdata)); \ + nextdata = __builtin_bswap32(nextdata) +#else +#define GetNextData(nextdata, bp) \ + nextdata = (((uint32_t)bp[0]) << 24) | (((uint32_t)bp[1]) << 16) | \ + (((uint32_t)bp[2]) << 8) | (((uint32_t)bp[3])) +#endif +#else +#error "Unhandled SIZEOF_WORDTYPE" +#endif + +#define GetNextCodeLZW() \ + do \ + { \ + nextbits -= nbits; \ + if (nextbits < 0) \ + { \ + if (dec_bitsleft >= 8 * SIZEOF_WORDTYPE) \ + { \ + unsigned codetmp = (unsigned)(nextdata << (-nextbits)); \ + GetNextData(nextdata, bp); \ + bp += SIZEOF_WORDTYPE; \ + nextbits += 8 * SIZEOF_WORDTYPE; \ + dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \ + code = (WordType)((codetmp | (nextdata >> nextbits)) & \ + nbitsmask); \ + break; \ + } \ + else \ + { \ + if (dec_bitsleft < 8) \ + { \ + goto no_eoi; \ + } \ + nextdata = (nextdata << 8) | *(bp)++; \ + nextbits += 8; \ + dec_bitsleft -= 8; \ + if (nextbits < 0) \ + { \ + if (dec_bitsleft < 8) \ + { \ + goto no_eoi; \ + } \ + nextdata = (nextdata << 8) | *(bp)++; \ + nextbits += 8; \ + dec_bitsleft -= 8; \ + } \ + } \ + } \ + code = (WordType)((nextdata >> nextbits) & nbitsmask); \ + } while (0) + +static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) +{ + static const char module[] = "LZWDecode"; + LZWCodecState *sp = DecoderState(tif); + uint8_t *op = (uint8_t *)op0; + tmsize_t occ = occ0; + uint8_t *bp; + long nbits, nextbits, nbitsmask; + WordType nextdata; + code_t *free_entp, *maxcodep, *oldcodep; + + (void)s; + assert(sp != NULL); + assert(sp->dec_codetab != NULL); + + if (sp->read_error) + { + TIFFErrorExtR(tif, module, + "LZWDecode: Scanline %" PRIu32 " cannot be read due to " + "previous error", + tif->tif_row); + return 0; + } + + /* + * Restart interrupted output operation. + */ + if (sp->dec_restart) + { + tmsize_t residue; + + code_t *codep = sp->dec_codep; + residue = codep->length - sp->dec_restart; + if (residue > occ) + { + /* + * Residue from previous decode is sufficient + * to satisfy decode request. Skip to the + * start of the decoded string, place decoded + * values in the output buffer, and return. + */ + sp->dec_restart += occ; + do + { + codep = codep->next; + } while (--residue > occ && codep); + if (codep) + { + uint8_t *tp = op + occ; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--occ && codep); + } + return (1); + } + /* + * Residue satisfies only part of the decode request. + */ + op += residue; + occ -= residue; + uint8_t *tp = op; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--residue && codep); + sp->dec_restart = 0; + } + + bp = (uint8_t *)tif->tif_rawcp; + sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); + uint64_t dec_bitsleft = sp->dec_bitsleft; + nbits = sp->lzw_nbits; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + nbitsmask = sp->dec_nbitsmask; + oldcodep = sp->dec_oldcodep; + free_entp = sp->dec_free_entp; + maxcodep = sp->dec_maxcodep; + code_t *const dec_codetab = sp->dec_codetab; + code_t *codep; + + if (occ == 0) + { + goto after_loop; + } + +begin: +{ + WordType code; + GetNextCodeLZW(); + codep = dec_codetab + code; + if (code >= CODE_FIRST) + goto code_above_or_equal_to_258; + if (code < 256) + goto code_below_256; + if (code == CODE_EOI) + goto after_loop; + goto code_clear; + +code_below_256: +{ + if (codep > free_entp) + goto error_code; + free_entp->next = oldcodep; + free_entp->firstchar = oldcodep->firstchar; + free_entp->length = oldcodep->length + 1; + free_entp->value = (uint8_t)code; + free_entp->repeated = + (bool)(oldcodep->repeated & (oldcodep->value == code)); + if (++free_entp > maxcodep) + { + if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = dec_codetab + nbitsmask - 1; + if (free_entp >= &dec_codetab[CSIZE]) + { + /* At that point, the next valid states are either EOI or a */ + /* CODE_CLEAR. If a regular code is read, at the next */ + /* attempt at registering a new entry, we will error out */ + /* due to setting free_entp before any valid code */ + free_entp = dec_codetab - 1; + } + } + oldcodep = codep; + *op++ = (uint8_t)code; + occ--; + if (occ == 0) + goto after_loop; + goto begin; +} + +code_above_or_equal_to_258: +{ + /* + * Add the new entry to the code table. + */ + + if (codep >= free_entp) + { + if (codep != free_entp) + goto error_code; + free_entp->value = oldcodep->firstchar; + } + else + { + free_entp->value = codep->firstchar; + } + free_entp->repeated = + (bool)(oldcodep->repeated & (oldcodep->value == free_entp->value)); + free_entp->next = oldcodep; + + free_entp->firstchar = oldcodep->firstchar; + free_entp->length = oldcodep->length + 1; + if (++free_entp > maxcodep) + { + if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = dec_codetab + nbitsmask - 1; + if (free_entp >= &dec_codetab[CSIZE]) + { + /* At that point, the next valid states are either EOI or a */ + /* CODE_CLEAR. If a regular code is read, at the next */ + /* attempt at registering a new entry, we will error out */ + /* due to setting free_entp before any valid code */ + free_entp = dec_codetab - 1; + } + } + oldcodep = codep; + + /* + * Code maps to a string, copy string + * value to output (written in reverse). + */ + /* tiny bit faster on x86_64 to store in unsigned short than int */ + unsigned short len = codep->length; + + if (len < 3) /* equivalent to len == 2 given all other conditions */ + { + if (occ <= 2) + { + if (occ == 2) + { + memcpy(op, &(codep->firstchar), 2); + op += 2; + occ -= 2; + goto after_loop; + } + goto too_short_buffer; + } + + memcpy(op, &(codep->firstchar), 2); + op += 2; + occ -= 2; + goto begin; /* we can save the comparison occ > 0 */ + } + + if (len == 3) + { + if (occ <= 3) + { + if (occ == 3) + { + op[0] = codep->firstchar; + op[1] = codep->next->value; + op[2] = codep->value; + op += 3; + occ -= 3; + goto after_loop; + } + goto too_short_buffer; + } + + op[0] = codep->firstchar; + op[1] = codep->next->value; + op[2] = codep->value; + op += 3; + occ -= 3; + goto begin; /* we can save the comparison occ > 0 */ + } + + if (len > occ) + { + goto too_short_buffer; + } + + if (codep->repeated) + { + memset(op, codep->value, len); + op += len; + occ -= len; + if (occ == 0) + goto after_loop; + goto begin; + } + + uint8_t *tp = op + len; + + assert(len >= 4); + + *--tp = codep->value; + codep = codep->next; + *--tp = codep->value; + codep = codep->next; + *--tp = codep->value; + codep = codep->next; + *--tp = codep->value; + if (tp > op) + { + do + { + codep = codep->next; + *--tp = codep->value; + } while (tp > op); + } + + assert(occ >= len); + op += len; + occ -= len; + if (occ == 0) + goto after_loop; + goto begin; +} + +code_clear: +{ + free_entp = dec_codetab + CODE_FIRST; + nbits = BITS_MIN; + nbitsmask = MAXCODE(BITS_MIN); + maxcodep = dec_codetab + nbitsmask - 1; + do + { + GetNextCodeLZW(); + } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ + if (code == CODE_EOI) + goto after_loop; + if (code > CODE_EOI) + { + goto error_code; + } + *op++ = (uint8_t)code; + occ--; + oldcodep = dec_codetab + code; + if (occ == 0) + goto after_loop; + goto begin; +} +} + +too_short_buffer: +{ + /* + * String is too long for decode buffer, + * locate portion that will fit, copy to + * the decode buffer, and setup restart + * logic for the next decoding call. + */ + sp->dec_codep = codep; + do + { + codep = codep->next; + } while (codep->length > occ); + + sp->dec_restart = occ; + uint8_t *tp = op + occ; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--occ); +} + +after_loop: + tif->tif_rawcc -= (tmsize_t)((uint8_t *)bp - tif->tif_rawcp); + tif->tif_rawcp = (uint8_t *)bp; + sp->old_tif_rawcc = tif->tif_rawcc; + sp->dec_bitsleft = dec_bitsleft; + sp->lzw_nbits = (unsigned short)nbits; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->dec_nbitsmask = nbitsmask; + sp->dec_oldcodep = oldcodep; + sp->dec_free_entp = free_entp; + sp->dec_maxcodep = maxcodep; + + if (occ > 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %" PRIu32 " (short %" PRIu64 + " bytes)", + tif->tif_row, (uint64_t)occ); + return (0); + } + return (1); + +no_eoi: + sp->read_error = 1; + TIFFErrorExtR(tif, module, + "LZWDecode: Strip %" PRIu32 " not terminated with EOI code", + tif->tif_curstrip); + return 0; +error_code: + sp->read_error = 1; + TIFFErrorExtR(tif, tif->tif_name, "Using code not yet in table"); + return 0; } #ifdef LZW_COMPAT + +/* + * This check shouldn't be necessary because each + * strip is suppose to be terminated with CODE_EOI. + */ +#define NextCode(_tif, _sp, _bp, _code, _get, dec_bitsleft) \ + { \ + if (dec_bitsleft < (uint64_t)nbits) \ + { \ + TIFFWarningExtR(_tif, module, \ + "LZWDecode: Strip %" PRIu32 \ + " not terminated with EOI code", \ + _tif->tif_curstrip); \ + _code = CODE_EOI; \ + } \ + else \ + { \ + _get(_sp, _bp, _code); \ + dec_bitsleft -= nbits; \ + } \ + } + /* * Decode a "hunk of data" for old images. */ -#define GetNextCodeCompat(sp, bp, code) { \ - nextdata |= (unsigned long) *(bp)++ << nextbits; \ - nextbits += 8; \ - if (nextbits < nbits) { \ - nextdata |= (unsigned long) *(bp)++ << nextbits;\ - nextbits += 8; \ - } \ - code = (hcode_t)(nextdata & nbitsmask); \ - nextdata >>= nbits; \ - nextbits -= nbits; \ -} +#define GetNextCodeCompat(sp, bp, code) \ + { \ + nextdata |= (unsigned long)*(bp)++ << nextbits; \ + nextbits += 8; \ + if (nextbits < nbits) \ + { \ + nextdata |= (unsigned long)*(bp)++ << nextbits; \ + nextbits += 8; \ + } \ + code = (hcode_t)(nextdata & nbitsmask); \ + nextdata >>= nbits; \ + nextbits -= nbits; \ + } -static int -LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) +static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) { - static const char module[] = "LZWDecodeCompat"; - LZWCodecState *sp = DecoderState(tif); - char *op = (char*) op0; - long occ = (long) occ0; - char *tp; - unsigned char *bp; - int code, nbits; - int len; - long nextbits, nextdata, nbitsmask; - code_t *codep, *free_entp, *maxcodep, *oldcodep; + static const char module[] = "LZWDecodeCompat"; + LZWCodecState *sp = DecoderState(tif); + uint8_t *op = (uint8_t *)op0; + tmsize_t occ = occ0; + uint8_t *tp; + uint8_t *bp; + int code, nbits; + int len; + long nextbits, nbitsmask; + WordType nextdata; + code_t *codep, *free_entp, *maxcodep, *oldcodep; - (void) s; - assert(sp != NULL); + (void)s; + assert(sp != NULL); - /* - Fail if value does not fit in long. - */ - if ((tmsize_t) occ != occ0) - return (0); + /* + * Restart interrupted output operation. + */ + if (sp->dec_restart) + { + tmsize_t residue; - /* - * Restart interrupted output operation. - */ - if (sp->dec_restart) { - long residue; + codep = sp->dec_codep; + residue = codep->length - sp->dec_restart; + if (residue > occ) + { + /* + * Residue from previous decode is sufficient + * to satisfy decode request. Skip to the + * start of the decoded string, place decoded + * values in the output buffer, and return. + */ + sp->dec_restart += occ; + do + { + codep = codep->next; + } while (--residue > occ); + tp = op + occ; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--occ); + return (1); + } + /* + * Residue satisfies only part of the decode request. + */ + op += residue; + occ -= residue; + tp = op; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--residue); + sp->dec_restart = 0; + } - codep = sp->dec_codep; - residue = codep->length - sp->dec_restart; - if (residue > occ) { - /* - * Residue from previous decode is sufficient - * to satisfy decode request. Skip to the - * start of the decoded string, place decoded - * values in the output buffer, and return. - */ - sp->dec_restart += occ; - do { - codep = codep->next; - } while (--residue > occ); - tp = op + occ; - do { - *--tp = codep->value; - codep = codep->next; - } while (--occ); - return (1); - } - /* - * Residue satisfies only part of the decode request. - */ - op += residue; - occ -= residue; - tp = op; - do { - *--tp = codep->value; - codep = codep->next; - } while (--residue); - sp->dec_restart = 0; - } + bp = (uint8_t *)tif->tif_rawcp; - bp = (unsigned char *)tif->tif_rawcp; -#ifdef LZW_CHECKEOS - sp->dec_bitsleft += (((uint64)tif->tif_rawcc - sp->old_tif_rawcc) << 3); -#endif - nbits = sp->lzw_nbits; - nextdata = sp->lzw_nextdata; - nextbits = sp->lzw_nextbits; - nbitsmask = sp->dec_nbitsmask; - oldcodep = sp->dec_oldcodep; - free_entp = sp->dec_free_entp; - maxcodep = sp->dec_maxcodep; + sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); + uint64_t dec_bitsleft = sp->dec_bitsleft; - while (occ > 0) { - NextCode(tif, sp, bp, code, GetNextCodeCompat); - if (code == CODE_EOI) - break; - if (code == CODE_CLEAR) { - do { - free_entp = sp->dec_codetab + CODE_FIRST; - _TIFFmemset(free_entp, 0, - (CSIZE - CODE_FIRST) * sizeof (code_t)); - nbits = BITS_MIN; - nbitsmask = MAXCODE(BITS_MIN); - maxcodep = sp->dec_codetab + nbitsmask; - NextCode(tif, sp, bp, code, GetNextCodeCompat); - } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ - if (code == CODE_EOI) - break; - if (code > CODE_CLEAR) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecode: Corrupted LZW table at scanline %d", - tif->tif_row); - return (0); - } - *op++ = (char)code; - occ--; - oldcodep = sp->dec_codetab + code; - continue; - } - codep = sp->dec_codetab + code; + nbits = sp->lzw_nbits; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + nbitsmask = sp->dec_nbitsmask; + oldcodep = sp->dec_oldcodep; + free_entp = sp->dec_free_entp; + maxcodep = sp->dec_maxcodep; - /* - * Add the new entry to the code table. - */ - if (free_entp < &sp->dec_codetab[0] || - free_entp >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, module, - "Corrupted LZW table at scanline %d", tif->tif_row); - return (0); - } + while (occ > 0) + { + NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); + if (code == CODE_EOI) + break; + if (code == CODE_CLEAR) + { + do + { + free_entp = sp->dec_codetab + CODE_FIRST; + _TIFFmemset(free_entp, 0, + (CSIZE - CODE_FIRST) * sizeof(code_t)); + nbits = BITS_MIN; + nbitsmask = MAXCODE(BITS_MIN); + maxcodep = sp->dec_codetab + nbitsmask; + NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); + } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ + if (code == CODE_EOI) + break; + if (code > CODE_CLEAR) + { + TIFFErrorExtR( + tif, tif->tif_name, + "LZWDecode: Corrupted LZW table at scanline %" PRIu32, + tif->tif_row); + return (0); + } + *op++ = (uint8_t)code; + occ--; + oldcodep = sp->dec_codetab + code; + continue; + } + codep = sp->dec_codetab + code; - free_entp->next = oldcodep; - if (free_entp->next < &sp->dec_codetab[0] || - free_entp->next >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, module, - "Corrupted LZW table at scanline %d", tif->tif_row); - return (0); - } - free_entp->firstchar = free_entp->next->firstchar; - free_entp->length = free_entp->next->length+1; - free_entp->value = (codep < free_entp) ? - codep->firstchar : free_entp->firstchar; - if (++free_entp > maxcodep) { - if (++nbits > BITS_MAX) /* should not happen */ - nbits = BITS_MAX; - nbitsmask = MAXCODE(nbits); - maxcodep = sp->dec_codetab + nbitsmask; - } - oldcodep = codep; - if (code >= 256) { - /* - * Code maps to a string, copy string - * value to output (written in reverse). - */ - if(codep->length == 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Wrong length of decoded " - "string: data probably corrupted at scanline %d", - tif->tif_row); - return (0); - } - if (codep->length > occ) { - /* - * String is too long for decode buffer, - * locate portion that will fit, copy to - * the decode buffer, and setup restart - * logic for the next decoding call. - */ - sp->dec_codep = codep; - do { - codep = codep->next; - } while (codep->length > occ); - sp->dec_restart = occ; - tp = op + occ; - do { - *--tp = codep->value; - codep = codep->next; - } while (--occ); - break; - } - len = codep->length; - tp = op + len; - do { - int t; - --tp; - t = codep->value; - codep = codep->next; - *tp = (char)t; - } while (codep && tp > op); - assert(occ >= len); - op += len; - occ -= len; - } else { - *op++ = (char)code; - occ--; - } - } + /* + * Add the new entry to the code table. + */ + if (free_entp < &sp->dec_codetab[0] || + free_entp >= &sp->dec_codetab[CSIZE]) + { + TIFFErrorExtR(tif, module, + "Corrupted LZW table at scanline %" PRIu32, + tif->tif_row); + return (0); + } - tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp ); - tif->tif_rawcp = (uint8*) bp; -#ifdef LZW_CHECKEOS - sp->old_tif_rawcc = tif->tif_rawcc; -#endif - sp->lzw_nbits = (unsigned short)nbits; - sp->lzw_nextdata = nextdata; - sp->lzw_nextbits = nextbits; - sp->dec_nbitsmask = nbitsmask; - sp->dec_oldcodep = oldcodep; - sp->dec_free_entp = free_entp; - sp->dec_maxcodep = maxcodep; + free_entp->next = oldcodep; + if (free_entp->next < &sp->dec_codetab[0] || + free_entp->next >= &sp->dec_codetab[CSIZE]) + { + TIFFErrorExtR(tif, module, + "Corrupted LZW table at scanline %" PRIu32, + tif->tif_row); + return (0); + } + free_entp->firstchar = free_entp->next->firstchar; + free_entp->length = free_entp->next->length + 1; + free_entp->value = + (codep < free_entp) ? codep->firstchar : free_entp->firstchar; + if (++free_entp > maxcodep) + { + if (++nbits > BITS_MAX) /* should not happen */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = sp->dec_codetab + nbitsmask; + } + oldcodep = codep; + if (code >= 256) + { + /* + * Code maps to a string, copy string + * value to output (written in reverse). + */ + if (codep->length == 0) + { + TIFFErrorExtR( + tif, module, + "Wrong length of decoded " + "string: data probably corrupted at scanline %" PRIu32, + tif->tif_row); + return (0); + } + if (codep->length > occ) + { + /* + * String is too long for decode buffer, + * locate portion that will fit, copy to + * the decode buffer, and setup restart + * logic for the next decoding call. + */ + sp->dec_codep = codep; + do + { + codep = codep->next; + } while (codep->length > occ); + sp->dec_restart = occ; + tp = op + occ; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--occ); + break; + } + len = codep->length; + tp = op + len; + do + { + *--tp = codep->value; + codep = codep->next; + } while (codep && tp > op); + assert(occ >= len); + op += len; + occ -= len; + } + else + { + *op++ = (uint8_t)code; + occ--; + } + } - if (occ > 0) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %d (short %I64d bytes)", - tif->tif_row, (unsigned __int64) occ); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %d (short %llu bytes)", - tif->tif_row, (unsigned long long) occ); -#endif - return (0); - } - return (1); + tif->tif_rawcc -= (tmsize_t)((uint8_t *)bp - tif->tif_rawcp); + tif->tif_rawcp = (uint8_t *)bp; + + sp->old_tif_rawcc = tif->tif_rawcc; + sp->dec_bitsleft = dec_bitsleft; + + sp->lzw_nbits = (unsigned short)nbits; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->dec_nbitsmask = nbitsmask; + sp->dec_oldcodep = oldcodep; + sp->dec_free_entp = free_entp; + sp->dec_maxcodep = maxcodep; + + if (occ > 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %" PRIu32 " (short %" PRIu64 + " bytes)", + tif->tif_row, (uint64_t)occ); + return (0); + } + return (1); } #endif /* LZW_COMPAT */ @@ -809,393 +1023,416 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) * LZW Encoding. */ -static int -LZWSetupEncode(TIFF* tif) +static int LZWSetupEncode(TIFF *tif) { - static const char module[] = "LZWSetupEncode"; - LZWCodecState* sp = EncoderState(tif); + static const char module[] = "LZWSetupEncode"; + LZWCodecState *sp = EncoderState(tif); - assert(sp != NULL); - sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t)); - if (sp->enc_hashtab == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, - "No space for LZW hash table"); - return (0); - } - return (1); + assert(sp != NULL); + sp->enc_hashtab = (hash_t *)_TIFFmallocExt(tif, HSIZE * sizeof(hash_t)); + if (sp->enc_hashtab == NULL) + { + TIFFErrorExtR(tif, module, "No space for LZW hash table"); + return (0); + } + return (1); } /* * Reset encoding state at the start of a strip. */ -static int -LZWPreEncode(TIFF* tif, uint16 s) +static int LZWPreEncode(TIFF *tif, uint16_t s) { - LZWCodecState *sp = EncoderState(tif); + LZWCodecState *sp = EncoderState(tif); - (void) s; - assert(sp != NULL); + (void)s; + assert(sp != NULL); - if( sp->enc_hashtab == NULL ) - { - tif->tif_setupencode( tif ); - } + if (sp->enc_hashtab == NULL) + { + tif->tif_setupencode(tif); + } - sp->lzw_nbits = BITS_MIN; - sp->lzw_maxcode = MAXCODE(BITS_MIN); - sp->lzw_free_ent = CODE_FIRST; - sp->lzw_nextbits = 0; - sp->lzw_nextdata = 0; - sp->enc_checkpoint = CHECK_GAP; - sp->enc_ratio = 0; - sp->enc_incount = 0; - sp->enc_outcount = 0; - /* - * The 4 here insures there is space for 2 max-sized - * codes in LZWEncode and LZWPostDecode. - */ - sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4; - cl_hash(sp); /* clear hash table */ - sp->enc_oldcode = (hcode_t) -1; /* generates CODE_CLEAR in LZWEncode */ - return (1); + sp->lzw_nbits = BITS_MIN; + sp->lzw_maxcode = MAXCODE(BITS_MIN); + sp->lzw_free_ent = CODE_FIRST; + sp->lzw_nextbits = 0; + sp->lzw_nextdata = 0; + sp->enc_checkpoint = CHECK_GAP; + sp->enc_ratio = 0; + sp->enc_incount = 0; + sp->enc_outcount = 0; + /* + * The 4 here insures there is space for 2 max-sized + * codes in LZWEncode and LZWPostDecode. + */ + sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize - 1 - 4; + cl_hash(sp); /* clear hash table */ + sp->enc_oldcode = (hcode_t)-1; /* generates CODE_CLEAR in LZWEncode */ + return (1); } -#define CALCRATIO(sp, rat) { \ - if (incount > 0x007fffff) { /* NB: shift will overflow */\ - rat = outcount >> 8; \ - rat = (rat == 0 ? 0x7fffffff : incount/rat); \ - } else \ - rat = (incount<<8) / outcount; \ -} +#define CALCRATIO(sp, rat) \ + { \ + if (incount > 0x007fffff) \ + { /* NB: shift will overflow */ \ + rat = outcount >> 8; \ + rat = (rat == 0 ? 0x7fffffff : incount / rat); \ + } \ + else \ + rat = (incount << 8) / outcount; \ + } /* Explicit 0xff masking to make icc -check=conversions happy */ -#define PutNextCode(op, c) { \ - nextdata = (nextdata << nbits) | c; \ - nextbits += nbits; \ - *op++ = (unsigned char)((nextdata >> (nextbits-8))&0xff); \ - nextbits -= 8; \ - if (nextbits >= 8) { \ - *op++ = (unsigned char)((nextdata >> (nextbits-8))&0xff); \ - nextbits -= 8; \ - } \ - outcount += nbits; \ -} +#define PutNextCode(op, c) \ + { \ + nextdata = (nextdata << nbits) | c; \ + nextbits += nbits; \ + *op++ = (unsigned char)((nextdata >> (nextbits - 8)) & 0xff); \ + nextbits -= 8; \ + if (nextbits >= 8) \ + { \ + *op++ = (unsigned char)((nextdata >> (nextbits - 8)) & 0xff); \ + nextbits -= 8; \ + } \ + outcount += nbits; \ + } /* * Encode a chunk of pixels. * - * Uses an open addressing double hashing (no chaining) on the + * Uses an open addressing double hashing (no chaining) on the * prefix code/next character combination. We do a variant of * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's * relatively-prime secondary probe. Here, the modular division - * first probe is gives way to a faster exclusive-or manipulation. + * first probe is gives way to a faster exclusive-or manipulation. * Also do block compression with an adaptive reset, whereby the * code table is cleared when the compression ratio decreases, * but after the table fills. The variable-length output codes * are re-sized at this point, and a CODE_CLEAR is generated - * for the decoder. + * for the decoder. */ -static int -LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - register LZWCodecState *sp = EncoderState(tif); - register long fcode; - register hash_t *hp; - register int h, c; - hcode_t ent; - long disp; - long incount, outcount, checkpoint; - unsigned long nextdata; - long nextbits; - int free_ent, maxcode, nbits; - uint8* op; - uint8* limit; + register LZWCodecState *sp = EncoderState(tif); + register long fcode; + register hash_t *hp; + register int h, c; + hcode_t ent; + long disp; + tmsize_t incount, outcount, checkpoint; + WordType nextdata; + long nextbits; + int free_ent, maxcode, nbits; + uint8_t *op; + uint8_t *limit; - (void) s; - if (sp == NULL) - return (0); + (void)s; + if (sp == NULL) + return (0); - assert(sp->enc_hashtab != NULL); + assert(sp->enc_hashtab != NULL); - /* - * Load local state. - */ - incount = sp->enc_incount; - outcount = sp->enc_outcount; - checkpoint = sp->enc_checkpoint; - nextdata = sp->lzw_nextdata; - nextbits = sp->lzw_nextbits; - free_ent = sp->lzw_free_ent; - maxcode = sp->lzw_maxcode; - nbits = sp->lzw_nbits; - op = tif->tif_rawcp; - limit = sp->enc_rawlimit; - ent = (hcode_t)sp->enc_oldcode; + /* + * Load local state. + */ + incount = sp->enc_incount; + outcount = sp->enc_outcount; + checkpoint = sp->enc_checkpoint; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + free_ent = sp->lzw_free_ent; + maxcode = sp->lzw_maxcode; + nbits = sp->lzw_nbits; + op = tif->tif_rawcp; + limit = sp->enc_rawlimit; + ent = (hcode_t)sp->enc_oldcode; - if (ent == (hcode_t) -1 && cc > 0) { - /* - * NB: This is safe because it can only happen - * at the start of a strip where we know there - * is space in the data buffer. - */ - PutNextCode(op, CODE_CLEAR); - ent = *bp++; cc--; incount++; - } - while (cc > 0) { - c = *bp++; cc--; incount++; - fcode = ((long)c << BITS_MAX) + ent; - h = (c << HSHIFT) ^ ent; /* xor hashing */ + if (ent == (hcode_t)-1 && cc > 0) + { + /* + * NB: This is safe because it can only happen + * at the start of a strip where we know there + * is space in the data buffer. + */ + PutNextCode(op, CODE_CLEAR); + ent = *bp++; + cc--; + incount++; + } + while (cc > 0) + { + c = *bp++; + cc--; + incount++; + fcode = ((long)c << BITS_MAX) + ent; + h = (c << HSHIFT) ^ ent; /* xor hashing */ #ifdef _WINDOWS - /* - * Check hash index for an overflow. - */ - if (h >= HSIZE) - h -= HSIZE; + /* + * Check hash index for an overflow. + */ + if (h >= HSIZE) + h -= HSIZE; #endif - hp = &sp->enc_hashtab[h]; - if (hp->hash == fcode) { - ent = hp->code; - continue; - } - if (hp->hash >= 0) { - /* - * Primary hash failed, check secondary hash. - */ - disp = HSIZE - h; - if (h == 0) - disp = 1; - do { - /* - * Avoid pointer arithmetic because of - * wraparound problems with segments. - */ - if ((h -= disp) < 0) - h += HSIZE; - hp = &sp->enc_hashtab[h]; - if (hp->hash == fcode) { - ent = hp->code; - goto hit; - } - } while (hp->hash >= 0); - } - /* - * New entry, emit code and add to table. - */ - /* - * Verify there is space in the buffer for the code - * and any potential Clear code that might be emitted - * below. The value of limit is setup so that there - * are at least 4 bytes free--room for 2 codes. - */ - if (op > limit) { - tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - if( !TIFFFlushData1(tif) ) - return 0; - op = tif->tif_rawdata; - } - PutNextCode(op, ent); - ent = (hcode_t)c; - hp->code = (hcode_t)(free_ent++); - hp->hash = fcode; - if (free_ent == CODE_MAX-1) { - /* table is full, emit clear code and reset */ - cl_hash(sp); - sp->enc_ratio = 0; - incount = 0; - outcount = 0; - free_ent = CODE_FIRST; - PutNextCode(op, CODE_CLEAR); - nbits = BITS_MIN; - maxcode = MAXCODE(BITS_MIN); - } else { - /* - * If the next entry is going to be too big for - * the code size, then increase it, if possible. - */ - if (free_ent > maxcode) { - nbits++; - assert(nbits <= BITS_MAX); - maxcode = (int) MAXCODE(nbits); - } else if (incount >= checkpoint) { - long rat; - /* - * Check compression ratio and, if things seem - * to be slipping, clear the hash table and - * reset state. The compression ratio is a - * 24+8-bit fractional number. - */ - checkpoint = incount+CHECK_GAP; - CALCRATIO(sp, rat); - if (rat <= sp->enc_ratio) { - cl_hash(sp); - sp->enc_ratio = 0; - incount = 0; - outcount = 0; - free_ent = CODE_FIRST; - PutNextCode(op, CODE_CLEAR); - nbits = BITS_MIN; - maxcode = MAXCODE(BITS_MIN); - } else - sp->enc_ratio = rat; - } - } - hit: - ; - } + hp = &sp->enc_hashtab[h]; + if (hp->hash == fcode) + { + ent = hp->code; + continue; + } + if (hp->hash >= 0) + { + /* + * Primary hash failed, check secondary hash. + */ + disp = HSIZE - h; + if (h == 0) + disp = 1; + do + { + /* + * Avoid pointer arithmetic because of + * wraparound problems with segments. + */ + if ((h -= disp) < 0) + h += HSIZE; + hp = &sp->enc_hashtab[h]; + if (hp->hash == fcode) + { + ent = hp->code; + goto hit; + } + } while (hp->hash >= 0); + } + /* + * New entry, emit code and add to table. + */ + /* + * Verify there is space in the buffer for the code + * and any potential Clear code that might be emitted + * below. The value of limit is setup so that there + * are at least 4 bytes free--room for 2 codes. + */ + if (op > limit) + { + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + if (!TIFFFlushData1(tif)) + return 0; + op = tif->tif_rawdata; + } + PutNextCode(op, ent); + ent = (hcode_t)c; + hp->code = (hcode_t)(free_ent++); + hp->hash = fcode; + if (free_ent == CODE_MAX - 1) + { + /* table is full, emit clear code and reset */ + cl_hash(sp); + sp->enc_ratio = 0; + incount = 0; + outcount = 0; + free_ent = CODE_FIRST; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + maxcode = MAXCODE(BITS_MIN); + } + else + { + /* + * If the next entry is going to be too big for + * the code size, then increase it, if possible. + */ + if (free_ent > maxcode) + { + nbits++; + assert(nbits <= BITS_MAX); + maxcode = (int)MAXCODE(nbits); + } + else if (incount >= checkpoint) + { + tmsize_t rat; + /* + * Check compression ratio and, if things seem + * to be slipping, clear the hash table and + * reset state. The compression ratio is a + * 24+8-bit fractional number. + */ + checkpoint = incount + CHECK_GAP; + CALCRATIO(sp, rat); + if (rat <= sp->enc_ratio) + { + cl_hash(sp); + sp->enc_ratio = 0; + incount = 0; + outcount = 0; + free_ent = CODE_FIRST; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + maxcode = MAXCODE(BITS_MIN); + } + else + sp->enc_ratio = rat; + } + } + hit:; + } - /* - * Restore global state. - */ - sp->enc_incount = incount; - sp->enc_outcount = outcount; - sp->enc_checkpoint = checkpoint; - sp->enc_oldcode = ent; - sp->lzw_nextdata = nextdata; - sp->lzw_nextbits = nextbits; - sp->lzw_free_ent = (unsigned short)free_ent; - sp->lzw_maxcode = (unsigned short)maxcode; - sp->lzw_nbits = (unsigned short)nbits; - tif->tif_rawcp = op; - return (1); + /* + * Restore global state. + */ + sp->enc_incount = incount; + sp->enc_outcount = outcount; + sp->enc_checkpoint = checkpoint; + sp->enc_oldcode = ent; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->lzw_free_ent = (unsigned short)free_ent; + sp->lzw_maxcode = (unsigned short)maxcode; + sp->lzw_nbits = (unsigned short)nbits; + tif->tif_rawcp = op; + return (1); } /* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ -static int -LZWPostEncode(TIFF* tif) +static int LZWPostEncode(TIFF *tif) { - register LZWCodecState *sp = EncoderState(tif); - uint8* op = tif->tif_rawcp; - long nextbits = sp->lzw_nextbits; - unsigned long nextdata = sp->lzw_nextdata; - long outcount = sp->enc_outcount; - int nbits = sp->lzw_nbits; + register LZWCodecState *sp = EncoderState(tif); + uint8_t *op = tif->tif_rawcp; + long nextbits = sp->lzw_nextbits; + WordType nextdata = sp->lzw_nextdata; + tmsize_t outcount = sp->enc_outcount; + int nbits = sp->lzw_nbits; - if (op > sp->enc_rawlimit) { - tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - if( !TIFFFlushData1(tif) ) - return 0; - op = tif->tif_rawdata; - } - if (sp->enc_oldcode != (hcode_t) -1) { - int free_ent = sp->lzw_free_ent; + if (op > sp->enc_rawlimit) + { + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + if (!TIFFFlushData1(tif)) + return 0; + op = tif->tif_rawdata; + } + if (sp->enc_oldcode != (hcode_t)-1) + { + int free_ent = sp->lzw_free_ent; - PutNextCode(op, sp->enc_oldcode); - sp->enc_oldcode = (hcode_t) -1; - free_ent ++; + PutNextCode(op, sp->enc_oldcode); + sp->enc_oldcode = (hcode_t)-1; + free_ent++; - if (free_ent == CODE_MAX-1) { - /* table is full, emit clear code and reset */ - outcount = 0; - PutNextCode(op, CODE_CLEAR); - nbits = BITS_MIN; - } else { - /* - * If the next entry is going to be too big for - * the code size, then increase it, if possible. - */ - if (free_ent > sp->lzw_maxcode) { - nbits++; - assert(nbits <= BITS_MAX); - } - } - } - PutNextCode(op, CODE_EOI); - /* Explicit 0xff masking to make icc -check=conversions happy */ - if (nextbits > 0) - *op++ = (unsigned char)((nextdata << (8-nextbits))&0xff); - tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - return (1); + if (free_ent == CODE_MAX - 1) + { + /* table is full, emit clear code and reset */ + outcount = 0; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + } + else + { + /* + * If the next entry is going to be too big for + * the code size, then increase it, if possible. + */ + if (free_ent > sp->lzw_maxcode) + { + nbits++; + assert(nbits <= BITS_MAX); + } + } + } + PutNextCode(op, CODE_EOI); + /* Explicit 0xff masking to make icc -check=conversions happy */ + if (nextbits > 0) + *op++ = (unsigned char)((nextdata << (8 - nextbits)) & 0xff); + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + (void)outcount; + return (1); } /* * Reset encoding hash table. */ -static void -cl_hash(LZWCodecState* sp) +static void cl_hash(LZWCodecState *sp) { - register hash_t *hp = &sp->enc_hashtab[HSIZE-1]; - register long i = HSIZE-8; + register hash_t *hp = &sp->enc_hashtab[HSIZE - 1]; + register long i = HSIZE - 8; - do { - i -= 8; - hp[-7].hash = -1; - hp[-6].hash = -1; - hp[-5].hash = -1; - hp[-4].hash = -1; - hp[-3].hash = -1; - hp[-2].hash = -1; - hp[-1].hash = -1; - hp[ 0].hash = -1; - hp -= 8; - } while (i >= 0); - for (i += 8; i > 0; i--, hp--) - hp->hash = -1; + do + { + i -= 8; + hp[-7].hash = -1; + hp[-6].hash = -1; + hp[-5].hash = -1; + hp[-4].hash = -1; + hp[-3].hash = -1; + hp[-2].hash = -1; + hp[-1].hash = -1; + hp[0].hash = -1; + hp -= 8; + } while (i >= 0); + for (i += 8; i > 0; i--, hp--) + hp->hash = -1; } -static void -LZWCleanup(TIFF* tif) +static void LZWCleanup(TIFF *tif) { - (void)TIFFPredictorCleanup(tif); + (void)TIFFPredictorCleanup(tif); - assert(tif->tif_data != 0); + assert(tif->tif_data != 0); - if (DecoderState(tif)->dec_codetab) - _TIFFfree(DecoderState(tif)->dec_codetab); + if (DecoderState(tif)->dec_codetab) + _TIFFfreeExt(tif, DecoderState(tif)->dec_codetab); - if (EncoderState(tif)->enc_hashtab) - _TIFFfree(EncoderState(tif)->enc_hashtab); + if (EncoderState(tif)->enc_hashtab) + _TIFFfreeExt(tif, EncoderState(tif)->enc_hashtab); - _TIFFfree(tif->tif_data); - tif->tif_data = NULL; + _TIFFfreeExt(tif, tif->tif_data); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -int -TIFFInitLZW(TIFF* tif, int scheme) +int TIFFInitLZW(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitLZW"; - (void)scheme; - assert(scheme == COMPRESSION_LZW); - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LZWCodecState)); - if (tif->tif_data == NULL) - goto bad; - DecoderState(tif)->dec_codetab = NULL; - DecoderState(tif)->dec_decode = NULL; - EncoderState(tif)->enc_hashtab = NULL; - LZWState(tif)->rw_mode = tif->tif_mode; + static const char module[] = "TIFFInitLZW"; + (void)scheme; + assert(scheme == COMPRESSION_LZW); + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState)); + if (tif->tif_data == NULL) + goto bad; + DecoderState(tif)->dec_codetab = NULL; + DecoderState(tif)->dec_decode = NULL; + EncoderState(tif)->enc_hashtab = NULL; + LZWState(tif)->rw_mode = tif->tif_mode; - /* - * Install codec methods. - */ - tif->tif_fixuptags = LZWFixupTags; - tif->tif_setupdecode = LZWSetupDecode; - tif->tif_predecode = LZWPreDecode; - tif->tif_decoderow = LZWDecode; - tif->tif_decodestrip = LZWDecode; - tif->tif_decodetile = LZWDecode; - tif->tif_setupencode = LZWSetupEncode; - tif->tif_preencode = LZWPreEncode; - tif->tif_postencode = LZWPostEncode; - tif->tif_encoderow = LZWEncode; - tif->tif_encodestrip = LZWEncode; - tif->tif_encodetile = LZWEncode; - tif->tif_cleanup = LZWCleanup; - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - return (1); + /* + * Install codec methods. + */ + tif->tif_fixuptags = LZWFixupTags; + tif->tif_setupdecode = LZWSetupDecode; + tif->tif_predecode = LZWPreDecode; + tif->tif_decoderow = LZWDecode; + tif->tif_decodestrip = LZWDecode; + tif->tif_decodetile = LZWDecode; + tif->tif_setupencode = LZWSetupEncode; + tif->tif_preencode = LZWPreEncode; + tif->tif_postencode = LZWPostEncode; + tif->tif_encoderow = LZWEncode; + tif->tif_encodestrip = LZWEncode; + tif->tif_encodetile = LZWEncode; + tif->tif_cleanup = LZWCleanup; + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + return (1); bad: - TIFFErrorExt(tif->tif_clientdata, module, - "No space for LZW state block"); - return (0); + TIFFErrorExtR(tif, module, "No space for LZW state block"); + return (0); } /* @@ -1219,12 +1456,3 @@ bad: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #endif /* LZW_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_next.c b/3rdparty/libtiff/tif_next.c index 0ba61aed3a..f000574ee7 100644 --- a/3rdparty/libtiff/tif_next.c +++ b/3rdparty/libtiff/tif_next.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -30,158 +30,165 @@ * NeXT 2-bit Grey Scale Compression Algorithm Support */ -#define SETPIXEL(op, v) { \ - switch (npixels++ & 3) { \ - case 0: op[0] = (unsigned char) ((v) << 6); break; \ - case 1: op[0] |= (v) << 4; break; \ - case 2: op[0] |= (v) << 2; break; \ - case 3: *op++ |= (v); op_offset++; break; \ - } \ -} +#define SETPIXEL(op, v) \ + { \ + switch (npixels++ & 3) \ + { \ + case 0: \ + op[0] = (unsigned char)((v) << 6); \ + break; \ + case 1: \ + op[0] |= (v) << 4; \ + break; \ + case 2: \ + op[0] |= (v) << 2; \ + break; \ + case 3: \ + *op++ |= (v); \ + op_offset++; \ + break; \ + } \ + } -#define LITERALROW 0x00 -#define LITERALSPAN 0x40 -#define WHITE ((1<<2)-1) +#define LITERALROW 0x00 +#define LITERALSPAN 0x40 +#define WHITE ((1 << 2) - 1) -static int -NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - static const char module[] = "NeXTDecode"; - unsigned char *bp, *op; - tmsize_t cc; - uint8* row; - tmsize_t scanline, n; + static const char module[] = "NeXTDecode"; + unsigned char *bp, *op; + tmsize_t cc; + uint8_t *row; + tmsize_t scanline, n; - (void) s; - /* - * Each scanline is assumed to start off as all - * white (we assume a PhotometricInterpretation - * of ``min-is-black''). - */ - for (op = (unsigned char*) buf, cc = occ; cc-- > 0;) - *op++ = 0xff; + (void)s; + /* + * Each scanline is assumed to start off as all + * white (we assume a PhotometricInterpretation + * of ``min-is-black''). + */ + for (op = (unsigned char *)buf, cc = occ; cc-- > 0;) + *op++ = 0xff; - bp = (unsigned char *)tif->tif_rawcp; - cc = tif->tif_rawcc; - scanline = tif->tif_scanlinesize; - if (occ % scanline) - { - TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); - return (0); - } - for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) { - n = *bp++; - cc--; - switch (n) { - case LITERALROW: - /* - * The entire scanline is given as literal values. - */ - if (cc < scanline) - goto bad; - _TIFFmemcpy(row, bp, scanline); - bp += scanline; - cc -= scanline; - break; - case LITERALSPAN: { - tmsize_t off; - /* - * The scanline has a literal span that begins at some - * offset. - */ - if( cc < 4 ) - goto bad; - off = (bp[0] * 256) + bp[1]; - n = (bp[2] * 256) + bp[3]; - if (cc < 4+n || off+n > scanline) - goto bad; - _TIFFmemcpy(row+off, bp+4, n); - bp += 4+n; - cc -= 4+n; - break; - } - default: { - uint32 npixels = 0, grey; - tmsize_t op_offset = 0; - uint32 imagewidth = tif->tif_dir.td_imagewidth; - if( isTiled(tif) ) - imagewidth = tif->tif_dir.td_tilewidth; + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + scanline = tif->tif_scanlinesize; + if (occ % scanline) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (0); + } + for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) + { + n = *bp++; + cc--; + switch (n) + { + case LITERALROW: + /* + * The entire scanline is given as literal values. + */ + if (cc < scanline) + goto bad; + _TIFFmemcpy(row, bp, scanline); + bp += scanline; + cc -= scanline; + break; + case LITERALSPAN: + { + tmsize_t off; + /* + * The scanline has a literal span that begins at some + * offset. + */ + if (cc < 4) + goto bad; + off = (bp[0] * 256) + bp[1]; + n = (bp[2] * 256) + bp[3]; + if (cc < 4 + n || off + n > scanline) + goto bad; + _TIFFmemcpy(row + off, bp + 4, n); + bp += 4 + n; + cc -= 4 + n; + break; + } + default: + { + uint32_t npixels = 0, grey; + tmsize_t op_offset = 0; + uint32_t imagewidth = tif->tif_dir.td_imagewidth; + if (isTiled(tif)) + imagewidth = tif->tif_dir.td_tilewidth; - /* - * The scanline is composed of a sequence of constant - * color ``runs''. We shift into ``run mode'' and - * interpret bytes as codes of the form - * until we've filled the scanline. - */ - op = row; - for (;;) { - grey = (uint32)((n>>6) & 0x3); - n &= 0x3f; - /* - * Ensure the run does not exceed the scanline - * bounds, potentially resulting in a security - * issue. - */ - while (n-- > 0 && npixels < imagewidth && op_offset < scanline) - SETPIXEL(op, grey); - if (npixels >= imagewidth) - break; - if (op_offset >= scanline ) { - TIFFErrorExt(tif->tif_clientdata, module, "Invalid data for scanline %ld", - (long) tif->tif_row); - return (0); + /* + * The scanline is composed of a sequence of constant + * color ``runs''. We shift into ``run mode'' and + * interpret bytes as codes of the form + * until we've filled the scanline. + */ + op = row; + for (;;) + { + grey = (uint32_t)((n >> 6) & 0x3); + n &= 0x3f; + /* + * Ensure the run does not exceed the scanline + * bounds, potentially resulting in a security + * issue. + */ + while (n-- > 0 && npixels < imagewidth && + op_offset < scanline) + SETPIXEL(op, grey); + if (npixels >= imagewidth) + break; + if (op_offset >= scanline) + { + TIFFErrorExtR(tif, module, + "Invalid data for scanline %" PRIu32, + tif->tif_row); + return (0); + } + if (cc == 0) + goto bad; + n = *bp++; + cc--; } - if (cc == 0) - goto bad; - n = *bp++; - cc--; - } - break; - } - } - } - tif->tif_rawcp = (uint8*) bp; - tif->tif_rawcc = cc; - return (1); + break; + } + } + } + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (1); bad: - TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld", - (long) tif->tif_row); - return (0); + TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32, + tif->tif_row); + return (0); } -static int -NeXTPreDecode(TIFF* tif, uint16 s) +static int NeXTPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "NeXTPreDecode"; - TIFFDirectory *td = &tif->tif_dir; - (void)s; + static const char module[] = "NeXTPreDecode"; + TIFFDirectory *td = &tif->tif_dir; + (void)s; - if( td->td_bitspersample != 2 ) - { - TIFFErrorExt(tif->tif_clientdata, module, "Unsupported BitsPerSample = %d", - td->td_bitspersample); - return (0); - } - return (1); + if (td->td_bitspersample != 2) + { + TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16, + td->td_bitspersample); + return (0); + } + return (1); } - -int -TIFFInitNeXT(TIFF* tif, int scheme) + +int TIFFInitNeXT(TIFF *tif, int scheme) { - (void) scheme; - tif->tif_predecode = NeXTPreDecode; - tif->tif_decoderow = NeXTDecode; - tif->tif_decodestrip = NeXTDecode; - tif->tif_decodetile = NeXTDecode; - return (1); + (void)scheme; + tif->tif_predecode = NeXTPreDecode; + tif->tif_decoderow = NeXTDecode; + tif->tif_decodestrip = NeXTDecode; + tif->tif_decodetile = NeXTDecode; + return (1); } #endif /* NEXT_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_ojpeg.c b/3rdparty/libtiff/tif_ojpeg.c index 133d1f1c49..ea572091e5 100644 --- a/3rdparty/libtiff/tif_ojpeg.c +++ b/3rdparty/libtiff/tif_ojpeg.c @@ -43,79 +43,83 @@ /* What is what, and what is not? - This decoder starts with an input stream, that is essentially the JpegInterchangeFormat - stream, if any, followed by the strile data, if any. This stream is read in - OJPEGReadByte and related functions. + This decoder starts with an input stream, that is essentially the + JpegInterchangeFormat stream, if any, followed by the strile data, if any. + This stream is read in OJPEGReadByte and related functions. - It analyzes the start of this stream, until it encounters non-marker data, i.e. - compressed image data. Some of the header markers it sees have no actual content, - like the SOI marker, and APP/COM markers that really shouldn't even be there. Some - other markers do have content, and the valuable bits and pieces of information - in these markers are saved, checking all to verify that the stream is more or - less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx + It analyzes the start of this stream, until it encounters non-marker data, + i.e. compressed image data. Some of the header markers it sees have no actual + content, like the SOI marker, and APP/COM markers that really shouldn't even + be there. Some other markers do have content, and the valuable bits and + pieces of information in these markers are saved, checking all to verify that + the stream is more or less within expected bounds. This happens inside the + OJPEGReadHeaderInfoSecStreamXxx functions. + + Some OJPEG imagery contains no valid JPEG header markers. This situation is + picked up on if we've seen no SOF marker when we're at the start of the + compressed image data. In this case, the tables are read from JpegXxxTables + tags, and the other bits and pieces of information is initialized to its most + basic value. This is implemented in the OJPEGReadHeaderInfoSecTablesXxx functions. - Some OJPEG imagery contains no valid JPEG header markers. This situation is picked - up on if we've seen no SOF marker when we're at the start of the compressed image - data. In this case, the tables are read from JpegXxxTables tags, and the other - bits and pieces of information is initialized to its most basic value. This is - implemented in the OJPEGReadHeaderInfoSecTablesXxx functions. + When this is complete, a good and valid JPEG header can be assembled, and + this is passed through to LibJpeg. When that's done, the remainder of the + input stream, i.e. the compressed image data, can be passed through + unchanged. This is done in OJPEGWriteStream functions. - When this is complete, a good and valid JPEG header can be assembled, and this is - passed through to LibJpeg. When that's done, the remainder of the input stream, i.e. - the compressed image data, can be passed through unchanged. This is done in - OJPEGWriteStream functions. - - LibTiff rightly expects to know the subsampling values before decompression. Just like - in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling - tag is notoriously unreliable. To correct these tag values with the ones inside - the JPEG stream, the first part of the input stream is pre-scanned in - OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings - or errors, up to the point where either these values are read, or it's clear they - aren't there. This means that some of the data is read twice, but we feel speed - in correcting these values is important enough to warrant this sacrifice. Although - there is currently no define or other configuration mechanism to disable this behavior, - the actual header scanning is build to robustly respond with error report if it - should encounter an uncorrected mismatch of subsampling values. See + LibTiff rightly expects to know the subsampling values before decompression. + Just like in new-style JPEG-in-TIFF, though, or even more so, actually, the + YCbCrsubsampling tag is notoriously unreliable. To correct these tag values + with the ones inside the JPEG stream, the first part of the input stream is + pre-scanned in OJPEGSubsamplingCorrect, making no note of any other data, + reporting no warnings or errors, up to the point where either these values + are read, or it's clear they aren't there. This means that some of the data + is read twice, but we feel speed in correcting these values is important + enough to warrant this sacrifice. Although there is currently no define or + other configuration mechanism to disable this behavior, the actual header + scanning is build to robustly respond with error report if it should + encounter an uncorrected mismatch of subsampling values. See OJPEGReadHeaderInfoSecStreamSof. - The restart interval and restart markers are the most tricky part... The restart - interval can be specified in a tag. It can also be set inside the input JPEG stream. - It can be used inside the input JPEG stream. If reading from strile data, we've - consistently discovered the need to insert restart markers in between the different - striles, as is also probably the most likely interpretation of the original TIFF 6.0 - specification. With all this setting of interval, and actual use of markers that is not - predictable at the time of valid JPEG header assembly, the restart thing may turn - out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors - succeed in reading back what they write, which may be the reason why we've been able - to discover ways that seem to work. + The restart interval and restart markers are the most tricky part... The + restart interval can be specified in a tag. It can also be set inside the + input JPEG stream. It can be used inside the input JPEG stream. If reading + from strile data, we've consistently discovered the need to insert restart + markers in between the different striles, as is also probably the most likely + interpretation of the original TIFF 6.0 specification. With all this setting + of interval, and actual use of markers that is not predictable at the time of + valid JPEG header assembly, the restart thing may turn out the Achilles heel + of this implementation. Fortunately, most OJPEG writer vendors succeed in + reading back what they write, which may be the reason why we've been able to + discover ways that seem to work. - Some special provision is made for planarconfig separate OJPEG files. These seem - to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS, - and plane. This may or may not be a valid JPEG configuration, we don't know and don't - care. We want LibTiff to be able to access the planes individually, without huge - buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this - case, that allow us to pass a single plane such that LibJpeg sees a valid - single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent - planes, is done inside OJPEGReadSecondarySos. + Some special provision is made for planarconfig separate OJPEG files. These + seem to consistently contain header info, a SOS marker, a plane, SOS marker, + plane, SOS, and plane. This may or may not be a valid JPEG configuration, we + don't know and don't care. We want LibTiff to be able to access the planes + individually, without huge buffering inside LibJpeg, anyway. So we compose + headers to feed to LibJpeg, in this case, that allow us to pass a single + plane such that LibJpeg sees a valid single-channel JPEG stream. Locating + subsequent SOS markers, and thus subsequent planes, is done inside + OJPEGReadSecondarySos. - The benefit of the scheme is... that it works, basically. We know of no other that - does. It works without checking software tag, or otherwise going about things in an - OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases - with and without JpegInterchangeFormat, with and without striles, with part of - the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving - and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out - of the data. + The benefit of the scheme is... that it works, basically. We know of no other + that does. It works without checking software tag, or otherwise going about + things in an OJPEG flavor specific manner. Instead, it is a single scheme, + that covers the cases with and without JpegInterchangeFormat, with and + without striles, with part of the header in JpegInterchangeFormat and + remainder in first strile, etc. It is forgiving and robust, may likely work + with OJPEG flavors we've not seen yet, and makes most out of the data. - Another nice side-effect is that a complete JPEG single valid stream is build if - planarconfig is not separate (vast majority). We may one day use that to build - converters to JPEG, and/or to new-style JPEG compression inside TIFF. + Another nice side-effect is that a complete JPEG single valid stream is build + if planarconfig is not separate (vast majority). We may one day use that to + build converters to JPEG, and/or to new-style JPEG compression inside TIFF. - A disadvantage is the lack of random access to the individual striles. This is the - reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode. - Applications would do well accessing all striles in order, as this will result in - a single sequential scan of the input stream, and no restarting of LibJpeg decoding - session. + A disadvantage is the lack of random access to the individual striles. This + is the reason for much of the complicated restart-and-position stuff inside + OJPEGPreDecode. Applications would do well accessing all striles in order, as + this will result in a single sequential scan of the input stream, and no + restarting of LibJpeg decoding session. */ #define WIN32_LEAN_AND_MEAN @@ -125,30 +129,31 @@ #ifdef OJPEG_SUPPORT /* Configuration defines here are: - * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments, - * like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to - * libjpeg, with longjump stuff, are encapsulated in dedicated functions. When - * JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external - * to this unit, and can be defined elsewhere to use stuff other then longjump. - * The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators - * here, internally, with normal longjump. - * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is - * conveniently available, but still it may be worthwhile to use _setjmp or sigsetjmp - * in place of plain setjmp. These macros will make it easier. It is useless - * to fiddle with these if you define JPEG_ENCAP_EXTERNAL. - * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee - * instant processing, optimal streaming and optimal use of processor cache, but also big - * enough so as to not result in significant call overhead. It should be at least a few - * bytes to accommodate some structures (this is verified in asserts), but it would not be - * sensible to make it this small anyway, and it should be at most 64K since it is indexed - * with uint16. We recommend 2K. - * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has - * absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly. + * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some + * environments, like eg LibTiffDelphi, this is not possible. For this reason, + * the actual calls to libjpeg, with longjump stuff, are encapsulated in + * dedicated functions. When JPEG_ENCAP_EXTERNAL is defined, these encapsulating + * functions are declared external to this unit, and can be defined elsewhere to + * use stuff other then longjump. The default mode, without JPEG_ENCAP_EXTERNAL, + * implements the call encapsulators here, internally, with normal longjump. + * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent + * is conveniently available, but still it may be worthwhile to use _setjmp or + * sigsetjmp in place of plain setjmp. These macros will make it easier. It is + * useless to fiddle with these if you define JPEG_ENCAP_EXTERNAL. OJPEG_BUFFER: + * Define the size of the desired buffer here. Should be small enough so as to + * guarantee instant processing, optimal streaming and optimal use of processor + * cache, but also big enough so as to not result in significant call overhead. + * It should be at least a few bytes to accommodate some structures (this is + * verified in asserts), but it would not be sensible to make it this small + * anyway, and it should be at most 64K since it is indexed with uint16_t. We + * recommend 2K. EGYPTIANWALK: You could also define EGYPTIANWALK here, but it + * is not used anywhere and has absolutely no effect. That is why most people + * insist the EGYPTIANWALK is a bit silly. */ /* define LIBJPEG_ENCAP_EXTERNAL */ #define SETJMP(jbuf) setjmp(jbuf) -#define LONGJMP(jbuf,code) longjmp(jbuf,code) +#define LONGJMP(jbuf, code) longjmp(jbuf, code) #define JMP_BUF jmp_buf #define OJPEG_BUFFER 2048 /* define EGYPTIANWALK */ @@ -166,22 +171,36 @@ #define JPEG_MARKER_APP0 0xE0 #define JPEG_MARKER_COM 0xFE -#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0) -#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1) -#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2) -#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3) -#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4) -#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5) -#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6) +#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC + 0) +#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC + 1) +#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC + 2) +#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC + 3) +#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC + 4) +#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC + 5) +#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC + 6) static const TIFFField ojpegFields[] = { - {TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat",NULL}, - {TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength",NULL}, - {TIFFTAG_JPEGQTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables",NULL}, - {TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables",NULL}, - {TIFFTAG_JPEGACTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables",NULL}, - {TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc",NULL}, - {TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval",NULL}, + {TIFFTAG_JPEGIFOFFSET, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, + TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMAT, TRUE, FALSE, + "JpegInterchangeFormat", NULL}, + {TIFFTAG_JPEGIFBYTECOUNT, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, + TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH, TRUE, + FALSE, "JpegInterchangeFormatLength", NULL}, + {TIFFTAG_JPEGQTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0, + TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGQTABLES, + FALSE, TRUE, "JpegQTables", NULL}, + {TIFFTAG_JPEGDCTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0, + TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGDCTABLES, + FALSE, TRUE, "JpegDcTables", NULL}, + {TIFFTAG_JPEGACTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0, + TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGACTABLES, + FALSE, TRUE, "JpegAcTables", NULL}, + {TIFFTAG_JPEGPROC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGPROC, FALSE, FALSE, "JpegProc", + NULL}, + {TIFFTAG_JPEGRESTARTINTERVAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGRESTARTINTERVAL, FALSE, FALSE, + "JpegRestartInterval", NULL}, }; #ifndef LIBJPEG_ENCAP_EXTERNAL @@ -201,2405 +220,2596 @@ static const TIFFField ojpegFields[] = { a conflicting typedef given the headers which are included. */ #if defined(__BORLANDC__) || defined(__MINGW32__) -# define XMD_H 1 +#define XMD_H 1 #endif /* Define "boolean" as unsigned char, not int, per Windows custom. */ #if defined(__WIN32__) && !defined(__MINGW32__) -# ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ - typedef unsigned char boolean; -# endif -# define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ #endif -#include "jpeglib.h" #include "jerror.h" +#include "jpeglib.h" typedef struct jpeg_error_mgr jpeg_error_mgr; typedef struct jpeg_common_struct jpeg_common_struct; typedef struct jpeg_decompress_struct jpeg_decompress_struct; typedef struct jpeg_source_mgr jpeg_source_mgr; -typedef enum { - osibsNotSetYet, - osibsJpegInterchangeFormat, - osibsStrile, - osibsEof +typedef enum +{ + osibsNotSetYet, + osibsJpegInterchangeFormat, + osibsStrile, + osibsEof } OJPEGStateInBufferSource; -typedef enum { - ososSoi, - ososQTable0,ososQTable1,ososQTable2,ososQTable3, - ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3, - ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3, - ososDri, - ososSof, - ososSos, - ososCompressed, - ososRst, - ososEoi +typedef enum +{ + ososSoi, + ososQTable0, + ososQTable1, + ososQTable2, + ososQTable3, + ososDcTable0, + ososDcTable1, + ososDcTable2, + ososDcTable3, + ososAcTable0, + ososAcTable1, + ososAcTable2, + ososAcTable3, + ososDri, + ososSof, + ososSos, + ososCompressed, + ososRst, + ososEoi } OJPEGStateOutState; -typedef struct { - TIFF* tif; - int decoder_ok; - int error_in_raw_data_decoding; - #ifndef LIBJPEG_ENCAP_EXTERNAL - JMP_BUF exit_jmpbuf; - #endif - TIFFVGetMethod vgetparent; - TIFFVSetMethod vsetparent; - TIFFPrintMethod printdir; - uint64 file_size; - uint32 image_width; - uint32 image_length; - uint32 strile_width; - uint32 strile_length; - uint32 strile_length_total; - uint8 samples_per_pixel; - uint8 plane_sample_offset; - uint8 samples_per_pixel_per_plane; - uint64 jpeg_interchange_format; - uint64 jpeg_interchange_format_length; - uint8 jpeg_proc; - uint8 subsamplingcorrect; - uint8 subsamplingcorrect_done; - uint8 subsampling_tag; - uint8 subsampling_hor; - uint8 subsampling_ver; - uint8 subsampling_force_desubsampling_inside_decompression; - uint8 qtable_offset_count; - uint8 dctable_offset_count; - uint8 actable_offset_count; - uint64 qtable_offset[3]; - uint64 dctable_offset[3]; - uint64 actable_offset[3]; - uint8* qtable[4]; - uint8* dctable[4]; - uint8* actable[4]; - uint16 restart_interval; - uint8 restart_index; - uint8 sof_log; - uint8 sof_marker_id; - uint32 sof_x; - uint32 sof_y; - uint8 sof_c[3]; - uint8 sof_hv[3]; - uint8 sof_tq[3]; - uint8 sos_cs[3]; - uint8 sos_tda[3]; - struct { - uint8 log; - OJPEGStateInBufferSource in_buffer_source; - uint32 in_buffer_next_strile; - uint64 in_buffer_file_pos; - uint64 in_buffer_file_togo; - } sos_end[3]; - uint8 readheader_done; - uint8 writeheader_done; - uint16 write_cursample; - uint32 write_curstrile; - uint8 libjpeg_session_active; - uint8 libjpeg_jpeg_query_style; - jpeg_error_mgr libjpeg_jpeg_error_mgr; - jpeg_decompress_struct libjpeg_jpeg_decompress_struct; - jpeg_source_mgr libjpeg_jpeg_source_mgr; - uint8 subsampling_convert_log; - uint32 subsampling_convert_ylinelen; - uint32 subsampling_convert_ylines; - uint32 subsampling_convert_clinelen; - uint32 subsampling_convert_clines; - uint32 subsampling_convert_ybuflen; - uint32 subsampling_convert_cbuflen; - uint32 subsampling_convert_ycbcrbuflen; - uint8* subsampling_convert_ycbcrbuf; - uint8* subsampling_convert_ybuf; - uint8* subsampling_convert_cbbuf; - uint8* subsampling_convert_crbuf; - uint32 subsampling_convert_ycbcrimagelen; - uint8** subsampling_convert_ycbcrimage; - uint32 subsampling_convert_clinelenout; - uint32 subsampling_convert_state; - uint32 bytes_per_line; /* if the codec outputs subsampled data, a 'line' in bytes_per_line */ - uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows */ - OJPEGStateInBufferSource in_buffer_source; - uint32 in_buffer_next_strile; - uint32 in_buffer_strile_count; - uint64 in_buffer_file_pos; - uint8 in_buffer_file_pos_log; - uint64 in_buffer_file_togo; - uint16 in_buffer_togo; - uint8* in_buffer_cur; - uint8 in_buffer[OJPEG_BUFFER]; - OJPEGStateOutState out_state; - uint8 out_buffer[OJPEG_BUFFER]; - uint8* skip_buffer; +typedef struct +{ + TIFF *tif; + int decoder_ok; + int error_in_raw_data_decoding; +#ifndef LIBJPEG_ENCAP_EXTERNAL + JMP_BUF exit_jmpbuf; +#endif + TIFFVGetMethod vgetparent; + TIFFVSetMethod vsetparent; + TIFFPrintMethod printdir; + uint64_t file_size; + uint32_t image_width; + uint32_t image_length; + uint32_t strile_width; + uint32_t strile_length; + uint32_t strile_length_total; + uint8_t samples_per_pixel; + uint8_t plane_sample_offset; + uint8_t samples_per_pixel_per_plane; + uint64_t jpeg_interchange_format; + uint64_t jpeg_interchange_format_length; + uint8_t jpeg_proc; + uint8_t subsamplingcorrect; + uint8_t subsamplingcorrect_done; + uint8_t subsampling_tag; + uint8_t subsampling_hor; + uint8_t subsampling_ver; + uint8_t subsampling_force_desubsampling_inside_decompression; + uint8_t qtable_offset_count; + uint8_t dctable_offset_count; + uint8_t actable_offset_count; + uint64_t qtable_offset[3]; + uint64_t dctable_offset[3]; + uint64_t actable_offset[3]; + uint8_t *qtable[4]; + uint8_t *dctable[4]; + uint8_t *actable[4]; + uint16_t restart_interval; + uint8_t restart_index; + uint8_t sof_log; + uint8_t sof_marker_id; + uint32_t sof_x; + uint32_t sof_y; + uint8_t sof_c[3]; + uint8_t sof_hv[3]; + uint8_t sof_tq[3]; + uint8_t sos_cs[3]; + uint8_t sos_tda[3]; + struct + { + uint8_t log; + OJPEGStateInBufferSource in_buffer_source; + uint32_t in_buffer_next_strile; + uint64_t in_buffer_file_pos; + uint64_t in_buffer_file_togo; + } sos_end[3]; + uint8_t readheader_done; + uint8_t writeheader_done; + uint16_t write_cursample; + uint32_t write_curstrile; + uint8_t libjpeg_session_active; + uint8_t libjpeg_jpeg_query_style; + jpeg_error_mgr libjpeg_jpeg_error_mgr; + jpeg_decompress_struct libjpeg_jpeg_decompress_struct; + jpeg_source_mgr libjpeg_jpeg_source_mgr; + uint8_t subsampling_convert_log; + uint32_t subsampling_convert_ylinelen; + uint32_t subsampling_convert_ylines; + uint32_t subsampling_convert_clinelen; + uint32_t subsampling_convert_clines; + uint32_t subsampling_convert_ybuflen; + uint32_t subsampling_convert_cbuflen; + uint32_t subsampling_convert_ycbcrbuflen; + uint8_t *subsampling_convert_ycbcrbuf; + uint8_t *subsampling_convert_ybuf; + uint8_t *subsampling_convert_cbbuf; + uint8_t *subsampling_convert_crbuf; + uint32_t subsampling_convert_ycbcrimagelen; + uint8_t **subsampling_convert_ycbcrimage; + uint32_t subsampling_convert_clinelenout; + uint32_t subsampling_convert_state; + uint32_t bytes_per_line; /* if the codec outputs subsampled data, a 'line' + in bytes_per_line */ + uint32_t lines_per_strile; /* and lines_per_strile means subsampling_ver + desubsampled rows */ + OJPEGStateInBufferSource in_buffer_source; + uint32_t in_buffer_next_strile; + uint32_t in_buffer_strile_count; + uint64_t in_buffer_file_pos; + uint8_t in_buffer_file_pos_log; + uint64_t in_buffer_file_togo; + uint16_t in_buffer_togo; + uint8_t *in_buffer_cur; + uint8_t in_buffer[OJPEG_BUFFER]; + OJPEGStateOutState out_state; + uint8_t out_buffer[OJPEG_BUFFER]; + uint8_t *skip_buffer; } OJPEGState; -static int OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap); -static int OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap); -static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags); +static int OJPEGVGetField(TIFF *tif, uint32_t tag, va_list ap); +static int OJPEGVSetField(TIFF *tif, uint32_t tag, va_list ap); +static void OJPEGPrintDir(TIFF *tif, FILE *fd, long flags); -static int OJPEGFixupTags(TIFF* tif); -static int OJPEGSetupDecode(TIFF* tif); -static int OJPEGPreDecode(TIFF* tif, uint16 s); -static int OJPEGPreDecodeSkipRaw(TIFF* tif); -static int OJPEGPreDecodeSkipScanlines(TIFF* tif); -static int OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); -static int OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc); -static int OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc); -static void OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc); -static int OJPEGSetupEncode(TIFF* tif); -static int OJPEGPreEncode(TIFF* tif, uint16 s); -static int OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); -static int OJPEGPostEncode(TIFF* tif); -static void OJPEGCleanup(TIFF* tif); +static int OJPEGFixupTags(TIFF *tif); +static int OJPEGSetupDecode(TIFF *tif); +static int OJPEGPreDecode(TIFF *tif, uint16_t s); +static int OJPEGPreDecodeSkipRaw(TIFF *tif); +static int OJPEGPreDecodeSkipScanlines(TIFF *tif); +static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc); +static int OJPEGDecodeScanlines(TIFF *tif, uint8_t *buf, tmsize_t cc); +static void OJPEGPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc); +static int OJPEGSetupEncode(TIFF *tif); +static int OJPEGPreEncode(TIFF *tif, uint16_t s); +static int OJPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int OJPEGPostEncode(TIFF *tif); +static void OJPEGCleanup(TIFF *tif); -static void OJPEGSubsamplingCorrect(TIFF* tif); -static int OJPEGReadHeaderInfo(TIFF* tif); -static int OJPEGReadSecondarySos(TIFF* tif, uint16 s); -static int OJPEGWriteHeaderInfo(TIFF* tif); -static void OJPEGLibjpegSessionAbort(TIFF* tif); +static void OJPEGSubsamplingCorrect(TIFF *tif); +static int OJPEGReadHeaderInfo(TIFF *tif); +static int OJPEGReadSecondarySos(TIFF *tif, uint16_t s); +static int OJPEGWriteHeaderInfo(TIFF *tif); +static void OJPEGLibjpegSessionAbort(TIFF *tif); -static int OJPEGReadHeaderInfoSec(TIFF* tif); -static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif); -static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif); -static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif); -static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id); -static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif); -static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif); -static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif); -static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif); +static int OJPEGReadHeaderInfoSec(TIFF *tif); +static int OJPEGReadHeaderInfoSecStreamDri(TIFF *tif); +static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif); +static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif); +static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id); +static int OJPEGReadHeaderInfoSecStreamSos(TIFF *tif); +static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif); +static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif); +static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif); -static int OJPEGReadBufferFill(OJPEGState* sp); -static int OJPEGReadByte(OJPEGState* sp, uint8* byte); -static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte); -static void OJPEGReadByteAdvance(OJPEGState* sp); -static int OJPEGReadWord(OJPEGState* sp, uint16* word); -static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem); -static void OJPEGReadSkip(OJPEGState* sp, uint16 len); +static int OJPEGReadBufferFill(OJPEGState *sp); +static int OJPEGReadByte(OJPEGState *sp, uint8_t *byte); +static int OJPEGReadBytePeek(OJPEGState *sp, uint8_t *byte); +static void OJPEGReadByteAdvance(OJPEGState *sp); +static int OJPEGReadWord(OJPEGState *sp, uint16_t *word); +static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem); +static void OJPEGReadSkip(OJPEGState *sp, uint16_t len); -static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len); -static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len); -static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len); -static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len); -static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len); -static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len); -static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len); -static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len); -static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len); -static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len); -static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len); +static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len); +static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len); +static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len); +static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len); +static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len); #ifdef LIBJPEG_ENCAP_EXTERNAL -extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); -extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image); -extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); -extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines); -extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines); -extern void jpeg_encap_unwind(TIFF* tif); +extern int jpeg_create_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo); +extern int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, + uint8_t require_image); +extern int jpeg_start_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo); +extern int jpeg_read_scanlines_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, + void *scanlines, uint32_t max_lines); +extern int jpeg_read_raw_data_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, void *data, + uint32_t max_lines); +extern void jpeg_encap_unwind(TIFF *tif); #else -static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j); -static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image); -static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); -static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines); -static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines); -static void jpeg_encap_unwind(TIFF* tif); +static int jpeg_create_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *j); +static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, + uint8_t require_image); +static int jpeg_start_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo); +static int jpeg_read_scanlines_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, + void *scanlines, uint32_t max_lines); +static int jpeg_read_raw_data_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, void *data, + uint32_t max_lines); +static void jpeg_encap_unwind(TIFF *tif); #endif -static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo); -static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo); -static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo); -static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo); -static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes); -static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired); -static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo); - -int -TIFFInitOJPEG(TIFF* tif, int scheme) -{ - static const char module[]="TIFFInitOJPEG"; - OJPEGState* sp; - - (void)scheme; - assert(scheme==COMPRESSION_OJPEG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Merging Old JPEG codec-specific tags failed"); - return 0; - } - - /* state block */ - sp=_TIFFmalloc(sizeof(OJPEGState)); - if (sp==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block"); - return(0); - } - _TIFFmemset(sp,0,sizeof(OJPEGState)); - sp->tif=tif; - sp->jpeg_proc=1; - sp->subsampling_hor=2; - sp->subsampling_ver=2; - TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2); - /* tif codec methods */ - tif->tif_fixuptags=OJPEGFixupTags; - tif->tif_setupdecode=OJPEGSetupDecode; - tif->tif_predecode=OJPEGPreDecode; - tif->tif_postdecode=OJPEGPostDecode; - tif->tif_decoderow=OJPEGDecode; - tif->tif_decodestrip=OJPEGDecode; - tif->tif_decodetile=OJPEGDecode; - tif->tif_setupencode=OJPEGSetupEncode; - tif->tif_preencode=OJPEGPreEncode; - tif->tif_postencode=OJPEGPostEncode; - tif->tif_encoderow=OJPEGEncode; - tif->tif_encodestrip=OJPEGEncode; - tif->tif_encodetile=OJPEGEncode; - tif->tif_cleanup=OJPEGCleanup; - tif->tif_data=(uint8*)sp; - /* tif tag methods */ - sp->vgetparent=tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield=OJPEGVGetField; - sp->vsetparent=tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield=OJPEGVSetField; - sp->printdir=tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir=OJPEGPrintDir; - /* Some OJPEG files don't have strip or tile offsets or bytecounts tags. - Some others do, but have totally meaningless or corrupt values - in these tags. In these cases, the JpegInterchangeFormat stream is - reliable. In any case, this decoder reads the compressed data itself, - from the most reliable locations, and we need to notify encapsulating - LibTiff not to read raw strips or tiles for us. */ - tif->tif_flags|=TIFF_NOREADRAW; - return(1); -} - -static int -OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - switch(tag) - { - case TIFFTAG_JPEGIFOFFSET: - *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format; - break; - case TIFFTAG_JPEGIFBYTECOUNT: - *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format_length; - break; - case TIFFTAG_YCBCRSUBSAMPLING: - if (sp->subsamplingcorrect_done==0) - OJPEGSubsamplingCorrect(tif); - *va_arg(ap,uint16*)=(uint16)sp->subsampling_hor; - *va_arg(ap,uint16*)=(uint16)sp->subsampling_ver; - break; - case TIFFTAG_JPEGQTABLES: - *va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count; - *va_arg(ap,const void**)=(const void*)sp->qtable_offset; - break; - case TIFFTAG_JPEGDCTABLES: - *va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count; - *va_arg(ap,const void**)=(const void*)sp->dctable_offset; - break; - case TIFFTAG_JPEGACTABLES: - *va_arg(ap,uint32*)=(uint32)sp->actable_offset_count; - *va_arg(ap,const void**)=(const void*)sp->actable_offset; - break; - case TIFFTAG_JPEGPROC: - *va_arg(ap,uint16*)=(uint16)sp->jpeg_proc; - break; - case TIFFTAG_JPEGRESTARTINTERVAL: - *va_arg(ap,uint16*)=sp->restart_interval; - break; - default: - return (*sp->vgetparent)(tif,tag,ap); - } - return (1); -} - -static int -OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap) -{ - static const char module[]="OJPEGVSetField"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint32 ma; - uint64* mb; - uint32 n; - const TIFFField* fip; - - switch(tag) - { - case TIFFTAG_JPEGIFOFFSET: - sp->jpeg_interchange_format=(uint64)va_arg(ap,uint64); - break; - case TIFFTAG_JPEGIFBYTECOUNT: - sp->jpeg_interchange_format_length=(uint64)va_arg(ap,uint64); - break; - case TIFFTAG_YCBCRSUBSAMPLING: - sp->subsampling_tag=1; - sp->subsampling_hor=(uint8)va_arg(ap,uint16_vap); - sp->subsampling_ver=(uint8)va_arg(ap,uint16_vap); - tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor; - tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver; - break; - case TIFFTAG_JPEGQTABLES: - ma=(uint32)va_arg(ap,uint32); - if (ma!=0) - { - if (ma>3) - { - TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count"); - return(0); - } - sp->qtable_offset_count=(uint8)ma; - mb=(uint64*)va_arg(ap,uint64*); - for (n=0; nqtable_offset[n]=mb[n]; - } - break; - case TIFFTAG_JPEGDCTABLES: - ma=(uint32)va_arg(ap,uint32); - if (ma!=0) - { - if (ma>3) - { - TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count"); - return(0); - } - sp->dctable_offset_count=(uint8)ma; - mb=(uint64*)va_arg(ap,uint64*); - for (n=0; ndctable_offset[n]=mb[n]; - } - break; - case TIFFTAG_JPEGACTABLES: - ma=(uint32)va_arg(ap,uint32); - if (ma!=0) - { - if (ma>3) - { - TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count"); - return(0); - } - sp->actable_offset_count=(uint8)ma; - mb=(uint64*)va_arg(ap,uint64*); - for (n=0; nactable_offset[n]=mb[n]; - } - break; - case TIFFTAG_JPEGPROC: - sp->jpeg_proc=(uint8)va_arg(ap,uint16_vap); - break; - case TIFFTAG_JPEGRESTARTINTERVAL: - sp->restart_interval=(uint16)va_arg(ap,uint16_vap); - break; - default: - return (*sp->vsetparent)(tif,tag,ap); - } - fip = TIFFFieldWithTag(tif,tag); - if( fip == NULL ) /* shouldn't happen */ - return(0); - TIFFSetFieldBit(tif,fip->field_bit); - tif->tif_flags|=TIFF_DIRTYDIRECT; - return(1); -} - +static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo); +static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo); +static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo); +static boolean +OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo); static void -OJPEGPrintDir(TIFF* tif, FILE* fd, long flags) +OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo, + long num_bytes); +static boolean +OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo, + int desired); +static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo); + +int TIFFInitOJPEG(TIFF *tif, int scheme) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8 m; - (void)flags; - assert(sp!=NULL); - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT)) - fprintf(fd," JpegInterchangeFormat: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format); - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH)) - fprintf(fd," JpegInterchangeFormatLength: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format_length); - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES)) - { - fprintf(fd," JpegQTables:"); - for (m=0; mqtable_offset_count; m++) - fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->qtable_offset[m]); - fprintf(fd,"\n"); - } - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES)) - { - fprintf(fd," JpegDcTables:"); - for (m=0; mdctable_offset_count; m++) - fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->dctable_offset[m]); - fprintf(fd,"\n"); - } - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES)) - { - fprintf(fd," JpegAcTables:"); - for (m=0; mactable_offset_count; m++) - fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->actable_offset[m]); - fprintf(fd,"\n"); - } - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC)) - fprintf(fd," JpegProc: %u\n",(unsigned int)sp->jpeg_proc); - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL)) - fprintf(fd," JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval); - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); + static const char module[] = "TIFFInitOJPEG"; + OJPEGState *sp; + + (void)scheme; + assert(scheme == COMPRESSION_OJPEG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) + { + TIFFErrorExtR(tif, module, + "Merging Old JPEG codec-specific tags failed"); + return 0; + } + + /* state block */ + sp = _TIFFmallocExt(tif, sizeof(OJPEGState)); + if (sp == NULL) + { + TIFFErrorExtR(tif, module, "No space for OJPEG state block"); + return (0); + } + _TIFFmemset(sp, 0, sizeof(OJPEGState)); + sp->tif = tif; + sp->jpeg_proc = 1; + sp->subsampling_hor = 2; + sp->subsampling_ver = 2; + TIFFSetField(tif, TIFFTAG_YCBCRSUBSAMPLING, 2, 2); + /* tif codec methods */ + tif->tif_fixuptags = OJPEGFixupTags; + tif->tif_setupdecode = OJPEGSetupDecode; + tif->tif_predecode = OJPEGPreDecode; + tif->tif_postdecode = OJPEGPostDecode; + tif->tif_decoderow = OJPEGDecode; + tif->tif_decodestrip = OJPEGDecode; + tif->tif_decodetile = OJPEGDecode; + tif->tif_setupencode = OJPEGSetupEncode; + tif->tif_preencode = OJPEGPreEncode; + tif->tif_postencode = OJPEGPostEncode; + tif->tif_encoderow = OJPEGEncode; + tif->tif_encodestrip = OJPEGEncode; + tif->tif_encodetile = OJPEGEncode; + tif->tif_cleanup = OJPEGCleanup; + tif->tif_data = (uint8_t *)sp; + /* tif tag methods */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = OJPEGVGetField; + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = OJPEGVSetField; + sp->printdir = tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir = OJPEGPrintDir; + /* Some OJPEG files don't have strip or tile offsets or bytecounts tags. + Some others do, but have totally meaningless or corrupt values + in these tags. In these cases, the JpegInterchangeFormat stream is + reliable. In any case, this decoder reads the compressed data itself, + from the most reliable locations, and we need to notify encapsulating + LibTiff not to read raw strips or tiles for us. */ + tif->tif_flags |= TIFF_NOREADRAW; + return (1); } -static int -OJPEGFixupTags(TIFF* tif) +static int OJPEGVGetField(TIFF *tif, uint32_t tag, va_list ap) { - (void) tif; - return(1); + OJPEGState *sp = (OJPEGState *)tif->tif_data; + switch (tag) + { + case TIFFTAG_JPEGIFOFFSET: + *va_arg(ap, uint64_t *) = (uint64_t)sp->jpeg_interchange_format; + break; + case TIFFTAG_JPEGIFBYTECOUNT: + *va_arg(ap, uint64_t *) = + (uint64_t)sp->jpeg_interchange_format_length; + break; + case TIFFTAG_YCBCRSUBSAMPLING: + if (sp->subsamplingcorrect_done == 0) + OJPEGSubsamplingCorrect(tif); + *va_arg(ap, uint16_t *) = (uint16_t)sp->subsampling_hor; + *va_arg(ap, uint16_t *) = (uint16_t)sp->subsampling_ver; + break; + case TIFFTAG_JPEGQTABLES: + *va_arg(ap, uint32_t *) = (uint32_t)sp->qtable_offset_count; + *va_arg(ap, const void **) = (const void *)sp->qtable_offset; + break; + case TIFFTAG_JPEGDCTABLES: + *va_arg(ap, uint32_t *) = (uint32_t)sp->dctable_offset_count; + *va_arg(ap, const void **) = (const void *)sp->dctable_offset; + break; + case TIFFTAG_JPEGACTABLES: + *va_arg(ap, uint32_t *) = (uint32_t)sp->actable_offset_count; + *va_arg(ap, const void **) = (const void *)sp->actable_offset; + break; + case TIFFTAG_JPEGPROC: + *va_arg(ap, uint16_t *) = (uint16_t)sp->jpeg_proc; + break; + case TIFFTAG_JPEGRESTARTINTERVAL: + *va_arg(ap, uint16_t *) = sp->restart_interval; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); } -static int -OJPEGSetupDecode(TIFF* tif) +static int OJPEGVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[]="OJPEGSetupDecode"; - TIFFWarningExt(tif->tif_clientdata,module,"Deprecated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software"); - return(1); -} + static const char module[] = "OJPEGVSetField"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint32_t ma; + uint64_t *mb; + uint32_t n; + const TIFFField *fip; -static int -OJPEGPreDecode(TIFF* tif, uint16 s) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint32 m; - if (sp->subsamplingcorrect_done==0) - OJPEGSubsamplingCorrect(tif); - if (sp->readheader_done==0) - { - if (OJPEGReadHeaderInfo(tif)==0) - return(0); - } - if (sp->sos_end[s].log==0) - { - if (OJPEGReadSecondarySos(tif,s)==0) - return(0); - } - if (isTiled(tif)) - m=tif->tif_curtile; - else - m=tif->tif_curstrip; - if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m))) - { - if (sp->libjpeg_session_active!=0) - OJPEGLibjpegSessionAbort(tif); - sp->writeheader_done=0; - } - if (sp->writeheader_done==0) - { - sp->plane_sample_offset=(uint8)s; - sp->write_cursample=s; - sp->write_curstrile=s*tif->tif_dir.td_stripsperimage; - if ((sp->in_buffer_file_pos_log==0) || - (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos)) - { - sp->in_buffer_source=sp->sos_end[s].in_buffer_source; - sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile; - sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos; - sp->in_buffer_file_pos_log=0; - sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo; - sp->in_buffer_togo=0; - sp->in_buffer_cur=0; - } - if (OJPEGWriteHeaderInfo(tif)==0) - return(0); - } - while (sp->write_curstrilelibjpeg_jpeg_query_style==0) - { - if (OJPEGPreDecodeSkipRaw(tif)==0) - return(0); - } - else - { - if (OJPEGPreDecodeSkipScanlines(tif)==0) - return(0); - } - sp->write_curstrile++; - } - sp->decoder_ok = 1; - return(1); -} - -static int -OJPEGPreDecodeSkipRaw(TIFF* tif) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint32 m; - m=sp->lines_per_strile; - if (sp->subsampling_convert_state!=0) - { - if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m) - { - sp->subsampling_convert_state+=m; - if (sp->subsampling_convert_state==sp->subsampling_convert_clines) - sp->subsampling_convert_state=0; - return(1); - } - m-=sp->subsampling_convert_clines-sp->subsampling_convert_state; - sp->subsampling_convert_state=0; - sp->error_in_raw_data_decoding=0; - } - while (m>=sp->subsampling_convert_clines) - { - if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) - return(0); - m-=sp->subsampling_convert_clines; - } - if (m>0) - { - if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) - return(0); - sp->subsampling_convert_state=m; - } - return(1); -} - -static int -OJPEGPreDecodeSkipScanlines(TIFF* tif) -{ - static const char module[]="OJPEGPreDecodeSkipScanlines"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint32 m; - if (sp->skip_buffer==NULL) - { - sp->skip_buffer=_TIFFmalloc(sp->bytes_per_line); - if (sp->skip_buffer==NULL) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - } - for (m=0; mlines_per_strile; m++) - { - if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0) - return(0); - } - return(1); -} - -static int -OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) -{ - static const char module[]="OJPEGDecode"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - (void)s; - if( !sp->decoder_ok ) - { - TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized"); - return 0; - } - if( sp->error_in_raw_data_decoding ) - { - return 0; - } - if (sp->libjpeg_jpeg_query_style==0) - { - if (OJPEGDecodeRaw(tif,buf,cc)==0) - return(0); - } - else - { - if (OJPEGDecodeScanlines(tif,buf,cc)==0) - return(0); - } - return(1); -} - -static int -OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc) -{ - static const char module[]="OJPEGDecodeRaw"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8* m; - tmsize_t n; - uint8* oy; - uint8* ocb; - uint8* ocr; - uint8* p; - uint32 q; - uint8* r; - uint8 sx,sy; - if (cc%sp->bytes_per_line!=0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read"); - return(0); - } - assert(cc>0); - m=buf; - n=cc; - do - { - if (sp->subsampling_convert_state==0) - { - if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) - { - sp->error_in_raw_data_decoding = 1; - return(0); - } - } - oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen; - ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen; - ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen; - p=m; - for (q=0; qsubsampling_convert_clinelenout; q++) - { - r=oy; - for (sy=0; sysubsampling_ver; sy++) - { - for (sx=0; sxsubsampling_hor; sx++) - *p++=*r++; - r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor; - } - oy+=sp->subsampling_hor; - *p++=*ocb++; - *p++=*ocr++; - } - sp->subsampling_convert_state++; - if (sp->subsampling_convert_state==sp->subsampling_convert_clines) - sp->subsampling_convert_state=0; - m+=sp->bytes_per_line; - n-=sp->bytes_per_line; - } while(n>0); - return(1); -} - -static int -OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc) -{ - static const char module[]="OJPEGDecodeScanlines"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8* m; - tmsize_t n; - if (cc%sp->bytes_per_line!=0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read"); - return(0); - } - assert(cc>0); - m=buf; - n=cc; - do - { - if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0) - return(0); - m+=sp->bytes_per_line; - n-=sp->bytes_per_line; - } while(n>0); - return(1); -} - -static void -OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - (void)buf; - (void)cc; - sp->write_curstrile++; - if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0) - { - assert(sp->libjpeg_session_active!=0); - OJPEGLibjpegSessionAbort(tif); - sp->writeheader_done=0; - } -} - -static int -OJPEGSetupEncode(TIFF* tif) -{ - static const char module[]="OJPEGSetupEncode"; - TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); - return(0); -} - -static int -OJPEGPreEncode(TIFF* tif, uint16 s) -{ - static const char module[]="OJPEGPreEncode"; - (void)s; - TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); - return(0); -} - -static int -OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) -{ - static const char module[]="OJPEGEncode"; - (void)buf; - (void)cc; - (void)s; - TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); - return(0); -} - -static int -OJPEGPostEncode(TIFF* tif) -{ - static const char module[]="OJPEGPostEncode"; - TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); - return(0); -} - -static void -OJPEGCleanup(TIFF* tif) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp!=0) - { - tif->tif_tagmethods.vgetfield=sp->vgetparent; - tif->tif_tagmethods.vsetfield=sp->vsetparent; - tif->tif_tagmethods.printdir=sp->printdir; - if (sp->qtable[0]!=0) - _TIFFfree(sp->qtable[0]); - if (sp->qtable[1]!=0) - _TIFFfree(sp->qtable[1]); - if (sp->qtable[2]!=0) - _TIFFfree(sp->qtable[2]); - if (sp->qtable[3]!=0) - _TIFFfree(sp->qtable[3]); - if (sp->dctable[0]!=0) - _TIFFfree(sp->dctable[0]); - if (sp->dctable[1]!=0) - _TIFFfree(sp->dctable[1]); - if (sp->dctable[2]!=0) - _TIFFfree(sp->dctable[2]); - if (sp->dctable[3]!=0) - _TIFFfree(sp->dctable[3]); - if (sp->actable[0]!=0) - _TIFFfree(sp->actable[0]); - if (sp->actable[1]!=0) - _TIFFfree(sp->actable[1]); - if (sp->actable[2]!=0) - _TIFFfree(sp->actable[2]); - if (sp->actable[3]!=0) - _TIFFfree(sp->actable[3]); - if (sp->libjpeg_session_active!=0) - OJPEGLibjpegSessionAbort(tif); - if (sp->subsampling_convert_ycbcrbuf!=0) - _TIFFfree(sp->subsampling_convert_ycbcrbuf); - if (sp->subsampling_convert_ycbcrimage!=0) - _TIFFfree(sp->subsampling_convert_ycbcrimage); - if (sp->skip_buffer!=0) - _TIFFfree(sp->skip_buffer); - _TIFFfree(sp); - tif->tif_data=NULL; - _TIFFSetDefaultCompressionState(tif); - } -} - -static void -OJPEGSubsamplingCorrect(TIFF* tif) -{ - static const char module[]="OJPEGSubsamplingCorrect"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8 mh; - uint8 mv; - - assert(sp->subsamplingcorrect_done==0); - if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) && - (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB))) - { - if (sp->subsampling_tag!=0) - TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel"); - sp->subsampling_hor=1; - sp->subsampling_ver=1; - sp->subsampling_force_desubsampling_inside_decompression=0; - } - else - { - sp->subsamplingcorrect_done=1; - mh=sp->subsampling_hor; - mv=sp->subsampling_ver; - sp->subsamplingcorrect=1; - OJPEGReadHeaderInfoSec(tif); - if (sp->subsampling_force_desubsampling_inside_decompression!=0) - { - sp->subsampling_hor=1; - sp->subsampling_ver=1; - } - sp->subsamplingcorrect=0; - if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0)) - { - if (sp->subsampling_tag==0) - TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data [%d,%d] does not match default values [2,2]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver); - else - TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data [%d,%d] does not match subsampling tag values [%d,%d]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver,mh,mv); - } - if (sp->subsampling_force_desubsampling_inside_decompression!=0) - { - if (sp->subsampling_tag==0) - TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data does not match default values [2,2] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression"); - else - TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data does not match subsampling tag values [%d,%d] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression",mh,mv); - } - if (sp->subsampling_force_desubsampling_inside_decompression==0) - { - if (sp->subsampling_horsubsampling_ver) - TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver); - } - } - sp->subsamplingcorrect_done=1; -} - -static int -OJPEGReadHeaderInfo(TIFF* tif) -{ - static const char module[]="OJPEGReadHeaderInfo"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(sp->readheader_done==0); - sp->image_width=tif->tif_dir.td_imagewidth; - sp->image_length=tif->tif_dir.td_imagelength; - if (isTiled(tif)) - { - sp->strile_width=tif->tif_dir.td_tilewidth; - sp->strile_length=tif->tif_dir.td_tilelength; - sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length; - } - else - { - sp->strile_width=sp->image_width; - sp->strile_length=tif->tif_dir.td_rowsperstrip; - if( sp->strile_length == (uint32)-1 ) - sp->strile_length = sp->image_length; - sp->strile_length_total=sp->image_length; - } - if (tif->tif_dir.td_samplesperpixel==1) - { - sp->samples_per_pixel=1; - sp->plane_sample_offset=0; - sp->samples_per_pixel_per_plane=sp->samples_per_pixel; - sp->subsampling_hor=1; - sp->subsampling_ver=1; - } - else - { - if (tif->tif_dir.td_samplesperpixel!=3) - { - TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel); - return(0); - } - sp->samples_per_pixel=3; - sp->plane_sample_offset=0; - if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG) - sp->samples_per_pixel_per_plane=3; - else - sp->samples_per_pixel_per_plane=1; - } - if (sp->strile_lengthimage_length) - { - if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) || - ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4))) - { - TIFFErrorExt(tif->tif_clientdata,module,"Invalid subsampling values"); - return(0); - } - if (sp->strile_length%(sp->subsampling_ver*8)!=0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length"); - return(0); - } - sp->restart_interval=(uint16)(((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8))); - } - if (OJPEGReadHeaderInfoSec(tif)==0) - return(0); - sp->sos_end[0].log=1; - sp->sos_end[0].in_buffer_source=sp->in_buffer_source; - sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile; - sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo; - sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; - sp->readheader_done=1; - return(1); -} - -static int -OJPEGReadSecondarySos(TIFF* tif, uint16 s) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8 m; - assert(s>0); - assert(s<3); - assert(sp->sos_end[0].log!=0); - assert(sp->sos_end[s].log==0); - sp->plane_sample_offset=(uint8)(s-1); - while(sp->sos_end[sp->plane_sample_offset].log==0) - sp->plane_sample_offset--; - sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source; - sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile; - sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos; - sp->in_buffer_file_pos_log=0; - sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo; - sp->in_buffer_togo=0; - sp->in_buffer_cur=0; - while(sp->plane_sample_offsetplane_sample_offset++; - if (OJPEGReadHeaderInfoSecStreamSos(tif)==0) - return(0); - sp->sos_end[sp->plane_sample_offset].log=1; - sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source; - sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile; - sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo; - sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; - } - return(1); -} - -static int -OJPEGWriteHeaderInfo(TIFF* tif) -{ - static const char module[]="OJPEGWriteHeaderInfo"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8** m; - uint32 n; - /* if a previous attempt failed, don't try again */ - if (sp->libjpeg_session_active != 0) - return 0; - sp->out_state=ososSoi; - sp->restart_index=0; - jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr)); - sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage; - sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit; - sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr); - sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif; - if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0) - return(0); - sp->libjpeg_session_active=1; - sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0; - sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource; - sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer; - sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData; - sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart; - sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource; - sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr); - if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0) - return(0); - if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1)) - { - sp->libjpeg_jpeg_decompress_struct.raw_data_out=1; -#if JPEG_LIB_VERSION >= 70 - sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE; -#endif - sp->libjpeg_jpeg_query_style=0; - if (sp->subsampling_convert_log==0) - { - assert(sp->subsampling_convert_ycbcrbuf==0); - assert(sp->subsampling_convert_ycbcrimage==0); - sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8); - sp->subsampling_convert_ylines=sp->subsampling_ver*8; - sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor; - sp->subsampling_convert_clines=8; - sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines; - sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines; - sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen; - /* The calloc is not normally necessary, except in some edge/broken cases */ - /* for example for a tiled image of height 1 with a tile height of 1 and subsampling_hor=subsampling_ver=2 */ - /* In that case, libjpeg will only fill the 8 first lines of the 16 lines */ - /* See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844 */ - /* Even if this case is allowed (?), its handling is broken because OJPEGPreDecode() should also likely */ - /* reset subsampling_convert_state to 0 when changing tile. */ - sp->subsampling_convert_ycbcrbuf=_TIFFcalloc(1, sp->subsampling_convert_ycbcrbuflen); - if (sp->subsampling_convert_ycbcrbuf==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf; - sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen; - sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen; - sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines; - sp->subsampling_convert_ycbcrimage=_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen*sizeof(uint8*)); - if (sp->subsampling_convert_ycbcrimage==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - m=sp->subsampling_convert_ycbcrimage; - *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3); - *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines); - *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines); - for (n=0; nsubsampling_convert_ylines; n++) - *m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen; - for (n=0; nsubsampling_convert_clines; n++) - *m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen; - for (n=0; nsubsampling_convert_clines; n++) - *m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen; - sp->subsampling_convert_clinelenout=sp->strile_width/sp->subsampling_hor + ((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0); - sp->subsampling_convert_state=0; - sp->error_in_raw_data_decoding=0; - sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2); - sp->lines_per_strile=sp->strile_length/sp->subsampling_ver + ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0); - sp->subsampling_convert_log=1; - } - } - else - { - sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN; - sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN; - sp->libjpeg_jpeg_query_style=1; - sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width; - sp->lines_per_strile=sp->strile_length; - } - if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0) - return(0); - if(sp->libjpeg_jpeg_decompress_struct.image_width != sp->strile_width ) { - TIFFErrorExt(tif->tif_clientdata,module, - "jpeg_start_decompress() returned image_width = %d, " - "expected %d", - sp->libjpeg_jpeg_decompress_struct.image_width, - sp->strile_width); - return 0; - } - if(sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor != sp->subsampling_hor || - sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor != sp->subsampling_ver) { - TIFFErrorExt(tif->tif_clientdata,module, - "jpeg_start_decompress() returned max_h_samp_factor = %d " - "and max_v_samp_factor = %d, expected %d and %d", - sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor, - sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor, - sp->subsampling_hor, - sp->subsampling_ver); - return 0; - } - - sp->writeheader_done=1; - return(1); -} - -static void -OJPEGLibjpegSessionAbort(TIFF* tif) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(sp->libjpeg_session_active!=0); - jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct))); - sp->libjpeg_session_active=0; -} - -static int -OJPEGReadHeaderInfoSec(TIFF* tif) -{ - static const char module[]="OJPEGReadHeaderInfoSec"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8 m; - uint16 n; - uint8 o; - if (sp->file_size==0) - sp->file_size=TIFFGetFileSize(tif); - if (sp->jpeg_interchange_format!=0) - { - if (sp->jpeg_interchange_format>=sp->file_size) - { - sp->jpeg_interchange_format=0; - sp->jpeg_interchange_format_length=0; - } - else - { - if ((sp->jpeg_interchange_format_length==0) || - (sp->jpeg_interchange_format > TIFF_UINT64_MAX - sp->jpeg_interchange_format_length) || - (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size)) - sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format; - } - } - sp->in_buffer_source=osibsNotSetYet; - sp->in_buffer_next_strile=0; - sp->in_buffer_strile_count=tif->tif_dir.td_nstrips; - sp->in_buffer_file_togo=0; - sp->in_buffer_togo=0; - do - { - if (OJPEGReadBytePeek(sp,&m)==0) - return(0); - if (m!=255) - break; - OJPEGReadByteAdvance(sp); - do - { - if (OJPEGReadByte(sp,&m)==0) - return(0); - } while(m==255); - switch(m) - { - case JPEG_MARKER_SOI: - /* this type of marker has no data, and should be skipped */ - break; - case JPEG_MARKER_COM: - case JPEG_MARKER_APP0: - case JPEG_MARKER_APP0+1: - case JPEG_MARKER_APP0+2: - case JPEG_MARKER_APP0+3: - case JPEG_MARKER_APP0+4: - case JPEG_MARKER_APP0+5: - case JPEG_MARKER_APP0+6: - case JPEG_MARKER_APP0+7: - case JPEG_MARKER_APP0+8: - case JPEG_MARKER_APP0+9: - case JPEG_MARKER_APP0+10: - case JPEG_MARKER_APP0+11: - case JPEG_MARKER_APP0+12: - case JPEG_MARKER_APP0+13: - case JPEG_MARKER_APP0+14: - case JPEG_MARKER_APP0+15: - /* this type of marker has data, but it has no use to us (and no place here) and should be skipped */ - if (OJPEGReadWord(sp,&n)==0) - return(0); - if (n<2) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data"); - return(0); - } - if (n>2) - OJPEGReadSkip(sp,n-2); - break; - case JPEG_MARKER_DRI: - if (OJPEGReadHeaderInfoSecStreamDri(tif)==0) - return(0); - break; - case JPEG_MARKER_DQT: - if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0) - return(0); - break; - case JPEG_MARKER_DHT: - if (OJPEGReadHeaderInfoSecStreamDht(tif)==0) - return(0); - break; - case JPEG_MARKER_SOF0: - case JPEG_MARKER_SOF1: - case JPEG_MARKER_SOF3: - if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0) - return(0); - if (sp->subsamplingcorrect!=0) - return(1); - break; - case JPEG_MARKER_SOS: - if (sp->subsamplingcorrect!=0) - return(1); - assert(sp->plane_sample_offset==0); - if (OJPEGReadHeaderInfoSecStreamSos(tif)==0) - return(0); - break; - default: - TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m); - return(0); - } - } while(m!=JPEG_MARKER_SOS); - if (sp->subsamplingcorrect) - return(1); - if (sp->sof_log==0) - { - if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0) - return(0); - sp->sof_marker_id=JPEG_MARKER_SOF0; - for (o=0; osamples_per_pixel; o++) - sp->sof_c[o]=o; - sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver); - for (o=1; osamples_per_pixel; o++) - sp->sof_hv[o]=17; - sp->sof_x=sp->strile_width; - sp->sof_y=sp->strile_length_total; - sp->sof_log=1; - if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0) - return(0); - if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0) - return(0); - for (o=1; osamples_per_pixel; o++) - sp->sos_cs[o]=o; - } - return(1); -} - -static int -OJPEGReadHeaderInfoSecStreamDri(TIFF* tif) -{ - /* This could easily cause trouble in some cases... but no such cases have - occurred so far */ - static const char module[]="OJPEGReadHeaderInfoSecStreamDri"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16 m; - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m!=4) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data"); - return(0); - } - if (OJPEGReadWord(sp,&m)==0) - return(0); - sp->restart_interval=m; - return(1); -} - -static int -OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif) -{ - /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */ - static const char module[]="OJPEGReadHeaderInfoSecStreamDqt"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16 m; - uint32 na; - uint8* nb; - uint8 o; - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m<=2) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data"); - return(0); - } - if (sp->subsamplingcorrect!=0) - OJPEGReadSkip(sp,m-2); - else - { - m-=2; - do - { - if (m<65) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data"); - return(0); - } - na=sizeof(uint32)+69; - nb=_TIFFmalloc(na); - if (nb==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - *(uint32*)nb=na; - nb[sizeof(uint32)]=255; - nb[sizeof(uint32)+1]=JPEG_MARKER_DQT; - nb[sizeof(uint32)+2]=0; - nb[sizeof(uint32)+3]=67; - if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0) { - _TIFFfree(nb); - return(0); - } - o=nb[sizeof(uint32)+4]&15; - if (3tif_clientdata,module,"Corrupt DQT marker in JPEG data"); - _TIFFfree(nb); - return(0); - } - if (sp->qtable[o]!=0) - _TIFFfree(sp->qtable[o]); - sp->qtable[o]=nb; - m-=65; - } while(m>0); - } - return(1); -} - -static int -OJPEGReadHeaderInfoSecStreamDht(TIFF* tif) -{ - /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */ - /* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */ - static const char module[]="OJPEGReadHeaderInfoSecStreamDht"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16 m; - uint32 na; - uint8* nb; - uint8 o; - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m<=2) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); - return(0); - } - if (sp->subsamplingcorrect!=0) - { - OJPEGReadSkip(sp,m-2); - } - else - { - na=sizeof(uint32)+2+m; - nb=_TIFFmalloc(na); - if (nb==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - *(uint32*)nb=na; - nb[sizeof(uint32)]=255; - nb[sizeof(uint32)+1]=JPEG_MARKER_DHT; - nb[sizeof(uint32)+2]=(m>>8); - nb[sizeof(uint32)+3]=(m&255); - if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0) { - _TIFFfree(nb); - return(0); + switch (tag) + { + case TIFFTAG_JPEGIFOFFSET: + sp->jpeg_interchange_format = (uint64_t)va_arg(ap, uint64_t); + break; + case TIFFTAG_JPEGIFBYTECOUNT: + sp->jpeg_interchange_format_length = (uint64_t)va_arg(ap, uint64_t); + break; + case TIFFTAG_YCBCRSUBSAMPLING: + sp->subsampling_tag = 1; + sp->subsampling_hor = (uint8_t)va_arg(ap, uint16_vap); + sp->subsampling_ver = (uint8_t)va_arg(ap, uint16_vap); + tif->tif_dir.td_ycbcrsubsampling[0] = sp->subsampling_hor; + tif->tif_dir.td_ycbcrsubsampling[1] = sp->subsampling_ver; + break; + case TIFFTAG_JPEGQTABLES: + ma = (uint32_t)va_arg(ap, uint32_t); + if (ma != 0) + { + if (ma > 3) + { + TIFFErrorExtR(tif, module, + "JpegQTables tag has incorrect count"); + return (0); } - o=nb[sizeof(uint32)+4]; - if ((o&240)==0) - { - if (3tif_clientdata,module,"Corrupt DHT marker in JPEG data"); - _TIFFfree(nb); - return(0); - } - if (sp->dctable[o]!=0) - _TIFFfree(sp->dctable[o]); - sp->dctable[o]=nb; - } - else - { - if ((o&240)!=16) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); - _TIFFfree(nb); - return(0); - } - o&=15; - if (3tif_clientdata,module,"Corrupt DHT marker in JPEG data"); - _TIFFfree(nb); - return(0); - } - if (sp->actable[o]!=0) - _TIFFfree(sp->actable[o]); - sp->actable[o]=nb; - } - } - return(1); + sp->qtable_offset_count = (uint8_t)ma; + mb = (uint64_t *)va_arg(ap, uint64_t *); + for (n = 0; n < ma; n++) + sp->qtable_offset[n] = mb[n]; + } + break; + case TIFFTAG_JPEGDCTABLES: + ma = (uint32_t)va_arg(ap, uint32_t); + if (ma != 0) + { + if (ma > 3) + { + TIFFErrorExtR(tif, module, + "JpegDcTables tag has incorrect count"); + return (0); + } + sp->dctable_offset_count = (uint8_t)ma; + mb = (uint64_t *)va_arg(ap, uint64_t *); + for (n = 0; n < ma; n++) + sp->dctable_offset[n] = mb[n]; + } + break; + case TIFFTAG_JPEGACTABLES: + ma = (uint32_t)va_arg(ap, uint32_t); + if (ma != 0) + { + if (ma > 3) + { + TIFFErrorExtR(tif, module, + "JpegAcTables tag has incorrect count"); + return (0); + } + sp->actable_offset_count = (uint8_t)ma; + mb = (uint64_t *)va_arg(ap, uint64_t *); + for (n = 0; n < ma; n++) + sp->actable_offset[n] = mb[n]; + } + break; + case TIFFTAG_JPEGPROC: + sp->jpeg_proc = (uint8_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_JPEGRESTARTINTERVAL: + sp->restart_interval = (uint16_t)va_arg(ap, uint16_vap); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + fip = TIFFFieldWithTag(tif, tag); + if (fip == NULL) /* shouldn't happen */ + return (0); + TIFFSetFieldBit(tif, fip->field_bit); + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); } -static int -OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id) +static void OJPEGPrintDir(TIFF *tif, FILE *fd, long flags) { - /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */ - static const char module[]="OJPEGReadHeaderInfoSecStreamSof"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16 m; - uint16 n; - uint8 o; - uint16 p; - uint16 q; - if (sp->sof_log!=0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data"); - return(0); - } - if (sp->subsamplingcorrect==0) - sp->sof_marker_id=marker_id; - /* Lf: data length */ - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m<11) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data"); - return(0); - } - m-=8; - if (m%3!=0) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data"); - return(0); - } - n=m/3; - if (sp->subsamplingcorrect==0) - { - if (n!=sp->samples_per_pixel) - { - TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples"); - return(0); - } - } - /* P: Sample precision */ - if (OJPEGReadByte(sp,&o)==0) - return(0); - if (o!=8) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample"); - return(0); - } - /* Y: Number of lines, X: Number of samples per line */ - if (sp->subsamplingcorrect) - OJPEGReadSkip(sp,4); - else - { - /* Y: Number of lines */ - if (OJPEGReadWord(sp,&p)==0) - return(0); - if (((uint32)pimage_length) && ((uint32)pstrile_length_total)) - { - TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height"); - return(0); - } - sp->sof_y=p; - /* X: Number of samples per line */ - if (OJPEGReadWord(sp,&p)==0) - return(0); - if (((uint32)pimage_width) && ((uint32)pstrile_width)) - { - TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width"); - return(0); - } - if ((uint32)p>sp->strile_width) - { - TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width"); - return(0); - } - sp->sof_x=p; - } - /* Nf: Number of image components in frame */ - if (OJPEGReadByte(sp,&o)==0) - return(0); - if (o!=n) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data"); - return(0); - } - /* per component stuff */ - /* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */ - for (q=0; qsubsamplingcorrect==0) - sp->sof_c[q]=o; - /* H: Horizontal sampling factor, and V: Vertical sampling factor */ - if (OJPEGReadByte(sp,&o)==0) - return(0); - if (sp->subsamplingcorrect!=0) - { - if (q==0) - { - sp->subsampling_hor=(o>>4); - sp->subsampling_ver=(o&15); - if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) || - ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4))) - sp->subsampling_force_desubsampling_inside_decompression=1; - } - else - { - if (o!=17) - sp->subsampling_force_desubsampling_inside_decompression=1; - } - } - else - { - sp->sof_hv[q]=o; - if (sp->subsampling_force_desubsampling_inside_decompression==0) - { - if (q==0) - { - if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver)) - { - TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values"); - return(0); - } - } - else - { - if (o!=17) - { - TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values"); - return(0); - } - } - } - } - /* Tq: Quantization table destination selector */ - if (OJPEGReadByte(sp,&o)==0) - return(0); - if (sp->subsamplingcorrect==0) - sp->sof_tq[q]=o; - } - if (sp->subsamplingcorrect==0) - sp->sof_log=1; - return(1); + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + (void)flags; + assert(sp != NULL); + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGINTERCHANGEFORMAT)) + fprintf(fd, " JpegInterchangeFormat: %" PRIu64 "\n", + (uint64_t)sp->jpeg_interchange_format); + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH)) + fprintf(fd, " JpegInterchangeFormatLength: %" PRIu64 "\n", + (uint64_t)sp->jpeg_interchange_format_length); + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGQTABLES)) + { + fprintf(fd, " JpegQTables:"); + for (m = 0; m < sp->qtable_offset_count; m++) + fprintf(fd, " %" PRIu64, (uint64_t)sp->qtable_offset[m]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGDCTABLES)) + { + fprintf(fd, " JpegDcTables:"); + for (m = 0; m < sp->dctable_offset_count; m++) + fprintf(fd, " %" PRIu64, (uint64_t)sp->dctable_offset[m]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGACTABLES)) + { + fprintf(fd, " JpegAcTables:"); + for (m = 0; m < sp->actable_offset_count; m++) + fprintf(fd, " %" PRIu64, (uint64_t)sp->actable_offset[m]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGPROC)) + fprintf(fd, " JpegProc: %" PRIu8 "\n", sp->jpeg_proc); + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGRESTARTINTERVAL)) + fprintf(fd, " JpegRestartInterval: %" PRIu16 "\n", + sp->restart_interval); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); } -static int -OJPEGReadHeaderInfoSecStreamSos(TIFF* tif) +static int OJPEGFixupTags(TIFF *tif) { - /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */ - static const char module[]="OJPEGReadHeaderInfoSecStreamSos"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16 m; - uint8 n; - uint8 o; - assert(sp->subsamplingcorrect==0); - if (sp->sof_log==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data"); - return(0); - } - /* Ls */ - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m!=6+sp->samples_per_pixel_per_plane*2) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data"); - return(0); - } - /* Ns */ - if (OJPEGReadByte(sp,&n)==0) - return(0); - if (n!=sp->samples_per_pixel_per_plane) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data"); - return(0); - } - /* Cs, Td, and Ta */ - for (o=0; osamples_per_pixel_per_plane; o++) - { - /* Cs */ - if (OJPEGReadByte(sp,&n)==0) - return(0); - sp->sos_cs[sp->plane_sample_offset+o]=n; - /* Td and Ta */ - if (OJPEGReadByte(sp,&n)==0) - return(0); - sp->sos_tda[sp->plane_sample_offset+o]=n; - } - /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */ - OJPEGReadSkip(sp,3); - return(1); + (void)tif; + return (1); } -static int -OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif) +static int OJPEGSetupDecode(TIFF *tif) { - static const char module[]="OJPEGReadHeaderInfoSecTablesQTable"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8 m; - uint8 n; - uint32 oa; - uint8* ob; - uint32 p; - if (sp->qtable_offset[0]==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables"); - return(0); - } - sp->in_buffer_file_pos_log=0; - for (m=0; msamples_per_pixel; m++) - { - if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1]))) - { - for (n=0; nqtable_offset[m]==sp->qtable_offset[n]) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value"); - return(0); - } - } - oa=sizeof(uint32)+69; - ob=_TIFFmalloc(oa); - if (ob==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - *(uint32*)ob=oa; - ob[sizeof(uint32)]=255; - ob[sizeof(uint32)+1]=JPEG_MARKER_DQT; - ob[sizeof(uint32)+2]=0; - ob[sizeof(uint32)+3]=67; - ob[sizeof(uint32)+4]=m; - TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); - p=(uint32)TIFFReadFile(tif,&ob[sizeof(uint32)+5],64); - if (p!=64) + static const char module[] = "OJPEGSetupDecode"; + TIFFWarningExtR(tif, module, + "Deprecated and troublesome old-style JPEG compression " + "mode, please convert to new-style JPEG compression and " + "notify vendor of writing software"); + return (1); +} + +static int OJPEGPreDecode(TIFF *tif, uint16_t s) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint32_t m; + if (sp->subsamplingcorrect_done == 0) + OJPEGSubsamplingCorrect(tif); + if (sp->readheader_done == 0) + { + if (OJPEGReadHeaderInfo(tif) == 0) + return (0); + } + if (sp->sos_end[s].log == 0) + { + if (OJPEGReadSecondarySos(tif, s) == 0) + return (0); + } + if (isTiled(tif)) + m = tif->tif_curtile; + else + m = tif->tif_curstrip; + if ((sp->writeheader_done != 0) && + ((sp->write_cursample != s) || (sp->write_curstrile > m))) + { + if (sp->libjpeg_session_active != 0) + OJPEGLibjpegSessionAbort(tif); + sp->writeheader_done = 0; + } + if (sp->writeheader_done == 0) + { + sp->plane_sample_offset = (uint8_t)s; + sp->write_cursample = s; + sp->write_curstrile = s * tif->tif_dir.td_stripsperimage; + if ((sp->in_buffer_file_pos_log == 0) || + (sp->in_buffer_file_pos - sp->in_buffer_togo != + sp->sos_end[s].in_buffer_file_pos)) + { + sp->in_buffer_source = sp->sos_end[s].in_buffer_source; + sp->in_buffer_next_strile = sp->sos_end[s].in_buffer_next_strile; + sp->in_buffer_file_pos = sp->sos_end[s].in_buffer_file_pos; + sp->in_buffer_file_pos_log = 0; + sp->in_buffer_file_togo = sp->sos_end[s].in_buffer_file_togo; + sp->in_buffer_togo = 0; + sp->in_buffer_cur = 0; + } + if (OJPEGWriteHeaderInfo(tif) == 0) + return (0); + } + while (sp->write_curstrile < m) + { + if (sp->libjpeg_jpeg_query_style == 0) + { + if (OJPEGPreDecodeSkipRaw(tif) == 0) + return (0); + } + else + { + if (OJPEGPreDecodeSkipScanlines(tif) == 0) + return (0); + } + sp->write_curstrile++; + } + sp->decoder_ok = 1; + return (1); +} + +static int OJPEGPreDecodeSkipRaw(TIFF *tif) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint32_t m; + m = sp->lines_per_strile; + if (sp->subsampling_convert_state != 0) + { + if (sp->subsampling_convert_clines - sp->subsampling_convert_state >= m) + { + sp->subsampling_convert_state += m; + if (sp->subsampling_convert_state == sp->subsampling_convert_clines) + sp->subsampling_convert_state = 0; + return (1); + } + m -= sp->subsampling_convert_clines - sp->subsampling_convert_state; + sp->subsampling_convert_state = 0; + sp->error_in_raw_data_decoding = 0; + } + while (m >= sp->subsampling_convert_clines) + { + if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), + sp->subsampling_convert_ycbcrimage, + sp->subsampling_ver * 8) == 0) + return (0); + m -= sp->subsampling_convert_clines; + } + if (m > 0) + { + if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), + sp->subsampling_convert_ycbcrimage, + sp->subsampling_ver * 8) == 0) + return (0); + sp->subsampling_convert_state = m; + } + return (1); +} + +static int OJPEGPreDecodeSkipScanlines(TIFF *tif) +{ + static const char module[] = "OJPEGPreDecodeSkipScanlines"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint32_t m; + if (sp->skip_buffer == NULL) + { + sp->skip_buffer = _TIFFmallocExt(tif, sp->bytes_per_line); + if (sp->skip_buffer == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + } + for (m = 0; m < sp->lines_per_strile; m++) + { + if (jpeg_read_scanlines_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), + &sp->skip_buffer, 1) == 0) + return (0); + } + return (1); +} + +static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) +{ + static const char module[] = "OJPEGDecode"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + (void)s; + if (!sp->decoder_ok) + { + TIFFErrorExtR(tif, module, + "Cannot decode: decoder not correctly initialized"); + return 0; + } + if (sp->libjpeg_session_active == 0) + { + /* This should normally not happen, except that it does when */ + /* using TIFFReadScanline() which calls OJPEGPostDecode() for */ + /* each scanline, which assumes that a whole strile was read */ + /* and may thus incorrectly consider it has read the whole image, + * causing */ + /* OJPEGLibjpegSessionAbort() to be called prematurely. */ + /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ + TIFFErrorExtR(tif, module, + "Cannot decode: libjpeg_session_active == 0"); + return 0; + } + if (sp->error_in_raw_data_decoding) + { + return 0; + } + if (sp->libjpeg_jpeg_query_style == 0) + { + if (OJPEGDecodeRaw(tif, buf, cc) == 0) + return (0); + } + else + { + if (OJPEGDecodeScanlines(tif, buf, cc) == 0) + return (0); + } + return (1); +} + +static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc) +{ + static const char module[] = "OJPEGDecodeRaw"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t *m; + tmsize_t n; + uint8_t *oy; + uint8_t *ocb; + uint8_t *ocr; + uint8_t *p; + uint32_t q; + uint8_t *r; + uint8_t sx, sy; + if (cc % sp->bytes_per_line != 0) + { + TIFFErrorExtR(tif, module, "Fractional scanline not read"); + return (0); + } + assert(cc > 0); + m = buf; + n = cc; + do + { + if (sp->subsampling_convert_state == 0) + { + if (jpeg_read_raw_data_encap(sp, + &(sp->libjpeg_jpeg_decompress_struct), + sp->subsampling_convert_ycbcrimage, + sp->subsampling_ver * 8) == 0) + { + sp->error_in_raw_data_decoding = 1; + return (0); + } + } + oy = sp->subsampling_convert_ybuf + + sp->subsampling_convert_state * sp->subsampling_ver * + sp->subsampling_convert_ylinelen; + ocb = sp->subsampling_convert_cbbuf + + sp->subsampling_convert_state * sp->subsampling_convert_clinelen; + ocr = sp->subsampling_convert_crbuf + + sp->subsampling_convert_state * sp->subsampling_convert_clinelen; + p = m; + for (q = 0; q < sp->subsampling_convert_clinelenout; q++) + { + r = oy; + for (sy = 0; sy < sp->subsampling_ver; sy++) + { + for (sx = 0; sx < sp->subsampling_hor; sx++) + *p++ = *r++; + r += sp->subsampling_convert_ylinelen - sp->subsampling_hor; + } + oy += sp->subsampling_hor; + *p++ = *ocb++; + *p++ = *ocr++; + } + sp->subsampling_convert_state++; + if (sp->subsampling_convert_state == sp->subsampling_convert_clines) + sp->subsampling_convert_state = 0; + m += sp->bytes_per_line; + n -= sp->bytes_per_line; + } while (n > 0); + return (1); +} + +static int OJPEGDecodeScanlines(TIFF *tif, uint8_t *buf, tmsize_t cc) +{ + static const char module[] = "OJPEGDecodeScanlines"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t *m; + tmsize_t n; + if (cc % sp->bytes_per_line != 0) + { + TIFFErrorExtR(tif, module, "Fractional scanline not read"); + return (0); + } + assert(cc > 0); + m = buf; + n = cc; + do + { + if (jpeg_read_scanlines_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), + &m, 1) == 0) + return (0); + m += sp->bytes_per_line; + n -= sp->bytes_per_line; + } while (n > 0); + return (1); +} + +static void OJPEGPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + (void)buf; + (void)cc; + /* This function somehow incorrectly assumes that a whole strile was read, + */ + /* which is not true when TIFFReadScanline() is called, */ + /* and may thus incorrectly consider it has read the whole image, causing */ + /* OJPEGLibjpegSessionAbort() to be called prematurely. */ + /* So this logic should be fixed to take into account cc, or disable */ + /* the scan line reading interface. */ + /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ + sp->write_curstrile++; + if (sp->write_curstrile % tif->tif_dir.td_stripsperimage == 0) + { + assert(sp->libjpeg_session_active != 0); + OJPEGLibjpegSessionAbort(tif); + sp->writeheader_done = 0; + } +} + +static int OJPEGSetupEncode(TIFF *tif) +{ + static const char module[] = "OJPEGSetupEncode"; + TIFFErrorExtR( + tif, module, + "OJPEG encoding not supported; use new-style JPEG compression instead"); + return (0); +} + +static int OJPEGPreEncode(TIFF *tif, uint16_t s) +{ + static const char module[] = "OJPEGPreEncode"; + (void)s; + TIFFErrorExtR( + tif, module, + "OJPEG encoding not supported; use new-style JPEG compression instead"); + return (0); +} + +static int OJPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) +{ + static const char module[] = "OJPEGEncode"; + (void)buf; + (void)cc; + (void)s; + TIFFErrorExtR( + tif, module, + "OJPEG encoding not supported; use new-style JPEG compression instead"); + return (0); +} + +static int OJPEGPostEncode(TIFF *tif) +{ + static const char module[] = "OJPEGPostEncode"; + TIFFErrorExtR( + tif, module, + "OJPEG encoding not supported; use new-style JPEG compression instead"); + return (0); +} + +static void OJPEGCleanup(TIFF *tif) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp != 0) + { + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.printdir = sp->printdir; + if (sp->qtable[0] != 0) + _TIFFfreeExt(tif, sp->qtable[0]); + if (sp->qtable[1] != 0) + _TIFFfreeExt(tif, sp->qtable[1]); + if (sp->qtable[2] != 0) + _TIFFfreeExt(tif, sp->qtable[2]); + if (sp->qtable[3] != 0) + _TIFFfreeExt(tif, sp->qtable[3]); + if (sp->dctable[0] != 0) + _TIFFfreeExt(tif, sp->dctable[0]); + if (sp->dctable[1] != 0) + _TIFFfreeExt(tif, sp->dctable[1]); + if (sp->dctable[2] != 0) + _TIFFfreeExt(tif, sp->dctable[2]); + if (sp->dctable[3] != 0) + _TIFFfreeExt(tif, sp->dctable[3]); + if (sp->actable[0] != 0) + _TIFFfreeExt(tif, sp->actable[0]); + if (sp->actable[1] != 0) + _TIFFfreeExt(tif, sp->actable[1]); + if (sp->actable[2] != 0) + _TIFFfreeExt(tif, sp->actable[2]); + if (sp->actable[3] != 0) + _TIFFfreeExt(tif, sp->actable[3]); + if (sp->libjpeg_session_active != 0) + OJPEGLibjpegSessionAbort(tif); + if (sp->subsampling_convert_ycbcrbuf != 0) + _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrbuf); + if (sp->subsampling_convert_ycbcrimage != 0) + _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrimage); + if (sp->skip_buffer != 0) + _TIFFfreeExt(tif, sp->skip_buffer); + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; + _TIFFSetDefaultCompressionState(tif); + } +} + +static void OJPEGSubsamplingCorrect(TIFF *tif) +{ + static const char module[] = "OJPEGSubsamplingCorrect"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t mh; + uint8_t mv; + + assert(sp->subsamplingcorrect_done == 0); + if ((tif->tif_dir.td_samplesperpixel != 3) || + ((tif->tif_dir.td_photometric != PHOTOMETRIC_YCBCR) && + (tif->tif_dir.td_photometric != PHOTOMETRIC_ITULAB))) + { + if (sp->subsampling_tag != 0) + TIFFWarningExtR(tif, module, + "Subsampling tag not appropriate for this " + "Photometric and/or SamplesPerPixel"); + sp->subsampling_hor = 1; + sp->subsampling_ver = 1; + sp->subsampling_force_desubsampling_inside_decompression = 0; + } + else + { + sp->subsamplingcorrect_done = 1; + mh = sp->subsampling_hor; + mv = sp->subsampling_ver; + sp->subsamplingcorrect = 1; + OJPEGReadHeaderInfoSec(tif); + if (sp->subsampling_force_desubsampling_inside_decompression != 0) + { + sp->subsampling_hor = 1; + sp->subsampling_ver = 1; + } + sp->subsamplingcorrect = 0; + if (((sp->subsampling_hor != mh) || (sp->subsampling_ver != mv)) && + (sp->subsampling_force_desubsampling_inside_decompression == 0)) + { + if (sp->subsampling_tag == 0) + TIFFWarningExtR( + tif, module, + "Subsampling tag is not set, yet subsampling inside JPEG " + "data [%" PRIu8 ",%" PRIu8 + "] does not match default values [2,2]; assuming " + "subsampling inside JPEG data is correct", + sp->subsampling_hor, sp->subsampling_ver); + else + TIFFWarningExtR( + tif, module, + "Subsampling inside JPEG data [%" PRIu8 ",%" PRIu8 + "] does not match subsampling tag values [%" PRIu8 + ",%" PRIu8 + "]; assuming subsampling inside JPEG data is correct", + sp->subsampling_hor, sp->subsampling_ver, mh, mv); + } + if (sp->subsampling_force_desubsampling_inside_decompression != 0) + { + if (sp->subsampling_tag == 0) + TIFFWarningExtR( + tif, module, + "Subsampling tag is not set, yet subsampling inside JPEG " + "data does not match default values [2,2] (nor any other " + "values allowed in TIFF); assuming subsampling inside JPEG " + "data is correct and desubsampling inside JPEG " + "decompression"); + else + TIFFWarningExtR( + tif, module, + "Subsampling inside JPEG data does not match subsampling " + "tag values [%" PRIu8 ",%" PRIu8 + "] (nor any other values allowed in TIFF); assuming " + "subsampling inside JPEG data is correct and desubsampling " + "inside JPEG decompression", + mh, mv); + } + if (sp->subsampling_force_desubsampling_inside_decompression == 0) + { + if (sp->subsampling_hor < sp->subsampling_ver) + TIFFWarningExtR(tif, module, + "Subsampling values [%" PRIu8 ",%" PRIu8 + "] are not allowed in TIFF", + sp->subsampling_hor, sp->subsampling_ver); + } + } + sp->subsamplingcorrect_done = 1; +} + +static int OJPEGReadHeaderInfo(TIFF *tif) +{ + static const char module[] = "OJPEGReadHeaderInfo"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(sp->readheader_done == 0); + sp->image_width = tif->tif_dir.td_imagewidth; + sp->image_length = tif->tif_dir.td_imagelength; + if (isTiled(tif)) + { + sp->strile_width = tif->tif_dir.td_tilewidth; + sp->strile_length = tif->tif_dir.td_tilelength; + sp->strile_length_total = + ((sp->image_length + sp->strile_length - 1) / sp->strile_length) * + sp->strile_length; + } + else + { + sp->strile_width = sp->image_width; + sp->strile_length = tif->tif_dir.td_rowsperstrip; + if (sp->strile_length == (uint32_t)-1) + sp->strile_length = sp->image_length; + sp->strile_length_total = sp->image_length; + } + if (tif->tif_dir.td_samplesperpixel == 1) + { + sp->samples_per_pixel = 1; + sp->plane_sample_offset = 0; + sp->samples_per_pixel_per_plane = sp->samples_per_pixel; + sp->subsampling_hor = 1; + sp->subsampling_ver = 1; + } + else + { + if (tif->tif_dir.td_samplesperpixel != 3) + { + TIFFErrorExtR(tif, module, + "SamplesPerPixel %" PRIu8 + " not supported for this compression scheme", + sp->samples_per_pixel); + return (0); + } + sp->samples_per_pixel = 3; + sp->plane_sample_offset = 0; + if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) + sp->samples_per_pixel_per_plane = 3; + else + sp->samples_per_pixel_per_plane = 1; + } + if (sp->strile_length < sp->image_length) + { + if (((sp->subsampling_hor != 1) && (sp->subsampling_hor != 2) && + (sp->subsampling_hor != 4)) || + ((sp->subsampling_ver != 1) && (sp->subsampling_ver != 2) && + (sp->subsampling_ver != 4))) + { + TIFFErrorExtR(tif, module, "Invalid subsampling values"); + return (0); + } + if (sp->strile_length % (sp->subsampling_ver * 8) != 0) + { + TIFFErrorExtR(tif, module, + "Incompatible vertical subsampling and image " + "strip/tile length"); + return (0); + } + sp->restart_interval = + (uint16_t)(((sp->strile_width + sp->subsampling_hor * 8 - 1) / + (sp->subsampling_hor * 8)) * + (sp->strile_length / (sp->subsampling_ver * 8))); + } + if (OJPEGReadHeaderInfoSec(tif) == 0) + return (0); + sp->sos_end[0].log = 1; + sp->sos_end[0].in_buffer_source = sp->in_buffer_source; + sp->sos_end[0].in_buffer_next_strile = sp->in_buffer_next_strile; + sp->sos_end[0].in_buffer_file_pos = + sp->in_buffer_file_pos - sp->in_buffer_togo; + sp->sos_end[0].in_buffer_file_togo = + sp->in_buffer_file_togo + sp->in_buffer_togo; + sp->readheader_done = 1; + return (1); +} + +static int OJPEGReadSecondarySos(TIFF *tif, uint16_t s) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + assert(s > 0); + assert(s < 3); + assert(sp->sos_end[0].log != 0); + assert(sp->sos_end[s].log == 0); + sp->plane_sample_offset = (uint8_t)(s - 1); + while (sp->sos_end[sp->plane_sample_offset].log == 0) + sp->plane_sample_offset--; + sp->in_buffer_source = + sp->sos_end[sp->plane_sample_offset].in_buffer_source; + sp->in_buffer_next_strile = + sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile; + sp->in_buffer_file_pos = + sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos; + sp->in_buffer_file_pos_log = 0; + sp->in_buffer_file_togo = + sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo; + sp->in_buffer_togo = 0; + sp->in_buffer_cur = 0; + while (sp->plane_sample_offset < s) + { + do + { + if (OJPEGReadByte(sp, &m) == 0) + return (0); + if (m == 255) + { + do + { + if (OJPEGReadByte(sp, &m) == 0) + return (0); + if (m != 255) + break; + } while (1); + if (m == JPEG_MARKER_SOS) + break; + } + } while (1); + sp->plane_sample_offset++; + if (OJPEGReadHeaderInfoSecStreamSos(tif) == 0) + return (0); + sp->sos_end[sp->plane_sample_offset].log = 1; + sp->sos_end[sp->plane_sample_offset].in_buffer_source = + sp->in_buffer_source; + sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile = + sp->in_buffer_next_strile; + sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos = + sp->in_buffer_file_pos - sp->in_buffer_togo; + sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo = + sp->in_buffer_file_togo + sp->in_buffer_togo; + } + return (1); +} + +static int OJPEGWriteHeaderInfo(TIFF *tif) +{ + static const char module[] = "OJPEGWriteHeaderInfo"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t **m; + uint32_t n; + /* if a previous attempt failed, don't try again */ + if (sp->libjpeg_session_active != 0) + return 0; + sp->out_state = ososSoi; + sp->restart_index = 0; + jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr)); + sp->libjpeg_jpeg_error_mgr.output_message = + OJPEGLibjpegJpegErrorMgrOutputMessage; + sp->libjpeg_jpeg_error_mgr.error_exit = OJPEGLibjpegJpegErrorMgrErrorExit; + sp->libjpeg_jpeg_decompress_struct.err = &(sp->libjpeg_jpeg_error_mgr); + sp->libjpeg_jpeg_decompress_struct.client_data = (void *)tif; + if (jpeg_create_decompress_encap( + sp, &(sp->libjpeg_jpeg_decompress_struct)) == 0) + return (0); + sp->libjpeg_session_active = 1; + sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = 0; + sp->libjpeg_jpeg_source_mgr.init_source = + OJPEGLibjpegJpegSourceMgrInitSource; + sp->libjpeg_jpeg_source_mgr.fill_input_buffer = + OJPEGLibjpegJpegSourceMgrFillInputBuffer; + sp->libjpeg_jpeg_source_mgr.skip_input_data = + OJPEGLibjpegJpegSourceMgrSkipInputData; + sp->libjpeg_jpeg_source_mgr.resync_to_restart = + OJPEGLibjpegJpegSourceMgrResyncToRestart; + sp->libjpeg_jpeg_source_mgr.term_source = + OJPEGLibjpegJpegSourceMgrTermSource; + sp->libjpeg_jpeg_decompress_struct.src = &(sp->libjpeg_jpeg_source_mgr); + if (jpeg_read_header_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), 1) == + 0) + return (0); + if ((sp->subsampling_force_desubsampling_inside_decompression == 0) && + (sp->samples_per_pixel_per_plane > 1)) + { + sp->libjpeg_jpeg_decompress_struct.raw_data_out = 1; +#if JPEG_LIB_VERSION >= 70 + sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling = FALSE; +#endif + sp->libjpeg_jpeg_query_style = 0; + if (sp->subsampling_convert_log == 0) + { + assert(sp->subsampling_convert_ycbcrbuf == 0); + assert(sp->subsampling_convert_ycbcrimage == 0); + /* Check for division by zero. */ + if (sp->subsampling_hor == 0 || sp->subsampling_ver == 0) + return (0); + sp->subsampling_convert_ylinelen = + ((sp->strile_width + sp->subsampling_hor * 8 - 1) / + (sp->subsampling_hor * 8) * sp->subsampling_hor * 8); + sp->subsampling_convert_ylines = sp->subsampling_ver * 8; + sp->subsampling_convert_clinelen = + sp->subsampling_convert_ylinelen / sp->subsampling_hor; + sp->subsampling_convert_clines = 8; + sp->subsampling_convert_ybuflen = sp->subsampling_convert_ylinelen * + sp->subsampling_convert_ylines; + sp->subsampling_convert_cbuflen = sp->subsampling_convert_clinelen * + sp->subsampling_convert_clines; + sp->subsampling_convert_ycbcrbuflen = + sp->subsampling_convert_ybuflen + + 2 * sp->subsampling_convert_cbuflen; + /* The calloc is not normally necessary, except in some edge/broken + * cases */ + /* for example for a tiled image of height 1 with a tile height of 1 + * and subsampling_hor=subsampling_ver=2 */ + /* In that case, libjpeg will only fill the 8 first lines of the 16 + * lines */ + /* See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844 + */ + /* Even if this case is allowed (?), its handling is broken because + * OJPEGPreDecode() should also likely */ + /* reset subsampling_convert_state to 0 when changing tile. */ + sp->subsampling_convert_ycbcrbuf = + _TIFFcallocExt(tif, 1, sp->subsampling_convert_ycbcrbuflen); + if (sp->subsampling_convert_ycbcrbuf == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + sp->subsampling_convert_ybuf = sp->subsampling_convert_ycbcrbuf; + sp->subsampling_convert_cbbuf = + sp->subsampling_convert_ybuf + sp->subsampling_convert_ybuflen; + sp->subsampling_convert_crbuf = + sp->subsampling_convert_cbbuf + sp->subsampling_convert_cbuflen; + sp->subsampling_convert_ycbcrimagelen = + 3 + sp->subsampling_convert_ylines + + 2 * sp->subsampling_convert_clines; + sp->subsampling_convert_ycbcrimage = _TIFFmallocExt( + tif, sp->subsampling_convert_ycbcrimagelen * sizeof(uint8_t *)); + if (sp->subsampling_convert_ycbcrimage == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + m = sp->subsampling_convert_ycbcrimage; + *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3); + *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3 + + sp->subsampling_convert_ylines); + *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3 + + sp->subsampling_convert_ylines + + sp->subsampling_convert_clines); + for (n = 0; n < sp->subsampling_convert_ylines; n++) + *m++ = sp->subsampling_convert_ybuf + + n * sp->subsampling_convert_ylinelen; + for (n = 0; n < sp->subsampling_convert_clines; n++) + *m++ = sp->subsampling_convert_cbbuf + + n * sp->subsampling_convert_clinelen; + for (n = 0; n < sp->subsampling_convert_clines; n++) + *m++ = sp->subsampling_convert_crbuf + + n * sp->subsampling_convert_clinelen; + sp->subsampling_convert_clinelenout = + sp->strile_width / sp->subsampling_hor + + ((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0); + sp->subsampling_convert_state = 0; + sp->error_in_raw_data_decoding = 0; + sp->bytes_per_line = + sp->subsampling_convert_clinelenout * + (sp->subsampling_ver * sp->subsampling_hor + 2); + sp->lines_per_strile = + sp->strile_length / sp->subsampling_ver + + ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0); + sp->subsampling_convert_log = 1; + } + } + else + { + sp->libjpeg_jpeg_decompress_struct.jpeg_color_space = JCS_UNKNOWN; + sp->libjpeg_jpeg_decompress_struct.out_color_space = JCS_UNKNOWN; + sp->libjpeg_jpeg_query_style = 1; + sp->bytes_per_line = sp->samples_per_pixel_per_plane * sp->strile_width; + sp->lines_per_strile = sp->strile_length; + } + if (jpeg_start_decompress_encap(sp, + &(sp->libjpeg_jpeg_decompress_struct)) == 0) + return (0); + if (sp->libjpeg_jpeg_decompress_struct.image_width != sp->strile_width) + { + TIFFErrorExtR(tif, module, + "jpeg_start_decompress() returned image_width = %u, " + "expected %" PRIu32, + sp->libjpeg_jpeg_decompress_struct.image_width, + sp->strile_width); + return 0; + } + if (sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor != + sp->subsampling_hor || + sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor != + sp->subsampling_ver) + { + TIFFErrorExtR(tif, module, + "jpeg_start_decompress() returned max_h_samp_factor = %d " + "and max_v_samp_factor = %d, expected %" PRIu8 + " and %" PRIu8, + sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor, + sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor, + sp->subsampling_hor, sp->subsampling_ver); + return 0; + } + + sp->writeheader_done = 1; + return (1); +} + +static void OJPEGLibjpegSessionAbort(TIFF *tif) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(sp->libjpeg_session_active != 0); + jpeg_destroy((jpeg_common_struct *)(&(sp->libjpeg_jpeg_decompress_struct))); + sp->libjpeg_session_active = 0; +} + +static int OJPEGReadHeaderInfoSec(TIFF *tif) +{ + static const char module[] = "OJPEGReadHeaderInfoSec"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + uint16_t n; + uint8_t o; + if (sp->file_size == 0) + sp->file_size = TIFFGetFileSize(tif); + if (sp->jpeg_interchange_format != 0) + { + if (sp->jpeg_interchange_format >= sp->file_size) + { + sp->jpeg_interchange_format = 0; + sp->jpeg_interchange_format_length = 0; + } + else + { + if ((sp->jpeg_interchange_format_length == 0) || + (sp->jpeg_interchange_format > + UINT64_MAX - sp->jpeg_interchange_format_length) || + (sp->jpeg_interchange_format + + sp->jpeg_interchange_format_length > + sp->file_size)) + sp->jpeg_interchange_format_length = + sp->file_size - sp->jpeg_interchange_format; + } + } + sp->in_buffer_source = osibsNotSetYet; + sp->in_buffer_next_strile = 0; + sp->in_buffer_strile_count = tif->tif_dir.td_nstrips; + sp->in_buffer_file_togo = 0; + sp->in_buffer_togo = 0; + do + { + if (OJPEGReadBytePeek(sp, &m) == 0) + return (0); + if (m != 255) + break; + OJPEGReadByteAdvance(sp); + do + { + if (OJPEGReadByte(sp, &m) == 0) + return (0); + } while (m == 255); + switch (m) + { + case JPEG_MARKER_SOI: + /* this type of marker has no data, and should be skipped */ + break; + case JPEG_MARKER_COM: + case JPEG_MARKER_APP0: + case JPEG_MARKER_APP0 + 1: + case JPEG_MARKER_APP0 + 2: + case JPEG_MARKER_APP0 + 3: + case JPEG_MARKER_APP0 + 4: + case JPEG_MARKER_APP0 + 5: + case JPEG_MARKER_APP0 + 6: + case JPEG_MARKER_APP0 + 7: + case JPEG_MARKER_APP0 + 8: + case JPEG_MARKER_APP0 + 9: + case JPEG_MARKER_APP0 + 10: + case JPEG_MARKER_APP0 + 11: + case JPEG_MARKER_APP0 + 12: + case JPEG_MARKER_APP0 + 13: + case JPEG_MARKER_APP0 + 14: + case JPEG_MARKER_APP0 + 15: + /* this type of marker has data, but it has no use to us (and no + * place here) and should be skipped */ + if (OJPEGReadWord(sp, &n) == 0) + return (0); + if (n < 2) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt JPEG data"); + return (0); + } + if (n > 2) + OJPEGReadSkip(sp, n - 2); + break; + case JPEG_MARKER_DRI: + if (OJPEGReadHeaderInfoSecStreamDri(tif) == 0) + return (0); + break; + case JPEG_MARKER_DQT: + if (OJPEGReadHeaderInfoSecStreamDqt(tif) == 0) + return (0); + break; + case JPEG_MARKER_DHT: + if (OJPEGReadHeaderInfoSecStreamDht(tif) == 0) + return (0); + break; + case JPEG_MARKER_SOF0: + case JPEG_MARKER_SOF1: + case JPEG_MARKER_SOF3: + if (OJPEGReadHeaderInfoSecStreamSof(tif, m) == 0) + return (0); + if (sp->subsamplingcorrect != 0) + return (1); + break; + case JPEG_MARKER_SOS: + if (sp->subsamplingcorrect != 0) + return (1); + assert(sp->plane_sample_offset == 0); + if (OJPEGReadHeaderInfoSecStreamSos(tif) == 0) + return (0); + break; + default: + TIFFErrorExtR(tif, module, + "Unknown marker type %" PRIu8 " in JPEG data", m); + return (0); + } + } while (m != JPEG_MARKER_SOS); + if (sp->subsamplingcorrect) + return (1); + if (sp->sof_log == 0) + { + if (OJPEGReadHeaderInfoSecTablesQTable(tif) == 0) + return (0); + sp->sof_marker_id = JPEG_MARKER_SOF0; + for (o = 0; o < sp->samples_per_pixel; o++) + sp->sof_c[o] = o; + sp->sof_hv[0] = ((sp->subsampling_hor << 4) | sp->subsampling_ver); + for (o = 1; o < sp->samples_per_pixel; o++) + sp->sof_hv[o] = 17; + sp->sof_x = sp->strile_width; + sp->sof_y = sp->strile_length_total; + sp->sof_log = 1; + if (OJPEGReadHeaderInfoSecTablesDcTable(tif) == 0) + return (0); + if (OJPEGReadHeaderInfoSecTablesAcTable(tif) == 0) + return (0); + for (o = 1; o < sp->samples_per_pixel; o++) + sp->sos_cs[o] = o; + } + return (1); +} + +static int OJPEGReadHeaderInfoSecStreamDri(TIFF *tif) +{ + /* This could easily cause trouble in some cases... but no such cases have + occurred so far */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamDri"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m != 4) + { + TIFFErrorExtR(tif, module, "Corrupt DRI marker in JPEG data"); + return (0); + } + if (OJPEGReadWord(sp, &m) == 0) + return (0); + sp->restart_interval = m; + return (1); +} + +static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif) +{ + /* this is a table marker, and it is to be saved as a whole for exact + * pushing on the jpeg stream later on */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamDqt"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + uint32_t na; + uint8_t *nb; + uint8_t o; + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m <= 2) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data"); + return (0); + } + if (sp->subsamplingcorrect != 0) + OJPEGReadSkip(sp, m - 2); + else + { + m -= 2; + do + { + if (m < 65) + { + TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data"); + return (0); + } + na = sizeof(uint32_t) + 69; + nb = _TIFFmallocExt(tif, na); + if (nb == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)nb = na; + nb[sizeof(uint32_t)] = 255; + nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DQT; + nb[sizeof(uint32_t) + 2] = 0; + nb[sizeof(uint32_t) + 3] = 67; + if (OJPEGReadBlock(sp, 65, &nb[sizeof(uint32_t) + 4]) == 0) + { + _TIFFfreeExt(tif, nb); + return (0); + } + o = nb[sizeof(uint32_t) + 4] & 15; + if (3 < o) + { + TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data"); + _TIFFfreeExt(tif, nb); + return (0); + } + if (sp->qtable[o] != 0) + _TIFFfreeExt(tif, sp->qtable[o]); + sp->qtable[o] = nb; + m -= 65; + } while (m > 0); + } + return (1); +} + +static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif) +{ + /* this is a table marker, and it is to be saved as a whole for exact + * pushing on the jpeg stream later on */ + /* TODO: the following assumes there is only one table in this marker... but + * i'm not quite sure that assumption is guaranteed correct */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamDht"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + uint32_t na; + uint8_t *nb; + uint8_t o; + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m <= 2) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); + return (0); + } + if (sp->subsamplingcorrect != 0) + { + OJPEGReadSkip(sp, m - 2); + } + else + { + na = sizeof(uint32_t) + 2 + m; + nb = _TIFFmallocExt(tif, na); + if (nb == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)nb = na; + nb[sizeof(uint32_t)] = 255; + nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT; + nb[sizeof(uint32_t) + 2] = (m >> 8); + nb[sizeof(uint32_t) + 3] = (m & 255); + if (OJPEGReadBlock(sp, m - 2, &nb[sizeof(uint32_t) + 4]) == 0) + { + _TIFFfreeExt(tif, nb); + return (0); + } + o = nb[sizeof(uint32_t) + 4]; + if ((o & 240) == 0) + { + if (3 < o) + { + TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); + _TIFFfreeExt(tif, nb); + return (0); + } + if (sp->dctable[o] != 0) + _TIFFfreeExt(tif, sp->dctable[o]); + sp->dctable[o] = nb; + } + else + { + if ((o & 240) != 16) + { + TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); + _TIFFfreeExt(tif, nb); + return (0); + } + o &= 15; + if (3 < o) + { + TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); + _TIFFfreeExt(tif, nb); + return (0); + } + if (sp->actable[o] != 0) + _TIFFfreeExt(tif, sp->actable[o]); + sp->actable[o] = nb; + } + } + return (1); +} + +static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id) +{ + /* this marker needs to be checked, and part of its data needs to be saved + * for regeneration later on */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamSof"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + uint16_t n; + uint8_t o; + uint16_t p; + uint16_t q; + if (sp->sof_log != 0) + { + TIFFErrorExtR(tif, module, "Corrupt JPEG data"); + return (0); + } + if (sp->subsamplingcorrect == 0) + sp->sof_marker_id = marker_id; + /* Lf: data length */ + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m < 11) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); + return (0); + } + m -= 8; + if (m % 3 != 0) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); + return (0); + } + n = m / 3; + if (sp->subsamplingcorrect == 0) + { + if (n != sp->samples_per_pixel) + { + TIFFErrorExtR( + tif, module, + "JPEG compressed data indicates unexpected number of samples"); + return (0); + } + } + /* P: Sample precision */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (o != 8) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates unexpected number of " + "bits per sample"); + return (0); + } + /* Y: Number of lines, X: Number of samples per line */ + if (sp->subsamplingcorrect) + OJPEGReadSkip(sp, 4); + else + { + /* Y: Number of lines */ + if (OJPEGReadWord(sp, &p) == 0) + return (0); + if (((uint32_t)p < sp->image_length) && + ((uint32_t)p < sp->strile_length_total)) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates unexpected height"); + return (0); + } + sp->sof_y = p; + /* X: Number of samples per line */ + if (OJPEGReadWord(sp, &p) == 0) + return (0); + if (((uint32_t)p < sp->image_width) && ((uint32_t)p < sp->strile_width)) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates unexpected width"); + return (0); + } + if ((uint32_t)p > sp->strile_width) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data image width exceeds expected " + "image width"); + return (0); + } + sp->sof_x = p; + } + /* Nf: Number of image components in frame */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (o != n) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); + return (0); + } + /* per component stuff */ + /* TODO: double-check that flow implies that n cannot be as big as to make + * us overflow sof_c, sof_hv and sof_tq arrays */ + for (q = 0; q < n; q++) + { + /* C: Component identifier */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (sp->subsamplingcorrect == 0) + sp->sof_c[q] = o; + /* H: Horizontal sampling factor, and V: Vertical sampling factor */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (sp->subsamplingcorrect != 0) + { + if (q == 0) + { + sp->subsampling_hor = (o >> 4); + sp->subsampling_ver = (o & 15); + if (((sp->subsampling_hor != 1) && (sp->subsampling_hor != 2) && + (sp->subsampling_hor != 4)) || + ((sp->subsampling_ver != 1) && (sp->subsampling_ver != 2) && + (sp->subsampling_ver != 4))) + sp->subsampling_force_desubsampling_inside_decompression = + 1; + } + else + { + if (o != 17) + sp->subsampling_force_desubsampling_inside_decompression = + 1; + } + } + else + { + sp->sof_hv[q] = o; + if (sp->subsampling_force_desubsampling_inside_decompression == 0) + { + if (q == 0) + { + if (o != ((sp->subsampling_hor << 4) | sp->subsampling_ver)) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates " + "unexpected subsampling values"); + return (0); + } + } + else + { + if (o != 17) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates " + "unexpected subsampling values"); + return (0); + } + } + } + } + /* Tq: Quantization table destination selector */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (sp->subsamplingcorrect == 0) + sp->sof_tq[q] = o; + } + if (sp->subsamplingcorrect == 0) + sp->sof_log = 1; + return (1); +} + +static int OJPEGReadHeaderInfoSecStreamSos(TIFF *tif) +{ + /* this marker needs to be checked, and part of its data needs to be saved + * for regeneration later on */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamSos"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + uint8_t n; + uint8_t o; + assert(sp->subsamplingcorrect == 0); + if (sp->sof_log == 0) + { + TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data"); + return (0); + } + /* Ls */ + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m != 6 + sp->samples_per_pixel_per_plane * 2) + { + TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data"); + return (0); + } + /* Ns */ + if (OJPEGReadByte(sp, &n) == 0) + return (0); + if (n != sp->samples_per_pixel_per_plane) + { + TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data"); + return (0); + } + /* Cs, Td, and Ta */ + for (o = 0; o < sp->samples_per_pixel_per_plane; o++) + { + /* Cs */ + if (OJPEGReadByte(sp, &n) == 0) + return (0); + sp->sos_cs[sp->plane_sample_offset + o] = n; + /* Td and Ta */ + if (OJPEGReadByte(sp, &n) == 0) + return (0); + sp->sos_tda[sp->plane_sample_offset + o] = n; + } + /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as + * per LibJpeg source */ + OJPEGReadSkip(sp, 3); + return (1); +} + +static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif) +{ + static const char module[] = "OJPEGReadHeaderInfoSecTablesQTable"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + uint8_t n; + uint32_t oa; + uint8_t *ob; + uint32_t p; + if (sp->qtable_offset[0] == 0) + { + TIFFErrorExtR(tif, module, "Missing JPEG tables"); + return (0); + } + sp->in_buffer_file_pos_log = 0; + for (m = 0; m < sp->samples_per_pixel; m++) + { + if ((sp->qtable_offset[m] != 0) && + ((m == 0) || (sp->qtable_offset[m] != sp->qtable_offset[m - 1]))) + { + for (n = 0; n < m - 1; n++) + { + if (sp->qtable_offset[m] == sp->qtable_offset[n]) + { + TIFFErrorExtR(tif, module, "Corrupt JpegQTables tag value"); + return (0); + } + } + oa = sizeof(uint32_t) + 69; + ob = _TIFFmallocExt(tif, oa); + if (ob == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)ob = oa; + ob[sizeof(uint32_t)] = 255; + ob[sizeof(uint32_t) + 1] = JPEG_MARKER_DQT; + ob[sizeof(uint32_t) + 2] = 0; + ob[sizeof(uint32_t) + 3] = 67; + ob[sizeof(uint32_t) + 4] = m; + TIFFSeekFile(tif, sp->qtable_offset[m], SEEK_SET); + p = (uint32_t)TIFFReadFile(tif, &ob[sizeof(uint32_t) + 5], 64); + if (p != 64) + { + _TIFFfreeExt(tif, ob); + return (0); + } + if (sp->qtable[m] != 0) + _TIFFfreeExt(tif, sp->qtable[m]); + sp->qtable[m] = ob; + sp->sof_tq[m] = m; + } + else + sp->sof_tq[m] = sp->sof_tq[m - 1]; + } + return (1); +} + +static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif) +{ + static const char module[] = "OJPEGReadHeaderInfoSecTablesDcTable"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + uint8_t n; + uint8_t o[16]; + uint32_t p; + uint32_t q; + uint32_t ra; + uint8_t *rb; + if (sp->dctable_offset[0] == 0) + { + TIFFErrorExtR(tif, module, "Missing JPEG tables"); + return (0); + } + sp->in_buffer_file_pos_log = 0; + for (m = 0; m < sp->samples_per_pixel; m++) + { + if ((sp->dctable_offset[m] != 0) && + ((m == 0) || (sp->dctable_offset[m] != sp->dctable_offset[m - 1]))) + { + for (n = 0; n < m - 1; n++) + { + if (sp->dctable_offset[m] == sp->dctable_offset[n]) + { + TIFFErrorExtR(tif, module, + "Corrupt JpegDcTables tag value"); + return (0); + } + } + TIFFSeekFile(tif, sp->dctable_offset[m], SEEK_SET); + p = (uint32_t)TIFFReadFile(tif, o, 16); + if (p != 16) + return (0); + q = 0; + for (n = 0; n < 16; n++) + q += o[n]; + ra = sizeof(uint32_t) + 21 + q; + rb = _TIFFmallocExt(tif, ra); + if (rb == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)rb = ra; + rb[sizeof(uint32_t)] = 255; + rb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT; + rb[sizeof(uint32_t) + 2] = (uint8_t)((19 + q) >> 8); + rb[sizeof(uint32_t) + 3] = ((19 + q) & 255); + rb[sizeof(uint32_t) + 4] = m; + for (n = 0; n < 16; n++) + rb[sizeof(uint32_t) + 5 + n] = o[n]; + p = (uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q); + if (p != q) + { + _TIFFfreeExt(tif, rb); + return (0); + } + if (sp->dctable[m] != 0) + _TIFFfreeExt(tif, sp->dctable[m]); + sp->dctable[m] = rb; + sp->sos_tda[m] = (m << 4); + } + else + sp->sos_tda[m] = sp->sos_tda[m - 1]; + } + return (1); +} + +static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif) +{ + static const char module[] = "OJPEGReadHeaderInfoSecTablesAcTable"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + uint8_t n; + uint8_t o[16]; + uint32_t p; + uint32_t q; + uint32_t ra; + uint8_t *rb; + if (sp->actable_offset[0] == 0) + { + TIFFErrorExtR(tif, module, "Missing JPEG tables"); + return (0); + } + sp->in_buffer_file_pos_log = 0; + for (m = 0; m < sp->samples_per_pixel; m++) + { + if ((sp->actable_offset[m] != 0) && + ((m == 0) || (sp->actable_offset[m] != sp->actable_offset[m - 1]))) + { + for (n = 0; n < m - 1; n++) + { + if (sp->actable_offset[m] == sp->actable_offset[n]) + { + TIFFErrorExtR(tif, module, + "Corrupt JpegAcTables tag value"); + return (0); + } + } + TIFFSeekFile(tif, sp->actable_offset[m], SEEK_SET); + p = (uint32_t)TIFFReadFile(tif, o, 16); + if (p != 16) + return (0); + q = 0; + for (n = 0; n < 16; n++) + q += o[n]; + ra = sizeof(uint32_t) + 21 + q; + rb = _TIFFmallocExt(tif, ra); + if (rb == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)rb = ra; + rb[sizeof(uint32_t)] = 255; + rb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT; + rb[sizeof(uint32_t) + 2] = (uint8_t)((19 + q) >> 8); + rb[sizeof(uint32_t) + 3] = ((19 + q) & 255); + rb[sizeof(uint32_t) + 4] = (16 | m); + for (n = 0; n < 16; n++) + rb[sizeof(uint32_t) + 5 + n] = o[n]; + p = (uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q); + if (p != q) + { + _TIFFfreeExt(tif, rb); + return (0); + } + if (sp->actable[m] != 0) + _TIFFfreeExt(tif, sp->actable[m]); + sp->actable[m] = rb; + sp->sos_tda[m] = (sp->sos_tda[m] | m); + } + else + sp->sos_tda[m] = (sp->sos_tda[m] | (sp->sos_tda[m - 1] & 15)); + } + return (1); +} + +static int OJPEGReadBufferFill(OJPEGState *sp) +{ + uint16_t m; + tmsize_t n; + /* TODO: double-check: when subsamplingcorrect is set, no call to + * TIFFErrorExt or TIFFWarningExt should be made in any other case, seek or + * read errors should be passed through */ + do + { + if (sp->in_buffer_file_togo != 0) + { + if (sp->in_buffer_file_pos_log == 0) + { + TIFFSeekFile(sp->tif, sp->in_buffer_file_pos, SEEK_SET); + sp->in_buffer_file_pos_log = 1; + } + m = OJPEG_BUFFER; + if ((uint64_t)m > sp->in_buffer_file_togo) + m = (uint16_t)sp->in_buffer_file_togo; + n = TIFFReadFile(sp->tif, sp->in_buffer, (tmsize_t)m); + if (n == 0) + return (0); + assert(n > 0); + assert(n <= OJPEG_BUFFER); + assert(n < 65536); + assert((uint64_t)n <= sp->in_buffer_file_togo); + m = (uint16_t)n; + sp->in_buffer_togo = m; + sp->in_buffer_cur = sp->in_buffer; + sp->in_buffer_file_togo -= m; + sp->in_buffer_file_pos += m; + break; + } + sp->in_buffer_file_pos_log = 0; + switch (sp->in_buffer_source) + { + case osibsNotSetYet: + if (sp->jpeg_interchange_format != 0) + { + sp->in_buffer_file_pos = sp->jpeg_interchange_format; + sp->in_buffer_file_togo = + sp->jpeg_interchange_format_length; + } + sp->in_buffer_source = osibsJpegInterchangeFormat; + break; + case osibsJpegInterchangeFormat: + sp->in_buffer_source = osibsStrile; + break; + case osibsStrile: + if (sp->in_buffer_next_strile == sp->in_buffer_strile_count) + sp->in_buffer_source = osibsEof; + else + { + int err = 0; + sp->in_buffer_file_pos = TIFFGetStrileOffsetWithErr( + sp->tif, sp->in_buffer_next_strile, &err); + if (err) + return 0; + if (sp->in_buffer_file_pos != 0) + { + uint64_t bytecount = TIFFGetStrileByteCountWithErr( + sp->tif, sp->in_buffer_next_strile, &err); + if (err) + return 0; + if (sp->in_buffer_file_pos >= sp->file_size) + sp->in_buffer_file_pos = 0; + else if (bytecount == 0) + sp->in_buffer_file_togo = + sp->file_size - sp->in_buffer_file_pos; + else { - _TIFFfree(ob); - return(0); + sp->in_buffer_file_togo = bytecount; + if (sp->in_buffer_file_togo == 0) + sp->in_buffer_file_pos = 0; + else if (sp->in_buffer_file_pos > + UINT64_MAX - sp->in_buffer_file_togo || + sp->in_buffer_file_pos + + sp->in_buffer_file_togo > + sp->file_size) + sp->in_buffer_file_togo = + sp->file_size - sp->in_buffer_file_pos; } - if (sp->qtable[m]!=0) - _TIFFfree(sp->qtable[m]); - sp->qtable[m]=ob; - sp->sof_tq[m]=m; - } - else - sp->sof_tq[m]=sp->sof_tq[m-1]; - } - return(1); + } + sp->in_buffer_next_strile++; + } + break; + default: + return (0); + } + } while (1); + return (1); } -static int -OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif) +static int OJPEGReadByte(OJPEGState *sp, uint8_t *byte) { - static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8 m; - uint8 n; - uint8 o[16]; - uint32 p; - uint32 q; - uint32 ra; - uint8* rb; - if (sp->dctable_offset[0]==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables"); - return(0); - } - sp->in_buffer_file_pos_log=0; - for (m=0; msamples_per_pixel; m++) - { - if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1]))) - { - for (n=0; ndctable_offset[m]==sp->dctable_offset[n]) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value"); - return(0); - } - } - TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET); - p=(uint32)TIFFReadFile(tif,o,16); - if (p!=16) - return(0); - q=0; - for (n=0; n<16; n++) - q+=o[n]; - ra=sizeof(uint32)+21+q; - rb=_TIFFmalloc(ra); - if (rb==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - *(uint32*)rb=ra; - rb[sizeof(uint32)]=255; - rb[sizeof(uint32)+1]=JPEG_MARKER_DHT; - rb[sizeof(uint32)+2]=(uint8)((19+q)>>8); - rb[sizeof(uint32)+3]=((19+q)&255); - rb[sizeof(uint32)+4]=m; - for (n=0; n<16; n++) - rb[sizeof(uint32)+5+n]=o[n]; - p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); - if (p!=q) - { - _TIFFfree(rb); - return(0); - } - if (sp->dctable[m]!=0) - _TIFFfree(sp->dctable[m]); - sp->dctable[m]=rb; - sp->sos_tda[m]=(m<<4); - } - else - sp->sos_tda[m]=sp->sos_tda[m-1]; - } - return(1); + if (sp->in_buffer_togo == 0) + { + if (OJPEGReadBufferFill(sp) == 0) + return (0); + assert(sp->in_buffer_togo > 0); + } + *byte = *(sp->in_buffer_cur); + sp->in_buffer_cur++; + sp->in_buffer_togo--; + return (1); } -static int -OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif) +static int OJPEGReadBytePeek(OJPEGState *sp, uint8_t *byte) { - static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8 m; - uint8 n; - uint8 o[16]; - uint32 p; - uint32 q; - uint32 ra; - uint8* rb; - if (sp->actable_offset[0]==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables"); - return(0); - } - sp->in_buffer_file_pos_log=0; - for (m=0; msamples_per_pixel; m++) - { - if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1]))) - { - for (n=0; nactable_offset[m]==sp->actable_offset[n]) - { - TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value"); - return(0); - } - } - TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET); - p=(uint32)TIFFReadFile(tif,o,16); - if (p!=16) - return(0); - q=0; - for (n=0; n<16; n++) - q+=o[n]; - ra=sizeof(uint32)+21+q; - rb=_TIFFmalloc(ra); - if (rb==0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); - return(0); - } - *(uint32*)rb=ra; - rb[sizeof(uint32)]=255; - rb[sizeof(uint32)+1]=JPEG_MARKER_DHT; - rb[sizeof(uint32)+2]=(uint8)((19+q)>>8); - rb[sizeof(uint32)+3]=((19+q)&255); - rb[sizeof(uint32)+4]=(16|m); - for (n=0; n<16; n++) - rb[sizeof(uint32)+5+n]=o[n]; - p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); - if (p!=q) - { - _TIFFfree(rb); - return(0); - } - if (sp->actable[m]!=0) - _TIFFfree(sp->actable[m]); - sp->actable[m]=rb; - sp->sos_tda[m]=(sp->sos_tda[m]|m); - } - else - sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15)); - } - return(1); + if (sp->in_buffer_togo == 0) + { + if (OJPEGReadBufferFill(sp) == 0) + return (0); + assert(sp->in_buffer_togo > 0); + } + *byte = *(sp->in_buffer_cur); + return (1); } -static int -OJPEGReadBufferFill(OJPEGState* sp) +static void OJPEGReadByteAdvance(OJPEGState *sp) { - uint16 m; - tmsize_t n; - /* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made - * in any other case, seek or read errors should be passed through */ - do - { - if (sp->in_buffer_file_togo!=0) - { - if (sp->in_buffer_file_pos_log==0) - { - TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET); - sp->in_buffer_file_pos_log=1; - } - m=OJPEG_BUFFER; - if ((uint64)m>sp->in_buffer_file_togo) - m=(uint16)sp->in_buffer_file_togo; - n=TIFFReadFile(sp->tif,sp->in_buffer,(tmsize_t)m); - if (n==0) - return(0); - assert(n>0); - assert(n<=OJPEG_BUFFER); - assert(n<65536); - assert((uint64)n<=sp->in_buffer_file_togo); - m=(uint16)n; - sp->in_buffer_togo=m; - sp->in_buffer_cur=sp->in_buffer; - sp->in_buffer_file_togo-=m; - sp->in_buffer_file_pos+=m; - break; - } - sp->in_buffer_file_pos_log=0; - switch(sp->in_buffer_source) - { - case osibsNotSetYet: - if (sp->jpeg_interchange_format!=0) - { - sp->in_buffer_file_pos=sp->jpeg_interchange_format; - sp->in_buffer_file_togo=sp->jpeg_interchange_format_length; - } - sp->in_buffer_source=osibsJpegInterchangeFormat; - break; - case osibsJpegInterchangeFormat: - sp->in_buffer_source=osibsStrile; - break; - case osibsStrile: - if (sp->in_buffer_next_strile==sp->in_buffer_strile_count) - sp->in_buffer_source=osibsEof; - else - { - int err = 0; - sp->in_buffer_file_pos=TIFFGetStrileOffsetWithErr(sp->tif, sp->in_buffer_next_strile, &err); - if( err ) - return 0; - if (sp->in_buffer_file_pos!=0) - { - uint64 bytecount = TIFFGetStrileByteCountWithErr(sp->tif, sp->in_buffer_next_strile, &err); - if( err ) - return 0; - if (sp->in_buffer_file_pos>=sp->file_size) - sp->in_buffer_file_pos=0; - else if (bytecount==0) - sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; - else - { - sp->in_buffer_file_togo=bytecount; - if (sp->in_buffer_file_togo==0) - sp->in_buffer_file_pos=0; - else if (sp->in_buffer_file_pos > TIFF_UINT64_MAX - sp->in_buffer_file_togo || - sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size) - sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; - } - } - sp->in_buffer_next_strile++; - } - break; - default: - return(0); - } - } while (1); - return(1); + assert(sp->in_buffer_togo > 0); + sp->in_buffer_cur++; + sp->in_buffer_togo--; } -static int -OJPEGReadByte(OJPEGState* sp, uint8* byte) +static int OJPEGReadWord(OJPEGState *sp, uint16_t *word) { - if (sp->in_buffer_togo==0) - { - if (OJPEGReadBufferFill(sp)==0) - return(0); - assert(sp->in_buffer_togo>0); - } - *byte=*(sp->in_buffer_cur); - sp->in_buffer_cur++; - sp->in_buffer_togo--; - return(1); + uint8_t m; + if (OJPEGReadByte(sp, &m) == 0) + return (0); + *word = (m << 8); + if (OJPEGReadByte(sp, &m) == 0) + return (0); + *word |= m; + return (1); } -static int -OJPEGReadBytePeek(OJPEGState* sp, uint8* byte) +static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem) { - if (sp->in_buffer_togo==0) - { - if (OJPEGReadBufferFill(sp)==0) - return(0); - assert(sp->in_buffer_togo>0); - } - *byte=*(sp->in_buffer_cur); - return(1); + uint16_t mlen; + uint8_t *mmem; + uint16_t n; + assert(len > 0); + mlen = len; + mmem = mem; + do + { + if (sp->in_buffer_togo == 0) + { + if (OJPEGReadBufferFill(sp) == 0) + return (0); + assert(sp->in_buffer_togo > 0); + } + n = mlen; + if (n > sp->in_buffer_togo) + n = sp->in_buffer_togo; + _TIFFmemcpy(mmem, sp->in_buffer_cur, n); + sp->in_buffer_cur += n; + sp->in_buffer_togo -= n; + mlen -= n; + mmem += n; + } while (mlen > 0); + return (1); } -static void -OJPEGReadByteAdvance(OJPEGState* sp) +static void OJPEGReadSkip(OJPEGState *sp, uint16_t len) { - assert(sp->in_buffer_togo>0); - sp->in_buffer_cur++; - sp->in_buffer_togo--; + uint16_t m; + uint16_t n; + m = len; + n = m; + if (n > sp->in_buffer_togo) + n = sp->in_buffer_togo; + sp->in_buffer_cur += n; + sp->in_buffer_togo -= n; + m -= n; + if (m > 0) + { + assert(sp->in_buffer_togo == 0); + n = m; + if ((uint64_t)n > sp->in_buffer_file_togo) + n = (uint16_t)sp->in_buffer_file_togo; + sp->in_buffer_file_pos += n; + sp->in_buffer_file_togo -= n; + sp->in_buffer_file_pos_log = 0; + /* we don't skip past jpeginterchangeformat/strile block... + * if that is asked from us, we're dealing with totally bazurk + * data anyway, and we've not seen this happening on any + * testfile, so we might as well likely cause some other + * meaningless error to be passed at some later time + */ + } } -static int -OJPEGReadWord(OJPEGState* sp, uint16* word) +static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len) { - uint8 m; - if (OJPEGReadByte(sp,&m)==0) - return(0); - *word=(m<<8); - if (OJPEGReadByte(sp,&m)==0) - return(0); - *word|=m; - return(1); + OJPEGState *sp = (OJPEGState *)tif->tif_data; + *len = 0; + do + { + assert(sp->out_state <= ososEoi); + switch (sp->out_state) + { + case ososSoi: + OJPEGWriteStreamSoi(tif, mem, len); + break; + case ososQTable0: + OJPEGWriteStreamQTable(tif, 0, mem, len); + break; + case ososQTable1: + OJPEGWriteStreamQTable(tif, 1, mem, len); + break; + case ososQTable2: + OJPEGWriteStreamQTable(tif, 2, mem, len); + break; + case ososQTable3: + OJPEGWriteStreamQTable(tif, 3, mem, len); + break; + case ososDcTable0: + OJPEGWriteStreamDcTable(tif, 0, mem, len); + break; + case ososDcTable1: + OJPEGWriteStreamDcTable(tif, 1, mem, len); + break; + case ososDcTable2: + OJPEGWriteStreamDcTable(tif, 2, mem, len); + break; + case ososDcTable3: + OJPEGWriteStreamDcTable(tif, 3, mem, len); + break; + case ososAcTable0: + OJPEGWriteStreamAcTable(tif, 0, mem, len); + break; + case ososAcTable1: + OJPEGWriteStreamAcTable(tif, 1, mem, len); + break; + case ososAcTable2: + OJPEGWriteStreamAcTable(tif, 2, mem, len); + break; + case ososAcTable3: + OJPEGWriteStreamAcTable(tif, 3, mem, len); + break; + case ososDri: + OJPEGWriteStreamDri(tif, mem, len); + break; + case ososSof: + OJPEGWriteStreamSof(tif, mem, len); + break; + case ososSos: + OJPEGWriteStreamSos(tif, mem, len); + break; + case ososCompressed: + if (OJPEGWriteStreamCompressed(tif, mem, len) == 0) + return (0); + break; + case ososRst: + OJPEGWriteStreamRst(tif, mem, len); + break; + case ososEoi: + OJPEGWriteStreamEoi(tif, mem, len); + break; + } + } while (*len == 0); + return (1); } -static int -OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem) +static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len) { - uint16 mlen; - uint8* mmem; - uint16 n; - assert(len>0); - mlen=len; - mmem=mem; - do - { - if (sp->in_buffer_togo==0) - { - if (OJPEGReadBufferFill(sp)==0) - return(0); - assert(sp->in_buffer_togo>0); - } - n=mlen; - if (n>sp->in_buffer_togo) - n=sp->in_buffer_togo; - _TIFFmemcpy(mmem,sp->in_buffer_cur,n); - sp->in_buffer_cur+=n; - sp->in_buffer_togo-=n; - mlen-=n; - mmem+=n; - } while(mlen>0); - return(1); + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(OJPEG_BUFFER >= 2); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_SOI; + *len = 2; + *mem = (void *)sp->out_buffer; + sp->out_state++; } -static void -OJPEGReadSkip(OJPEGState* sp, uint16 len) +static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len) { - uint16 m; - uint16 n; - m=len; - n=m; - if (n>sp->in_buffer_togo) - n=sp->in_buffer_togo; - sp->in_buffer_cur+=n; - sp->in_buffer_togo-=n; - m-=n; - if (m>0) - { - assert(sp->in_buffer_togo==0); - n=m; - if ((uint64)n>sp->in_buffer_file_togo) - n=(uint16)sp->in_buffer_file_togo; - sp->in_buffer_file_pos+=n; - sp->in_buffer_file_togo-=n; - sp->in_buffer_file_pos_log=0; - /* we don't skip past jpeginterchangeformat/strile block... - * if that is asked from us, we're dealing with totally bazurk - * data anyway, and we've not seen this happening on any - * testfile, so we might as well likely cause some other - * meaningless error to be passed at some later time - */ - } + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp->qtable[table_index] != 0) + { + *mem = (void *)(sp->qtable[table_index] + sizeof(uint32_t)); + *len = *((uint32_t *)sp->qtable[table_index]) - sizeof(uint32_t); + } + sp->out_state++; } -static int -OJPEGWriteStream(TIFF* tif, void** mem, uint32* len) +static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - *len=0; - do - { - assert(sp->out_state<=ososEoi); - switch(sp->out_state) - { - case ososSoi: - OJPEGWriteStreamSoi(tif,mem,len); - break; - case ososQTable0: - OJPEGWriteStreamQTable(tif,0,mem,len); - break; - case ososQTable1: - OJPEGWriteStreamQTable(tif,1,mem,len); - break; - case ososQTable2: - OJPEGWriteStreamQTable(tif,2,mem,len); - break; - case ososQTable3: - OJPEGWriteStreamQTable(tif,3,mem,len); - break; - case ososDcTable0: - OJPEGWriteStreamDcTable(tif,0,mem,len); - break; - case ososDcTable1: - OJPEGWriteStreamDcTable(tif,1,mem,len); - break; - case ososDcTable2: - OJPEGWriteStreamDcTable(tif,2,mem,len); - break; - case ososDcTable3: - OJPEGWriteStreamDcTable(tif,3,mem,len); - break; - case ososAcTable0: - OJPEGWriteStreamAcTable(tif,0,mem,len); - break; - case ososAcTable1: - OJPEGWriteStreamAcTable(tif,1,mem,len); - break; - case ososAcTable2: - OJPEGWriteStreamAcTable(tif,2,mem,len); - break; - case ososAcTable3: - OJPEGWriteStreamAcTable(tif,3,mem,len); - break; - case ososDri: - OJPEGWriteStreamDri(tif,mem,len); - break; - case ososSof: - OJPEGWriteStreamSof(tif,mem,len); - break; - case ososSos: - OJPEGWriteStreamSos(tif,mem,len); - break; - case ososCompressed: - if (OJPEGWriteStreamCompressed(tif,mem,len)==0) - return(0); - break; - case ososRst: - OJPEGWriteStreamRst(tif,mem,len); - break; - case ososEoi: - OJPEGWriteStreamEoi(tif,mem,len); - break; - } - } while (*len==0); - return(1); + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp->dctable[table_index] != 0) + { + *mem = (void *)(sp->dctable[table_index] + sizeof(uint32_t)); + *len = *((uint32_t *)sp->dctable[table_index]) - sizeof(uint32_t); + } + sp->out_state++; } -static void -OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len) +static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(OJPEG_BUFFER>=2); - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_SOI; - *len=2; - *mem=(void*)sp->out_buffer; - sp->out_state++; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp->actable[table_index] != 0) + { + *mem = (void *)(sp->actable[table_index] + sizeof(uint32_t)); + *len = *((uint32_t *)sp->actable[table_index]) - sizeof(uint32_t); + } + sp->out_state++; } -static void -OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len) +static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp->qtable[table_index]!=0) - { - *mem=(void*)(sp->qtable[table_index]+sizeof(uint32)); - *len=*((uint32*)sp->qtable[table_index])-sizeof(uint32); - } - sp->out_state++; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(OJPEG_BUFFER >= 6); + if (sp->restart_interval != 0) + { + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_DRI; + sp->out_buffer[2] = 0; + sp->out_buffer[3] = 4; + sp->out_buffer[4] = (sp->restart_interval >> 8); + sp->out_buffer[5] = (sp->restart_interval & 255); + *len = 6; + *mem = (void *)sp->out_buffer; + } + sp->out_state++; } -static void -OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len) +static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp->dctable[table_index]!=0) - { - *mem=(void*)(sp->dctable[table_index]+sizeof(uint32)); - *len=*((uint32*)sp->dctable[table_index])-sizeof(uint32); - } - sp->out_state++; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + assert(OJPEG_BUFFER >= 2 + 8 + sp->samples_per_pixel_per_plane * 3); + assert(255 >= 8 + sp->samples_per_pixel_per_plane * 3); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = sp->sof_marker_id; + /* Lf */ + sp->out_buffer[2] = 0; + sp->out_buffer[3] = 8 + sp->samples_per_pixel_per_plane * 3; + /* P */ + sp->out_buffer[4] = 8; + /* Y */ + sp->out_buffer[5] = (uint8_t)(sp->sof_y >> 8); + sp->out_buffer[6] = (sp->sof_y & 255); + /* X */ + sp->out_buffer[7] = (uint8_t)(sp->sof_x >> 8); + sp->out_buffer[8] = (sp->sof_x & 255); + /* Nf */ + sp->out_buffer[9] = sp->samples_per_pixel_per_plane; + for (m = 0; m < sp->samples_per_pixel_per_plane; m++) + { + /* C */ + sp->out_buffer[10 + m * 3] = sp->sof_c[sp->plane_sample_offset + m]; + /* H and V */ + sp->out_buffer[10 + m * 3 + 1] = + sp->sof_hv[sp->plane_sample_offset + m]; + /* Tq */ + sp->out_buffer[10 + m * 3 + 2] = + sp->sof_tq[sp->plane_sample_offset + m]; + } + *len = 10 + sp->samples_per_pixel_per_plane * 3; + *mem = (void *)sp->out_buffer; + sp->out_state++; } -static void -OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len) +static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp->actable[table_index]!=0) - { - *mem=(void*)(sp->actable[table_index]+sizeof(uint32)); - *len=*((uint32*)sp->actable[table_index])-sizeof(uint32); - } - sp->out_state++; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + assert(OJPEG_BUFFER >= 2 + 6 + sp->samples_per_pixel_per_plane * 2); + assert(255 >= 6 + sp->samples_per_pixel_per_plane * 2); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_SOS; + /* Ls */ + sp->out_buffer[2] = 0; + sp->out_buffer[3] = 6 + sp->samples_per_pixel_per_plane * 2; + /* Ns */ + sp->out_buffer[4] = sp->samples_per_pixel_per_plane; + for (m = 0; m < sp->samples_per_pixel_per_plane; m++) + { + /* Cs */ + sp->out_buffer[5 + m * 2] = sp->sos_cs[sp->plane_sample_offset + m]; + /* Td and Ta */ + sp->out_buffer[5 + m * 2 + 1] = + sp->sos_tda[sp->plane_sample_offset + m]; + } + /* Ss */ + sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2] = 0; + /* Se */ + sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 1] = 63; + /* Ah and Al */ + sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 2] = 0; + *len = 8 + sp->samples_per_pixel_per_plane * 2; + *mem = (void *)sp->out_buffer; + sp->out_state++; } -static void -OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len) +static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(OJPEG_BUFFER>=6); - if (sp->restart_interval!=0) - { - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_DRI; - sp->out_buffer[2]=0; - sp->out_buffer[3]=4; - sp->out_buffer[4]=(sp->restart_interval>>8); - sp->out_buffer[5]=(sp->restart_interval&255); - *len=6; - *mem=(void*)sp->out_buffer; - } - sp->out_state++; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp->in_buffer_togo == 0) + { + if (OJPEGReadBufferFill(sp) == 0) + return (0); + assert(sp->in_buffer_togo > 0); + } + *len = sp->in_buffer_togo; + *mem = (void *)sp->in_buffer_cur; + sp->in_buffer_togo = 0; + if (sp->in_buffer_file_togo == 0) + { + switch (sp->in_buffer_source) + { + case osibsStrile: + if (sp->in_buffer_next_strile < sp->in_buffer_strile_count) + sp->out_state = ososRst; + else + sp->out_state = ososEoi; + break; + case osibsEof: + sp->out_state = ososEoi; + break; + default: + break; + } + } + return (1); } -static void -OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len) +static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8 m; - assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3); - assert(255>=8+sp->samples_per_pixel_per_plane*3); - sp->out_buffer[0]=255; - sp->out_buffer[1]=sp->sof_marker_id; - /* Lf */ - sp->out_buffer[2]=0; - sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3; - /* P */ - sp->out_buffer[4]=8; - /* Y */ - sp->out_buffer[5]=(uint8)(sp->sof_y>>8); - sp->out_buffer[6]=(sp->sof_y&255); - /* X */ - sp->out_buffer[7]=(uint8)(sp->sof_x>>8); - sp->out_buffer[8]=(sp->sof_x&255); - /* Nf */ - sp->out_buffer[9]=sp->samples_per_pixel_per_plane; - for (m=0; msamples_per_pixel_per_plane; m++) - { - /* C */ - sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m]; - /* H and V */ - sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m]; - /* Tq */ - sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m]; - } - *len=10+sp->samples_per_pixel_per_plane*3; - *mem=(void*)sp->out_buffer; - sp->out_state++; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(OJPEG_BUFFER >= 2); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_RST0 + sp->restart_index; + sp->restart_index++; + if (sp->restart_index == 8) + sp->restart_index = 0; + *len = 2; + *mem = (void *)sp->out_buffer; + sp->out_state = ososCompressed; } -static void -OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len) +static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8 m; - assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2); - assert(255>=6+sp->samples_per_pixel_per_plane*2); - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_SOS; - /* Ls */ - sp->out_buffer[2]=0; - sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2; - /* Ns */ - sp->out_buffer[4]=sp->samples_per_pixel_per_plane; - for (m=0; msamples_per_pixel_per_plane; m++) - { - /* Cs */ - sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m]; - /* Td and Ta */ - sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m]; - } - /* Ss */ - sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0; - /* Se */ - sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63; - /* Ah and Al */ - sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0; - *len=8+sp->samples_per_pixel_per_plane*2; - *mem=(void*)sp->out_buffer; - sp->out_state++; -} - -static int -OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp->in_buffer_togo==0) - { - if (OJPEGReadBufferFill(sp)==0) - return(0); - assert(sp->in_buffer_togo>0); - } - *len=sp->in_buffer_togo; - *mem=(void*)sp->in_buffer_cur; - sp->in_buffer_togo=0; - if (sp->in_buffer_file_togo==0) - { - switch(sp->in_buffer_source) - { - case osibsStrile: - if (sp->in_buffer_next_strilein_buffer_strile_count) - sp->out_state=ososRst; - else - sp->out_state=ososEoi; - break; - case osibsEof: - sp->out_state=ososEoi; - break; - default: - break; - } - } - return(1); -} - -static void -OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(OJPEG_BUFFER>=2); - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index; - sp->restart_index++; - if (sp->restart_index==8) - sp->restart_index=0; - *len=2; - *mem=(void*)sp->out_buffer; - sp->out_state=ososCompressed; -} - -static void -OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(OJPEG_BUFFER>=2); - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_EOI; - *len=2; - *mem=(void*)sp->out_buffer; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(OJPEG_BUFFER >= 2); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_EOI; + *len = 2; + *mem = (void *)sp->out_buffer; } #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo) +static int jpeg_create_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo) { - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_create_decompress(cinfo); - return 1; - } + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_create_decompress(cinfo); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image) +static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, + uint8_t require_image) { - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_read_header(cinfo,require_image); - return 1; - } + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_read_header(cinfo, require_image); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo) +static int jpeg_start_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo) { - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_start_decompress(cinfo); - return 1; - } + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_start_decompress(cinfo); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines) +static int jpeg_read_scanlines_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, + void *scanlines, uint32_t max_lines) { - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_read_scanlines(cinfo,scanlines,max_lines); - return 1; - } + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_read_scanlines(cinfo, scanlines, max_lines); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines) +static int jpeg_read_raw_data_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, void *data, + uint32_t max_lines) { - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_read_raw_data(cinfo,data,max_lines); - return 1; - } + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_read_raw_data(cinfo, data, max_lines); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static void -jpeg_encap_unwind(TIFF* tif) +static void jpeg_encap_unwind(TIFF *tif) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - LONGJMP(sp->exit_jmpbuf,1); + OJPEGState *sp = (OJPEGState *)tif->tif_data; + LONGJMP(sp->exit_jmpbuf, 1); } #endif -static void -OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo) +static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo) { - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo,buffer); - TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer); + char buffer[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo, buffer); + TIFFWarningExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer); } -static void -OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo) +static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo) { - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo,buffer); - TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer); - jpeg_encap_unwind((TIFF*)(cinfo->client_data)); + char buffer[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo, buffer); + TIFFErrorExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer); + jpeg_encap_unwind((TIFF *)(cinfo->client_data)); } -static void -OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo) +static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo) { - (void)cinfo; + (void)cinfo; } static boolean -OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo) +OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo) { - TIFF* tif=(TIFF*)cinfo->client_data; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - void* mem=0; - uint32 len=0U; - if (OJPEGWriteStream(tif,&mem,&len)==0) - { - TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data"); - jpeg_encap_unwind(tif); - } - sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len; - sp->libjpeg_jpeg_source_mgr.next_input_byte=mem; - return(1); + TIFF *tif = (TIFF *)cinfo->client_data; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + void *mem = 0; + uint32_t len = 0U; + if (OJPEGWriteStream(tif, &mem, &len) == 0) + { + TIFFErrorExtR(tif, "LibJpeg", "Premature end of JPEG data"); + jpeg_encap_unwind(tif); + } + sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = len; + sp->libjpeg_jpeg_source_mgr.next_input_byte = mem; + return (1); } static void -OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes) +OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo, + long num_bytes) { - TIFF* tif=(TIFF*)cinfo->client_data; - (void)num_bytes; - TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error"); - jpeg_encap_unwind(tif); + TIFF *tif = (TIFF *)cinfo->client_data; + (void)num_bytes; + TIFFErrorExtR(tif, "LibJpeg", "Unexpected error"); + jpeg_encap_unwind(tif); } #ifdef _MSC_VER -#pragma warning( push ) -#pragma warning( disable : 4702 ) /* unreachable code */ +#pragma warning(push) +#pragma warning(disable : 4702) /* unreachable code */ #endif static boolean -OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired) +OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo, + int desired) { - TIFF* tif=(TIFF*)cinfo->client_data; - (void)desired; - TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error"); - jpeg_encap_unwind(tif); - return(0); + TIFF *tif = (TIFF *)cinfo->client_data; + (void)desired; + TIFFErrorExtR(tif, "LibJpeg", "Unexpected error"); + jpeg_encap_unwind(tif); + return (0); } #ifdef _MSC_VER -#pragma warning( pop ) +#pragma warning(pop) #endif -static void -OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo) +static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo) { - (void)cinfo; + (void)cinfo; } #endif - - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_open.c b/3rdparty/libtiff/tif_open.c index a0e31583a6..23fcf81c43 100644 --- a/3rdparty/libtiff/tif_open.c +++ b/3rdparty/libtiff/tif_open.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -26,481 +26,626 @@ * TIFF Library. */ #include "tiffiop.h" +#include /* * Dummy functions to fill the omitted client procedures. */ -static int -_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) +static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize) { - (void) fd; (void) pbase; (void) psize; - return (0); + (void)fd; + (void)pbase; + (void)psize; + return (0); } -static void -_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; (void) base; (void) size; + (void)fd; + (void)base; + (void)size; } -int -_TIFFgetMode(const char* mode, const char* module) +int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode, + const char *module) { - int m = -1; + int m = -1; - switch (mode[0]) { - case 'r': - m = O_RDONLY; - if (mode[1] == '+') - m = O_RDWR; - break; - case 'w': - case 'a': - m = O_RDWR|O_CREAT; - if (mode[0] == 'w') - m |= O_TRUNC; - break; - default: - TIFFErrorExt(0, module, "\"%s\": Bad mode", mode); - break; - } - return (m); + switch (mode[0]) + { + case 'r': + m = O_RDONLY; + if (mode[1] == '+') + m = O_RDWR; + break; + case 'w': + case 'a': + m = O_RDWR | O_CREAT; + if (mode[0] == 'w') + m |= O_TRUNC; + break; + default: + _TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode); + break; + } + return (m); } -TIFF* -TIFFClientOpen( - const char* name, const char* mode, - thandle_t clientdata, - TIFFReadWriteProc readproc, - TIFFReadWriteProc writeproc, - TIFFSeekProc seekproc, - TIFFCloseProc closeproc, - TIFFSizeProc sizeproc, - TIFFMapFileProc mapproc, - TIFFUnmapFileProc unmapproc -) +TIFFOpenOptions *TIFFOpenOptionsAlloc() { - static const char module[] = "TIFFClientOpen"; - TIFF *tif; - int m; - const char* cp; + TIFFOpenOptions *opts = + (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions)); + return opts; +} - /* The following are configuration checks. They should be redundant, but should not - * compile to any actual code in an optimised release build anyway. If any of them - * fail, (makefile-based or other) configuration is not correct */ - assert(sizeof(uint8)==1); - assert(sizeof(int8)==1); - assert(sizeof(uint16)==2); - assert(sizeof(int16)==2); - assert(sizeof(uint32)==4); - assert(sizeof(int32)==4); - assert(sizeof(uint64)==8); - assert(sizeof(int64)==8); - assert(sizeof(tmsize_t)==sizeof(void*)); - { - union{ - uint8 a8[2]; - uint16 a16; - } n; - n.a8[0]=1; - n.a8[1]=0; - (void)n; - #ifdef WORDS_BIGENDIAN - assert(n.a16==256); - #else - assert(n.a16==1); - #endif - } +void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); } - m = _TIFFgetMode(mode, module); - if (m == -1) - goto bad2; - tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1)); - if (tif == NULL) { - TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name); - goto bad2; - } - _TIFFmemset(tif, 0, sizeof (*tif)); - tif->tif_name = (char *)tif + sizeof (TIFF); - strcpy(tif->tif_name, name); - tif->tif_mode = m &~ (O_CREAT|O_TRUNC); - tif->tif_curdir = (uint16) -1; /* non-existent directory */ - tif->tif_curoff = 0; - tif->tif_curstrip = (uint32) -1; /* invalid strip */ - tif->tif_row = (uint32) -1; /* read/write pre-increment */ - tif->tif_clientdata = clientdata; - if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { - TIFFErrorExt(clientdata, module, - "One of the client procedures is NULL pointer."); - _TIFFfree(tif); - goto bad2; - } - tif->tif_readproc = readproc; - tif->tif_writeproc = writeproc; - tif->tif_seekproc = seekproc; - tif->tif_closeproc = closeproc; - tif->tif_sizeproc = sizeproc; - if (mapproc) - tif->tif_mapproc = mapproc; - else - tif->tif_mapproc = _tiffDummyMapProc; - if (unmapproc) - tif->tif_unmapproc = unmapproc; - else - tif->tif_unmapproc = _tiffDummyUnmapProc; - _TIFFSetDefaultCompressionState(tif); /* setup default state */ - /* - * Default is to return data MSB2LSB and enable the - * use of memory-mapped files and strip chopping when - * a file is opened read-only. - */ - tif->tif_flags = FILLORDER_MSB2LSB; - if (m == O_RDONLY ) - tif->tif_flags |= TIFF_MAPPED; +/** Define a limit in bytes for a single memory allocation done by libtiff. + * If max_single_mem_alloc is set to 0, no other limit that the underlying + * _TIFFmalloc() will be applied, which is the default. + */ +void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts, + tmsize_t max_single_mem_alloc) +{ + opts->max_single_mem_alloc = max_single_mem_alloc; +} - #ifdef STRIPCHOP_DEFAULT - if (m == O_RDONLY || m == O_RDWR) - tif->tif_flags |= STRIPCHOP_DEFAULT; - #endif +void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts, + TIFFErrorHandlerExtR handler, + void *errorhandler_user_data) +{ + opts->errorhandler = handler; + opts->errorhandler_user_data = errorhandler_user_data; +} - /* - * Process library-specific flags in the open mode string. - * The following flags may be used to control intrinsic library - * behavior that may or may not be desirable (usually for - * compatibility with some application that claims to support - * TIFF but only supports some brain dead idea of what the - * vendor thinks TIFF is): - * - * 'l' use little-endian byte order for creating a file - * 'b' use big-endian byte order for creating a file - * 'L' read/write information using LSB2MSB bit order - * 'B' read/write information using MSB2LSB bit order - * 'H' read/write information using host bit order - * 'M' enable use of memory-mapped files when supported - * 'm' disable use of memory-mapped files - * 'C' enable strip chopping support when reading - * 'c' disable strip chopping support - * 'h' read TIFF header only, do not load the first IFD - * '4' ClassicTIFF for creating a file (default) - * '8' BigTIFF for creating a file - * 'D' enable use of deferred strip/tile offset/bytecount array loading. - * 'O' on-demand loading of values instead of whole array loading (implies D) - * - * The use of the 'l' and 'b' flags is strongly discouraged. - * These flags are provided solely because numerous vendors, - * typically on the PC, do not correctly support TIFF; they - * only support the Intel little-endian byte order. This - * support is not configured by default because it supports - * the violation of the TIFF spec that says that readers *MUST* - * support both byte orders. It is strongly recommended that - * you not use this feature except to deal with busted apps - * that write invalid TIFF. And even in those cases you should - * bang on the vendors to fix their software. - * - * The 'L', 'B', and 'H' flags are intended for applications - * that can optimize operations on data by using a particular - * bit order. By default the library returns data in MSB2LSB - * bit order for compatibility with older versions of this - * library. Returning data in the bit order of the native CPU - * makes the most sense but also requires applications to check - * the value of the FillOrder tag; something they probably do - * not do right now. - * - * The 'M' and 'm' flags are provided because some virtual memory - * systems exhibit poor behavior when large images are mapped. - * These options permit clients to control the use of memory-mapped - * files on a per-file basis. - * - * The 'C' and 'c' flags are provided because the library support - * for chopping up large strips into multiple smaller strips is not - * application-transparent and as such can cause problems. The 'c' - * option permits applications that only want to look at the tags, - * for example, to get the unadulterated TIFF tag information. - */ - for (cp = mode; *cp; cp++) - switch (*cp) { - case 'b': - #ifndef WORDS_BIGENDIAN - if (m&O_CREAT) - tif->tif_flags |= TIFF_SWAB; - #endif - break; - case 'l': - #ifdef WORDS_BIGENDIAN - if ((m&O_CREAT)) - tif->tif_flags |= TIFF_SWAB; - #endif - break; - case 'B': - tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | - FILLORDER_MSB2LSB; - break; - case 'L': - tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | - FILLORDER_LSB2MSB; - break; - case 'H': - tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | - HOST_FILLORDER; - break; - case 'M': - if (m == O_RDONLY) - tif->tif_flags |= TIFF_MAPPED; - break; - case 'm': - if (m == O_RDONLY) - tif->tif_flags &= ~TIFF_MAPPED; - break; - case 'C': - if (m == O_RDONLY) - tif->tif_flags |= TIFF_STRIPCHOP; - break; - case 'c': - if (m == O_RDONLY) - tif->tif_flags &= ~TIFF_STRIPCHOP; - break; - case 'h': - tif->tif_flags |= TIFF_HEADERONLY; - break; - case '8': - if (m&O_CREAT) - tif->tif_flags |= TIFF_BIGTIFF; - break; - case 'D': - tif->tif_flags |= TIFF_DEFERSTRILELOAD; - break; - case 'O': - if( m == O_RDONLY ) - tif->tif_flags |= (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD); - break; - } +void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts, + TIFFErrorHandlerExtR handler, + void *warnhandler_user_data) +{ + opts->warnhandler = handler; + opts->warnhandler_user_data = warnhandler_user_data; +} -#ifdef DEFER_STRILE_LOAD - /* Compatibility with old DEFER_STRILE_LOAD compilation flag */ - /* Probably unneeded, since to the best of my knowledge (E. Rouault) */ - /* GDAL was the only user of this, and will now use the new 'D' flag */ - tif->tif_flags |= TIFF_DEFERSTRILELOAD; +static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif, + const char *pszFunction, + tmsize_t s) +{ + TIFFErrorExtR(tif, pszFunction, + "Memory allocation of %" PRIu64 + " bytes is beyond the %" PRIu64 + " byte limit defined in open options", + (uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc); +} + +/** malloc() version that takes into account memory-specific open options */ +void *_TIFFmallocExt(TIFF *tif, tmsize_t s) +{ + if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && + s > tif->tif_max_single_mem_alloc) + { + _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s); + return NULL; + } + return _TIFFmalloc(s); +} + +/** calloc() version that takes into account memory-specific open options */ +void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz) +{ + if (tif != NULL && tif->tif_max_single_mem_alloc > 0) + { + if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz) + return NULL; + if (nmemb * siz > tif->tif_max_single_mem_alloc) + { + _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt", + nmemb * siz); + return NULL; + } + } + return _TIFFcalloc(nmemb, siz); +} + +/** realloc() version that takes into account memory-specific open options */ +void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s) +{ + if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && + s > tif->tif_max_single_mem_alloc) + { + _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s); + return NULL; + } + return _TIFFrealloc(p, s); +} + +/** free() version that takes into account memory-specific open options */ +void _TIFFfreeExt(TIFF *tif, void *p) +{ + (void)tif; + _TIFFfree(p); +} + +TIFF *TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata, + TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, + TIFFSeekProc seekproc, TIFFCloseProc closeproc, + TIFFSizeProc sizeproc, TIFFMapFileProc mapproc, + TIFFUnmapFileProc unmapproc) +{ + return TIFFClientOpenExt(name, mode, clientdata, readproc, writeproc, + seekproc, closeproc, sizeproc, mapproc, unmapproc, + NULL); +} + +TIFF *TIFFClientOpenExt(const char *name, const char *mode, + thandle_t clientdata, TIFFReadWriteProc readproc, + TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, + TIFFCloseProc closeproc, TIFFSizeProc sizeproc, + TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc, + TIFFOpenOptions *opts) +{ + static const char module[] = "TIFFClientOpenExt"; + TIFF *tif; + int m; + const char *cp; + + /* The following are configuration checks. They should be redundant, but + * should not compile to any actual code in an optimised release build + * anyway. If any of them fail, (makefile-based or other) configuration is + * not correct */ + assert(sizeof(uint8_t) == 1); + assert(sizeof(int8_t) == 1); + assert(sizeof(uint16_t) == 2); + assert(sizeof(int16_t) == 2); + assert(sizeof(uint32_t) == 4); + assert(sizeof(int32_t) == 4); + assert(sizeof(uint64_t) == 8); + assert(sizeof(int64_t) == 8); + { + union + { + uint8_t a8[2]; + uint16_t a16; + } n; + n.a8[0] = 1; + n.a8[1] = 0; + (void)n; +#ifdef WORDS_BIGENDIAN + assert(n.a16 == 256); +#else + assert(n.a16 == 1); +#endif + } + + m = _TIFFgetMode(opts, clientdata, mode, module); + if (m == -1) + goto bad2; + tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1); + if (opts && opts->max_single_mem_alloc > 0 && + size_to_alloc > opts->max_single_mem_alloc) + { + _TIFFErrorEarly(opts, clientdata, module, + "%s: Memory allocation of %" PRIu64 + " bytes is beyond the %" PRIu64 + " byte limit defined in open options", + name, (uint64_t)size_to_alloc, + (uint64_t)opts->max_single_mem_alloc); + goto bad2; + } + tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc); + if (tif == NULL) + { + _TIFFErrorEarly(opts, clientdata, module, + "%s: Out of memory (TIFF structure)", name); + goto bad2; + } + _TIFFmemset(tif, 0, sizeof(*tif)); + tif->tif_name = (char *)tif + sizeof(TIFF); + strcpy(tif->tif_name, name); + tif->tif_mode = m & ~(O_CREAT | O_TRUNC); + tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */ + tif->tif_curoff = 0; + tif->tif_curstrip = (uint32_t)-1; /* invalid strip */ + tif->tif_row = (uint32_t)-1; /* read/write pre-increment */ + tif->tif_clientdata = clientdata; + tif->tif_readproc = readproc; + tif->tif_writeproc = writeproc; + tif->tif_seekproc = seekproc; + tif->tif_closeproc = closeproc; + tif->tif_sizeproc = sizeproc; + tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc; + tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc; + if (opts) + { + tif->tif_errorhandler = opts->errorhandler; + tif->tif_errorhandler_user_data = opts->errorhandler_user_data; + tif->tif_warnhandler = opts->warnhandler; + tif->tif_warnhandler_user_data = opts->warnhandler_user_data; + tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc; + } + + if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) + { + TIFFErrorExtR(tif, module, + "One of the client procedures is NULL pointer."); + _TIFFfreeExt(NULL, tif); + goto bad2; + } + + _TIFFSetDefaultCompressionState(tif); /* setup default state */ + /* + * Default is to return data MSB2LSB and enable the + * use of memory-mapped files and strip chopping when + * a file is opened read-only. + */ + tif->tif_flags = FILLORDER_MSB2LSB; + if (m == O_RDONLY) + tif->tif_flags |= TIFF_MAPPED; + +#ifdef STRIPCHOP_DEFAULT + if (m == O_RDONLY || m == O_RDWR) + tif->tif_flags |= STRIPCHOP_DEFAULT; #endif - /* - * Read in TIFF header. - */ - if ((m & O_TRUNC) || - !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) { - if (tif->tif_mode == O_RDONLY) { - TIFFErrorExt(tif->tif_clientdata, name, - "Cannot read TIFF header"); - goto bad; - } - /* - * Setup header and write. - */ - #ifdef WORDS_BIGENDIAN - tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB) - ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; - #else - tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB) - ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; - #endif - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; - tif->tif_header.classic.tiff_diroff = 0; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&tif->tif_header.common.tiff_version); - tif->tif_header_size = sizeof(TIFFHeaderClassic); - } - else - { - tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; - tif->tif_header.big.tiff_offsetsize = 8; - tif->tif_header.big.tiff_unused = 0; - tif->tif_header.big.tiff_diroff = 0; - if (tif->tif_flags & TIFF_SWAB) - { - TIFFSwabShort(&tif->tif_header.common.tiff_version); - TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); - } - tif->tif_header_size = sizeof (TIFFHeaderBig); - } - /* - * The doc for "fopen" for some STD_C_LIBs says that if you - * open a file for modify ("+"), then you must fseek (or - * fflush?) between any freads and fwrites. This is not - * necessary on most systems, but has been shown to be needed - * on Solaris. - */ - TIFFSeekFile( tif, 0, SEEK_SET ); - if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) { - TIFFErrorExt(tif->tif_clientdata, name, - "Error writing TIFF header"); - goto bad; - } - /* - * Setup the byte order handling. - */ - if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { - #ifndef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; - #endif - } else { - #ifdef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; - #endif - } - /* - * Setup default directory. - */ - if (!TIFFDefaultDirectory(tif)) - goto bad; - tif->tif_diroff = 0; - tif->tif_dirlist = NULL; - tif->tif_dirlistsize = 0; - tif->tif_dirnumber = 0; - return (tif); - } - /* - * Setup the byte order handling. - */ - if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && - tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN - #if MDI_SUPPORT - && - #if HOST_BIGENDIAN - tif->tif_header.common.tiff_magic != MDI_BIGENDIAN - #else - tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN - #endif - ) { - TIFFErrorExt(tif->tif_clientdata, name, - "Not a TIFF or MDI file, bad magic number %d (0x%x)", - #else - ) { - TIFFErrorExt(tif->tif_clientdata, name, - "Not a TIFF file, bad magic number %d (0x%x)", - #endif - tif->tif_header.common.tiff_magic, - tif->tif_header.common.tiff_magic); - goto bad; - } - if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { - #ifndef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; - #endif - } else { - #ifdef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; - #endif - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&tif->tif_header.common.tiff_version); - if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&& - (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) { - TIFFErrorExt(tif->tif_clientdata, name, - "Not a TIFF file, bad version number %d (0x%x)", - tif->tif_header.common.tiff_version, - tif->tif_header.common.tiff_version); - goto bad; - } - if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); - tif->tif_header_size = sizeof(TIFFHeaderClassic); - } - else - { - if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic)))) - { - TIFFErrorExt(tif->tif_clientdata, name, - "Cannot read TIFF header"); - goto bad; - } - if (tif->tif_flags & TIFF_SWAB) - { - TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); - TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); - } - if (tif->tif_header.big.tiff_offsetsize != 8) - { - TIFFErrorExt(tif->tif_clientdata, name, - "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)", - tif->tif_header.big.tiff_offsetsize, - tif->tif_header.big.tiff_offsetsize); - goto bad; - } - if (tif->tif_header.big.tiff_unused != 0) - { - TIFFErrorExt(tif->tif_clientdata, name, - "Not a TIFF file, bad BigTIFF unused %d (0x%x)", - tif->tif_header.big.tiff_unused, - tif->tif_header.big.tiff_unused); - goto bad; - } - tif->tif_header_size = sizeof(TIFFHeaderBig); - tif->tif_flags |= TIFF_BIGTIFF; - } - tif->tif_flags |= TIFF_MYBUFFER; - tif->tif_rawcp = tif->tif_rawdata = 0; - tif->tif_rawdatasize = 0; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = 0; + /* + * Process library-specific flags in the open mode string. + * The following flags may be used to control intrinsic library + * behavior that may or may not be desirable (usually for + * compatibility with some application that claims to support + * TIFF but only supports some brain dead idea of what the + * vendor thinks TIFF is): + * + * 'l' use little-endian byte order for creating a file + * 'b' use big-endian byte order for creating a file + * 'L' read/write information using LSB2MSB bit order + * 'B' read/write information using MSB2LSB bit order + * 'H' read/write information using host bit order + * 'M' enable use of memory-mapped files when supported + * 'm' disable use of memory-mapped files + * 'C' enable strip chopping support when reading + * 'c' disable strip chopping support + * 'h' read TIFF header only, do not load the first IFD + * '4' ClassicTIFF for creating a file (default) + * '8' BigTIFF for creating a file + * 'D' enable use of deferred strip/tile offset/bytecount array loading. + * 'O' on-demand loading of values instead of whole array loading (implies + * D) + * + * The use of the 'l' and 'b' flags is strongly discouraged. + * These flags are provided solely because numerous vendors, + * typically on the PC, do not correctly support TIFF; they + * only support the Intel little-endian byte order. This + * support is not configured by default because it supports + * the violation of the TIFF spec that says that readers *MUST* + * support both byte orders. It is strongly recommended that + * you not use this feature except to deal with busted apps + * that write invalid TIFF. And even in those cases you should + * bang on the vendors to fix their software. + * + * The 'L', 'B', and 'H' flags are intended for applications + * that can optimize operations on data by using a particular + * bit order. By default the library returns data in MSB2LSB + * bit order for compatibility with older versions of this + * library. Returning data in the bit order of the native CPU + * makes the most sense but also requires applications to check + * the value of the FillOrder tag; something they probably do + * not do right now. + * + * The 'M' and 'm' flags are provided because some virtual memory + * systems exhibit poor behavior when large images are mapped. + * These options permit clients to control the use of memory-mapped + * files on a per-file basis. + * + * The 'C' and 'c' flags are provided because the library support + * for chopping up large strips into multiple smaller strips is not + * application-transparent and as such can cause problems. The 'c' + * option permits applications that only want to look at the tags, + * for example, to get the unadulterated TIFF tag information. + */ + for (cp = mode; *cp; cp++) + switch (*cp) + { + case 'b': +#ifndef WORDS_BIGENDIAN + if (m & O_CREAT) + tif->tif_flags |= TIFF_SWAB; +#endif + break; + case 'l': +#ifdef WORDS_BIGENDIAN + if ((m & O_CREAT)) + tif->tif_flags |= TIFF_SWAB; +#endif + break; + case 'B': + tif->tif_flags = + (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB; + break; + case 'L': + tif->tif_flags = + (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_LSB2MSB; + break; + case 'H': + TIFFWarningExtR(tif, name, + "H(ost) mode is deprecated. Since " + "libtiff 4.5.1, it is an alias of 'B' / " + "FILLORDER_MSB2LSB."); + tif->tif_flags = + (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB; + break; + case 'M': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_MAPPED; + break; + case 'm': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_MAPPED; + break; + case 'C': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_STRIPCHOP; + break; + case 'c': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_STRIPCHOP; + break; + case 'h': + tif->tif_flags |= TIFF_HEADERONLY; + break; + case '8': + if (m & O_CREAT) + tif->tif_flags |= TIFF_BIGTIFF; + break; + case 'D': + tif->tif_flags |= TIFF_DEFERSTRILELOAD; + break; + case 'O': + if (m == O_RDONLY) + tif->tif_flags |= + (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD); + break; + } - switch (mode[0]) { - case 'r': - if (!(tif->tif_flags&TIFF_BIGTIFF)) - tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; - else - tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; - /* - * Try to use a memory-mapped file if the client - * has not explicitly suppressed usage with the - * 'm' flag in the open mode (see above). - */ - if (tif->tif_flags & TIFF_MAPPED) - { - toff_t n; - if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n)) - { - tif->tif_size=(tmsize_t)n; - assert((toff_t)tif->tif_size==n); - } - else - tif->tif_flags &= ~TIFF_MAPPED; - } - /* - * Sometimes we do not want to read the first directory (for example, - * it may be broken) and want to proceed to other directories. I this - * case we use the TIFF_HEADERONLY flag to open file and return - * immediately after reading TIFF header. - */ - if (tif->tif_flags & TIFF_HEADERONLY) - return (tif); +#ifdef DEFER_STRILE_LOAD + /* Compatibility with old DEFER_STRILE_LOAD compilation flag */ + /* Probably unneeded, since to the best of my knowledge (E. Rouault) */ + /* GDAL was the only user of this, and will now use the new 'D' flag */ + tif->tif_flags |= TIFF_DEFERSTRILELOAD; +#endif - /* - * Setup initial directory. - */ - if (TIFFReadDirectory(tif)) { - tif->tif_rawcc = (tmsize_t)-1; - tif->tif_flags |= TIFF_BUFFERSETUP; - return (tif); - } - break; - case 'a': - /* - * New directories are automatically append - * to the end of the directory chain when they - * are written out (see TIFFWriteDirectory). - */ - if (!TIFFDefaultDirectory(tif)) - goto bad; - return (tif); - } + /* + * Read in TIFF header. + */ + if ((m & O_TRUNC) || + !ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic))) + { + if (tif->tif_mode == O_RDONLY) + { + TIFFErrorExtR(tif, name, "Cannot read TIFF header"); + goto bad; + } +/* + * Setup header and write. + */ +#ifdef WORDS_BIGENDIAN + tif->tif_header.common.tiff_magic = + (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; +#else + tif->tif_header.common.tiff_magic = + (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; +#endif + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; + tif->tif_header.classic.tiff_diroff = 0; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&tif->tif_header.common.tiff_version); + tif->tif_header_size = sizeof(TIFFHeaderClassic); + } + else + { + tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; + tif->tif_header.big.tiff_offsetsize = 8; + tif->tif_header.big.tiff_unused = 0; + tif->tif_header.big.tiff_diroff = 0; + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabShort(&tif->tif_header.common.tiff_version); + TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); + } + tif->tif_header_size = sizeof(TIFFHeaderBig); + } + /* + * The doc for "fopen" for some STD_C_LIBs says that if you + * open a file for modify ("+"), then you must fseek (or + * fflush?) between any freads and fwrites. This is not + * necessary on most systems, but has been shown to be needed + * on Solaris. + */ + TIFFSeekFile(tif, 0, SEEK_SET); + if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) + { + TIFFErrorExtR(tif, name, "Error writing TIFF header"); + goto bad; + } + /* + * Setup the byte order handling. + */ + if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) + { +#ifndef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; +#endif + } + else + { +#ifdef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; +#endif + } + /* + * Setup default directory. + */ + if (!TIFFDefaultDirectory(tif)) + goto bad; + tif->tif_diroff = 0; + tif->tif_lastdiroff = 0; + tif->tif_setdirectory_force_absolute = FALSE; + return (tif); + } + /* + * Setup the byte order handling. + */ + if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && + tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN +#if MDI_SUPPORT + && +#if HOST_BIGENDIAN + tif->tif_header.common.tiff_magic != MDI_BIGENDIAN +#else + tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN +#endif + ) + { + TIFFErrorExtR(tif, name, + "Not a TIFF or MDI file, bad magic number %" PRIu16 + " (0x%" PRIx16 ")", +#else + ) + { + TIFFErrorExtR(tif, name, + "Not a TIFF file, bad magic number %" PRIu16 + " (0x%" PRIx16 ")", +#endif + tif->tif_header.common.tiff_magic, + tif->tif_header.common.tiff_magic); + goto bad; + } + if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) + { +#ifndef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; +#endif + } + else + { +#ifdef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; +#endif + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&tif->tif_header.common.tiff_version); + if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC) && + (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) + { + TIFFErrorExtR(tif, name, + "Not a TIFF file, bad version number %" PRIu16 + " (0x%" PRIx16 ")", + tif->tif_header.common.tiff_version, + tif->tif_header.common.tiff_version); + goto bad; + } + if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); + tif->tif_header_size = sizeof(TIFFHeaderClassic); + } + else + { + if (!ReadOK(tif, + ((uint8_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), + (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic)))) + { + TIFFErrorExtR(tif, name, "Cannot read TIFF header"); + goto bad; + } + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); + TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); + } + if (tif->tif_header.big.tiff_offsetsize != 8) + { + TIFFErrorExtR(tif, name, + "Not a TIFF file, bad BigTIFF offsetsize %" PRIu16 + " (0x%" PRIx16 ")", + tif->tif_header.big.tiff_offsetsize, + tif->tif_header.big.tiff_offsetsize); + goto bad; + } + if (tif->tif_header.big.tiff_unused != 0) + { + TIFFErrorExtR(tif, name, + "Not a TIFF file, bad BigTIFF unused %" PRIu16 + " (0x%" PRIx16 ")", + tif->tif_header.big.tiff_unused, + tif->tif_header.big.tiff_unused); + goto bad; + } + tif->tif_header_size = sizeof(TIFFHeaderBig); + tif->tif_flags |= TIFF_BIGTIFF; + } + tif->tif_flags |= TIFF_MYBUFFER; + tif->tif_rawcp = tif->tif_rawdata = 0; + tif->tif_rawdatasize = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + + switch (mode[0]) + { + case 'r': + if (!(tif->tif_flags & TIFF_BIGTIFF)) + tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; + else + tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; + /* + * Try to use a memory-mapped file if the client + * has not explicitly suppressed usage with the + * 'm' flag in the open mode (see above). + */ + if (tif->tif_flags & TIFF_MAPPED) + { + toff_t n; + if (TIFFMapFileContents(tif, (void **)(&tif->tif_base), &n)) + { + tif->tif_size = (tmsize_t)n; + assert((toff_t)tif->tif_size == n); + } + else + tif->tif_flags &= ~TIFF_MAPPED; + } + /* + * Sometimes we do not want to read the first directory (for + * example, it may be broken) and want to proceed to other + * directories. I this case we use the TIFF_HEADERONLY flag to open + * file and return immediately after reading TIFF header. + */ + if (tif->tif_flags & TIFF_HEADERONLY) + return (tif); + + /* + * Setup initial directory. + */ + if (TIFFReadDirectory(tif)) + { + return (tif); + } + break; + case 'a': + /* + * New directories are automatically append + * to the end of the directory chain when they + * are written out (see TIFFWriteDirectory). + */ + if (!TIFFDefaultDirectory(tif)) + goto bad; + return (tif); + } bad: - tif->tif_mode = O_RDONLY; /* XXX avoid flush */ - TIFFCleanup(tif); + tif->tif_mode = O_RDONLY; /* XXX avoid flush */ + TIFFCleanup(tif); bad2: - return ((TIFF*)0); + return ((TIFF *)0); } /* @@ -510,233 +655,154 @@ bad2: /* * Return open file's name. */ -const char * -TIFFFileName(TIFF* tif) -{ - return (tif->tif_name); -} +const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); } /* * Set the file name. */ -const char * -TIFFSetFileName(TIFF* tif, const char *name) +const char *TIFFSetFileName(TIFF *tif, const char *name) { - const char* old_name = tif->tif_name; - tif->tif_name = (char *)name; - return (old_name); + const char *old_name = tif->tif_name; + tif->tif_name = (char *)name; + return (old_name); } /* * Return open file's I/O descriptor. */ -int -TIFFFileno(TIFF* tif) -{ - return (tif->tif_fd); -} +int TIFFFileno(TIFF *tif) { return (tif->tif_fd); } /* * Set open file's I/O descriptor, and return previous value. */ -int -TIFFSetFileno(TIFF* tif, int fd) +int TIFFSetFileno(TIFF *tif, int fd) { - int old_fd = tif->tif_fd; - tif->tif_fd = fd; - return old_fd; + int old_fd = tif->tif_fd; + tif->tif_fd = fd; + return old_fd; } /* * Return open file's clientdata. */ -thandle_t -TIFFClientdata(TIFF* tif) -{ - return (tif->tif_clientdata); -} +thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); } /* * Set open file's clientdata, and return previous value. */ -thandle_t -TIFFSetClientdata(TIFF* tif, thandle_t newvalue) +thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue) { - thandle_t m = tif->tif_clientdata; - tif->tif_clientdata = newvalue; - return m; + thandle_t m = tif->tif_clientdata; + tif->tif_clientdata = newvalue; + return m; } /* * Return read/write mode. */ -int -TIFFGetMode(TIFF* tif) -{ - return (tif->tif_mode); -} +int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); } /* * Return read/write mode. */ -int -TIFFSetMode(TIFF* tif, int mode) +int TIFFSetMode(TIFF *tif, int mode) { - int old_mode = tif->tif_mode; - tif->tif_mode = mode; - return (old_mode); + int old_mode = tif->tif_mode; + tif->tif_mode = mode; + return (old_mode); } /* * Return nonzero if file is organized in * tiles; zero if organized as strips. */ -int -TIFFIsTiled(TIFF* tif) -{ - return (isTiled(tif)); -} +int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); } /* * Return current row being read/written. */ -uint32 -TIFFCurrentRow(TIFF* tif) -{ - return (tif->tif_row); -} +uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); } /* * Return index of the current directory. */ -uint16 -TIFFCurrentDirectory(TIFF* tif) -{ - return (tif->tif_curdir); -} +tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); } /* * Return current strip. */ -uint32 -TIFFCurrentStrip(TIFF* tif) -{ - return (tif->tif_curstrip); -} +uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); } /* * Return current tile. */ -uint32 -TIFFCurrentTile(TIFF* tif) -{ - return (tif->tif_curtile); -} +uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); } /* * Return nonzero if the file has byte-swapped data. */ -int -TIFFIsByteSwapped(TIFF* tif) -{ - return ((tif->tif_flags & TIFF_SWAB) != 0); -} +int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); } /* * Return nonzero if the data is returned up-sampled. */ -int -TIFFIsUpSampled(TIFF* tif) -{ - return (isUpSampled(tif)); -} +int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); } /* * Return nonzero if the data is returned in MSB-to-LSB bit order. */ -int -TIFFIsMSB2LSB(TIFF* tif) -{ - return (isFillOrder(tif, FILLORDER_MSB2LSB)); -} +int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); } /* * Return nonzero if given file was written in big-endian order. */ -int -TIFFIsBigEndian(TIFF* tif) +int TIFFIsBigEndian(TIFF *tif) { - return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN); + return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN); +} + +/* + * Return nonzero if given file is BigTIFF style. + */ +int TIFFIsBigTIFF(TIFF *tif) +{ + return (tif->tif_header.common.tiff_version == TIFF_VERSION_BIG); } /* * Return pointer to file read method. */ -TIFFReadWriteProc -TIFFGetReadProc(TIFF* tif) -{ - return (tif->tif_readproc); -} +TIFFReadWriteProc TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); } /* * Return pointer to file write method. */ -TIFFReadWriteProc -TIFFGetWriteProc(TIFF* tif) -{ - return (tif->tif_writeproc); -} +TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); } /* * Return pointer to file seek method. */ -TIFFSeekProc -TIFFGetSeekProc(TIFF* tif) -{ - return (tif->tif_seekproc); -} +TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); } /* * Return pointer to file close method. */ -TIFFCloseProc -TIFFGetCloseProc(TIFF* tif) -{ - return (tif->tif_closeproc); -} +TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); } /* * Return pointer to file size requesting method. */ -TIFFSizeProc -TIFFGetSizeProc(TIFF* tif) -{ - return (tif->tif_sizeproc); -} +TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); } /* * Return pointer to memory mapping method. */ -TIFFMapFileProc -TIFFGetMapFileProc(TIFF* tif) -{ - return (tif->tif_mapproc); -} +TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); } /* * Return pointer to memory unmapping method. */ -TIFFUnmapFileProc -TIFFGetUnmapFileProc(TIFF* tif) +TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif) { - return (tif->tif_unmapproc); + return (tif->tif_unmapproc); } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_packbits.c b/3rdparty/libtiff/tif_packbits.c index a8f29e8757..62849f8f3c 100644 --- a/3rdparty/libtiff/tif_packbits.c +++ b/3rdparty/libtiff/tif_packbits.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -31,157 +31,178 @@ */ #include -static int -PackBitsPreEncode(TIFF* tif, uint16 s) +static int PackBitsPreEncode(TIFF *tif, uint16_t s) { - (void) s; + (void)s; - tif->tif_data = (uint8*)_TIFFmalloc(sizeof(tmsize_t)); - if (tif->tif_data == NULL) - return (0); - /* - * Calculate the scanline/tile-width size in bytes. - */ - if (isTiled(tif)) - *(tmsize_t*)tif->tif_data = TIFFTileRowSize(tif); - else - *(tmsize_t*)tif->tif_data = TIFFScanlineSize(tif); - return (1); + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(tmsize_t)); + if (tif->tif_data == NULL) + return (0); + /* + * Calculate the scanline/tile-width size in bytes. + */ + if (isTiled(tif)) + *(tmsize_t *)tif->tif_data = TIFFTileRowSize(tif); + else + *(tmsize_t *)tif->tif_data = TIFFScanlineSize(tif); + return (1); } -static int -PackBitsPostEncode(TIFF* tif) +static int PackBitsPostEncode(TIFF *tif) { - if (tif->tif_data) - _TIFFfree(tif->tif_data); - return (1); + if (tif->tif_data) + _TIFFfreeExt(tif, tif->tif_data); + return (1); } /* * Encode a run of pixels. */ -static int -PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) +static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - unsigned char* bp = (unsigned char*) buf; - uint8* op; - uint8* ep; - uint8* lastliteral; - long n, slop; - int b; - enum { BASE, LITERAL, RUN, LITERAL_RUN } state; + unsigned char *bp = (unsigned char *)buf; + uint8_t *op; + uint8_t *ep; + uint8_t *lastliteral; + long n, slop; + int b; + enum + { + BASE, + LITERAL, + RUN, + LITERAL_RUN + } state; - (void) s; - op = tif->tif_rawcp; - ep = tif->tif_rawdata + tif->tif_rawdatasize; - state = BASE; - lastliteral = 0; - while (cc > 0) { - /* - * Find the longest string of identical bytes. - */ - b = *bp++; - cc--; - n = 1; - for (; cc > 0 && b == *bp; cc--, bp++) - n++; - again: - if (op + 2 >= ep) { /* insure space for new data */ - /* - * Be careful about writing the last - * literal. Must write up to that point - * and then copy the remainder to the - * front of the buffer. - */ - if (state == LITERAL || state == LITERAL_RUN) { - slop = (long)(op - lastliteral); - tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp); - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - while (slop-- > 0) - *op++ = *lastliteral++; - lastliteral = tif->tif_rawcp; - } else { - tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - } - } - switch (state) { - case BASE: /* initial state, set run/literal */ - if (n > 1) { - state = RUN; - if (n > 128) { - *op++ = (uint8) -127; - *op++ = (uint8) b; - n -= 128; - goto again; - } - *op++ = (uint8)(-(n-1)); - *op++ = (uint8) b; - } else { - lastliteral = op; - *op++ = 0; - *op++ = (uint8) b; - state = LITERAL; - } - break; - case LITERAL: /* last object was literal string */ - if (n > 1) { - state = LITERAL_RUN; - if (n > 128) { - *op++ = (uint8) -127; - *op++ = (uint8) b; - n -= 128; - goto again; - } - *op++ = (uint8)(-(n-1)); /* encode run */ - *op++ = (uint8) b; - } else { /* extend literal */ - if (++(*lastliteral) == 127) - state = BASE; - *op++ = (uint8) b; - } - break; - case RUN: /* last object was run */ - if (n > 1) { - if (n > 128) { - *op++ = (uint8) -127; - *op++ = (uint8) b; - n -= 128; - goto again; - } - *op++ = (uint8)(-(n-1)); - *op++ = (uint8) b; - } else { - lastliteral = op; - *op++ = 0; - *op++ = (uint8) b; - state = LITERAL; - } - break; - case LITERAL_RUN: /* literal followed by a run */ - /* - * Check to see if previous run should - * be converted to a literal, in which - * case we convert literal-run-literal - * to a single literal. - */ - if (n == 1 && op[-2] == (uint8) -1 && - *lastliteral < 126) { - state = (((*lastliteral) += 2) == 127 ? - BASE : LITERAL); - op[-2] = op[-1]; /* replicate */ - } else - state = RUN; - goto again; - } - } - tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); - tif->tif_rawcp = op; - return (1); + (void)s; + op = tif->tif_rawcp; + ep = tif->tif_rawdata + tif->tif_rawdatasize; + state = BASE; + lastliteral = 0; + while (cc > 0) + { + /* + * Find the longest string of identical bytes. + */ + b = *bp++; + cc--; + n = 1; + for (; cc > 0 && b == *bp; cc--, bp++) + n++; + again: + if (op + 2 >= ep) + { /* insure space for new data */ + /* + * Be careful about writing the last + * literal. Must write up to that point + * and then copy the remainder to the + * front of the buffer. + */ + if (state == LITERAL || state == LITERAL_RUN) + { + slop = (long)(op - lastliteral); + tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp); + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + while (slop-- > 0) + *op++ = *lastliteral++; + lastliteral = tif->tif_rawcp; + } + else + { + tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + } + } + switch (state) + { + case BASE: /* initial state, set run/literal */ + if (n > 1) + { + state = RUN; + if (n > 128) + { + *op++ = (uint8_t)-127; + *op++ = (uint8_t)b; + n -= 128; + goto again; + } + *op++ = (uint8_t)(-(n - 1)); + *op++ = (uint8_t)b; + } + else + { + lastliteral = op; + *op++ = 0; + *op++ = (uint8_t)b; + state = LITERAL; + } + break; + case LITERAL: /* last object was literal string */ + if (n > 1) + { + state = LITERAL_RUN; + if (n > 128) + { + *op++ = (uint8_t)-127; + *op++ = (uint8_t)b; + n -= 128; + goto again; + } + *op++ = (uint8_t)(-(n - 1)); /* encode run */ + *op++ = (uint8_t)b; + } + else + { /* extend literal */ + if (++(*lastliteral) == 127) + state = BASE; + *op++ = (uint8_t)b; + } + break; + case RUN: /* last object was run */ + if (n > 1) + { + if (n > 128) + { + *op++ = (uint8_t)-127; + *op++ = (uint8_t)b; + n -= 128; + goto again; + } + *op++ = (uint8_t)(-(n - 1)); + *op++ = (uint8_t)b; + } + else + { + lastliteral = op; + *op++ = 0; + *op++ = (uint8_t)b; + state = LITERAL; + } + break; + case LITERAL_RUN: /* literal followed by a run */ + /* + * Check to see if previous run should + * be converted to a literal, in which + * case we convert literal-run-literal + * to a single literal. + */ + if (n == 1 && op[-2] == (uint8_t)-1 && *lastliteral < 126) + { + state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL); + op[-2] = op[-1]; /* replicate */ + } + else + state = RUN; + goto again; + } + } + tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); + tif->tif_rawcp = op; + return (1); } /* @@ -191,119 +212,112 @@ PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) * the decoder if data is read, for example, by scanlines * when it was encoded by strips. */ -static int -PackBitsEncodeChunk(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int PackBitsEncodeChunk(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowsize = *(tmsize_t*)tif->tif_data; + tmsize_t rowsize = *(tmsize_t *)tif->tif_data; - while (cc > 0) { - tmsize_t chunk = rowsize; - - if( cc < chunk ) - chunk = cc; + while (cc > 0) + { + tmsize_t chunk = rowsize; - if (PackBitsEncode(tif, bp, chunk, s) < 0) - return (-1); - bp += chunk; - cc -= chunk; - } - return (1); + if (cc < chunk) + chunk = cc; + + if (PackBitsEncode(tif, bp, chunk, s) < 0) + return (-1); + bp += chunk; + cc -= chunk; + } + return (1); } -static int -PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "PackBitsDecode"; - char *bp; - tmsize_t cc; - long n; - int b; + static const char module[] = "PackBitsDecode"; + int8_t *bp; + tmsize_t cc; + long n; + int b; - (void) s; - bp = (char*) tif->tif_rawcp; - cc = tif->tif_rawcc; - while (cc > 0 && occ > 0) { - n = (long) *bp++; - cc--; - /* - * Watch out for compilers that - * don't sign extend chars... - */ - if (n >= 128) - n -= 256; - if (n < 0) { /* replicate next byte -n+1 times */ - if (n == -128) /* nop */ - continue; - n = -n + 1; - if( occ < (tmsize_t)n ) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Discarding %lu bytes to avoid buffer overrun", - (unsigned long) ((tmsize_t)n - occ)); - n = (long)occ; - } - if( cc == 0 ) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Terminating PackBitsDecode due to lack of data."); - break; - } - occ -= n; - b = *bp++; - cc--; - while (n-- > 0) - *op++ = (uint8) b; - } else { /* copy next n+1 bytes literally */ - if (occ < (tmsize_t)(n + 1)) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Discarding %lu bytes to avoid buffer overrun", - (unsigned long) ((tmsize_t)n - occ + 1)); - n = (long)occ - 1; - } - if (cc < (tmsize_t) (n+1)) - { - TIFFWarningExt(tif->tif_clientdata, module, - "Terminating PackBitsDecode due to lack of data."); - break; - } - _TIFFmemcpy(op, bp, ++n); - op += n; occ -= n; - bp += n; cc -= n; - } - } - tif->tif_rawcp = (uint8*) bp; - tif->tif_rawcc = cc; - if (occ > 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data for scanline %lu", - (unsigned long) tif->tif_row); - return (0); - } - return (1); + (void)s; + bp = (int8_t *)tif->tif_rawcp; + cc = tif->tif_rawcc; + while (cc > 0 && occ > 0) + { + n = (long)*bp++; + cc--; + if (n < 0) + { /* replicate next byte -n+1 times */ + if (n == -128) /* nop */ + continue; + n = -n + 1; + if (occ < (tmsize_t)n) + { + TIFFWarningExtR(tif, module, + "Discarding %" TIFF_SSIZE_FORMAT + " bytes to avoid buffer overrun", + (tmsize_t)n - occ); + n = (long)occ; + } + if (cc == 0) + { + TIFFWarningExtR( + tif, module, + "Terminating PackBitsDecode due to lack of data."); + break; + } + occ -= n; + b = *bp++; + cc--; + while (n-- > 0) + *op++ = (uint8_t)b; + } + else + { /* copy next n+1 bytes literally */ + if (occ < (tmsize_t)(n + 1)) + { + TIFFWarningExtR(tif, module, + "Discarding %" TIFF_SSIZE_FORMAT + " bytes to avoid buffer overrun", + (tmsize_t)n - occ + 1); + n = (long)occ - 1; + } + if (cc < (tmsize_t)(n + 1)) + { + TIFFWarningExtR( + tif, module, + "Terminating PackBitsDecode due to lack of data."); + break; + } + _TIFFmemcpy(op, bp, ++n); + op += n; + occ -= n; + bp += n; + cc -= n; + } + } + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + if (occ > 0) + { + TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32, + tif->tif_row); + return (0); + } + return (1); } -int -TIFFInitPackBits(TIFF* tif, int scheme) +int TIFFInitPackBits(TIFF *tif, int scheme) { - (void) scheme; - tif->tif_decoderow = PackBitsDecode; - tif->tif_decodestrip = PackBitsDecode; - tif->tif_decodetile = PackBitsDecode; - tif->tif_preencode = PackBitsPreEncode; - tif->tif_postencode = PackBitsPostEncode; - tif->tif_encoderow = PackBitsEncode; - tif->tif_encodestrip = PackBitsEncodeChunk; - tif->tif_encodetile = PackBitsEncodeChunk; - return (1); + (void)scheme; + tif->tif_decoderow = PackBitsDecode; + tif->tif_decodestrip = PackBitsDecode; + tif->tif_decodetile = PackBitsDecode; + tif->tif_preencode = PackBitsPreEncode; + tif->tif_postencode = PackBitsPostEncode; + tif->tif_encoderow = PackBitsEncode; + tif->tif_encodestrip = PackBitsEncodeChunk; + tif->tif_encodetile = PackBitsEncodeChunk; + return (1); } #endif /* PACKBITS_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_pixarlog.c b/3rdparty/libtiff/tif_pixarlog.c index f291201505..5c0346b6ec 100644 --- a/3rdparty/libtiff/tif_pixarlog.c +++ b/3rdparty/libtiff/tif_pixarlog.c @@ -2,23 +2,23 @@ * Copyright (c) 1996-1997 Sam Leffler * Copyright (c) 1996 Pixar * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Pixar, Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,10 +32,10 @@ * Contributed by Dan McCoy. * * PixarLog film support uses the TIFF library to store companded - * 11 bit values into a tiff file, which are compressed using the - * zip compressor. + * 11 bit values into a tiff file, which are compressed using the + * zip compressor. * - * The codec can take as input and produce as output 32-bit IEEE float values + * The codec can take as input and produce as output 32-bit IEEE float values * as well as 16-bit or 8-bit unsigned integer values. * * On writing any of the above are converted into the internal @@ -49,7 +49,7 @@ * than the human eye can perceive with extra room to allow for * error introduced by further image computation. As with any quantized * color format, it is possible to perform image calculations which - * expose the quantization error. This format should certainly be less + * expose the quantization error. This format should certainly be less * susceptible to such errors than standard 8-bit encodings, but more * susceptible than straight 16-bit or 32-bit encodings. * @@ -90,363 +90,429 @@ #include "tif_predict.h" #include "zlib.h" +#include #include #include -#include /* Tables for converting to/from 11 bit coded values */ -#define TSIZE 2048 /* decode table size (11-bit tokens) */ -#define TSIZEP1 2049 /* Plus one for slop */ -#define ONE 1250 /* token value of 1.0 exactly */ -#define RATIO 1.004 /* nominal ratio for log part */ +#define TSIZE 2048 /* decode table size (11-bit tokens) */ +#define TSIZEP1 2049 /* Plus one for slop */ +#define ONE 1250 /* token value of 1.0 exactly */ +#define RATIO 1.004 /* nominal ratio for log part */ -#define CODE_MASK 0x7ff /* 11 bits. */ +#define CODE_MASK 0x7ff /* 11 bits. */ -static float Fltsize; -static float LogK1, LogK2; +static float Fltsize; +static float LogK1, LogK2; -#define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); } +#define REPEAT(n, op) \ + { \ + int i; \ + i = n; \ + do \ + { \ + i--; \ + op; \ + } while (i > 0); \ + } -static void -horizontalAccumulateF(uint16 *wp, int n, int stride, float *op, - float *ToLinearF) +static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op, + float *ToLinearF) { - register unsigned int cr, cg, cb, ca, mask; - register float t0, t1, t2, t3; + register unsigned int cr, cg, cb, ca, mask; + register float t0, t1, t2, t3; - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - t0 = ToLinearF[cr = (wp[0] & mask)]; - t1 = ToLinearF[cg = (wp[1] & mask)]; - t2 = ToLinearF[cb = (wp[2] & mask)]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - n -= 3; - while (n > 0) { - wp += 3; - op += 3; - n -= 3; - t0 = ToLinearF[(cr += wp[0]) & mask]; - t1 = ToLinearF[(cg += wp[1]) & mask]; - t2 = ToLinearF[(cb += wp[2]) & mask]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - } - } else if (stride == 4) { - t0 = ToLinearF[cr = (wp[0] & mask)]; - t1 = ToLinearF[cg = (wp[1] & mask)]; - t2 = ToLinearF[cb = (wp[2] & mask)]; - t3 = ToLinearF[ca = (wp[3] & mask)]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - n -= 4; - while (n > 0) { - wp += 4; - op += 4; - n -= 4; - t0 = ToLinearF[(cr += wp[0]) & mask]; - t1 = ToLinearF[(cg += wp[1]) & mask]; - t2 = ToLinearF[(cb += wp[2]) & mask]; - t3 = ToLinearF[(ca += wp[3]) & mask]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - } - } else { - REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++) - n -= stride; - } - } + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + t0 = ToLinearF[cr = (wp[0] & mask)]; + t1 = ToLinearF[cg = (wp[1] & mask)]; + t2 = ToLinearF[cb = (wp[2] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + n -= 3; + while (n > 0) + { + wp += 3; + op += 3; + n -= 3; + t0 = ToLinearF[(cr += wp[0]) & mask]; + t1 = ToLinearF[(cg += wp[1]) & mask]; + t2 = ToLinearF[(cb += wp[2]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + } + } + else if (stride == 4) + { + t0 = ToLinearF[cr = (wp[0] & mask)]; + t1 = ToLinearF[cg = (wp[1] & mask)]; + t2 = ToLinearF[cb = (wp[2] & mask)]; + t3 = ToLinearF[ca = (wp[3] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 4; + while (n > 0) + { + wp += 4; + op += 4; + n -= 4; + t0 = ToLinearF[(cr += wp[0]) & mask]; + t1 = ToLinearF[(cg += wp[1]) & mask]; + t2 = ToLinearF[(cb += wp[2]) & mask]; + t3 = ToLinearF[(ca += wp[3]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } + else + { + REPEAT(stride, *op = ToLinearF[*wp & mask]; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = ToLinearF[*wp & mask]; + wp++; op++) + n -= stride; + } + } } } -static void -horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op, - float *ToLinearF) +static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op, + float *ToLinearF) { - register unsigned int cr, cg, cb, ca, mask; - register float t0, t1, t2, t3; + register unsigned int cr, cg, cb, ca, mask; + register float t0, t1, t2, t3; #define SCALE12 2048.0F -#define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071) +#define CLAMP12(t) (((t) < 3071) ? (uint16_t)(t) : 3071) - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; - t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; - t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - n -= 3; - while (n > 0) { - wp += 3; - op += 3; - n -= 3; - t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; - t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; - t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - } - } else if (stride == 4) { - t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; - t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; - t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; - t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - op[3] = CLAMP12(t3); - n -= 4; - while (n > 0) { - wp += 4; - op += 4; - n -= 4; - t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; - t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; - t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; - t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - op[3] = CLAMP12(t3); - } - } else { - REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12; - *op = CLAMP12(t0); wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12; - *op = CLAMP12(t0); wp++; op++) - n -= stride; - } - } + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; + t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; + t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + n -= 3; + while (n > 0) + { + wp += 3; + op += 3; + n -= 3; + t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; + t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; + t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + } + } + else if (stride == 4) + { + t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; + t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; + t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; + t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + op[3] = CLAMP12(t3); + n -= 4; + while (n > 0) + { + wp += 4; + op += 4; + n -= 4; + t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; + t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; + t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; + t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + op[3] = CLAMP12(t3); + } + } + else + { + REPEAT(stride, t0 = ToLinearF[*wp & mask] * SCALE12; + *op = CLAMP12(t0); wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; + t0 = ToLinearF[wp[stride] & mask] * SCALE12; + *op = CLAMP12(t0); wp++; op++) + n -= stride; + } + } } } -static void -horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op, - uint16 *ToLinear16) -{ - register unsigned int cr, cg, cb, ca, mask; - - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - op[0] = ToLinear16[cr = (wp[0] & mask)]; - op[1] = ToLinear16[cg = (wp[1] & mask)]; - op[2] = ToLinear16[cb = (wp[2] & mask)]; - n -= 3; - while (n > 0) { - wp += 3; - op += 3; - n -= 3; - op[0] = ToLinear16[(cr += wp[0]) & mask]; - op[1] = ToLinear16[(cg += wp[1]) & mask]; - op[2] = ToLinear16[(cb += wp[2]) & mask]; - } - } else if (stride == 4) { - op[0] = ToLinear16[cr = (wp[0] & mask)]; - op[1] = ToLinear16[cg = (wp[1] & mask)]; - op[2] = ToLinear16[cb = (wp[2] & mask)]; - op[3] = ToLinear16[ca = (wp[3] & mask)]; - n -= 4; - while (n > 0) { - wp += 4; - op += 4; - n -= 4; - op[0] = ToLinear16[(cr += wp[0]) & mask]; - op[1] = ToLinear16[(cg += wp[1]) & mask]; - op[2] = ToLinear16[(cb += wp[2]) & mask]; - op[3] = ToLinear16[(ca += wp[3]) & mask]; - } - } else { - REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++) - n -= stride; - } - } - } -} - -/* - * Returns the log encoded 11-bit values with the horizontal - * differencing undone. - */ -static void -horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op) +static void horizontalAccumulate16(uint16_t *wp, int n, int stride, + uint16_t *op, uint16_t *ToLinear16) { register unsigned int cr, cg, cb, ca, mask; - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - op[0] = wp[0]; op[1] = wp[1]; op[2] = wp[2]; - cr = wp[0]; cg = wp[1]; cb = wp[2]; - n -= 3; - while (n > 0) { - wp += 3; - op += 3; - n -= 3; - op[0] = (uint16)((cr += wp[0]) & mask); - op[1] = (uint16)((cg += wp[1]) & mask); - op[2] = (uint16)((cb += wp[2]) & mask); - } - } else if (stride == 4) { - op[0] = wp[0]; op[1] = wp[1]; - op[2] = wp[2]; op[3] = wp[3]; - cr = wp[0]; cg = wp[1]; cb = wp[2]; ca = wp[3]; - n -= 4; - while (n > 0) { - wp += 4; - op += 4; - n -= 4; - op[0] = (uint16)((cr += wp[0]) & mask); - op[1] = (uint16)((cg += wp[1]) & mask); - op[2] = (uint16)((cb += wp[2]) & mask); - op[3] = (uint16)((ca += wp[3]) & mask); - } - } else { - REPEAT(stride, *op = *wp&mask; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = *wp&mask; wp++; op++) - n -= stride; - } - } + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + op[0] = ToLinear16[cr = (wp[0] & mask)]; + op[1] = ToLinear16[cg = (wp[1] & mask)]; + op[2] = ToLinear16[cb = (wp[2] & mask)]; + n -= 3; + while (n > 0) + { + wp += 3; + op += 3; + n -= 3; + op[0] = ToLinear16[(cr += wp[0]) & mask]; + op[1] = ToLinear16[(cg += wp[1]) & mask]; + op[2] = ToLinear16[(cb += wp[2]) & mask]; + } + } + else if (stride == 4) + { + op[0] = ToLinear16[cr = (wp[0] & mask)]; + op[1] = ToLinear16[cg = (wp[1] & mask)]; + op[2] = ToLinear16[cb = (wp[2] & mask)]; + op[3] = ToLinear16[ca = (wp[3] & mask)]; + n -= 4; + while (n > 0) + { + wp += 4; + op += 4; + n -= 4; + op[0] = ToLinear16[(cr += wp[0]) & mask]; + op[1] = ToLinear16[(cg += wp[1]) & mask]; + op[2] = ToLinear16[(cb += wp[2]) & mask]; + op[3] = ToLinear16[(ca += wp[3]) & mask]; + } + } + else + { + REPEAT(stride, *op = ToLinear16[*wp & mask]; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = ToLinear16[*wp & mask]; + wp++; op++) + n -= stride; + } + } } } -static void -horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op, - unsigned char *ToLinear8) +/* + * Returns the log encoded 11-bit values with the horizontal + * differencing undone. + */ +static void horizontalAccumulate11(uint16_t *wp, int n, int stride, + uint16_t *op) { - register unsigned int cr, cg, cb, ca, mask; + register unsigned int cr, cg, cb, ca, mask; - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - op[0] = ToLinear8[cr = (wp[0] & mask)]; - op[1] = ToLinear8[cg = (wp[1] & mask)]; - op[2] = ToLinear8[cb = (wp[2] & mask)]; - n -= 3; - while (n > 0) { - n -= 3; - wp += 3; - op += 3; - op[0] = ToLinear8[(cr += wp[0]) & mask]; - op[1] = ToLinear8[(cg += wp[1]) & mask]; - op[2] = ToLinear8[(cb += wp[2]) & mask]; - } - } else if (stride == 4) { - op[0] = ToLinear8[cr = (wp[0] & mask)]; - op[1] = ToLinear8[cg = (wp[1] & mask)]; - op[2] = ToLinear8[cb = (wp[2] & mask)]; - op[3] = ToLinear8[ca = (wp[3] & mask)]; - n -= 4; - while (n > 0) { - n -= 4; - wp += 4; - op += 4; - op[0] = ToLinear8[(cr += wp[0]) & mask]; - op[1] = ToLinear8[(cg += wp[1]) & mask]; - op[2] = ToLinear8[(cb += wp[2]) & mask]; - op[3] = ToLinear8[(ca += wp[3]) & mask]; - } - } else { - REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) - n -= stride; - } - } + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + op[0] = wp[0]; + op[1] = wp[1]; + op[2] = wp[2]; + cr = wp[0]; + cg = wp[1]; + cb = wp[2]; + n -= 3; + while (n > 0) + { + wp += 3; + op += 3; + n -= 3; + op[0] = (uint16_t)((cr += wp[0]) & mask); + op[1] = (uint16_t)((cg += wp[1]) & mask); + op[2] = (uint16_t)((cb += wp[2]) & mask); + } + } + else if (stride == 4) + { + op[0] = wp[0]; + op[1] = wp[1]; + op[2] = wp[2]; + op[3] = wp[3]; + cr = wp[0]; + cg = wp[1]; + cb = wp[2]; + ca = wp[3]; + n -= 4; + while (n > 0) + { + wp += 4; + op += 4; + n -= 4; + op[0] = (uint16_t)((cr += wp[0]) & mask); + op[1] = (uint16_t)((cg += wp[1]) & mask); + op[2] = (uint16_t)((cb += wp[2]) & mask); + op[3] = (uint16_t)((ca += wp[3]) & mask); + } + } + else + { + REPEAT(stride, *op = *wp & mask; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = *wp & mask; wp++; op++) + n -= stride; + } + } } } - -static void -horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op, - unsigned char *ToLinear8) +static void horizontalAccumulate8(uint16_t *wp, int n, int stride, + unsigned char *op, unsigned char *ToLinear8) { - register unsigned int cr, cg, cb, ca, mask; - register unsigned char t0, t1, t2, t3; + register unsigned int cr, cg, cb, ca, mask; - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - op[0] = 0; - t1 = ToLinear8[cb = (wp[2] & mask)]; - t2 = ToLinear8[cg = (wp[1] & mask)]; - t3 = ToLinear8[cr = (wp[0] & mask)]; - op[1] = t1; - op[2] = t2; - op[3] = t3; - n -= 3; - while (n > 0) { - n -= 3; - wp += 3; - op += 4; - op[0] = 0; - t1 = ToLinear8[(cb += wp[2]) & mask]; - t2 = ToLinear8[(cg += wp[1]) & mask]; - t3 = ToLinear8[(cr += wp[0]) & mask]; - op[1] = t1; - op[2] = t2; - op[3] = t3; - } - } else if (stride == 4) { - t0 = ToLinear8[ca = (wp[3] & mask)]; - t1 = ToLinear8[cb = (wp[2] & mask)]; - t2 = ToLinear8[cg = (wp[1] & mask)]; - t3 = ToLinear8[cr = (wp[0] & mask)]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - n -= 4; - while (n > 0) { - n -= 4; - wp += 4; - op += 4; - t0 = ToLinear8[(ca += wp[3]) & mask]; - t1 = ToLinear8[(cb += wp[2]) & mask]; - t2 = ToLinear8[(cg += wp[1]) & mask]; - t3 = ToLinear8[(cr += wp[0]) & mask]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - } - } else { - REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) - n -= stride; - } - } + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + op[0] = ToLinear8[cr = (wp[0] & mask)]; + op[1] = ToLinear8[cg = (wp[1] & mask)]; + op[2] = ToLinear8[cb = (wp[2] & mask)]; + n -= 3; + while (n > 0) + { + n -= 3; + wp += 3; + op += 3; + op[0] = ToLinear8[(cr += wp[0]) & mask]; + op[1] = ToLinear8[(cg += wp[1]) & mask]; + op[2] = ToLinear8[(cb += wp[2]) & mask]; + } + } + else if (stride == 4) + { + op[0] = ToLinear8[cr = (wp[0] & mask)]; + op[1] = ToLinear8[cg = (wp[1] & mask)]; + op[2] = ToLinear8[cb = (wp[2] & mask)]; + op[3] = ToLinear8[ca = (wp[3] & mask)]; + n -= 4; + while (n > 0) + { + n -= 4; + wp += 4; + op += 4; + op[0] = ToLinear8[(cr += wp[0]) & mask]; + op[1] = ToLinear8[(cg += wp[1]) & mask]; + op[2] = ToLinear8[(cb += wp[2]) & mask]; + op[3] = ToLinear8[(ca += wp[3]) & mask]; + } + } + else + { + REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask]; + wp++; op++) + n -= stride; + } + } + } +} + +static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride, + unsigned char *op, + unsigned char *ToLinear8) +{ + register unsigned int cr, cg, cb, ca, mask; + register unsigned char t0, t1, t2, t3; + + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + op[0] = 0; + t1 = ToLinear8[cb = (wp[2] & mask)]; + t2 = ToLinear8[cg = (wp[1] & mask)]; + t3 = ToLinear8[cr = (wp[0] & mask)]; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 3; + while (n > 0) + { + n -= 3; + wp += 3; + op += 4; + op[0] = 0; + t1 = ToLinear8[(cb += wp[2]) & mask]; + t2 = ToLinear8[(cg += wp[1]) & mask]; + t3 = ToLinear8[(cr += wp[0]) & mask]; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } + else if (stride == 4) + { + t0 = ToLinear8[ca = (wp[3] & mask)]; + t1 = ToLinear8[cb = (wp[2] & mask)]; + t2 = ToLinear8[cg = (wp[1] & mask)]; + t3 = ToLinear8[cr = (wp[0] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 4; + while (n > 0) + { + n -= 4; + wp += 4; + op += 4; + t0 = ToLinear8[(ca += wp[3]) & mask]; + t1 = ToLinear8[(cb += wp[2]) & mask]; + t2 = ToLinear8[(cg += wp[1]) & mask]; + t3 = ToLinear8[(cr += wp[0]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } + else + { + REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask]; + wp++; op++) + n -= stride; + } + } } } @@ -454,110 +520,121 @@ horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op, * State block for each open TIFF * file using PixarLog compression/decompression. */ -typedef struct { - TIFFPredictorState predict; - z_stream stream; - tmsize_t tbuf_size; /* only set/used on reading for now */ - uint16 *tbuf; - uint16 stride; - int state; - int user_datafmt; - int quality; +typedef struct +{ + TIFFPredictorState predict; + z_stream stream; + tmsize_t tbuf_size; /* only set/used on reading for now */ + uint16_t *tbuf; + uint16_t stride; + int state; + int user_datafmt; + int quality; #define PLSTATE_INIT 1 - TIFFVSetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVSetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + + float *ToLinearF; + uint16_t *ToLinear16; + unsigned char *ToLinear8; + uint16_t *FromLT2; + uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */ + uint16_t *From8; - float *ToLinearF; - uint16 *ToLinear16; - unsigned char *ToLinear8; - uint16 *FromLT2; - uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ - uint16 *From8; - } PixarLogState; -static int -PixarLogMakeTables(PixarLogState *sp) +static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp) { -/* - * We make several tables here to convert between various external - * representations (float, 16-bit, and 8-bit) and the internal - * 11-bit companded representation. The 11-bit representation has two - * distinct regions. A linear bottom end up through .018316 in steps - * of about .000073, and a region of constant ratio up to about 25. - * These floating point numbers are stored in the main table ToLinearF. - * All other tables are derived from this one. The tables (and the - * ratios) are continuous at the internal seam. - */ + /* + * We make several tables here to convert between various external + * representations (float, 16-bit, and 8-bit) and the internal + * 11-bit companded representation. The 11-bit representation has two + * distinct regions. A linear bottom end up through .018316 in steps + * of about .000073, and a region of constant ratio up to about 25. + * These floating point numbers are stored in the main table ToLinearF. + * All other tables are derived from this one. The tables (and the + * ratios) are continuous at the internal seam. + */ - int nlin, lt2size; - int i, j; - double b, c, linstep, v; + int nlin, lt2size; + int i, j; + double b, c, linstep, v; float *ToLinearF; - uint16 *ToLinear16; + uint16_t *ToLinear16; unsigned char *ToLinear8; - uint16 *FromLT2; - uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ - uint16 *From8; + uint16_t *FromLT2; + uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */ + uint16_t *From8; - c = log(RATIO); - nlin = (int)(1./c); /* nlin must be an integer */ - c = 1./nlin; - b = exp(-c*ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */ - linstep = b*c*exp(1.); + c = log(RATIO); + nlin = (int)(1. / c); /* nlin must be an integer */ + c = 1. / nlin; + b = exp(-c * ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */ + linstep = b * c * exp(1.); - LogK1 = (float)(1./c); /* if (v >= 2) token = k1*log(v*k2) */ - LogK2 = (float)(1./b); - lt2size = (int)(2./linstep) + 1; - FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16)); - From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16)); - From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16)); - ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float)); - ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16)); - ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char)); - if (FromLT2 == NULL || From14 == NULL || From8 == NULL || - ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) { - if (FromLT2) _TIFFfree(FromLT2); - if (From14) _TIFFfree(From14); - if (From8) _TIFFfree(From8); - if (ToLinearF) _TIFFfree(ToLinearF); - if (ToLinear16) _TIFFfree(ToLinear16); - if (ToLinear8) _TIFFfree(ToLinear8); - sp->FromLT2 = NULL; - sp->From14 = NULL; - sp->From8 = NULL; - sp->ToLinearF = NULL; - sp->ToLinear16 = NULL; - sp->ToLinear8 = NULL; - return 0; + LogK1 = (float)(1. / c); /* if (v >= 2) token = k1*log(v*k2) */ + LogK2 = (float)(1. / b); + lt2size = (int)(2. / linstep) + 1; + FromLT2 = (uint16_t *)_TIFFmallocExt(tif, lt2size * sizeof(uint16_t)); + From14 = (uint16_t *)_TIFFmallocExt(tif, 16384 * sizeof(uint16_t)); + From8 = (uint16_t *)_TIFFmallocExt(tif, 256 * sizeof(uint16_t)); + ToLinearF = (float *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(float)); + ToLinear16 = (uint16_t *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(uint16_t)); + ToLinear8 = + (unsigned char *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(unsigned char)); + if (FromLT2 == NULL || From14 == NULL || From8 == NULL || + ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) + { + if (FromLT2) + _TIFFfreeExt(tif, FromLT2); + if (From14) + _TIFFfreeExt(tif, From14); + if (From8) + _TIFFfreeExt(tif, From8); + if (ToLinearF) + _TIFFfreeExt(tif, ToLinearF); + if (ToLinear16) + _TIFFfreeExt(tif, ToLinear16); + if (ToLinear8) + _TIFFfreeExt(tif, ToLinear8); + sp->FromLT2 = NULL; + sp->From14 = NULL; + sp->From8 = NULL; + sp->ToLinearF = NULL; + sp->ToLinear16 = NULL; + sp->ToLinear8 = NULL; + return 0; } j = 0; - for (i = 0; i < nlin; i++) { - v = i * linstep; - ToLinearF[j++] = (float)v; + for (i = 0; i < nlin; i++) + { + v = i * linstep; + ToLinearF[j++] = (float)v; } for (i = nlin; i < TSIZE; i++) - ToLinearF[j++] = (float)(b*exp(c*i)); + ToLinearF[j++] = (float)(b * exp(c * i)); ToLinearF[2048] = ToLinearF[2047]; - for (i = 0; i < TSIZEP1; i++) { - v = ToLinearF[i]*65535.0 + 0.5; - ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v; - v = ToLinearF[i]*255.0 + 0.5; - ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v; + for (i = 0; i < TSIZEP1; i++) + { + v = ToLinearF[i] * 65535.0 + 0.5; + ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16_t)v; + v = ToLinearF[i] * 255.0 + 0.5; + ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v; } j = 0; - for (i = 0; i < lt2size; i++) { - if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1]) - j++; - FromLT2[i] = (uint16)j; + for (i = 0; i < lt2size; i++) + { + if ((i * linstep) * (i * linstep) > ToLinearF[j] * ToLinearF[j + 1]) + j++; + FromLT2[i] = (uint16_t)j; } /* @@ -566,20 +643,22 @@ PixarLogMakeTables(PixarLogState *sp) * saves a little table space. */ j = 0; - for (i = 0; i < 16384; i++) { - while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1]) - j++; - From14[i] = (uint16)j; + for (i = 0; i < 16384; i++) + { + while ((i / 16383.) * (i / 16383.) > ToLinearF[j] * ToLinearF[j + 1]) + j++; + From14[i] = (uint16_t)j; } j = 0; - for (i = 0; i < 256; i++) { - while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1]) - j++; - From8[i] = (uint16)j; + for (i = 0; i < 256; i++) + { + while ((i / 255.) * (i / 255.) > ToLinearF[j] * ToLinearF[j + 1]) + j++; + From8[i] = (uint16_t)j; } - Fltsize = (float)(lt2size/2); + Fltsize = (float)(lt2size / 2); sp->ToLinearF = ToLinearF; sp->ToLinear16 = ToLinear16; @@ -591,622 +670,727 @@ PixarLogMakeTables(PixarLogState *sp) return 1; } -#define DecoderState(tif) ((PixarLogState*) (tif)->tif_data) -#define EncoderState(tif) ((PixarLogState*) (tif)->tif_data) +#define DecoderState(tif) ((PixarLogState *)(tif)->tif_data) +#define EncoderState(tif) ((PixarLogState *)(tif)->tif_data) -static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); -static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); +static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -#define PIXARLOGDATAFMT_UNKNOWN -1 +#define PIXARLOGDATAFMT_UNKNOWN -1 -static int -PixarLogGuessDataFmt(TIFFDirectory *td) +static int PixarLogGuessDataFmt(TIFFDirectory *td) { - int guess = PIXARLOGDATAFMT_UNKNOWN; - int format = td->td_sampleformat; + int guess = PIXARLOGDATAFMT_UNKNOWN; + int format = td->td_sampleformat; - /* If the user didn't tell us his datafmt, - * take our best guess from the bitspersample. - */ - switch (td->td_bitspersample) { - case 32: - if (format == SAMPLEFORMAT_IEEEFP) - guess = PIXARLOGDATAFMT_FLOAT; - break; - case 16: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) - guess = PIXARLOGDATAFMT_16BIT; - break; - case 12: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT) - guess = PIXARLOGDATAFMT_12BITPICIO; - break; - case 11: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) - guess = PIXARLOGDATAFMT_11BITLOG; - break; - case 8: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) - guess = PIXARLOGDATAFMT_8BIT; - break; - } + /* If the user didn't tell us his datafmt, + * take our best guess from the bitspersample. + */ + switch (td->td_bitspersample) + { + case 32: + if (format == SAMPLEFORMAT_IEEEFP) + guess = PIXARLOGDATAFMT_FLOAT; + break; + case 16: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_16BIT; + break; + case 12: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT) + guess = PIXARLOGDATAFMT_12BITPICIO; + break; + case 11: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_11BITLOG; + break; + case 8: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_8BIT; + break; + } - return guess; + return guess; } -static tmsize_t -multiply_ms(tmsize_t m1, tmsize_t m2) +static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { - return _TIFFMultiplySSize(NULL, m1, m2, NULL); + return _TIFFMultiplySSize(NULL, m1, m2, NULL); } -static tmsize_t -add_ms(tmsize_t m1, tmsize_t m2) +static tmsize_t add_ms(tmsize_t m1, tmsize_t m2) { - assert(m1 >= 0 && m2 >= 0); - /* if either input is zero, assume overflow already occurred */ - if (m1 == 0 || m2 == 0) - return 0; - else if (m1 > TIFF_TMSIZE_T_MAX - m2) - return 0; + assert(m1 >= 0 && m2 >= 0); + /* if either input is zero, assume overflow already occurred */ + if (m1 == 0 || m2 == 0) + return 0; + else if (m1 > TIFF_TMSIZE_T_MAX - m2) + return 0; - return m1 + m2; + return m1 + m2; } -static int -PixarLogFixupTags(TIFF* tif) +static int PixarLogFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } -static int -PixarLogSetupDecode(TIFF* tif) +static int PixarLogSetupDecode(TIFF *tif) { - static const char module[] = "PixarLogSetupDecode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState* sp = DecoderState(tif); - tmsize_t tbuf_size; - uint32 strip_height; + static const char module[] = "PixarLogSetupDecode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = DecoderState(tif); + tmsize_t tbuf_size; + uint32_t strip_height; - assert(sp != NULL); + assert(sp != NULL); - /* This function can possibly be called several times by */ - /* PredictorSetupDecode() if this function succeeds but */ - /* PredictorSetup() fails */ - if( (sp->state & PLSTATE_INIT) != 0 ) - return 1; + /* This function can possibly be called several times by */ + /* PredictorSetupDecode() if this function succeeds but */ + /* PredictorSetup() fails */ + if ((sp->state & PLSTATE_INIT) != 0) + return 1; - strip_height = td->td_rowsperstrip; - if( strip_height > td->td_imagelength ) - strip_height = td->td_imagelength; + strip_height = td->td_rowsperstrip; + if (strip_height > td->td_imagelength) + strip_height = td->td_imagelength; - /* Make sure no byte swapping happens on the data - * after decompression. */ - tif->tif_postdecode = _TIFFNoPostDecode; + /* Make sure no byte swapping happens on the data + * after decompression. */ + tif->tif_postdecode = _TIFFNoPostDecode; - /* for some reason, we can't do this in TIFFInitPixarLog */ + /* for some reason, we can't do this in TIFFInitPixarLog */ - sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? - td->td_samplesperpixel : 1); - tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), - strip_height), sizeof(uint16)); - /* add one more stride in case input ends mid-stride */ - tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride); - if (tbuf_size == 0) - return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ - sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); - if (sp->tbuf == NULL) - return (0); - sp->tbuf_size = tbuf_size; - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) - sp->user_datafmt = PixarLogGuessDataFmt(td); - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { - _TIFFfree(sp->tbuf); - sp->tbuf = NULL; - sp->tbuf_size = 0; - TIFFErrorExt(tif->tif_clientdata, module, - "PixarLog compression can't handle bits depth/data format combination (depth: %d)", - td->td_bitspersample); - return (0); - } + sp->stride = + (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel + : 1); + tbuf_size = multiply_ms( + multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), strip_height), + sizeof(uint16_t)); + /* add one more stride in case input ends mid-stride */ + tbuf_size = add_ms(tbuf_size, sizeof(uint16_t) * sp->stride); + if (tbuf_size == 0) + return (0); /* TODO: this is an error return without error report + through TIFFErrorExt */ + sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size); + if (sp->tbuf == NULL) + return (0); + sp->tbuf_size = tbuf_size; + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + sp->user_datafmt = PixarLogGuessDataFmt(td); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + { + _TIFFfreeExt(tif, sp->tbuf); + sp->tbuf = NULL; + sp->tbuf_size = 0; + TIFFErrorExtR(tif, module, + "PixarLog compression can't handle bits depth/data " + "format combination (depth: %" PRIu16 ")", + td->td_bitspersample); + return (0); + } - if (inflateInit(&sp->stream) != Z_OK) { - _TIFFfree(sp->tbuf); - sp->tbuf = NULL; - sp->tbuf_size = 0; - TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } else { - sp->state |= PLSTATE_INIT; - return (1); - } + if (inflateInit(&sp->stream) != Z_OK) + { + _TIFFfreeExt(tif, sp->tbuf); + sp->tbuf = NULL; + sp->tbuf_size = 0; + TIFFErrorExtR(tif, module, "%s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + else + { + sp->state |= PLSTATE_INIT; + return (1); + } } /* * Setup state for decoding a strip. */ -static int -PixarLogPreDecode(TIFF* tif, uint16 s) +static int PixarLogPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "PixarLogPreDecode"; - PixarLogState* sp = DecoderState(tif); + static const char module[] = "PixarLogPreDecode"; + PixarLogState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); - sp->stream.next_in = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_in = (uInt) tif->tif_rawcc; - if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) - { - TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); - return (0); - } - return (inflateReset(&sp->stream) == Z_OK); + (void)s; + assert(sp != NULL); + sp->stream.next_in = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_in = (uInt)tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) + { + TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); + return (0); + } + return (inflateReset(&sp->stream) == Z_OK); } -static int -PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "PixarLogDecode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState* sp = DecoderState(tif); - tmsize_t i; - tmsize_t nsamples; - int llen; - uint16 *up; + static const char module[] = "PixarLogDecode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = DecoderState(tif); + tmsize_t i; + tmsize_t nsamples; + int llen; + uint16_t *up; - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_FLOAT: - nsamples = occ / sizeof(float); /* XXX float == 32 bits */ - break; - case PIXARLOGDATAFMT_16BIT: - case PIXARLOGDATAFMT_12BITPICIO: - case PIXARLOGDATAFMT_11BITLOG: - nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */ - break; - case PIXARLOGDATAFMT_8BIT: - case PIXARLOGDATAFMT_8BITABGR: - nsamples = occ; - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "%d bit input not supported in PixarLog", - td->td_bitspersample); - return 0; - } + switch (sp->user_datafmt) + { + case PIXARLOGDATAFMT_FLOAT: + nsamples = occ / sizeof(float); /* XXX float == 32 bits */ + break; + case PIXARLOGDATAFMT_16BIT: + case PIXARLOGDATAFMT_12BITPICIO: + case PIXARLOGDATAFMT_11BITLOG: + nsamples = occ / sizeof(uint16_t); /* XXX uint16_t == 16 bits */ + break; + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + nsamples = occ; + break; + default: + TIFFErrorExtR(tif, module, + "%" PRIu16 " bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } - llen = sp->stride * td->td_imagewidth; + llen = sp->stride * td->td_imagewidth; - (void) s; - assert(sp != NULL); + (void)s; + assert(sp != NULL); - sp->stream.next_in = tif->tif_rawcp; - sp->stream.avail_in = (uInt) tif->tif_rawcc; + sp->stream.next_in = tif->tif_rawcp; + sp->stream.avail_in = (uInt)tif->tif_rawcc; - sp->stream.next_out = (unsigned char *) sp->tbuf; - assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16)); - if (sp->stream.avail_out != nsamples * sizeof(uint16)) - { - TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); - return (0); - } - /* Check that we will not fill more than what was allocated */ - if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size) - { - TIFFErrorExt(tif->tif_clientdata, module, "sp->stream.avail_out > sp->tbuf_size"); - return (0); - } - do { - int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); - if (state == Z_STREAM_END) { - break; /* XXX */ - } - if (state == Z_DATA_ERROR) { - TIFFErrorExt(tif->tif_clientdata, module, - "Decoding error at scanline %lu, %s", - (unsigned long) tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - if (state != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - } while (sp->stream.avail_out > 0); + sp->stream.next_out = (unsigned char *)sp->tbuf; + assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_out = (uInt)(nsamples * sizeof(uint16_t)); + if (sp->stream.avail_out != nsamples * sizeof(uint16_t)) + { + TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); + return (0); + } + /* Check that we will not fill more than what was allocated */ + if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size) + { + TIFFErrorExtR(tif, module, "sp->stream.avail_out > sp->tbuf_size"); + return (0); + } + do + { + int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); + if (state == Z_STREAM_END) + { + break; /* XXX */ + } + if (state == Z_DATA_ERROR) + { + TIFFErrorExtR( + tif, module, "Decoding error at scanline %" PRIu32 ", %s", + tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + if (state != Z_OK) + { + TIFFErrorExtR(tif, module, "ZLib error: %s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + } while (sp->stream.avail_out > 0); - /* hopefully, we got all the bytes we needed */ - if (sp->stream.avail_out != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", - (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out); - return (0); - } + /* hopefully, we got all the bytes we needed */ + if (sp->stream.avail_out != 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %" PRIu32 + " (short %u bytes)", + tif->tif_row, sp->stream.avail_out); + return (0); + } - tif->tif_rawcp = sp->stream.next_in; - tif->tif_rawcc = sp->stream.avail_in; + tif->tif_rawcp = sp->stream.next_in; + tif->tif_rawcc = sp->stream.avail_in; - up = sp->tbuf; - /* Swap bytes in the data if from a different endian machine. */ - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfShort(up, nsamples); + up = sp->tbuf; + /* Swap bytes in the data if from a different endian machine. */ + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort(up, nsamples); - /* - * if llen is not an exact multiple of nsamples, the decode operation - * may overflow the output buffer, so truncate it enough to prevent - * that but still salvage as much data as possible. - */ - if (nsamples % llen) { - TIFFWarningExt(tif->tif_clientdata, module, - "stride %lu is not a multiple of sample count, " - "%lu, data truncated.", (unsigned long) llen, (unsigned long) nsamples); - nsamples -= nsamples % llen; - } + /* + * if llen is not an exact multiple of nsamples, the decode operation + * may overflow the output buffer, so truncate it enough to prevent + * that but still salvage as much data as possible. + */ + if (nsamples % llen) + { + TIFFWarningExtR(tif, module, + "stride %d is not a multiple of sample count, " + "%" TIFF_SSIZE_FORMAT ", data truncated.", + llen, nsamples); + nsamples -= nsamples % llen; + } - for (i = 0; i < nsamples; i += llen, up += llen) { - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_FLOAT: - horizontalAccumulateF(up, llen, sp->stride, - (float *)op, sp->ToLinearF); - op += llen * sizeof(float); - break; - case PIXARLOGDATAFMT_16BIT: - horizontalAccumulate16(up, llen, sp->stride, - (uint16 *)op, sp->ToLinear16); - op += llen * sizeof(uint16); - break; - case PIXARLOGDATAFMT_12BITPICIO: - horizontalAccumulate12(up, llen, sp->stride, - (int16 *)op, sp->ToLinearF); - op += llen * sizeof(int16); - break; - case PIXARLOGDATAFMT_11BITLOG: - horizontalAccumulate11(up, llen, sp->stride, - (uint16 *)op); - op += llen * sizeof(uint16); - break; - case PIXARLOGDATAFMT_8BIT: - horizontalAccumulate8(up, llen, sp->stride, - (unsigned char *)op, sp->ToLinear8); - op += llen * sizeof(unsigned char); - break; - case PIXARLOGDATAFMT_8BITABGR: - horizontalAccumulate8abgr(up, llen, sp->stride, - (unsigned char *)op, sp->ToLinear8); - op += llen * sizeof(unsigned char); - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "Unsupported bits/sample: %d", - td->td_bitspersample); - return (0); - } - } + for (i = 0; i < nsamples; i += llen, up += llen) + { + switch (sp->user_datafmt) + { + case PIXARLOGDATAFMT_FLOAT: + horizontalAccumulateF(up, llen, sp->stride, (float *)op, + sp->ToLinearF); + op += llen * sizeof(float); + break; + case PIXARLOGDATAFMT_16BIT: + horizontalAccumulate16(up, llen, sp->stride, (uint16_t *)op, + sp->ToLinear16); + op += llen * sizeof(uint16_t); + break; + case PIXARLOGDATAFMT_12BITPICIO: + horizontalAccumulate12(up, llen, sp->stride, (int16_t *)op, + sp->ToLinearF); + op += llen * sizeof(int16_t); + break; + case PIXARLOGDATAFMT_11BITLOG: + horizontalAccumulate11(up, llen, sp->stride, (uint16_t *)op); + op += llen * sizeof(uint16_t); + break; + case PIXARLOGDATAFMT_8BIT: + horizontalAccumulate8(up, llen, sp->stride, (unsigned char *)op, + sp->ToLinear8); + op += llen * sizeof(unsigned char); + break; + case PIXARLOGDATAFMT_8BITABGR: + horizontalAccumulate8abgr(up, llen, sp->stride, + (unsigned char *)op, sp->ToLinear8); + op += llen * sizeof(unsigned char); + break; + default: + TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16, + td->td_bitspersample); + return (0); + } + } - return (1); + return (1); } -static int -PixarLogSetupEncode(TIFF* tif) +static int PixarLogSetupEncode(TIFF *tif) { - static const char module[] = "PixarLogSetupEncode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState* sp = EncoderState(tif); - tmsize_t tbuf_size; + static const char module[] = "PixarLogSetupEncode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = EncoderState(tif); + tmsize_t tbuf_size; - assert(sp != NULL); + assert(sp != NULL); - /* for some reason, we can't do this in TIFFInitPixarLog */ + /* for some reason, we can't do this in TIFFInitPixarLog */ - sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? - td->td_samplesperpixel : 1); - tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), - td->td_rowsperstrip), sizeof(uint16)); - if (tbuf_size == 0) - return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ - sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); - if (sp->tbuf == NULL) - return (0); - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) - sp->user_datafmt = PixarLogGuessDataFmt(td); - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { - TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample); - return (0); - } + sp->stride = + (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel + : 1); + tbuf_size = + multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), + td->td_rowsperstrip), + sizeof(uint16_t)); + if (tbuf_size == 0) + return (0); /* TODO: this is an error return without error report + through TIFFErrorExt */ + sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size); + if (sp->tbuf == NULL) + return (0); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + sp->user_datafmt = PixarLogGuessDataFmt(td); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + { + TIFFErrorExtR(tif, module, + "PixarLog compression can't handle %" PRIu16 + " bit linear encodings", + td->td_bitspersample); + return (0); + } - if (deflateInit(&sp->stream, sp->quality) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } else { - sp->state |= PLSTATE_INIT; - return (1); - } + if (deflateInit(&sp->stream, sp->quality) != Z_OK) + { + TIFFErrorExtR(tif, module, "%s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + else + { + sp->state |= PLSTATE_INIT; + return (1); + } } /* * Reset encoding state at the start of a strip. */ -static int -PixarLogPreEncode(TIFF* tif, uint16 s) +static int PixarLogPreEncode(TIFF *tif, uint16_t s) { - static const char module[] = "PixarLogPreEncode"; - PixarLogState *sp = EncoderState(tif); + static const char module[] = "PixarLogPreEncode"; + PixarLogState *sp = EncoderState(tif); - (void) s; - assert(sp != NULL); - sp->stream.next_out = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_out = (uInt)tif->tif_rawdatasize; - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) - { - TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); - return (0); - } - return (deflateReset(&sp->stream) == Z_OK); + (void)s; + assert(sp != NULL); + sp->stream.next_out = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_out = (uInt)tif->tif_rawdatasize; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); + return (0); + } + return (deflateReset(&sp->stream) == Z_OK); } -static void -horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2) +static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp, + uint16_t *FromLT2) { - int32 r1, g1, b1, a1, r2, g2, b2, a2, mask; + int32_t r1, g1, b1, a1, r2, g2, b2, a2, mask; float fltsize = Fltsize; -#define CLAMP(v) ( (v<(float)0.) ? 0 \ - : (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \ - : (v>(float)24.2) ? 2047 \ - : LogK1*log(v*LogK2) + 0.5 ) +#define CLAMP(v) \ + ((v < (float)0.) ? 0 \ + : (v < (float)2.) ? FromLT2[(int)(v * fltsize)] \ + : (v > (float)24.2) ? 2047 \ + : LogK1 * log(v * LogK2) + 0.5) mask = CODE_MASK; - if (n >= stride) { - if (stride == 3) { - r2 = wp[0] = (uint16) CLAMP(ip[0]); - g2 = wp[1] = (uint16) CLAMP(ip[1]); - b2 = wp[2] = (uint16) CLAMP(ip[2]); - n -= 3; - while (n > 0) { - n -= 3; - wp += 3; - ip += 3; - r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; - g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; - b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; - } - } else if (stride == 4) { - r2 = wp[0] = (uint16) CLAMP(ip[0]); - g2 = wp[1] = (uint16) CLAMP(ip[1]); - b2 = wp[2] = (uint16) CLAMP(ip[2]); - a2 = wp[3] = (uint16) CLAMP(ip[3]); - n -= 4; - while (n > 0) { - n -= 4; - wp += 4; - ip += 4; - r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; - g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; - b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; - a1 = (int32) CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1; - } - } else { - REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp++; ip++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[0] = (uint16)(((int32)CLAMP(ip[0])-(int32)CLAMP(ip[-stride])) & mask); - wp++; ip++) - n -= stride; + if (n >= stride) + { + if (stride == 3) + { + r2 = wp[0] = (uint16_t)CLAMP(ip[0]); + g2 = wp[1] = (uint16_t)CLAMP(ip[1]); + b2 = wp[2] = (uint16_t)CLAMP(ip[2]); + n -= 3; + while (n > 0) + { + n -= 3; + wp += 3; + ip += 3; + r1 = (int32_t)CLAMP(ip[0]); + wp[0] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = (int32_t)CLAMP(ip[1]); + wp[1] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = (int32_t)CLAMP(ip[2]); + wp[2] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + } + } + else if (stride == 4) + { + r2 = wp[0] = (uint16_t)CLAMP(ip[0]); + g2 = wp[1] = (uint16_t)CLAMP(ip[1]); + b2 = wp[2] = (uint16_t)CLAMP(ip[2]); + a2 = wp[3] = (uint16_t)CLAMP(ip[3]); + n -= 4; + while (n > 0) + { + n -= 4; + wp += 4; + ip += 4; + r1 = (int32_t)CLAMP(ip[0]); + wp[0] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = (int32_t)CLAMP(ip[1]); + wp[1] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = (int32_t)CLAMP(ip[2]); + wp[2] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + a1 = (int32_t)CLAMP(ip[3]); + wp[3] = (uint16_t)((a1 - a2) & mask); + a2 = a1; + } + } + else + { + REPEAT(stride, wp[0] = (uint16_t)CLAMP(ip[0]); wp++; ip++) + n -= stride; + while (n > 0) + { + REPEAT(stride, + wp[0] = (uint16_t)(((int32_t)CLAMP(ip[0]) - + (int32_t)CLAMP(ip[-stride])) & + mask); + wp++; ip++) + n -= stride; + } } - } } } -static void -horizontalDifference16(unsigned short *ip, int n, int stride, - unsigned short *wp, uint16 *From14) +static void horizontalDifference16(unsigned short *ip, int n, int stride, + unsigned short *wp, uint16_t *From14) { - register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + register int r1, g1, b1, a1, r2, g2, b2, a2, mask; /* assumption is unsigned pixel values */ -#undef CLAMP -#define CLAMP(v) From14[(v) >> 2] +#undef CLAMP +#define CLAMP(v) From14[(v) >> 2] mask = CODE_MASK; - if (n >= stride) { - if (stride == 3) { - r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); - n -= 3; - while (n > 0) { - n -= 3; - wp += 3; - ip += 3; - r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; - g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; - b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; - } - } else if (stride == 4) { - r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); - n -= 4; - while (n > 0) { - n -= 4; - wp += 4; - ip += 4; - r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; - g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; - b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; - a1 = CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1; - } - } else { - REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask); - wp++; ip++) - n -= stride; + if (n >= stride) + { + if (stride == 3) + { + r2 = wp[0] = CLAMP(ip[0]); + g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + n -= 3; + while (n > 0) + { + n -= 3; + wp += 3; + ip += 3; + r1 = CLAMP(ip[0]); + wp[0] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = CLAMP(ip[1]); + wp[1] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = CLAMP(ip[2]); + wp[2] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + } + } + else if (stride == 4) + { + r2 = wp[0] = CLAMP(ip[0]); + g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + a2 = wp[3] = CLAMP(ip[3]); + n -= 4; + while (n > 0) + { + n -= 4; + wp += 4; + ip += 4; + r1 = CLAMP(ip[0]); + wp[0] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = CLAMP(ip[1]); + wp[1] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = CLAMP(ip[2]); + wp[2] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + a1 = CLAMP(ip[3]); + wp[3] = (uint16_t)((a1 - a2) & mask); + a2 = a1; + } + } + else + { + REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) + n -= stride; + while (n > 0) + { + REPEAT(stride, + wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) & + mask); + wp++; ip++) + n -= stride; + } } - } } } - -static void -horizontalDifference8(unsigned char *ip, int n, int stride, - unsigned short *wp, uint16 *From8) +static void horizontalDifference8(unsigned char *ip, int n, int stride, + unsigned short *wp, uint16_t *From8) { - register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + register int r1, g1, b1, a1, r2, g2, b2, a2, mask; -#undef CLAMP -#define CLAMP(v) (From8[(v)]) +#undef CLAMP +#define CLAMP(v) (From8[(v)]) mask = CODE_MASK; - if (n >= stride) { - if (stride == 3) { - r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); - n -= 3; - while (n > 0) { - n -= 3; - r1 = CLAMP(ip[3]); wp[3] = (uint16)((r1-r2) & mask); r2 = r1; - g1 = CLAMP(ip[4]); wp[4] = (uint16)((g1-g2) & mask); g2 = g1; - b1 = CLAMP(ip[5]); wp[5] = (uint16)((b1-b2) & mask); b2 = b1; - wp += 3; - ip += 3; - } - } else if (stride == 4) { - r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); - n -= 4; - while (n > 0) { - n -= 4; - r1 = CLAMP(ip[4]); wp[4] = (uint16)((r1-r2) & mask); r2 = r1; - g1 = CLAMP(ip[5]); wp[5] = (uint16)((g1-g2) & mask); g2 = g1; - b1 = CLAMP(ip[6]); wp[6] = (uint16)((b1-b2) & mask); b2 = b1; - a1 = CLAMP(ip[7]); wp[7] = (uint16)((a1-a2) & mask); a2 = a1; - wp += 4; - ip += 4; - } - } else { - REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask); - wp++; ip++) - n -= stride; + if (n >= stride) + { + if (stride == 3) + { + r2 = wp[0] = CLAMP(ip[0]); + g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + n -= 3; + while (n > 0) + { + n -= 3; + r1 = CLAMP(ip[3]); + wp[3] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = CLAMP(ip[4]); + wp[4] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = CLAMP(ip[5]); + wp[5] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + wp += 3; + ip += 3; + } + } + else if (stride == 4) + { + r2 = wp[0] = CLAMP(ip[0]); + g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + a2 = wp[3] = CLAMP(ip[3]); + n -= 4; + while (n > 0) + { + n -= 4; + r1 = CLAMP(ip[4]); + wp[4] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = CLAMP(ip[5]); + wp[5] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = CLAMP(ip[6]); + wp[6] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + a1 = CLAMP(ip[7]); + wp[7] = (uint16_t)((a1 - a2) & mask); + a2 = a1; + wp += 4; + ip += 4; + } + } + else + { + REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) + n -= stride; + while (n > 0) + { + REPEAT(stride, + wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) & + mask); + wp++; ip++) + n -= stride; + } } - } } } /* * Encode a chunk of pixels. */ -static int -PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "PixarLogEncode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState *sp = EncoderState(tif); - tmsize_t i; - tmsize_t n; - int llen; - unsigned short * up; + static const char module[] = "PixarLogEncode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = EncoderState(tif); + tmsize_t i; + tmsize_t n; + int llen; + unsigned short *up; - (void) s; + (void)s; - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_FLOAT: - n = cc / sizeof(float); /* XXX float == 32 bits */ - break; - case PIXARLOGDATAFMT_16BIT: - case PIXARLOGDATAFMT_12BITPICIO: - case PIXARLOGDATAFMT_11BITLOG: - n = cc / sizeof(uint16); /* XXX uint16 == 16 bits */ - break; - case PIXARLOGDATAFMT_8BIT: - case PIXARLOGDATAFMT_8BITABGR: - n = cc; - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "%d bit input not supported in PixarLog", - td->td_bitspersample); - return 0; - } - - llen = sp->stride * td->td_imagewidth; - /* Check against the number of elements (of size uint16) of sp->tbuf */ - if( n > ((tmsize_t)td->td_rowsperstrip * llen) ) + switch (sp->user_datafmt) { - TIFFErrorExt(tif->tif_clientdata, module, - "Too many input bytes provided"); + case PIXARLOGDATAFMT_FLOAT: + n = cc / sizeof(float); /* XXX float == 32 bits */ + break; + case PIXARLOGDATAFMT_16BIT: + case PIXARLOGDATAFMT_12BITPICIO: + case PIXARLOGDATAFMT_11BITLOG: + n = cc / sizeof(uint16_t); /* XXX uint16_t == 16 bits */ + break; + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + n = cc; + break; + default: + TIFFErrorExtR(tif, module, + "%" PRIu16 " bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + + llen = sp->stride * td->td_imagewidth; + /* Check against the number of elements (of size uint16_t) of sp->tbuf */ + if (n > ((tmsize_t)td->td_rowsperstrip * llen)) + { + TIFFErrorExtR(tif, module, "Too many input bytes provided"); return 0; } - for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) { - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_FLOAT: - horizontalDifferenceF((float *)bp, llen, - sp->stride, up, sp->FromLT2); - bp += llen * sizeof(float); - break; - case PIXARLOGDATAFMT_16BIT: - horizontalDifference16((uint16 *)bp, llen, - sp->stride, up, sp->From14); - bp += llen * sizeof(uint16); - break; - case PIXARLOGDATAFMT_8BIT: - horizontalDifference8((unsigned char *)bp, llen, - sp->stride, up, sp->From8); - bp += llen * sizeof(unsigned char); - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "%d bit input not supported in PixarLog", - td->td_bitspersample); - return 0; - } - } - - sp->stream.next_in = (unsigned char *) sp->tbuf; - assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_in = (uInt) (n * sizeof(uint16)); - if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n) - { - TIFFErrorExt(tif->tif_clientdata, module, - "ZLib cannot deal with buffers this size"); - return (0); - } + for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) + { + switch (sp->user_datafmt) + { + case PIXARLOGDATAFMT_FLOAT: + horizontalDifferenceF((float *)bp, llen, sp->stride, up, + sp->FromLT2); + bp += llen * sizeof(float); + break; + case PIXARLOGDATAFMT_16BIT: + horizontalDifference16((uint16_t *)bp, llen, sp->stride, up, + sp->From14); + bp += llen * sizeof(uint16_t); + break; + case PIXARLOGDATAFMT_8BIT: + horizontalDifference8((unsigned char *)bp, llen, sp->stride, up, + sp->From8); + bp += llen * sizeof(unsigned char); + break; + default: + TIFFErrorExtR(tif, module, + "%" PRIu16 " bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + } - do { - if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - if (sp->stream.avail_out == 0) { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ - } - } while (sp->stream.avail_in > 0); - return (1); + sp->stream.next_in = (unsigned char *)sp->tbuf; + assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_in = (uInt)(n * sizeof(uint16_t)); + if ((sp->stream.avail_in / sizeof(uint16_t)) != (uInt)n) + { + TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); + return (0); + } + + do + { + if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) + { + TIFFErrorExtR(tif, module, "Encoder error: %s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + if (sp->stream.avail_out == 0) + { + tif->tif_rawcc = tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (uInt)tif + ->tif_rawdatasize; /* this is a safe typecast, as check is + made already in PixarLogPreEncode */ + } + } while (sp->stream.avail_in > 0); + return (1); } /* @@ -1214,267 +1398,273 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) * string and tacking on an End Of Information code. */ -static int -PixarLogPostEncode(TIFF* tif) +static int PixarLogPostEncode(TIFF *tif) { - static const char module[] = "PixarLogPostEncode"; - PixarLogState *sp = EncoderState(tif); - int state; + static const char module[] = "PixarLogPostEncode"; + PixarLogState *sp = EncoderState(tif); + int state; - sp->stream.avail_in = 0; + sp->stream.avail_in = 0; - do { - state = deflate(&sp->stream, Z_FINISH); - switch (state) { - case Z_STREAM_END: - case Z_OK: - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { - tif->tif_rawcc = - tif->tif_rawdatasize - sp->stream.avail_out; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ - } - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - } while (state != Z_STREAM_END); - return (1); -} - -static void -PixarLogClose(TIFF* tif) -{ - PixarLogState* sp = (PixarLogState*) tif->tif_data; - TIFFDirectory *td = &tif->tif_dir; - - assert(sp != 0); - /* In a really sneaky (and really incorrect, and untruthful, and - * troublesome, and error-prone) maneuver that completely goes against - * the spirit of TIFF, and breaks TIFF, on close, we covertly - * modify both bitspersample and sampleformat in the directory to - * indicate 8-bit linear. This way, the decode "just works" even for - * readers that don't know about PixarLog, or how to set - * the PIXARLOGDATFMT pseudo-tag. - */ - - if (sp->state&PLSTATE_INIT) { - /* We test the state to avoid an issue such as in - * http://bugzilla.maptools.org/show_bug.cgi?id=2604 - * What appends in that case is that the bitspersample is 1 and - * a TransferFunction is set. The size of the TransferFunction - * depends on 1<td_bitspersample = 8; - td->td_sampleformat = SAMPLEFORMAT_UINT; + do + { + state = deflate(&sp->stream, Z_FINISH); + switch (state) + { + case Z_STREAM_END: + case Z_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (uInt)tif->tif_rawdatasize; /* this is a safe typecast, + as check is made already + in PixarLogPreEncode */ + } + break; + default: + TIFFErrorExtR(tif, module, "ZLib error: %s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); } + } while (state != Z_STREAM_END); + return (1); } -static void -PixarLogCleanup(TIFF* tif) +static void PixarLogClose(TIFF *tif) { - PixarLogState* sp = (PixarLogState*) tif->tif_data; + PixarLogState *sp = (PixarLogState *)tif->tif_data; + TIFFDirectory *td = &tif->tif_dir; - assert(sp != 0); + assert(sp != 0); + /* In a really sneaky (and really incorrect, and untruthful, and + * troublesome, and error-prone) maneuver that completely goes against + * the spirit of TIFF, and breaks TIFF, on close, we covertly + * modify both bitspersample and sampleformat in the directory to + * indicate 8-bit linear. This way, the decode "just works" even for + * readers that don't know about PixarLog, or how to set + * the PIXARLOGDATFMT pseudo-tag. + */ - (void)TIFFPredictorCleanup(tif); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->FromLT2) _TIFFfree(sp->FromLT2); - if (sp->From14) _TIFFfree(sp->From14); - if (sp->From8) _TIFFfree(sp->From8); - if (sp->ToLinearF) _TIFFfree(sp->ToLinearF); - if (sp->ToLinear16) _TIFFfree(sp->ToLinear16); - if (sp->ToLinear8) _TIFFfree(sp->ToLinear8); - if (sp->state&PLSTATE_INIT) { - if (tif->tif_mode == O_RDONLY) - inflateEnd(&sp->stream); - else - deflateEnd(&sp->stream); - } - if (sp->tbuf) - _TIFFfree(sp->tbuf); - _TIFFfree(sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); + if (sp->state & PLSTATE_INIT) + { + /* We test the state to avoid an issue such as in + * http://bugzilla.maptools.org/show_bug.cgi?id=2604 + * What appends in that case is that the bitspersample is 1 and + * a TransferFunction is set. The size of the TransferFunction + * depends on 1<td_bitspersample = 8; + td->td_sampleformat = SAMPLEFORMAT_UINT; + } } -static int -PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap) +static void PixarLogCleanup(TIFF *tif) +{ + PixarLogState *sp = (PixarLogState *)tif->tif_data; + + assert(sp != 0); + + (void)TIFFPredictorCleanup(tif); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->FromLT2) + _TIFFfreeExt(tif, sp->FromLT2); + if (sp->From14) + _TIFFfreeExt(tif, sp->From14); + if (sp->From8) + _TIFFfreeExt(tif, sp->From8); + if (sp->ToLinearF) + _TIFFfreeExt(tif, sp->ToLinearF); + if (sp->ToLinear16) + _TIFFfreeExt(tif, sp->ToLinear16); + if (sp->ToLinear8) + _TIFFfreeExt(tif, sp->ToLinear8); + if (sp->state & PLSTATE_INIT) + { + if (tif->tif_mode == O_RDONLY) + inflateEnd(&sp->stream); + else + deflateEnd(&sp->stream); + } + if (sp->tbuf) + _TIFFfreeExt(tif, sp->tbuf); + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static int PixarLogVSetField(TIFF *tif, uint32_t tag, va_list ap) { static const char module[] = "PixarLogVSetField"; PixarLogState *sp = (PixarLogState *)tif->tif_data; int result; - switch (tag) { - case TIFFTAG_PIXARLOGQUALITY: - sp->quality = (int) va_arg(ap, int); - if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) { - if (deflateParams(&sp->stream, - sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - } - return (1); - case TIFFTAG_PIXARLOGDATAFMT: - sp->user_datafmt = (int) va_arg(ap, int); - /* Tweak the TIFF header so that the rest of libtiff knows what - * size of data will be passed between app and library, and - * assume that the app knows what it is doing and is not - * confused by these header manipulations... - */ - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_8BIT: - case PIXARLOGDATAFMT_8BITABGR: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); - break; - case PIXARLOGDATAFMT_11BITLOG: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); - break; - case PIXARLOGDATAFMT_12BITPICIO: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); - break; - case PIXARLOGDATAFMT_16BIT: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); - break; - case PIXARLOGDATAFMT_FLOAT: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); - break; - } - /* - * Must recalculate sizes should bits/sample change. - */ - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); - tif->tif_scanlinesize = TIFFScanlineSize(tif); - result = 1; /* NB: pseudo tag */ - break; - default: - result = (*sp->vsetparent)(tif, tag, ap); + switch (tag) + { + case TIFFTAG_PIXARLOGQUALITY: + sp->quality = (int)va_arg(ap, int); + if (tif->tif_mode != O_RDONLY && (sp->state & PLSTATE_INIT)) + { + if (deflateParams(&sp->stream, sp->quality, + Z_DEFAULT_STRATEGY) != Z_OK) + { + TIFFErrorExtR(tif, module, "ZLib error: %s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + } + return (1); + case TIFFTAG_PIXARLOGDATAFMT: + sp->user_datafmt = (int)va_arg(ap, int); + /* Tweak the TIFF header so that the rest of libtiff knows what + * size of data will be passed between app and library, and + * assume that the app knows what it is doing and is not + * confused by these header manipulations... + */ + switch (sp->user_datafmt) + { + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_11BITLOG: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_12BITPICIO: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); + break; + case PIXARLOGDATAFMT_16BIT: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_FLOAT: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, + SAMPLEFORMAT_IEEEFP); + break; + } + /* + * Must recalculate sizes should bits/sample change. + */ + tif->tif_tilesize = + isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + result = 1; /* NB: pseudo tag */ + break; + default: + result = (*sp->vsetparent)(tif, tag, ap); } return (result); } -static int -PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap) +static int PixarLogVGetField(TIFF *tif, uint32_t tag, va_list ap) { PixarLogState *sp = (PixarLogState *)tif->tif_data; - switch (tag) { - case TIFFTAG_PIXARLOGQUALITY: - *va_arg(ap, int*) = sp->quality; - break; - case TIFFTAG_PIXARLOGDATAFMT: - *va_arg(ap, int*) = sp->user_datafmt; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); + switch (tag) + { + case TIFFTAG_PIXARLOGQUALITY: + *va_arg(ap, int *) = sp->quality; + break; + case TIFFTAG_PIXARLOGDATAFMT: + *va_arg(ap, int *) = sp->user_datafmt; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); } return (1); } static const TIFFField pixarlogFields[] = { - {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, - {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL} -}; + {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, + {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}}; -int -TIFFInitPixarLog(TIFF* tif, int scheme) +int TIFFInitPixarLog(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitPixarLog"; + static const char module[] = "TIFFInitPixarLog"; - PixarLogState* sp; + PixarLogState *sp; - (void)scheme; - assert(scheme == COMPRESSION_PIXARLOG); + (void)scheme; + assert(scheme == COMPRESSION_PIXARLOG); - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, pixarlogFields, - TIFFArrayCount(pixarlogFields))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Merging PixarLog codec-specific tags failed"); - return 0; - } + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, pixarlogFields, TIFFArrayCount(pixarlogFields))) + { + TIFFErrorExtR(tif, module, + "Merging PixarLog codec-specific tags failed"); + return 0; + } - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState)); - if (tif->tif_data == NULL) - goto bad; - sp = (PixarLogState*) tif->tif_data; - _TIFFmemset(sp, 0, sizeof (*sp)); - sp->stream.data_type = Z_BINARY; - sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN; + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(PixarLogState)); + if (tif->tif_data == NULL) + goto bad; + sp = (PixarLogState *)tif->tif_data; + _TIFFmemset(sp, 0, sizeof(*sp)); + sp->stream.data_type = Z_BINARY; + sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN; - /* - * Install codec methods. - */ - tif->tif_fixuptags = PixarLogFixupTags; - tif->tif_setupdecode = PixarLogSetupDecode; - tif->tif_predecode = PixarLogPreDecode; - tif->tif_decoderow = PixarLogDecode; - tif->tif_decodestrip = PixarLogDecode; - tif->tif_decodetile = PixarLogDecode; - tif->tif_setupencode = PixarLogSetupEncode; - tif->tif_preencode = PixarLogPreEncode; - tif->tif_postencode = PixarLogPostEncode; - tif->tif_encoderow = PixarLogEncode; - tif->tif_encodestrip = PixarLogEncode; - tif->tif_encodetile = PixarLogEncode; - tif->tif_close = PixarLogClose; - tif->tif_cleanup = PixarLogCleanup; + /* + * Install codec methods. + */ + tif->tif_fixuptags = PixarLogFixupTags; + tif->tif_setupdecode = PixarLogSetupDecode; + tif->tif_predecode = PixarLogPreDecode; + tif->tif_decoderow = PixarLogDecode; + tif->tif_decodestrip = PixarLogDecode; + tif->tif_decodetile = PixarLogDecode; + tif->tif_setupencode = PixarLogSetupEncode; + tif->tif_preencode = PixarLogPreEncode; + tif->tif_postencode = PixarLogPostEncode; + tif->tif_encoderow = PixarLogEncode; + tif->tif_encodestrip = PixarLogEncode; + tif->tif_encodetile = PixarLogEncode; + tif->tif_close = PixarLogClose; + tif->tif_cleanup = PixarLogCleanup; - /* Override SetField so we can handle our private pseudo-tag */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */ + /* Override SetField so we can handle our private pseudo-tag */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */ - /* Default values for codec-specific fields */ - sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */ - sp->state = 0; + /* Default values for codec-specific fields */ + sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; - /* we don't wish to use the predictor, - * the default is none, which predictor value 1 - */ - (void) TIFFPredictorInit(tif); + /* we don't wish to use the predictor, + * the default is none, which predictor value 1 + */ + (void)TIFFPredictorInit(tif); - /* - * build the companding tables - */ - PixarLogMakeTables(sp); + /* + * build the companding tables + */ + PixarLogMakeTables(tif, sp); - return (1); + return (1); bad: - TIFFErrorExt(tif->tif_clientdata, module, - "No space for PixarLog state block"); - return (0); + TIFFErrorExtR(tif, module, "No space for PixarLog state block"); + return (0); } #endif /* PIXARLOG_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_predict.c b/3rdparty/libtiff/tif_predict.c index c023397459..386b5fe82a 100644 --- a/3rdparty/libtiff/tif_predict.c +++ b/3rdparty/libtiff/tif_predict.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -27,246 +27,309 @@ * * Predictor Tag Support (used by multiple codecs). */ -#include "tiffiop.h" #include "tif_predict.h" +#include "tiffiop.h" -#define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data) +#define PredictorState(tif) ((TIFFPredictorState *)(tif)->tif_data) -static int horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc); -static int horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); -static int horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); -static int swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); -static int swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); -static int horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc); -static int horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc); -static int horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc); -static int swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc); -static int swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc); -static int fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc); -static int fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc); -static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); -static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); -static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); -static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s); +static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0, + uint16_t s); +static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0, + uint16_t s); +static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0, + uint16_t s); -static int -PredictorSetup(TIFF* tif) +static int PredictorSetup(TIFF *tif) { - static const char module[] = "PredictorSetup"; + static const char module[] = "PredictorSetup"; - TIFFPredictorState* sp = PredictorState(tif); - TIFFDirectory* td = &tif->tif_dir; + TIFFPredictorState *sp = PredictorState(tif); + TIFFDirectory *td = &tif->tif_dir; - switch (sp->predictor) /* no differencing */ - { - case PREDICTOR_NONE: - return 1; - case PREDICTOR_HORIZONTAL: - if (td->td_bitspersample != 8 - && td->td_bitspersample != 16 - && td->td_bitspersample != 32) { - TIFFErrorExt(tif->tif_clientdata, module, - "Horizontal differencing \"Predictor\" not supported with %d-bit samples", - td->td_bitspersample); - return 0; - } - break; - case PREDICTOR_FLOATINGPOINT: - if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) { - TIFFErrorExt(tif->tif_clientdata, module, - "Floating point \"Predictor\" not supported with %d data format", - td->td_sampleformat); - return 0; - } - if (td->td_bitspersample != 16 - && td->td_bitspersample != 24 - && td->td_bitspersample != 32 - && td->td_bitspersample != 64) { /* Should 64 be allowed? */ - TIFFErrorExt(tif->tif_clientdata, module, - "Floating point \"Predictor\" not supported with %d-bit samples", - td->td_bitspersample); - return 0; - } - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "\"Predictor\" value %d not supported", - sp->predictor); - return 0; - } - sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? - td->td_samplesperpixel : 1); - /* - * Calculate the scanline/tile-width size in bytes. - */ - if (isTiled(tif)) - sp->rowsize = TIFFTileRowSize(tif); - else - sp->rowsize = TIFFScanlineSize(tif); - if (sp->rowsize == 0) - return 0; - - return 1; -} - -static int -PredictorSetupDecode(TIFF* tif) -{ - TIFFPredictorState* sp = PredictorState(tif); - TIFFDirectory* td = &tif->tif_dir; - - /* Note: when PredictorSetup() fails, the effets of setupdecode() */ - /* will not be "canceled" so setupdecode() might be robust to */ - /* be called several times. */ - if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) - return 0; - - if (sp->predictor == 2) { - switch (td->td_bitspersample) { - case 8: sp->decodepfunc = horAcc8; break; - case 16: sp->decodepfunc = horAcc16; break; - case 32: sp->decodepfunc = horAcc32; break; - } - /* - * Override default decoding method with one that does the - * predictor stuff. - */ - if( tif->tif_decoderow != PredictorDecodeRow ) - { - sp->decoderow = tif->tif_decoderow; - tif->tif_decoderow = PredictorDecodeRow; - sp->decodestrip = tif->tif_decodestrip; - tif->tif_decodestrip = PredictorDecodeTile; - sp->decodetile = tif->tif_decodetile; - tif->tif_decodetile = PredictorDecodeTile; - } - - /* - * If the data is horizontally differenced 16-bit data that - * requires byte-swapping, then it must be byte swapped before - * the accumulation step. We do this with a special-purpose - * routine and override the normal post decoding logic that - * the library setup when the directory was read. - */ - if (tif->tif_flags & TIFF_SWAB) { - if (sp->decodepfunc == horAcc16) { - sp->decodepfunc = swabHorAcc16; - tif->tif_postdecode = _TIFFNoPostDecode; - } else if (sp->decodepfunc == horAcc32) { - sp->decodepfunc = swabHorAcc32; - tif->tif_postdecode = _TIFFNoPostDecode; + switch (sp->predictor) /* no differencing */ + { + case PREDICTOR_NONE: + return 1; + case PREDICTOR_HORIZONTAL: + if (td->td_bitspersample != 8 && td->td_bitspersample != 16 && + td->td_bitspersample != 32 && td->td_bitspersample != 64) + { + TIFFErrorExtR(tif, module, + "Horizontal differencing \"Predictor\" not " + "supported with %" PRIu16 "-bit samples", + td->td_bitspersample); + return 0; } - } - } + break; + case PREDICTOR_FLOATINGPOINT: + if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) + { + TIFFErrorExtR( + tif, module, + "Floating point \"Predictor\" not supported with %" PRIu16 + " data format", + td->td_sampleformat); + return 0; + } + if (td->td_bitspersample != 16 && td->td_bitspersample != 24 && + td->td_bitspersample != 32 && td->td_bitspersample != 64) + { /* Should 64 be allowed? */ + TIFFErrorExtR( + tif, module, + "Floating point \"Predictor\" not supported with %" PRIu16 + "-bit samples", + td->td_bitspersample); + return 0; + } + break; + default: + TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported", + sp->predictor); + return 0; + } + sp->stride = + (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel + : 1); + /* + * Calculate the scanline/tile-width size in bytes. + */ + if (isTiled(tif)) + sp->rowsize = TIFFTileRowSize(tif); + else + sp->rowsize = TIFFScanlineSize(tif); + if (sp->rowsize == 0) + return 0; - else if (sp->predictor == 3) { - sp->decodepfunc = fpAcc; - /* - * Override default decoding method with one that does the - * predictor stuff. - */ - if( tif->tif_decoderow != PredictorDecodeRow ) - { - sp->decoderow = tif->tif_decoderow; - tif->tif_decoderow = PredictorDecodeRow; - sp->decodestrip = tif->tif_decodestrip; - tif->tif_decodestrip = PredictorDecodeTile; - sp->decodetile = tif->tif_decodetile; - tif->tif_decodetile = PredictorDecodeTile; - } - /* - * The data should not be swapped outside of the floating - * point predictor, the accumulation routine should return - * byres in the native order. - */ - if (tif->tif_flags & TIFF_SWAB) { - tif->tif_postdecode = _TIFFNoPostDecode; - } - /* - * Allocate buffer to keep the decoded bytes before - * rearranging in the right order - */ - } - - return 1; + return 1; } -static int -PredictorSetupEncode(TIFF* tif) +static int PredictorSetupDecode(TIFF *tif) { - TIFFPredictorState* sp = PredictorState(tif); - TIFFDirectory* td = &tif->tif_dir; + TIFFPredictorState *sp = PredictorState(tif); + TIFFDirectory *td = &tif->tif_dir; - if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) - return 0; + /* Note: when PredictorSetup() fails, the effets of setupdecode() */ + /* will not be "canceled" so setupdecode() might be robust to */ + /* be called several times. */ + if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) + return 0; - if (sp->predictor == 2) { - switch (td->td_bitspersample) { - case 8: sp->encodepfunc = horDiff8; break; - case 16: sp->encodepfunc = horDiff16; break; - case 32: sp->encodepfunc = horDiff32; break; - } - /* - * Override default encoding method with one that does the - * predictor stuff. - */ - if( tif->tif_encoderow != PredictorEncodeRow ) - { - sp->encoderow = tif->tif_encoderow; - tif->tif_encoderow = PredictorEncodeRow; - sp->encodestrip = tif->tif_encodestrip; - tif->tif_encodestrip = PredictorEncodeTile; - sp->encodetile = tif->tif_encodetile; - tif->tif_encodetile = PredictorEncodeTile; - } - - /* - * If the data is horizontally differenced 16-bit data that - * requires byte-swapping, then it must be byte swapped after - * the differentiation step. We do this with a special-purpose - * routine and override the normal post decoding logic that - * the library setup when the directory was read. - */ - if (tif->tif_flags & TIFF_SWAB) { - if (sp->encodepfunc == horDiff16) { - sp->encodepfunc = swabHorDiff16; - tif->tif_postdecode = _TIFFNoPostDecode; - } else if (sp->encodepfunc == horDiff32) { - sp->encodepfunc = swabHorDiff32; - tif->tif_postdecode = _TIFFNoPostDecode; - } - } + if (sp->predictor == 2) + { + switch (td->td_bitspersample) + { + case 8: + sp->decodepfunc = horAcc8; + break; + case 16: + sp->decodepfunc = horAcc16; + break; + case 32: + sp->decodepfunc = horAcc32; + break; + case 64: + sp->decodepfunc = horAcc64; + break; + } + /* + * Override default decoding method with one that does the + * predictor stuff. + */ + if (tif->tif_decoderow != PredictorDecodeRow) + { + sp->decoderow = tif->tif_decoderow; + tif->tif_decoderow = PredictorDecodeRow; + sp->decodestrip = tif->tif_decodestrip; + tif->tif_decodestrip = PredictorDecodeTile; + sp->decodetile = tif->tif_decodetile; + tif->tif_decodetile = PredictorDecodeTile; } - else if (sp->predictor == 3) { - sp->encodepfunc = fpDiff; - /* - * Override default encoding method with one that does the - * predictor stuff. - */ - if( tif->tif_encoderow != PredictorEncodeRow ) - { - sp->encoderow = tif->tif_encoderow; - tif->tif_encoderow = PredictorEncodeRow; - sp->encodestrip = tif->tif_encodestrip; - tif->tif_encodestrip = PredictorEncodeTile; - sp->encodetile = tif->tif_encodetile; - tif->tif_encodetile = PredictorEncodeTile; - } - } + /* + * If the data is horizontally differenced 16-bit data that + * requires byte-swapping, then it must be byte swapped before + * the accumulation step. We do this with a special-purpose + * routine and override the normal post decoding logic that + * the library setup when the directory was read. + */ + if (tif->tif_flags & TIFF_SWAB) + { + if (sp->decodepfunc == horAcc16) + { + sp->decodepfunc = swabHorAcc16; + tif->tif_postdecode = _TIFFNoPostDecode; + } + else if (sp->decodepfunc == horAcc32) + { + sp->decodepfunc = swabHorAcc32; + tif->tif_postdecode = _TIFFNoPostDecode; + } + else if (sp->decodepfunc == horAcc64) + { + sp->decodepfunc = swabHorAcc64; + tif->tif_postdecode = _TIFFNoPostDecode; + } + } + } - return 1; + else if (sp->predictor == 3) + { + sp->decodepfunc = fpAcc; + /* + * Override default decoding method with one that does the + * predictor stuff. + */ + if (tif->tif_decoderow != PredictorDecodeRow) + { + sp->decoderow = tif->tif_decoderow; + tif->tif_decoderow = PredictorDecodeRow; + sp->decodestrip = tif->tif_decodestrip; + tif->tif_decodestrip = PredictorDecodeTile; + sp->decodetile = tif->tif_decodetile; + tif->tif_decodetile = PredictorDecodeTile; + } + /* + * The data should not be swapped outside of the floating + * point predictor, the accumulation routine should return + * byres in the native order. + */ + if (tif->tif_flags & TIFF_SWAB) + { + tif->tif_postdecode = _TIFFNoPostDecode; + } + /* + * Allocate buffer to keep the decoded bytes before + * rearranging in the right order + */ + } + + return 1; } -#define REPEAT4(n, op) \ - switch (n) { \ - default: { \ - tmsize_t i; for (i = n-4; i > 0; i--) { op; } } /*-fallthrough*/ \ - case 4: op; /*-fallthrough*/ \ - case 3: op; /*-fallthrough*/ \ - case 2: op; /*-fallthrough*/ \ - case 1: op; /*-fallthrough*/ \ - case 0: ; \ +static int PredictorSetupEncode(TIFF *tif) +{ + TIFFPredictorState *sp = PredictorState(tif); + TIFFDirectory *td = &tif->tif_dir; + + if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) + return 0; + + if (sp->predictor == 2) + { + switch (td->td_bitspersample) + { + case 8: + sp->encodepfunc = horDiff8; + break; + case 16: + sp->encodepfunc = horDiff16; + break; + case 32: + sp->encodepfunc = horDiff32; + break; + case 64: + sp->encodepfunc = horDiff64; + break; + } + /* + * Override default encoding method with one that does the + * predictor stuff. + */ + if (tif->tif_encoderow != PredictorEncodeRow) + { + sp->encoderow = tif->tif_encoderow; + tif->tif_encoderow = PredictorEncodeRow; + sp->encodestrip = tif->tif_encodestrip; + tif->tif_encodestrip = PredictorEncodeTile; + sp->encodetile = tif->tif_encodetile; + tif->tif_encodetile = PredictorEncodeTile; + } + + /* + * If the data is horizontally differenced 16-bit data that + * requires byte-swapping, then it must be byte swapped after + * the differentiation step. We do this with a special-purpose + * routine and override the normal post decoding logic that + * the library setup when the directory was read. + */ + if (tif->tif_flags & TIFF_SWAB) + { + if (sp->encodepfunc == horDiff16) + { + sp->encodepfunc = swabHorDiff16; + tif->tif_postdecode = _TIFFNoPostDecode; + } + else if (sp->encodepfunc == horDiff32) + { + sp->encodepfunc = swabHorDiff32; + tif->tif_postdecode = _TIFFNoPostDecode; + } + else if (sp->encodepfunc == horDiff64) + { + sp->encodepfunc = swabHorDiff64; + tif->tif_postdecode = _TIFFNoPostDecode; + } + } + } + + else if (sp->predictor == 3) + { + sp->encodepfunc = fpDiff; + /* + * Override default encoding method with one that does the + * predictor stuff. + */ + if (tif->tif_encoderow != PredictorEncodeRow) + { + sp->encoderow = tif->tif_encoderow; + tif->tif_encoderow = PredictorEncodeRow; + sp->encodestrip = tif->tif_encodestrip; + tif->tif_encodestrip = PredictorEncodeTile; + sp->encodetile = tif->tif_encodetile; + tif->tif_encodetile = PredictorEncodeTile; + } + } + + return 1; +} + +#define REPEAT4(n, op) \ + switch (n) \ + { \ + default: \ + { \ + tmsize_t i; \ + for (i = n - 4; i > 0; i--) \ + { \ + op; \ + } \ + } /*-fallthrough*/ \ + case 4: \ + op; /*-fallthrough*/ \ + case 3: \ + op; /*-fallthrough*/ \ + case 2: \ + op; /*-fallthrough*/ \ + case 1: \ + op; /*-fallthrough*/ \ + case 0:; \ } /* Remarks related to C standard compliance in all below functions : */ @@ -276,196 +339,236 @@ PredictorSetupEncode(TIFF* tif) /* as to make icc -check=conversions happy (not necessary by the standard) */ TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) +static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; + tmsize_t stride = PredictorState(tif)->stride; - unsigned char* cp = (unsigned char*) cp0; - if((cc%stride)!=0) + unsigned char *cp = (unsigned char *)cp0; + if ((cc % stride) != 0) { - TIFFErrorExt(tif->tif_clientdata, "horAcc8", - "%s", "(cc%stride)!=0"); + TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0"); return 0; } - if (cc > stride) { - /* - * Pipeline the most common cases. - */ - if (stride == 3) { - unsigned int cr = cp[0]; - unsigned int cg = cp[1]; - unsigned int cb = cp[2]; - cc -= 3; - cp += 3; - while (cc>0) { - cp[0] = (unsigned char) ((cr += cp[0]) & 0xff); - cp[1] = (unsigned char) ((cg += cp[1]) & 0xff); - cp[2] = (unsigned char) ((cb += cp[2]) & 0xff); - cc -= 3; - cp += 3; - } - } else if (stride == 4) { - unsigned int cr = cp[0]; - unsigned int cg = cp[1]; - unsigned int cb = cp[2]; - unsigned int ca = cp[3]; - cc -= 4; - cp += 4; - while (cc>0) { - cp[0] = (unsigned char) ((cr += cp[0]) & 0xff); - cp[1] = (unsigned char) ((cg += cp[1]) & 0xff); - cp[2] = (unsigned char) ((cb += cp[2]) & 0xff); - cp[3] = (unsigned char) ((ca += cp[3]) & 0xff); - cc -= 4; - cp += 4; - } - } else { - cc -= stride; - do { - REPEAT4(stride, cp[stride] = - (unsigned char) ((cp[stride] + *cp) & 0xff); cp++) - cc -= stride; - } while (cc>0); - } - } - return 1; + if (cc > stride) + { + /* + * Pipeline the most common cases. + */ + if (stride == 3) + { + unsigned int cr = cp[0]; + unsigned int cg = cp[1]; + unsigned int cb = cp[2]; + tmsize_t i = stride; + for (; i < cc; i += stride) + { + cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff); + cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff); + cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff); + } + } + else if (stride == 4) + { + unsigned int cr = cp[0]; + unsigned int cg = cp[1]; + unsigned int cb = cp[2]; + unsigned int ca = cp[3]; + tmsize_t i = stride; + for (; i < cc; i += stride) + { + cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff); + cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff); + cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff); + cp[i + 3] = (unsigned char)((ca += cp[i + 3]) & 0xff); + } + } + else + { + cc -= stride; + do + { + REPEAT4(stride, + cp[stride] = (unsigned char)((cp[stride] + *cp) & 0xff); + cp++) + cc -= stride; + } while (cc > 0); + } + } + return 1; } -static int -swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) +static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - uint16* wp = (uint16*) cp0; - tmsize_t wc = cc / 2; + uint16_t *wp = (uint16_t *)cp0; + tmsize_t wc = cc / 2; - TIFFSwabArrayOfShort(wp, wc); - return horAcc16(tif, cp0, cc); + TIFFSwabArrayOfShort(wp, wc); + return horAcc16(tif, cp0, cc); } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) +static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; - uint16* wp = (uint16*) cp0; - tmsize_t wc = cc / 2; + tmsize_t stride = PredictorState(tif)->stride; + uint16_t *wp = (uint16_t *)cp0; + tmsize_t wc = cc / 2; - if((cc%(2*stride))!=0) + if ((cc % (2 * stride)) != 0) { - TIFFErrorExt(tif->tif_clientdata, "horAcc16", - "%s", "cc%(2*stride))!=0"); + TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0"); return 0; } - if (wc > stride) { - wc -= stride; - do { - REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++) - wc -= stride; - } while (wc > 0); - } - return 1; + if (wc > stride) + { + wc -= stride; + do + { + REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] + + (unsigned int)wp[0]) & + 0xffff); + wp++) + wc -= stride; + } while (wc > 0); + } + return 1; } -static int -swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) +static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - uint32* wp = (uint32*) cp0; - tmsize_t wc = cc / 4; + uint32_t *wp = (uint32_t *)cp0; + tmsize_t wc = cc / 4; - TIFFSwabArrayOfLong(wp, wc); - return horAcc32(tif, cp0, cc); + TIFFSwabArrayOfLong(wp, wc); + return horAcc32(tif, cp0, cc); } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) +static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; - uint32* wp = (uint32*) cp0; - tmsize_t wc = cc / 4; + tmsize_t stride = PredictorState(tif)->stride; + uint32_t *wp = (uint32_t *)cp0; + tmsize_t wc = cc / 4; - if((cc%(4*stride))!=0) + if ((cc % (4 * stride)) != 0) { - TIFFErrorExt(tif->tif_clientdata, "horAcc32", - "%s", "cc%(4*stride))!=0"); + TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0"); return 0; } - if (wc > stride) { - wc -= stride; - do { - REPEAT4(stride, wp[stride] += wp[0]; wp++) - wc -= stride; - } while (wc > 0); - } - return 1; + if (wc > stride) + { + wc -= stride; + do + { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while (wc > 0); + } + return 1; +} + +static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc) +{ + uint64_t *wp = (uint64_t *)cp0; + tmsize_t wc = cc / 8; + + TIFFSwabArrayOfLong8(wp, wc); + return horAcc64(tif, cp0, cc); +} + +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW +static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc) +{ + tmsize_t stride = PredictorState(tif)->stride; + uint64_t *wp = (uint64_t *)cp0; + tmsize_t wc = cc / 8; + + if ((cc % (8 * stride)) != 0) + { + TIFFErrorExtR(tif, "horAcc64", "%s", "cc%(8*stride))!=0"); + return 0; + } + + if (wc > stride) + { + wc -= stride; + do + { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while (wc > 0); + } + return 1; } /* * Floating point predictor accumulation routine. */ -static int -fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc) +static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; - uint32 bps = tif->tif_dir.td_bitspersample / 8; - tmsize_t wc = cc / bps; - tmsize_t count = cc; - uint8 *cp = (uint8 *) cp0; - uint8 *tmp; + tmsize_t stride = PredictorState(tif)->stride; + uint32_t bps = tif->tif_dir.td_bitspersample / 8; + tmsize_t wc = cc / bps; + tmsize_t count = cc; + uint8_t *cp = (uint8_t *)cp0; + uint8_t *tmp; - if(cc%(bps*stride)!=0) + if (cc % (bps * stride) != 0) { - TIFFErrorExt(tif->tif_clientdata, "fpAcc", - "%s", "cc%(bps*stride))!=0"); + TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0"); return 0; } - tmp = (uint8 *)_TIFFmalloc(cc); - if (!tmp) - return 0; + tmp = (uint8_t *)_TIFFmallocExt(tif, cc); + if (!tmp) + return 0; - while (count > stride) { - REPEAT4(stride, cp[stride] = - (unsigned char) ((cp[stride] + cp[0]) & 0xff); cp++) - count -= stride; - } + while (count > stride) + { + REPEAT4(stride, + cp[stride] = (unsigned char)((cp[stride] + cp[0]) & 0xff); + cp++) + count -= stride; + } - _TIFFmemcpy(tmp, cp0, cc); - cp = (uint8 *) cp0; - for (count = 0; count < wc; count++) { - uint32 byte; - for (byte = 0; byte < bps; byte++) { - #if WORDS_BIGENDIAN - cp[bps * count + byte] = tmp[byte * wc + count]; - #else - cp[bps * count + byte] = - tmp[(bps - byte - 1) * wc + count]; - #endif - } - } - _TIFFfree(tmp); + _TIFFmemcpy(tmp, cp0, cc); + cp = (uint8_t *)cp0; + for (count = 0; count < wc; count++) + { + uint32_t byte; + for (byte = 0; byte < bps; byte++) + { +#if WORDS_BIGENDIAN + cp[bps * count + byte] = tmp[byte * wc + count]; +#else + cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count]; +#endif + } + } + _TIFFfreeExt(tif, tmp); return 1; } /* * Decode a scanline and apply the predictor routine. */ -static int -PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) +static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0, + uint16_t s) { - TIFFPredictorState *sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != NULL); - assert(sp->decoderow != NULL); - assert(sp->decodepfunc != NULL); + assert(sp != NULL); + assert(sp->decoderow != NULL); + assert(sp->decodepfunc != NULL); - if ((*sp->decoderow)(tif, op0, occ0, s)) { - return (*sp->decodepfunc)(tif, op0, occ0); - } else - return 0; + if ((*sp->decoderow)(tif, op0, occ0, s)) + { + return (*sp->decodepfunc)(tif, op0, occ0); + } + else + return 0; } /* @@ -475,123 +578,152 @@ PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) * been calculated at pre-decode time according to the * strip/tile dimensions. */ -static int -PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) +static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0, + uint16_t s) { - TIFFPredictorState *sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != NULL); - assert(sp->decodetile != NULL); + assert(sp != NULL); + assert(sp->decodetile != NULL); - if ((*sp->decodetile)(tif, op0, occ0, s)) { - tmsize_t rowsize = sp->rowsize; - assert(rowsize > 0); - if((occ0%rowsize) !=0) + if ((*sp->decodetile)(tif, op0, occ0, s)) + { + tmsize_t rowsize = sp->rowsize; + assert(rowsize > 0); + if ((occ0 % rowsize) != 0) { - TIFFErrorExt(tif->tif_clientdata, "PredictorDecodeTile", - "%s", "occ0%rowsize != 0"); + TIFFErrorExtR(tif, "PredictorDecodeTile", "%s", + "occ0%rowsize != 0"); return 0; } - assert(sp->decodepfunc != NULL); - while (occ0 > 0) { - if( !(*sp->decodepfunc)(tif, op0, rowsize) ) + assert(sp->decodepfunc != NULL); + while (occ0 > 0) + { + if (!(*sp->decodepfunc)(tif, op0, rowsize)) return 0; - occ0 -= rowsize; - op0 += rowsize; - } - return 1; - } else - return 0; + occ0 -= rowsize; + op0 += rowsize; + } + return 1; + } + else + return 0; } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) +static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - TIFFPredictorState* sp = PredictorState(tif); - tmsize_t stride = sp->stride; - unsigned char* cp = (unsigned char*) cp0; + TIFFPredictorState *sp = PredictorState(tif); + tmsize_t stride = sp->stride; + unsigned char *cp = (unsigned char *)cp0; - if((cc%stride)!=0) + if ((cc % stride) != 0) { - TIFFErrorExt(tif->tif_clientdata, "horDiff8", - "%s", "(cc%stride)!=0"); + TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0"); return 0; } - if (cc > stride) { - cc -= stride; - /* - * Pipeline the most common cases. - */ - if (stride == 3) { - unsigned int r1, g1, b1; - unsigned int r2 = cp[0]; - unsigned int g2 = cp[1]; - unsigned int b2 = cp[2]; - do { - r1 = cp[3]; cp[3] = (unsigned char)((r1-r2)&0xff); r2 = r1; - g1 = cp[4]; cp[4] = (unsigned char)((g1-g2)&0xff); g2 = g1; - b1 = cp[5]; cp[5] = (unsigned char)((b1-b2)&0xff); b2 = b1; - cp += 3; - } while ((cc -= 3) > 0); - } else if (stride == 4) { - unsigned int r1, g1, b1, a1; - unsigned int r2 = cp[0]; - unsigned int g2 = cp[1]; - unsigned int b2 = cp[2]; - unsigned int a2 = cp[3]; - do { - r1 = cp[4]; cp[4] = (unsigned char)((r1-r2)&0xff); r2 = r1; - g1 = cp[5]; cp[5] = (unsigned char)((g1-g2)&0xff); g2 = g1; - b1 = cp[6]; cp[6] = (unsigned char)((b1-b2)&0xff); b2 = b1; - a1 = cp[7]; cp[7] = (unsigned char)((a1-a2)&0xff); a2 = a1; - cp += 4; - } while ((cc -= 4) > 0); - } else { - cp += cc - 1; - do { - REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--) - } while ((cc -= stride) > 0); - } - } - return 1; + if (cc > stride) + { + cc -= stride; + /* + * Pipeline the most common cases. + */ + if (stride == 3) + { + unsigned int r1, g1, b1; + unsigned int r2 = cp[0]; + unsigned int g2 = cp[1]; + unsigned int b2 = cp[2]; + do + { + r1 = cp[3]; + cp[3] = (unsigned char)((r1 - r2) & 0xff); + r2 = r1; + g1 = cp[4]; + cp[4] = (unsigned char)((g1 - g2) & 0xff); + g2 = g1; + b1 = cp[5]; + cp[5] = (unsigned char)((b1 - b2) & 0xff); + b2 = b1; + cp += 3; + } while ((cc -= 3) > 0); + } + else if (stride == 4) + { + unsigned int r1, g1, b1, a1; + unsigned int r2 = cp[0]; + unsigned int g2 = cp[1]; + unsigned int b2 = cp[2]; + unsigned int a2 = cp[3]; + do + { + r1 = cp[4]; + cp[4] = (unsigned char)((r1 - r2) & 0xff); + r2 = r1; + g1 = cp[5]; + cp[5] = (unsigned char)((g1 - g2) & 0xff); + g2 = g1; + b1 = cp[6]; + cp[6] = (unsigned char)((b1 - b2) & 0xff); + b2 = b1; + a1 = cp[7]; + cp[7] = (unsigned char)((a1 - a2) & 0xff); + a2 = a1; + cp += 4; + } while ((cc -= 4) > 0); + } + else + { + cp += cc - 1; + do + { + REPEAT4(stride, + cp[stride] = + (unsigned char)((cp[stride] - cp[0]) & 0xff); + cp--) + } while ((cc -= stride) > 0); + } + } + return 1; } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) +static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - TIFFPredictorState* sp = PredictorState(tif); - tmsize_t stride = sp->stride; - uint16 *wp = (uint16*) cp0; - tmsize_t wc = cc/2; - - if((cc%(2*stride))!=0) - { - TIFFErrorExt(tif->tif_clientdata, "horDiff8", - "%s", "(cc%(2*stride))!=0"); - return 0; - } - - if (wc > stride) { - wc -= stride; - wp += wc - 1; - do { - REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] - (unsigned int)wp[0]) & 0xffff); wp--) - wc -= stride; - } while (wc > 0); - } - return 1; -} - -static int -swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) -{ - uint16* wp = (uint16*) cp0; + TIFFPredictorState *sp = PredictorState(tif); + tmsize_t stride = sp->stride; + uint16_t *wp = (uint16_t *)cp0; tmsize_t wc = cc / 2; - if( !horDiff16(tif, cp0, cc) ) + if ((cc % (2 * stride)) != 0) + { + TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0"); + return 0; + } + + if (wc > stride) + { + wc -= stride; + wp += wc - 1; + do + { + REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] - + (unsigned int)wp[0]) & + 0xffff); + wp--) + wc -= stride; + } while (wc > 0); + } + return 1; +} + +static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc) +{ + uint16_t *wp = (uint16_t *)cp0; + tmsize_t wc = cc / 2; + + if (!horDiff16(tif, cp0, cc)) return 0; TIFFSwabArrayOfShort(wp, wc); @@ -599,281 +731,316 @@ swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) +static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - TIFFPredictorState* sp = PredictorState(tif); - tmsize_t stride = sp->stride; - uint32 *wp = (uint32*) cp0; - tmsize_t wc = cc/4; + TIFFPredictorState *sp = PredictorState(tif); + tmsize_t stride = sp->stride; + uint32_t *wp = (uint32_t *)cp0; + tmsize_t wc = cc / 4; - if((cc%(4*stride))!=0) + if ((cc % (4 * stride)) != 0) { - TIFFErrorExt(tif->tif_clientdata, "horDiff32", - "%s", "(cc%(4*stride))!=0"); + TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0"); return 0; } - if (wc > stride) { - wc -= stride; - wp += wc - 1; - do { - REPEAT4(stride, wp[stride] -= wp[0]; wp--) - wc -= stride; - } while (wc > 0); - } - return 1; + if (wc > stride) + { + wc -= stride; + wp += wc - 1; + do + { + REPEAT4(stride, wp[stride] -= wp[0]; wp--) + wc -= stride; + } while (wc > 0); + } + return 1; } -static int -swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) +static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - uint32* wp = (uint32*) cp0; + uint32_t *wp = (uint32_t *)cp0; tmsize_t wc = cc / 4; - if( !horDiff32(tif, cp0, cc) ) + if (!horDiff32(tif, cp0, cc)) return 0; TIFFSwabArrayOfLong(wp, wc); return 1; } +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW +static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc) +{ + TIFFPredictorState *sp = PredictorState(tif); + tmsize_t stride = sp->stride; + uint64_t *wp = (uint64_t *)cp0; + tmsize_t wc = cc / 8; + + if ((cc % (8 * stride)) != 0) + { + TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0"); + return 0; + } + + if (wc > stride) + { + wc -= stride; + wp += wc - 1; + do + { + REPEAT4(stride, wp[stride] -= wp[0]; wp--) + wc -= stride; + } while (wc > 0); + } + return 1; +} + +static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc) +{ + uint64_t *wp = (uint64_t *)cp0; + tmsize_t wc = cc / 8; + + if (!horDiff64(tif, cp0, cc)) + return 0; + + TIFFSwabArrayOfLong8(wp, wc); + return 1; +} + /* * Floating point predictor differencing routine. */ TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) +static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; - uint32 bps = tif->tif_dir.td_bitspersample / 8; - tmsize_t wc = cc / bps; - tmsize_t count; - uint8 *cp = (uint8 *) cp0; - uint8 *tmp; + tmsize_t stride = PredictorState(tif)->stride; + uint32_t bps = tif->tif_dir.td_bitspersample / 8; + tmsize_t wc = cc / bps; + tmsize_t count; + uint8_t *cp = (uint8_t *)cp0; + uint8_t *tmp; - if((cc%(bps*stride))!=0) + if ((cc % (bps * stride)) != 0) { - TIFFErrorExt(tif->tif_clientdata, "fpDiff", - "%s", "(cc%(bps*stride))!=0"); + TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0"); return 0; } - tmp = (uint8 *)_TIFFmalloc(cc); - if (!tmp) - return 0; + tmp = (uint8_t *)_TIFFmallocExt(tif, cc); + if (!tmp) + return 0; - _TIFFmemcpy(tmp, cp0, cc); - for (count = 0; count < wc; count++) { - uint32 byte; - for (byte = 0; byte < bps; byte++) { - #if WORDS_BIGENDIAN - cp[byte * wc + count] = tmp[bps * count + byte]; - #else - cp[(bps - byte - 1) * wc + count] = - tmp[bps * count + byte]; - #endif - } - } - _TIFFfree(tmp); + _TIFFmemcpy(tmp, cp0, cc); + for (count = 0; count < wc; count++) + { + uint32_t byte; + for (byte = 0; byte < bps; byte++) + { +#if WORDS_BIGENDIAN + cp[byte * wc + count] = tmp[bps * count + byte]; +#else + cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte]; +#endif + } + } + _TIFFfreeExt(tif, tmp); - cp = (uint8 *) cp0; - cp += cc - stride - 1; - for (count = cc; count > stride; count -= stride) - REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--) + cp = (uint8_t *)cp0; + cp += cc - stride - 1; + for (count = cc; count > stride; count -= stride) + REPEAT4(stride, + cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff); + cp--) return 1; } -static int -PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - TIFFPredictorState *sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != NULL); - assert(sp->encodepfunc != NULL); - assert(sp->encoderow != NULL); + assert(sp != NULL); + assert(sp->encodepfunc != NULL); + assert(sp->encoderow != NULL); - /* XXX horizontal differencing alters user's data XXX */ - if( !(*sp->encodepfunc)(tif, bp, cc) ) + /* XXX horizontal differencing alters user's data XXX */ + if (!(*sp->encodepfunc)(tif, bp, cc)) return 0; - return (*sp->encoderow)(tif, bp, cc, s); + return (*sp->encoderow)(tif, bp, cc, s); } -static int -PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s) +static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0, + uint16_t s) { - static const char module[] = "PredictorEncodeTile"; - TIFFPredictorState *sp = PredictorState(tif); - uint8 *working_copy; - tmsize_t cc = cc0, rowsize; - unsigned char* bp; - int result_code; + static const char module[] = "PredictorEncodeTile"; + TIFFPredictorState *sp = PredictorState(tif); + uint8_t *working_copy; + tmsize_t cc = cc0, rowsize; + unsigned char *bp; + int result_code; - assert(sp != NULL); - assert(sp->encodepfunc != NULL); - assert(sp->encodetile != NULL); + assert(sp != NULL); + assert(sp->encodepfunc != NULL); + assert(sp->encodetile != NULL); - /* - * Do predictor manipulation in a working buffer to avoid altering - * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965 - */ - working_copy = (uint8*) _TIFFmalloc(cc0); - if( working_copy == NULL ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.", - cc0 ); - return 0; - } - memcpy( working_copy, bp0, cc0 ); - bp = working_copy; - - rowsize = sp->rowsize; - assert(rowsize > 0); - if((cc0%rowsize)!=0) + /* + * Do predictor manipulation in a working buffer to avoid altering + * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965 + */ + working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0); + if (working_copy == NULL) { - TIFFErrorExt(tif->tif_clientdata, "PredictorEncodeTile", - "%s", "(cc0%rowsize)!=0"); - _TIFFfree( working_copy ); + TIFFErrorExtR(tif, module, + "Out of memory allocating %" PRId64 " byte temp buffer.", + (int64_t)cc0); return 0; } - while (cc > 0) { - (*sp->encodepfunc)(tif, bp, rowsize); - cc -= rowsize; - bp += rowsize; - } - result_code = (*sp->encodetile)(tif, working_copy, cc0, s); + memcpy(working_copy, bp0, cc0); + bp = working_copy; - _TIFFfree( working_copy ); + rowsize = sp->rowsize; + assert(rowsize > 0); + if ((cc0 % rowsize) != 0) + { + TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0"); + _TIFFfreeExt(tif, working_copy); + return 0; + } + while (cc > 0) + { + (*sp->encodepfunc)(tif, bp, rowsize); + cc -= rowsize; + bp += rowsize; + } + result_code = (*sp->encodetile)(tif, working_copy, cc0, s); - return result_code; + _TIFFfreeExt(tif, working_copy); + + return result_code; } -#define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */ +#define FIELD_PREDICTOR (FIELD_CODEC + 0) /* XXX */ static const TIFFField predictFields[] = { - { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL }, + {TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL}, }; -static int -PredictorVSetField(TIFF* tif, uint32 tag, va_list ap) +static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap) { - TIFFPredictorState *sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != NULL); - assert(sp->vsetparent != NULL); + assert(sp != NULL); + assert(sp->vsetparent != NULL); - switch (tag) { - case TIFFTAG_PREDICTOR: - sp->predictor = (uint16) va_arg(ap, uint16_vap); - TIFFSetFieldBit(tif, FIELD_PREDICTOR); - break; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - tif->tif_flags |= TIFF_DIRTYDIRECT; - return 1; + switch (tag) + { + case TIFFTAG_PREDICTOR: + sp->predictor = (uint16_t)va_arg(ap, uint16_vap); + TIFFSetFieldBit(tif, FIELD_PREDICTOR); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + tif->tif_flags |= TIFF_DIRTYDIRECT; + return 1; } -static int -PredictorVGetField(TIFF* tif, uint32 tag, va_list ap) +static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap) { - TIFFPredictorState *sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != NULL); - assert(sp->vgetparent != NULL); + assert(sp != NULL); + assert(sp->vgetparent != NULL); - switch (tag) { - case TIFFTAG_PREDICTOR: - *va_arg(ap, uint16*) = (uint16)sp->predictor; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; + switch (tag) + { + case TIFFTAG_PREDICTOR: + *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; } -static void -PredictorPrintDir(TIFF* tif, FILE* fd, long flags) +static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags) { - TIFFPredictorState* sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - (void) flags; - if (TIFFFieldSet(tif,FIELD_PREDICTOR)) { - fprintf(fd, " Predictor: "); - switch (sp->predictor) { - case 1: fprintf(fd, "none "); break; - case 2: fprintf(fd, "horizontal differencing "); break; - case 3: fprintf(fd, "floating point predictor "); break; - } - fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor); - } - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); + (void)flags; + if (TIFFFieldSet(tif, FIELD_PREDICTOR)) + { + fprintf(fd, " Predictor: "); + switch (sp->predictor) + { + case 1: + fprintf(fd, "none "); + break; + case 2: + fprintf(fd, "horizontal differencing "); + break; + case 3: + fprintf(fd, "floating point predictor "); + break; + } + fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor); + } + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); } -int -TIFFPredictorInit(TIFF* tif) +int TIFFPredictorInit(TIFF *tif) { - TIFFPredictorState* sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != 0); + assert(sp != 0); - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, predictFields, - TIFFArrayCount(predictFields))) { - TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit", - "Merging Predictor codec-specific tags failed"); - return 0; - } + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields))) + { + TIFFErrorExtR(tif, "TIFFPredictorInit", + "Merging Predictor codec-specific tags failed"); + return 0; + } - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = - PredictorVGetField;/* hook for predictor tag */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = - PredictorVSetField;/* hook for predictor tag */ - sp->printdir = tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir = - PredictorPrintDir; /* hook for predictor tag */ + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = + PredictorVGetField; /* hook for predictor tag */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = + PredictorVSetField; /* hook for predictor tag */ + sp->printdir = tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir = + PredictorPrintDir; /* hook for predictor tag */ - sp->setupdecode = tif->tif_setupdecode; - tif->tif_setupdecode = PredictorSetupDecode; - sp->setupencode = tif->tif_setupencode; - tif->tif_setupencode = PredictorSetupEncode; + sp->setupdecode = tif->tif_setupdecode; + tif->tif_setupdecode = PredictorSetupDecode; + sp->setupencode = tif->tif_setupencode; + tif->tif_setupencode = PredictorSetupEncode; - sp->predictor = 1; /* default value */ - sp->encodepfunc = NULL; /* no predictor routine */ - sp->decodepfunc = NULL; /* no predictor routine */ - return 1; + sp->predictor = 1; /* default value */ + sp->encodepfunc = NULL; /* no predictor routine */ + sp->decodepfunc = NULL; /* no predictor routine */ + return 1; } -int -TIFFPredictorCleanup(TIFF* tif) +int TIFFPredictorCleanup(TIFF *tif) { - TIFFPredictorState* sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != 0); + assert(sp != 0); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - tif->tif_tagmethods.printdir = sp->printdir; - tif->tif_setupdecode = sp->setupdecode; - tif->tif_setupencode = sp->setupencode; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.printdir = sp->printdir; + tif->tif_setupdecode = sp->setupdecode; + tif->tif_setupencode = sp->setupencode; - return 1; + return 1; } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_predict.h b/3rdparty/libtiff/tif_predict.h index a326b9b8f8..de77328352 100644 --- a/3rdparty/libtiff/tif_predict.h +++ b/3rdparty/libtiff/tif_predict.h @@ -23,7 +23,7 @@ */ #ifndef _TIFFPREDICT_ -#define _TIFFPREDICT_ +#define _TIFFPREDICT_ #include "tiffio.h" #include "tiffiop.h" @@ -32,50 +32,43 @@ * ``Library-private'' Support for the Predictor Tag */ -typedef int (*TIFFEncodeDecodeMethod)(TIFF* tif, uint8* buf, tmsize_t size); +typedef int (*TIFFEncodeDecodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size); /* * Codecs that want to support the Predictor tag must place * this structure first in their private state block so that * the predictor code can cast tif_data to find its state. */ -typedef struct { - int predictor; /* predictor tag value */ - tmsize_t stride; /* sample stride over data */ - tmsize_t rowsize; /* tile/strip row size */ +typedef struct +{ + int predictor; /* predictor tag value */ + tmsize_t stride; /* sample stride over data */ + tmsize_t rowsize; /* tile/strip row size */ - TIFFCodeMethod encoderow; /* parent codec encode/decode row */ - TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */ - TIFFCodeMethod encodetile; /* parent codec encode/decode tile */ - TIFFEncodeDecodeMethod encodepfunc; /* horizontal differencer */ + TIFFCodeMethod encoderow; /* parent codec encode/decode row */ + TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */ + TIFFCodeMethod encodetile; /* parent codec encode/decode tile */ + TIFFEncodeDecodeMethod encodepfunc; /* horizontal differencer */ - TIFFCodeMethod decoderow; /* parent codec encode/decode row */ - TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */ - TIFFCodeMethod decodetile; /* parent codec encode/decode tile */ - TIFFEncodeDecodeMethod decodepfunc; /* horizontal accumulator */ + TIFFCodeMethod decoderow; /* parent codec encode/decode row */ + TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */ + TIFFCodeMethod decodetile; /* parent codec encode/decode tile */ + TIFFEncodeDecodeMethod decodepfunc; /* horizontal accumulator */ - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ - TIFFBoolMethod setupdecode; /* super-class method */ - TIFFBoolMethod setupencode; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ + TIFFBoolMethod setupdecode; /* super-class method */ + TIFFBoolMethod setupencode; /* super-class method */ } TIFFPredictorState; #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -extern int TIFFPredictorInit(TIFF*); -extern int TIFFPredictorCleanup(TIFF*); + extern int TIFFPredictorInit(TIFF *); + extern int TIFFPredictorCleanup(TIFF *); #if defined(__cplusplus) } #endif #endif /* _TIFFPREDICT_ */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_print.c b/3rdparty/libtiff/tif_print.c index a0737941f4..2b7fd1765a 100644 --- a/3rdparty/libtiff/tif_print.c +++ b/3rdparty/libtiff/tif_print.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,687 +32,724 @@ #include -static void -_TIFFprintAsciiBounded(FILE* fd, const char* cp, size_t max_chars); +static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars); -static const char * const photoNames[] = { - "min-is-white", /* PHOTOMETRIC_MINISWHITE */ - "min-is-black", /* PHOTOMETRIC_MINISBLACK */ - "RGB color", /* PHOTOMETRIC_RGB */ - "palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */ - "transparency mask", /* PHOTOMETRIC_MASK */ - "separated", /* PHOTOMETRIC_SEPARATED */ - "YCbCr", /* PHOTOMETRIC_YCBCR */ +static const char *const photoNames[] = { + "min-is-white", /* PHOTOMETRIC_MINISWHITE */ + "min-is-black", /* PHOTOMETRIC_MINISBLACK */ + "RGB color", /* PHOTOMETRIC_RGB */ + "palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */ + "transparency mask", /* PHOTOMETRIC_MASK */ + "separated", /* PHOTOMETRIC_SEPARATED */ + "YCbCr", /* PHOTOMETRIC_YCBCR */ "7 (0x7)", - "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */ - "ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */ - "ITU L*a*b*" /* PHOTOMETRIC_ITULAB */ + "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */ + "ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */ + "ITU L*a*b*" /* PHOTOMETRIC_ITULAB */ }; -#define NPHOTONAMES (sizeof (photoNames) / sizeof (photoNames[0])) +#define NPHOTONAMES (sizeof(photoNames) / sizeof(photoNames[0])) -static const char * const orientNames[] = { +static const char *const orientNames[] = { "0 (0x0)", - "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */ - "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */ - "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */ - "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */ - "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */ - "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */ - "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */ - "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */ + "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */ + "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */ + "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */ + "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */ + "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */ + "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */ + "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */ + "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */ }; -#define NORIENTNAMES (sizeof (orientNames) / sizeof (orientNames[0])) +#define NORIENTNAMES (sizeof(orientNames) / sizeof(orientNames[0])) -static void -_TIFFPrintField(FILE* fd, const TIFFField *fip, - uint32 value_count, void *raw_data) +static const struct tagname { - uint32 j; - - fprintf(fd, " %s: ", fip->field_name); + uint16_t tag; + const char *name; +} tagnames[] = { + {TIFFTAG_GDAL_METADATA, "GDAL Metadata"}, + {TIFFTAG_GDAL_NODATA, "GDAL NoDataValue"}, +}; +#define NTAGS (sizeof(tagnames) / sizeof(tagnames[0])) - for(j = 0; j < value_count; j++) { - if(fip->field_type == TIFF_BYTE) - fprintf(fd, "%u", ((uint8 *) raw_data)[j]); - else if(fip->field_type == TIFF_UNDEFINED) - fprintf(fd, "0x%x", - (unsigned int) ((unsigned char *) raw_data)[j]); - else if(fip->field_type == TIFF_SBYTE) - fprintf(fd, "%d", ((int8 *) raw_data)[j]); - else if(fip->field_type == TIFF_SHORT) - fprintf(fd, "%u", ((uint16 *) raw_data)[j]); - else if(fip->field_type == TIFF_SSHORT) - fprintf(fd, "%d", ((int16 *) raw_data)[j]); - else if(fip->field_type == TIFF_LONG) - fprintf(fd, "%lu", - (unsigned long)((uint32 *) raw_data)[j]); - else if(fip->field_type == TIFF_SLONG) - fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]); - else if(fip->field_type == TIFF_IFD) - fprintf(fd, "0x%lx", - (unsigned long)((uint32 *) raw_data)[j]); - else if(fip->field_type == TIFF_RATIONAL - || fip->field_type == TIFF_SRATIONAL - || fip->field_type == TIFF_FLOAT) - fprintf(fd, "%f", ((float *) raw_data)[j]); - else if(fip->field_type == TIFF_LONG8) -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - fprintf(fd, "%I64u", - (unsigned __int64)((uint64 *) raw_data)[j]); -#else - fprintf(fd, "%llu", - (unsigned long long)((uint64 *) raw_data)[j]); -#endif - else if(fip->field_type == TIFF_SLONG8) -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - fprintf(fd, "%I64d", (__int64)((int64 *) raw_data)[j]); -#else - fprintf(fd, "%lld", (long long)((int64 *) raw_data)[j]); -#endif - else if(fip->field_type == TIFF_IFD8) -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - fprintf(fd, "0x%I64x", - (unsigned __int64)((uint64 *) raw_data)[j]); -#else - fprintf(fd, "0x%llx", - (unsigned long long)((uint64 *) raw_data)[j]); -#endif - else if(fip->field_type == TIFF_FLOAT) - fprintf(fd, "%f", ((float *)raw_data)[j]); - else if(fip->field_type == TIFF_DOUBLE) - fprintf(fd, "%f", ((double *) raw_data)[j]); - else if(fip->field_type == TIFF_ASCII) { - fprintf(fd, "%s", (char *) raw_data); - break; - } - else { - fprintf(fd, ""); - break; - } +static void _TIFFPrintField(FILE *fd, const TIFFField *fip, + uint32_t value_count, void *raw_data) +{ + uint32_t j; - if(j < value_count - 1) - fprintf(fd, ","); - } + /* Print a user-friendly name for tags of relatively common use, but */ + /* which aren't registered by libtiff itself. */ + const char *field_name = fip->field_name; + if (TIFFFieldIsAnonymous(fip)) + { + for (size_t i = 0; i < NTAGS; ++i) + { + if (fip->field_tag == tagnames[i].tag) + { + field_name = tagnames[i].name; + break; + } + } + } + fprintf(fd, " %s: ", field_name); - fprintf(fd, "\n"); + for (j = 0; j < value_count; j++) + { + if (fip->field_type == TIFF_BYTE) + fprintf(fd, "%" PRIu8, ((uint8_t *)raw_data)[j]); + else if (fip->field_type == TIFF_UNDEFINED) + fprintf(fd, "0x%" PRIx8, ((uint8_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SBYTE) + fprintf(fd, "%" PRId8, ((int8_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SHORT) + fprintf(fd, "%" PRIu16, ((uint16_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SSHORT) + fprintf(fd, "%" PRId16, ((int16_t *)raw_data)[j]); + else if (fip->field_type == TIFF_LONG) + fprintf(fd, "%" PRIu32, ((uint32_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SLONG) + fprintf(fd, "%" PRId32, ((int32_t *)raw_data)[j]); + else if (fip->field_type == TIFF_IFD) + fprintf(fd, "0x%" PRIx32, ((uint32_t *)raw_data)[j]); + else if (fip->field_type == TIFF_RATIONAL || + fip->field_type == TIFF_SRATIONAL) + { + int tv_size = TIFFFieldSetGetSize(fip); + if (tv_size == 8) + fprintf(fd, "%lf", ((double *)raw_data)[j]); + else + fprintf(fd, "%f", ((float *)raw_data)[j]); + } + else if (fip->field_type == TIFF_FLOAT) + fprintf(fd, "%f", ((float *)raw_data)[j]); + else if (fip->field_type == TIFF_LONG8) + fprintf(fd, "%" PRIu64, ((uint64_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SLONG8) + fprintf(fd, "%" PRId64, ((int64_t *)raw_data)[j]); + else if (fip->field_type == TIFF_IFD8) + fprintf(fd, "0x%" PRIx64, ((uint64_t *)raw_data)[j]); + else if (fip->field_type == TIFF_DOUBLE) + fprintf(fd, "%lf", ((double *)raw_data)[j]); + else if (fip->field_type == TIFF_ASCII) + { + fprintf(fd, "%s", (char *)raw_data); + break; + } + else + { + fprintf(fd, ""); + break; + } + + if (j < value_count - 1) + fprintf(fd, ","); + } + + fprintf(fd, "\n"); } -static int -_TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag, - uint32 value_count, void *raw_data) +static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd, + uint32_t tag, uint32_t value_count, + void *raw_data) { - (void) tif; + (void)tif; - /* do not try to pretty print auto-defined fields */ - if (strncmp(fip->field_name,"Tag ", 4) == 0) { - return 0; - } - - switch (tag) - { - case TIFFTAG_INKSET: - if (value_count == 2 && fip->field_type == TIFF_SHORT) { - fprintf(fd, " Ink Set: "); - switch (*((uint16*)raw_data)) { - case INKSET_CMYK: - fprintf(fd, "CMYK\n"); - break; - default: - fprintf(fd, "%u (0x%x)\n", - *((uint16*)raw_data), - *((uint16*)raw_data)); - break; - } - return 1; - } - return 0; + /* do not try to pretty print auto-defined fields */ + if (TIFFFieldIsAnonymous(fip)) + { + return 0; + } - case TIFFTAG_DOTRANGE: - if (value_count == 2 && fip->field_type == TIFF_SHORT) { - fprintf(fd, " Dot Range: %u-%u\n", - ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]); - return 1; - } - return 0; + switch (tag) + { + case TIFFTAG_INKSET: + if (value_count == 2 && fip->field_type == TIFF_SHORT) + { + fprintf(fd, " Ink Set: "); + switch (*((uint16_t *)raw_data)) + { + case INKSET_CMYK: + fprintf(fd, "CMYK\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + *((uint16_t *)raw_data), + *((uint16_t *)raw_data)); + break; + } + return 1; + } + return 0; - case TIFFTAG_WHITEPOINT: - if (value_count == 2 && fip->field_type == TIFF_RATIONAL) { - fprintf(fd, " White Point: %g-%g\n", - ((float *)raw_data)[0], ((float *)raw_data)[1]); - return 1; - } - return 0; + case TIFFTAG_DOTRANGE: + if (value_count == 2 && fip->field_type == TIFF_SHORT) + { + fprintf(fd, " Dot Range: %" PRIu16 "-%" PRIu16 "\n", + ((uint16_t *)raw_data)[0], ((uint16_t *)raw_data)[1]); + return 1; + } + return 0; - case TIFFTAG_XMLPACKET: - { - uint32 i; + case TIFFTAG_WHITEPOINT: + if (value_count == 2 && fip->field_type == TIFF_RATIONAL) + { + fprintf(fd, " White Point: %g-%g\n", ((float *)raw_data)[0], + ((float *)raw_data)[1]); + return 1; + } + return 0; - fprintf(fd, " XMLPacket (XMP Metadata):\n" ); - for(i = 0; i < value_count; i++) - fputc(((char *)raw_data)[i], fd); - fprintf( fd, "\n" ); - return 1; - } - case TIFFTAG_RICHTIFFIPTC: - /* - * XXX: for some weird reason RichTIFFIPTC tag - * defined as array of LONG values. - */ - fprintf(fd, - " RichTIFFIPTC Data: , %lu bytes\n", - (unsigned long) value_count * 4); - return 1; + case TIFFTAG_XMLPACKET: + { + uint32_t i; - case TIFFTAG_PHOTOSHOP: - fprintf(fd, " Photoshop Data: , %lu bytes\n", - (unsigned long) value_count); - return 1; + fprintf(fd, " XMLPacket (XMP Metadata):\n"); + for (i = 0; i < value_count; i++) + fputc(((char *)raw_data)[i], fd); + fprintf(fd, "\n"); + return 1; + } + case TIFFTAG_RICHTIFFIPTC: + fprintf(fd, " RichTIFFIPTC Data: , %" PRIu32 " bytes\n", + value_count); + return 1; - case TIFFTAG_ICCPROFILE: - fprintf(fd, " ICC Profile: , %lu bytes\n", - (unsigned long) value_count); - return 1; + case TIFFTAG_PHOTOSHOP: + fprintf(fd, " Photoshop Data: , %" PRIu32 " bytes\n", + value_count); + return 1; - case TIFFTAG_STONITS: - if (value_count == 1 && fip->field_type == TIFF_DOUBLE) { - fprintf(fd, - " Sample to Nits conversion factor: %.4e\n", - *((double*)raw_data)); - return 1; - } - return 0; - } + case TIFFTAG_ICCPROFILE: + fprintf(fd, " ICC Profile: , %" PRIu32 " bytes\n", + value_count); + return 1; - return 0; + case TIFFTAG_STONITS: + if (value_count == 1 && fip->field_type == TIFF_DOUBLE) + { + fprintf(fd, " Sample to Nits conversion factor: %.4e\n", + *((double *)raw_data)); + return 1; + } + return 0; + } + + return 0; } /* * Print the contents of the current directory * to the specified stdio file stream. */ -void -TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) +void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) { - TIFFDirectory *td = &tif->tif_dir; - char *sep; - long l, n; + TIFFDirectory *td = &tif->tif_dir; + char *sep; + long l, n; -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n", - (unsigned __int64) tif->tif_diroff, - (unsigned __int64) tif->tif_diroff); -#else - fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n", - (unsigned long long) tif->tif_diroff, - (unsigned long long) tif->tif_diroff); -#endif - if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) { - fprintf(fd, " Subfile Type:"); - sep = " "; - if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) { - fprintf(fd, "%sreduced-resolution image", sep); - sep = "/"; - } - if (td->td_subfiletype & FILETYPE_PAGE) { - fprintf(fd, "%smulti-page document", sep); - sep = "/"; - } - if (td->td_subfiletype & FILETYPE_MASK) - fprintf(fd, "%stransparency mask", sep); - fprintf(fd, " (%lu = 0x%lx)\n", - (unsigned long) td->td_subfiletype, (long) td->td_subfiletype); - } - if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) { - fprintf(fd, " Image Width: %lu Image Length: %lu", - (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength); - if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH)) - fprintf(fd, " Image Depth: %lu", - (unsigned long) td->td_imagedepth); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) { - fprintf(fd, " Tile Width: %lu Tile Length: %lu", - (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength); - if (TIFFFieldSet(tif,FIELD_TILEDEPTH)) - fprintf(fd, " Tile Depth: %lu", - (unsigned long) td->td_tiledepth); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_RESOLUTION)) { - fprintf(fd, " Resolution: %g, %g", - td->td_xresolution, td->td_yresolution); - if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) { - switch (td->td_resolutionunit) { - case RESUNIT_NONE: - fprintf(fd, " (unitless)"); - break; - case RESUNIT_INCH: - fprintf(fd, " pixels/inch"); - break; - case RESUNIT_CENTIMETER: - fprintf(fd, " pixels/cm"); - break; - default: - fprintf(fd, " (unit %u = 0x%x)", - td->td_resolutionunit, - td->td_resolutionunit); - break; - } - } - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_POSITION)) - fprintf(fd, " Position: %g, %g\n", - td->td_xposition, td->td_yposition); - if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) - fprintf(fd, " Bits/Sample: %u\n", td->td_bitspersample); - if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) { - fprintf(fd, " Sample Format: "); - switch (td->td_sampleformat) { - case SAMPLEFORMAT_VOID: - fprintf(fd, "void\n"); - break; - case SAMPLEFORMAT_INT: - fprintf(fd, "signed integer\n"); - break; - case SAMPLEFORMAT_UINT: - fprintf(fd, "unsigned integer\n"); - break; - case SAMPLEFORMAT_IEEEFP: - fprintf(fd, "IEEE floating point\n"); - break; - case SAMPLEFORMAT_COMPLEXINT: - fprintf(fd, "complex signed integer\n"); - break; - case SAMPLEFORMAT_COMPLEXIEEEFP: - fprintf(fd, "complex IEEE floating point\n"); - break; - default: - fprintf(fd, "%u (0x%x)\n", - td->td_sampleformat, td->td_sampleformat); - break; - } - } - if (TIFFFieldSet(tif,FIELD_COMPRESSION)) { - const TIFFCodec* c = TIFFFindCODEC(td->td_compression); - fprintf(fd, " Compression Scheme: "); - if (c) - fprintf(fd, "%s\n", c->name); - else - fprintf(fd, "%u (0x%x)\n", - td->td_compression, td->td_compression); - } - if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) { - fprintf(fd, " Photometric Interpretation: "); - if (td->td_photometric < NPHOTONAMES) - fprintf(fd, "%s\n", photoNames[td->td_photometric]); - else { - switch (td->td_photometric) { - case PHOTOMETRIC_LOGL: - fprintf(fd, "CIE Log2(L)\n"); - break; - case PHOTOMETRIC_LOGLUV: - fprintf(fd, "CIE Log2(L) (u',v')\n"); - break; - default: - fprintf(fd, "%u (0x%x)\n", - td->td_photometric, td->td_photometric); - break; - } - } - } - if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) { - uint16 i; - fprintf(fd, " Extra Samples: %u<", td->td_extrasamples); - sep = ""; - for (i = 0; i < td->td_extrasamples; i++) { - switch (td->td_sampleinfo[i]) { - case EXTRASAMPLE_UNSPECIFIED: - fprintf(fd, "%sunspecified", sep); - break; - case EXTRASAMPLE_ASSOCALPHA: - fprintf(fd, "%sassoc-alpha", sep); - break; - case EXTRASAMPLE_UNASSALPHA: - fprintf(fd, "%sunassoc-alpha", sep); - break; - default: - fprintf(fd, "%s%u (0x%x)", sep, - td->td_sampleinfo[i], td->td_sampleinfo[i]); - break; - } - sep = ", "; - } - fprintf(fd, ">\n"); - } - if (TIFFFieldSet(tif,FIELD_INKNAMES)) { - char* cp; - uint16 i; - fprintf(fd, " Ink Names: "); - i = td->td_samplesperpixel; - sep = ""; - for (cp = td->td_inknames; - i > 0 && cp < td->td_inknames + td->td_inknameslen; - cp = strchr(cp,'\0')+1, i--) { - size_t max_chars = - td->td_inknameslen - (cp - td->td_inknames); - fputs(sep, fd); - _TIFFprintAsciiBounded(fd, cp, max_chars); - sep = ", "; - } - fputs("\n", fd); - } - if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) { - fprintf(fd, " Thresholding: "); - switch (td->td_threshholding) { - case THRESHHOLD_BILEVEL: - fprintf(fd, "bilevel art scan\n"); - break; - case THRESHHOLD_HALFTONE: - fprintf(fd, "halftone or dithered scan\n"); - break; - case THRESHHOLD_ERRORDIFFUSE: - fprintf(fd, "error diffused\n"); - break; - default: - fprintf(fd, "%u (0x%x)\n", - td->td_threshholding, td->td_threshholding); - break; - } - } - if (TIFFFieldSet(tif,FIELD_FILLORDER)) { - fprintf(fd, " FillOrder: "); - switch (td->td_fillorder) { - case FILLORDER_MSB2LSB: - fprintf(fd, "msb-to-lsb\n"); - break; - case FILLORDER_LSB2MSB: - fprintf(fd, "lsb-to-msb\n"); - break; - default: - fprintf(fd, "%u (0x%x)\n", - td->td_fillorder, td->td_fillorder); - break; - } - } - if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING)) + fprintf(fd, "TIFF Directory at offset 0x%" PRIx64 " (%" PRIu64 ")\n", + tif->tif_diroff, tif->tif_diroff); + if (TIFFFieldSet(tif, FIELD_SUBFILETYPE)) + { + fprintf(fd, " Subfile Type:"); + sep = " "; + if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) { - fprintf(fd, " YCbCr Subsampling: %u, %u\n", - td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] ); - } - if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) { - fprintf(fd, " YCbCr Positioning: "); - switch (td->td_ycbcrpositioning) { - case YCBCRPOSITION_CENTERED: - fprintf(fd, "centered\n"); - break; - case YCBCRPOSITION_COSITED: - fprintf(fd, "cosited\n"); - break; - default: - fprintf(fd, "%u (0x%x)\n", - td->td_ycbcrpositioning, td->td_ycbcrpositioning); - break; - } - } - if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS)) - fprintf(fd, " Halftone Hints: light %u dark %u\n", - td->td_halftonehints[0], td->td_halftonehints[1]); - if (TIFFFieldSet(tif,FIELD_ORIENTATION)) { - fprintf(fd, " Orientation: "); - if (td->td_orientation < NORIENTNAMES) - fprintf(fd, "%s\n", orientNames[td->td_orientation]); - else - fprintf(fd, "%u (0x%x)\n", - td->td_orientation, td->td_orientation); - } - if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) - fprintf(fd, " Samples/Pixel: %u\n", td->td_samplesperpixel); - if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) { - fprintf(fd, " Rows/Strip: "); - if (td->td_rowsperstrip == (uint32) -1) - fprintf(fd, "(infinite)\n"); - else - fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip); - } - if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE)) - fprintf(fd, " Min Sample Value: %u\n", td->td_minsamplevalue); - if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) - fprintf(fd, " Max Sample Value: %u\n", td->td_maxsamplevalue); - if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) { - int i; - int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; - fprintf(fd, " SMin Sample Value:"); - for (i = 0; i < count; ++i) - fprintf(fd, " %g", td->td_sminsamplevalue[i]); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) { - int i; - int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; - fprintf(fd, " SMax Sample Value:"); - for (i = 0; i < count; ++i) - fprintf(fd, " %g", td->td_smaxsamplevalue[i]); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) { - fprintf(fd, " Planar Configuration: "); - switch (td->td_planarconfig) { - case PLANARCONFIG_CONTIG: - fprintf(fd, "single image plane\n"); - break; - case PLANARCONFIG_SEPARATE: - fprintf(fd, "separate image planes\n"); - break; - default: - fprintf(fd, "%u (0x%x)\n", - td->td_planarconfig, td->td_planarconfig); - break; - } - } - if (TIFFFieldSet(tif,FIELD_PAGENUMBER)) - fprintf(fd, " Page Number: %u-%u\n", - td->td_pagenumber[0], td->td_pagenumber[1]); - if (TIFFFieldSet(tif,FIELD_COLORMAP)) { - fprintf(fd, " Color Map: "); - if (flags & TIFFPRINT_COLORMAP) { - fprintf(fd, "\n"); - n = 1L<td_bitspersample; - for (l = 0; l < n; l++) - fprintf(fd, " %5ld: %5u %5u %5u\n", - l, - td->td_colormap[0][l], - td->td_colormap[1][l], - td->td_colormap[2][l]); - } else - fprintf(fd, "(present)\n"); - } - if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) { - int i; - fprintf(fd, " Reference Black/White:\n"); - for (i = 0; i < 3; i++) - fprintf(fd, " %2d: %5g %5g\n", i, - td->td_refblackwhite[2*i+0], - td->td_refblackwhite[2*i+1]); - } - if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) { - fprintf(fd, " Transfer Function: "); - if (flags & TIFFPRINT_CURVES) { - fprintf(fd, "\n"); - n = 1L<td_bitspersample; - for (l = 0; l < n; l++) { - uint16 i; - fprintf(fd, " %2ld: %5u", - l, td->td_transferfunction[0][l]); - for (i = 1; i < td->td_samplesperpixel - td->td_extrasamples && i < 3; i++) - fprintf(fd, " %5u", - td->td_transferfunction[i][l]); - fputc('\n', fd); - } - } else - fprintf(fd, "(present)\n"); - } - if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) { - uint16 i; - fprintf(fd, " SubIFD Offsets:"); - for (i = 0; i < td->td_nsubifd; i++) -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - fprintf(fd, " %5I64u", - (unsigned __int64) td->td_subifd[i]); -#else - fprintf(fd, " %5llu", - (unsigned long long) td->td_subifd[i]); -#endif - fputc('\n', fd); - } + fprintf(fd, "%sreduced-resolution image", sep); + sep = "/"; + } + if (td->td_subfiletype & FILETYPE_PAGE) + { + fprintf(fd, "%smulti-page document", sep); + sep = "/"; + } + if (td->td_subfiletype & FILETYPE_MASK) + fprintf(fd, "%stransparency mask", sep); + fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", td->td_subfiletype, + td->td_subfiletype); + } + if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) + { + fprintf(fd, " Image Width: %" PRIu32 " Image Length: %" PRIu32, + td->td_imagewidth, td->td_imagelength); + if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH)) + fprintf(fd, " Image Depth: %" PRIu32, td->td_imagedepth); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) + { + fprintf(fd, " Tile Width: %" PRIu32 " Tile Length: %" PRIu32, + td->td_tilewidth, td->td_tilelength); + if (TIFFFieldSet(tif, FIELD_TILEDEPTH)) + fprintf(fd, " Tile Depth: %" PRIu32, td->td_tiledepth); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_RESOLUTION)) + { + fprintf(fd, " Resolution: %g, %g", td->td_xresolution, + td->td_yresolution); + if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT)) + { + switch (td->td_resolutionunit) + { + case RESUNIT_NONE: + fprintf(fd, " (unitless)"); + break; + case RESUNIT_INCH: + fprintf(fd, " pixels/inch"); + break; + case RESUNIT_CENTIMETER: + fprintf(fd, " pixels/cm"); + break; + default: + fprintf(fd, " (unit %" PRIu16 " = 0x%" PRIx16 ")", + td->td_resolutionunit, td->td_resolutionunit); + break; + } + } + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_POSITION)) + fprintf(fd, " Position: %g, %g\n", td->td_xposition, td->td_yposition); + if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) + fprintf(fd, " Bits/Sample: %" PRIu16 "\n", td->td_bitspersample); + if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT)) + { + fprintf(fd, " Sample Format: "); + switch (td->td_sampleformat) + { + case SAMPLEFORMAT_VOID: + fprintf(fd, "void\n"); + break; + case SAMPLEFORMAT_INT: + fprintf(fd, "signed integer\n"); + break; + case SAMPLEFORMAT_UINT: + fprintf(fd, "unsigned integer\n"); + break; + case SAMPLEFORMAT_IEEEFP: + fprintf(fd, "IEEE floating point\n"); + break; + case SAMPLEFORMAT_COMPLEXINT: + fprintf(fd, "complex signed integer\n"); + break; + case SAMPLEFORMAT_COMPLEXIEEEFP: + fprintf(fd, "complex IEEE floating point\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_sampleformat, td->td_sampleformat); + break; + } + } + if (TIFFFieldSet(tif, FIELD_COMPRESSION)) + { + const TIFFCodec *c = TIFFFindCODEC(td->td_compression); + fprintf(fd, " Compression Scheme: "); + if (c) + fprintf(fd, "%s\n", c->name); + else + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_compression, + td->td_compression); + } + if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) + { + fprintf(fd, " Photometric Interpretation: "); + if (td->td_photometric < NPHOTONAMES) + fprintf(fd, "%s\n", photoNames[td->td_photometric]); + else + { + switch (td->td_photometric) + { + case PHOTOMETRIC_LOGL: + fprintf(fd, "CIE Log2(L)\n"); + break; + case PHOTOMETRIC_LOGLUV: + fprintf(fd, "CIE Log2(L) (u',v')\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_photometric, td->td_photometric); + break; + } + } + } + if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples) + { + uint16_t i; + fprintf(fd, " Extra Samples: %" PRIu16 "<", td->td_extrasamples); + sep = ""; + for (i = 0; i < td->td_extrasamples; i++) + { + switch (td->td_sampleinfo[i]) + { + case EXTRASAMPLE_UNSPECIFIED: + fprintf(fd, "%sunspecified", sep); + break; + case EXTRASAMPLE_ASSOCALPHA: + fprintf(fd, "%sassoc-alpha", sep); + break; + case EXTRASAMPLE_UNASSALPHA: + fprintf(fd, "%sunassoc-alpha", sep); + break; + default: + fprintf(fd, "%s%" PRIu16 " (0x%" PRIx16 ")", sep, + td->td_sampleinfo[i], td->td_sampleinfo[i]); + break; + } + sep = ", "; + } + fprintf(fd, ">\n"); + } + if (TIFFFieldSet(tif, FIELD_INKNAMES)) + { + char *cp; + uint16_t i; + fprintf(fd, " Ink Names: "); + i = td->td_samplesperpixel; + sep = ""; + for (cp = td->td_inknames; + i > 0 && cp < td->td_inknames + td->td_inknameslen; + cp = strchr(cp, '\0') + 1, i--) + { + size_t max_chars = td->td_inknameslen - (cp - td->td_inknames); + fputs(sep, fd); + _TIFFprintAsciiBounded(fd, cp, max_chars); + sep = ", "; + } + fputs("\n", fd); + } + if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) + { + fprintf(fd, " NumberOfInks: %d\n", td->td_numberofinks); + } + if (TIFFFieldSet(tif, FIELD_THRESHHOLDING)) + { + fprintf(fd, " Thresholding: "); + switch (td->td_threshholding) + { + case THRESHHOLD_BILEVEL: + fprintf(fd, "bilevel art scan\n"); + break; + case THRESHHOLD_HALFTONE: + fprintf(fd, "halftone or dithered scan\n"); + break; + case THRESHHOLD_ERRORDIFFUSE: + fprintf(fd, "error diffused\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_threshholding, td->td_threshholding); + break; + } + } + if (TIFFFieldSet(tif, FIELD_FILLORDER)) + { + fprintf(fd, " FillOrder: "); + switch (td->td_fillorder) + { + case FILLORDER_MSB2LSB: + fprintf(fd, "msb-to-lsb\n"); + break; + case FILLORDER_LSB2MSB: + fprintf(fd, "lsb-to-msb\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_fillorder, + td->td_fillorder); + break; + } + } + if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING)) + { + fprintf(fd, " YCbCr Subsampling: %" PRIu16 ", %" PRIu16 "\n", + td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1]); + } + if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING)) + { + fprintf(fd, " YCbCr Positioning: "); + switch (td->td_ycbcrpositioning) + { + case YCBCRPOSITION_CENTERED: + fprintf(fd, "centered\n"); + break; + case YCBCRPOSITION_COSITED: + fprintf(fd, "cosited\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_ycbcrpositioning, td->td_ycbcrpositioning); + break; + } + } + if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS)) + fprintf(fd, " Halftone Hints: light %" PRIu16 " dark %" PRIu16 "\n", + td->td_halftonehints[0], td->td_halftonehints[1]); + if (TIFFFieldSet(tif, FIELD_ORIENTATION)) + { + fprintf(fd, " Orientation: "); + if (td->td_orientation < NORIENTNAMES) + fprintf(fd, "%s\n", orientNames[td->td_orientation]); + else + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_orientation, + td->td_orientation); + } + if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + fprintf(fd, " Samples/Pixel: %" PRIx16 "\n", td->td_samplesperpixel); + if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) + { + fprintf(fd, " Rows/Strip: "); + if (td->td_rowsperstrip == (uint32_t)-1) + fprintf(fd, "(infinite)\n"); + else + fprintf(fd, "%" PRIu32 "\n", td->td_rowsperstrip); + } + if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE)) + fprintf(fd, " Min Sample Value: %" PRIu16 "\n", td->td_minsamplevalue); + if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) + fprintf(fd, " Max Sample Value: %" PRIu16 "\n", td->td_maxsamplevalue); + if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE)) + { + int i; + int count = + (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; + fprintf(fd, " SMin Sample Value:"); + for (i = 0; i < count; ++i) + fprintf(fd, " %g", td->td_sminsamplevalue[i]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE)) + { + int i; + int count = + (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; + fprintf(fd, " SMax Sample Value:"); + for (i = 0; i < count; ++i) + fprintf(fd, " %g", td->td_smaxsamplevalue[i]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_PLANARCONFIG)) + { + fprintf(fd, " Planar Configuration: "); + switch (td->td_planarconfig) + { + case PLANARCONFIG_CONTIG: + fprintf(fd, "single image plane\n"); + break; + case PLANARCONFIG_SEPARATE: + fprintf(fd, "separate image planes\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_planarconfig, td->td_planarconfig); + break; + } + } + if (TIFFFieldSet(tif, FIELD_PAGENUMBER)) + fprintf(fd, " Page Number: %" PRIu16 "-%" PRIu16 "\n", + td->td_pagenumber[0], td->td_pagenumber[1]); + if (TIFFFieldSet(tif, FIELD_COLORMAP)) + { + fprintf(fd, " Color Map: "); + if (flags & TIFFPRINT_COLORMAP) + { + fprintf(fd, "\n"); + n = 1L << td->td_bitspersample; + for (l = 0; l < n; l++) + fprintf(fd, " %5ld: %5" PRIu16 " %5" PRIu16 " %5" PRIu16 "\n", + l, td->td_colormap[0][l], td->td_colormap[1][l], + td->td_colormap[2][l]); + } + else + fprintf(fd, "(present)\n"); + } + if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE)) + { + int i; + fprintf(fd, " Reference Black/White:\n"); + for (i = 0; i < 3; i++) + fprintf(fd, " %2d: %5g %5g\n", i, + td->td_refblackwhite[2 * i + 0], + td->td_refblackwhite[2 * i + 1]); + } + if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION)) + { + fprintf(fd, " Transfer Function: "); + if (flags & TIFFPRINT_CURVES) + { + fprintf(fd, "\n"); + n = 1L << td->td_bitspersample; + for (l = 0; l < n; l++) + { + uint16_t i; + fprintf(fd, " %2ld: %5" PRIu16, l, + td->td_transferfunction[0][l]); + for (i = 1; + i < td->td_samplesperpixel - td->td_extrasamples && i < 3; + i++) + fprintf(fd, " %5" PRIu16, td->td_transferfunction[i][l]); + fputc('\n', fd); + } + } + else + fprintf(fd, "(present)\n"); + } + if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) + { + uint16_t i; + fprintf(fd, " SubIFD Offsets:"); + for (i = 0; i < td->td_nsubifd; i++) + fprintf(fd, " %5" PRIu64, td->td_subifd[i]); + fputc('\n', fd); + } - /* - ** Custom tag support. - */ - { - int i; - short count; + /* + ** Custom tag support. + */ + { + int i; + short count; - count = (short) TIFFGetTagListCount(tif); - for(i = 0; i < count; i++) { - uint32 tag = TIFFGetTagListEntry(tif, i); - const TIFFField *fip; - uint32 value_count; - int mem_alloc = 0; - void *raw_data; + count = (short)TIFFGetTagListCount(tif); + for (i = 0; i < count; i++) + { + uint32_t tag = TIFFGetTagListEntry(tif, i); + const TIFFField *fip; + uint32_t value_count; + int mem_alloc = 0; + void *raw_data = NULL; + uint16_t dotrange[2]; /* must be kept in that scope and not moved in + the below TIFFTAG_DOTRANGE specific case */ - fip = TIFFFieldWithTag(tif, tag); - if(fip == NULL) - continue; + fip = TIFFFieldWithTag(tif, tag); + if (fip == NULL) + continue; - if(fip->field_passcount) { - if (fip->field_readcount == TIFF_VARIABLE2 ) { - if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) - continue; - } else if (fip->field_readcount == TIFF_VARIABLE ) { - uint16 small_value_count; - if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1) - continue; - value_count = small_value_count; - } else { - assert (fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2); - continue; - } - } else { - if (fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2) - value_count = 1; - else if (fip->field_readcount == TIFF_SPP) - value_count = td->td_samplesperpixel; - else - value_count = fip->field_readcount; - if (fip->field_tag == TIFFTAG_DOTRANGE - && strcmp(fip->field_name,"DotRange") == 0) { - /* TODO: This is an evil exception and should not have been - handled this way ... likely best if we move it into - the directory structure with an explicit field in - libtiff 4.1 and assign it a FIELD_ value */ - static uint16 dotrange[2]; - raw_data = dotrange; - TIFFGetField(tif, tag, dotrange+0, dotrange+1); - } else if (fip->field_type == TIFF_ASCII - || fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2 - || fip->field_readcount == TIFF_SPP - || value_count > 1) { - if(TIFFGetField(tif, tag, &raw_data) != 1) - continue; - } else { - raw_data = _TIFFmalloc( - _TIFFDataSize(fip->field_type) - * value_count); - mem_alloc = 1; - if(TIFFGetField(tif, tag, raw_data) != 1) { - _TIFFfree(raw_data); - continue; - } - } - } + if (fip->field_passcount) + { + if (fip->field_readcount == TIFF_VARIABLE2) + { + if (TIFFGetField(tif, tag, &value_count, &raw_data) != 1) + continue; + } + else if (fip->field_readcount == TIFF_VARIABLE) + { + uint16_t small_value_count; + if (TIFFGetField(tif, tag, &small_value_count, &raw_data) != + 1) + continue; + value_count = small_value_count; + } + else + { + assert(fip->field_readcount == TIFF_VARIABLE || + fip->field_readcount == TIFF_VARIABLE2); + continue; + } + } + else + { + if (fip->field_readcount == TIFF_VARIABLE || + fip->field_readcount == TIFF_VARIABLE2) + value_count = 1; + else if (fip->field_readcount == TIFF_SPP) + value_count = td->td_samplesperpixel; + else + value_count = fip->field_readcount; + if (fip->field_tag == TIFFTAG_DOTRANGE && + strcmp(fip->field_name, "DotRange") == 0) + { + /* TODO: This is an evil exception and should not have been + handled this way ... likely best if we move it into + the directory structure with an explicit field in + libtiff 4.1 and assign it a FIELD_ value */ + raw_data = dotrange; + TIFFGetField(tif, tag, dotrange + 0, dotrange + 1); + } + else if (fip->field_type == TIFF_ASCII || + fip->field_readcount == TIFF_VARIABLE || + fip->field_readcount == TIFF_VARIABLE2 || + fip->field_readcount == TIFF_SPP || value_count > 1) + { + if (TIFFGetField(tif, tag, &raw_data) != 1) + continue; + } + else + { + /*--: Rational2Double: For Rationals evaluate + * "set_field_type" to determine internal storage size. */ + int tv_size = TIFFFieldSetGetSize(fip); + raw_data = _TIFFmallocExt(tif, tv_size * value_count); + mem_alloc = 1; + if (TIFFGetField(tif, tag, raw_data) != 1) + { + _TIFFfreeExt(tif, raw_data); + continue; + } + } + } - /* - * Catch the tags which needs to be specially handled - * and pretty print them. If tag not handled in - * _TIFFPrettyPrintField() fall down and print it as - * any other tag. - */ - if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data)) - _TIFFPrintField(fd, fip, value_count, raw_data); + /* + * Catch the tags which needs to be specially handled + * and pretty print them. If tag not handled in + * _TIFFPrettyPrintField() fall down and print it as + * any other tag. + */ + if (raw_data != NULL && + !_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, + raw_data)) + _TIFFPrintField(fd, fip, value_count, raw_data); - if(mem_alloc) - _TIFFfree(raw_data); - } - } - - if (tif->tif_tagmethods.printdir) - (*tif->tif_tagmethods.printdir)(tif, fd, flags); + if (mem_alloc) + _TIFFfreeExt(tif, raw_data); + } + } - if ((flags & TIFFPRINT_STRIPS) && - TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) { - uint32 s; + if (tif->tif_tagmethods.printdir) + (*tif->tif_tagmethods.printdir)(tif, fd, flags); - fprintf(fd, " %lu %s:\n", - (unsigned long) td->td_nstrips, - isTiled(tif) ? "Tiles" : "Strips"); - for (s = 0; s < td->td_nstrips; s++) -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - fprintf(fd, " %3lu: [%8I64u, %8I64u]\n", - (unsigned long) s, - (unsigned __int64) TIFFGetStrileOffset(tif, s), - (unsigned __int64) TIFFGetStrileByteCount(tif, s)); -#else - fprintf(fd, " %3lu: [%8llu, %8llu]\n", - (unsigned long) s, - (unsigned long long) TIFFGetStrileOffset(tif, s), - (unsigned long long) TIFFGetStrileByteCount(tif, s)); -#endif - } + if ((flags & TIFFPRINT_STRIPS) && TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) + { + uint32_t s; + + fprintf(fd, " %" PRIu32 " %s:\n", td->td_nstrips, + isTiled(tif) ? "Tiles" : "Strips"); + for (s = 0; s < td->td_nstrips; s++) + fprintf(fd, " %3" PRIu32 ": [%8" PRIu64 ", %8" PRIu64 "]\n", s, + TIFFGetStrileOffset(tif, s), + TIFFGetStrileByteCount(tif, s)); + } } -void -_TIFFprintAscii(FILE* fd, const char* cp) +void _TIFFprintAscii(FILE *fd, const char *cp) { - _TIFFprintAsciiBounded( fd, cp, strlen(cp)); + _TIFFprintAsciiBounded(fd, cp, strlen(cp)); } -static void -_TIFFprintAsciiBounded(FILE* fd, const char* cp, size_t max_chars) +static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars) { - for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) { - const char* tp; + for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) + { + const char *tp; - if (isprint((int)*cp)) { - fputc(*cp, fd); - continue; - } - for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++) - if (*tp++ == *cp) - break; - if (*tp) - fprintf(fd, "\\%c", *tp); - else - fprintf(fd, "\\%03o", *cp & 0xff); - } + if (isprint((int)*cp)) + { + fputc(*cp, fd); + continue; + } + for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++) + if (*tp++ == *cp) + break; + if (*tp) + fprintf(fd, "\\%c", *tp); + else + fprintf(fd, "\\%03o", *cp & 0xff); + } } -void -_TIFFprintAsciiTag(FILE* fd, const char* name, const char* value) +void _TIFFprintAsciiTag(FILE *fd, const char *name, const char *value) { - fprintf(fd, " %s: \"", name); - _TIFFprintAscii(fd, value); - fprintf(fd, "\"\n"); + fprintf(fd, " %s: \"", name); + _TIFFprintAscii(fd, value); + fprintf(fd, "\"\n"); } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_read.c b/3rdparty/libtiff/tif_read.c index c4c868b1c5..4fec83969e 100644 --- a/3rdparty/libtiff/tif_read.c +++ b/3rdparty/libtiff/tif_read.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,292 +29,273 @@ #include "tiffiop.h" #include -int TIFFFillStrip(TIFF* tif, uint32 strip); -int TIFFFillTile(TIFF* tif, uint32 tile); -static int TIFFStartStrip(TIFF* tif, uint32 strip); -static int TIFFStartTile(TIFF* tif, uint32 tile); -static int TIFFCheckRead(TIFF*, int); -static tmsize_t -TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,const char* module); -static tmsize_t -TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module); +int TIFFFillStrip(TIFF *tif, uint32_t strip); +int TIFFFillTile(TIFF *tif, uint32_t tile); +static int TIFFStartStrip(TIFF *tif, uint32_t strip); +static int TIFFStartTile(TIFF *tif, uint32_t tile); +static int TIFFCheckRead(TIFF *, int); +static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size, const char *module); +static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf, + tmsize_t size, const char *module); -#define NOSTRIP ((uint32)(-1)) /* undefined state */ -#define NOTILE ((uint32)(-1)) /* undefined state */ +#define NOSTRIP ((uint32_t)(-1)) /* undefined state */ +#define NOTILE ((uint32_t)(-1)) /* undefined state */ #define INITIAL_THRESHOLD (1024 * 1024) #define THRESHOLD_MULTIPLIER 10 -#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD) +#define MAX_THRESHOLD \ + (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \ + INITIAL_THRESHOLD) -#define TIFF_INT64_MAX ((((int64)0x7FFFFFFF) << 32) | 0xFFFFFFFF) +#define TIFF_INT64_MAX ((((int64_t)0x7FFFFFFF) << 32) | 0xFFFFFFFF) /* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset' * Returns 1 in case of success, 0 otherwise. */ -static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size, - tmsize_t rawdata_offset, - int is_strip, uint32 strip_or_tile, - const char* module ) +static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset, + int is_strip, uint32_t strip_or_tile, + const char *module) { #if SIZEOF_SIZE_T == 8 - tmsize_t threshold = INITIAL_THRESHOLD; + tmsize_t threshold = INITIAL_THRESHOLD; #endif - tmsize_t already_read = 0; - + tmsize_t already_read = 0; #if SIZEOF_SIZE_T != 8 - /* On 32 bit processes, if the request is large enough, check against */ - /* file size */ - if( size > 1000 * 1000 * 1000 ) + /* On 32 bit processes, if the request is large enough, check against */ + /* file size */ + if (size > 1000 * 1000 * 1000) + { + uint64_t filesize = TIFFGetFileSize(tif); + if ((uint64_t)size >= filesize) { - uint64 filesize = TIFFGetFileSize(tif); - if( (uint64)size >= filesize ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Chunk size requested is larger than file size."); - return 0; - } + TIFFErrorExtR(tif, module, + "Chunk size requested is larger than file size."); + return 0; } + } #endif - /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ - /* so as to avoid allocating too much memory in case the file is too */ - /* short. We could ask for the file size, but this might be */ - /* expensive with some I/O layers (think of reading a gzipped file) */ - /* Restrict to 64 bit processes, so as to avoid reallocs() */ - /* on 32 bit processes where virtual memory is scarce. */ - while( already_read < size ) - { - tmsize_t bytes_read; - tmsize_t to_read = size - already_read; + /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ + /* so as to avoid allocating too much memory in case the file is too */ + /* short. We could ask for the file size, but this might be */ + /* expensive with some I/O layers (think of reading a gzipped file) */ + /* Restrict to 64 bit processes, so as to avoid reallocs() */ + /* on 32 bit processes where virtual memory is scarce. */ + while (already_read < size) + { + tmsize_t bytes_read; + tmsize_t to_read = size - already_read; #if SIZEOF_SIZE_T == 8 - if( to_read >= threshold && threshold < MAX_THRESHOLD && - already_read + to_read + rawdata_offset > tif->tif_rawdatasize ) - { - to_read = threshold; - threshold *= THRESHOLD_MULTIPLIER; - } -#endif - if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) { - uint8* new_rawdata; - assert((tif->tif_flags & TIFF_MYBUFFER) != 0); - tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64( - (uint64)already_read + to_read + rawdata_offset, 1024); - if (tif->tif_rawdatasize==0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Invalid buffer size"); - return 0; - } - new_rawdata = (uint8*) _TIFFrealloc( - tif->tif_rawdata, tif->tif_rawdatasize); - if( new_rawdata == 0 ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "No space for data buffer at scanline %lu", - (unsigned long) tif->tif_row); - _TIFFfree(tif->tif_rawdata); - tif->tif_rawdata = 0; - tif->tif_rawdatasize = 0; - return 0; - } - tif->tif_rawdata = new_rawdata; - } - if( tif->tif_rawdata == NULL ) - { - /* should not happen in practice but helps CoverityScan */ - return 0; - } - - bytes_read = TIFFReadFile(tif, - tif->tif_rawdata + rawdata_offset + already_read, to_read); - already_read += bytes_read; - if (bytes_read != to_read) { - memset( tif->tif_rawdata + rawdata_offset + already_read, 0, - tif->tif_rawdatasize - rawdata_offset - already_read ); -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - if( is_strip ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at scanline %lu; got %I64u bytes, " - "expected %I64u", - (unsigned long) tif->tif_row, - (unsigned __int64) already_read, - (unsigned __int64) size); - } - else - { - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at row %lu, col %lu, tile %lu; " - "got %I64u bytes, expected %I64u", - (unsigned long) tif->tif_row, - (unsigned long) tif->tif_col, - (unsigned long) strip_or_tile, - (unsigned __int64) already_read, - (unsigned __int64) size); - } -#else - if( is_strip ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at scanline %lu; got %llu bytes, " - "expected %llu", - (unsigned long) tif->tif_row, - (unsigned long long) already_read, - (unsigned long long) size); - } - else - { - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at row %lu, col %lu, tile %lu; " - "got %llu bytes, expected %llu", - (unsigned long) tif->tif_row, - (unsigned long) tif->tif_col, - (unsigned long) strip_or_tile, - (unsigned long long) already_read, - (unsigned long long) size); - } -#endif - return 0; - } + if (to_read >= threshold && threshold < MAX_THRESHOLD && + already_read + to_read + rawdata_offset > tif->tif_rawdatasize) + { + to_read = threshold; + threshold *= THRESHOLD_MULTIPLIER; } - return 1; +#endif + if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) + { + uint8_t *new_rawdata; + assert((tif->tif_flags & TIFF_MYBUFFER) != 0); + tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64( + (uint64_t)already_read + to_read + rawdata_offset, 1024); + if (tif->tif_rawdatasize == 0) + { + TIFFErrorExtR(tif, module, "Invalid buffer size"); + return 0; + } + new_rawdata = + (uint8_t *)_TIFFrealloc(tif->tif_rawdata, tif->tif_rawdatasize); + if (new_rawdata == 0) + { + TIFFErrorExtR(tif, module, + "No space for data buffer at scanline %" PRIu32, + tif->tif_row); + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = 0; + tif->tif_rawdatasize = 0; + return 0; + } + tif->tif_rawdata = new_rawdata; + } + if (tif->tif_rawdata == NULL) + { + /* should not happen in practice but helps CoverityScan */ + return 0; + } + + bytes_read = TIFFReadFile( + tif, tif->tif_rawdata + rawdata_offset + already_read, to_read); + already_read += bytes_read; + if (bytes_read != to_read) + { + memset(tif->tif_rawdata + rawdata_offset + already_read, 0, + tif->tif_rawdatasize - rawdata_offset - already_read); + if (is_strip) + { + TIFFErrorExtR(tif, module, + "Read error at scanline %" PRIu32 + "; got %" TIFF_SSIZE_FORMAT " bytes, " + "expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, already_read, size); + } + else + { + TIFFErrorExtR(tif, module, + "Read error at row %" PRIu32 ", col %" PRIu32 + ", tile %" PRIu32 "; " + "got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT "", + tif->tif_row, tif->tif_col, strip_or_tile, + already_read, size); + } + return 0; + } + } + return 1; } - -static int -TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) +static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead, + int restart) { - static const char module[] = "TIFFFillStripPartial"; - register TIFFDirectory *td = &tif->tif_dir; - tmsize_t unused_data; - uint64 read_offset; - tmsize_t to_read; - tmsize_t read_ahead_mod; - /* tmsize_t bytecountm; */ + static const char module[] = "TIFFFillStripPartial"; + register TIFFDirectory *td = &tif->tif_dir; + tmsize_t unused_data; + uint64_t read_offset; + tmsize_t to_read; + tmsize_t read_ahead_mod; + /* tmsize_t bytecountm; */ - /* - * Expand raw data buffer, if needed, to hold data - * strip coming from file (perhaps should set upper - * bound on the size of a buffer we'll use?). - */ + /* + * Expand raw data buffer, if needed, to hold data + * strip coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ - /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */ + /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */ - /* Not completely sure where the * 2 comes from, but probably for */ - /* an exponentional growth strategy of tif_rawdatasize */ - if( read_ahead < TIFF_TMSIZE_T_MAX / 2 ) - read_ahead_mod = read_ahead * 2; - else - read_ahead_mod = read_ahead; - if (read_ahead_mod > tif->tif_rawdatasize) { - assert( restart ); - - tif->tif_curstrip = NOSTRIP; - if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Data buffer too small to hold part of strip %lu", - (unsigned long) strip); - return (0); - } - } + /* Not completely sure where the * 2 comes from, but probably for */ + /* an exponentional growth strategy of tif_rawdatasize */ + if (read_ahead < TIFF_TMSIZE_T_MAX / 2) + read_ahead_mod = read_ahead * 2; + else + read_ahead_mod = read_ahead; + if (read_ahead_mod > tif->tif_rawdatasize) + { + assert(restart); - if( restart ) + tif->tif_curstrip = NOSTRIP; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - tif->tif_rawdataloaded = 0; - tif->tif_rawdataoff = 0; + TIFFErrorExtR(tif, module, + "Data buffer too small to hold part of strip %d", + strip); + return (0); } + } - /* - ** If we are reading more data, move any unused data to the - ** start of the buffer. - */ - if( tif->tif_rawdataloaded > 0 ) - unused_data = tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata); - else - unused_data = 0; - - if( unused_data > 0 ) - { - assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); - memmove( tif->tif_rawdata, tif->tif_rawcp, unused_data ); - } + if (restart) + { + tif->tif_rawdataloaded = 0; + tif->tif_rawdataoff = 0; + } - /* - ** Seek to the point in the file where more data should be read. - */ - read_offset = TIFFGetStrileOffset(tif, strip) - + tif->tif_rawdataoff + tif->tif_rawdataloaded; + /* + ** If we are reading more data, move any unused data to the + ** start of the buffer. + */ + if (tif->tif_rawdataloaded > 0) + unused_data = + tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata); + else + unused_data = 0; - if (!SeekOK(tif, read_offset)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Seek error at scanline %lu, strip %lu", - (unsigned long) tif->tif_row, (unsigned long) strip); - return 0; - } + if (unused_data > 0) + { + assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); + memmove(tif->tif_rawdata, tif->tif_rawcp, unused_data); + } - /* - ** How much do we want to read? - */ - if( read_ahead_mod > tif->tif_rawdatasize ) - to_read = read_ahead_mod - unused_data; - else - to_read = tif->tif_rawdatasize - unused_data; - if( (uint64) to_read > TIFFGetStrileByteCount(tif, strip) - - tif->tif_rawdataoff - tif->tif_rawdataloaded ) - { - to_read = (tmsize_t) TIFFGetStrileByteCount(tif, strip) - - tif->tif_rawdataoff - tif->tif_rawdataloaded; - } + /* + ** Seek to the point in the file where more data should be read. + */ + read_offset = TIFFGetStrileOffset(tif, strip) + tif->tif_rawdataoff + + tif->tif_rawdataloaded; - assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); - if( !TIFFReadAndRealloc( tif, to_read, unused_data, - 1, /* is_strip */ - 0, /* strip_or_tile */ - module) ) - { - return 0; - } + if (!SeekOK(tif, read_offset)) + { + TIFFErrorExtR(tif, module, + "Seek error at scanline %" PRIu32 ", strip %d", + tif->tif_row, strip); + return 0; + } - tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ; - tif->tif_rawdataloaded = unused_data + to_read; + /* + ** How much do we want to read? + */ + if (read_ahead_mod > tif->tif_rawdatasize) + to_read = read_ahead_mod - unused_data; + else + to_read = tif->tif_rawdatasize - unused_data; + if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, strip) - + tif->tif_rawdataoff - tif->tif_rawdataloaded) + { + to_read = (tmsize_t)TIFFGetStrileByteCount(tif, strip) - + tif->tif_rawdataoff - tif->tif_rawdataloaded; + } - tif->tif_rawcc = tif->tif_rawdataloaded; - tif->tif_rawcp = tif->tif_rawdata; - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) { - assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); - TIFFReverseBits(tif->tif_rawdata + unused_data, to_read ); - } + assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); + if (!TIFFReadAndRealloc(tif, to_read, unused_data, 1, /* is_strip */ + 0, /* strip_or_tile */ + module)) + { + return 0; + } - /* - ** When starting a strip from the beginning we need to - ** restart the decoder. - */ - if( restart ) - { + tif->tif_rawdataoff = + tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data; + tif->tif_rawdataloaded = unused_data + to_read; + + tif->tif_rawcc = tif->tif_rawdataloaded; + tif->tif_rawcp = tif->tif_rawdata; + + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + { + assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); + TIFFReverseBits(tif->tif_rawdata + unused_data, to_read); + } + + /* + ** When starting a strip from the beginning we need to + ** restart the decoder. + */ + if (restart) + { #ifdef JPEG_SUPPORT - /* A bit messy since breaks the codec abstraction. Ultimately */ - /* there should be a function pointer for that, but it seems */ - /* only JPEG is affected. */ - /* For JPEG, if there are multiple scans (can generally be known */ - /* with the read_ahead used), we need to read the whole strip */ - if( tif->tif_dir.td_compression==COMPRESSION_JPEG && - (uint64)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip) ) + /* A bit messy since breaks the codec abstraction. Ultimately */ + /* there should be a function pointer for that, but it seems */ + /* only JPEG is affected. */ + /* For JPEG, if there are multiple scans (can generally be known */ + /* with the read_ahead used), we need to read the whole strip */ + if (tif->tif_dir.td_compression == COMPRESSION_JPEG && + (uint64_t)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip)) + { + if (TIFFJPEGIsFullStripRequired(tif)) { - if( TIFFJPEGIsFullStripRequired(tif) ) - { - return TIFFFillStrip(tif, strip); - } + return TIFFFillStrip(tif, strip); } + } #endif - return TIFFStartStrip(tif, strip); - } - else - { - return 1; - } + return TIFFStartStrip(tif, strip); + } + else + { + return 1; + } } /* @@ -325,159 +306,165 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) * and avoid reading the whole compressed raw data for big * strips. */ -static int -TIFFSeek(TIFF* tif, uint32 row, uint16 sample ) +static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) { - register TIFFDirectory *td = &tif->tif_dir; - uint32 strip; - int whole_strip; - tmsize_t read_ahead = 0; + register TIFFDirectory *td = &tif->tif_dir; + uint32_t strip; + int whole_strip; + tmsize_t read_ahead = 0; - /* - ** Establish what strip we are working from. - */ - if (row >= td->td_imagelength) { /* out of range */ - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Row out of range, max %lu", - (unsigned long) row, - (unsigned long) td->td_imagelength); - return (0); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - if (sample >= td->td_samplesperpixel) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Sample out of range, max %lu", - (unsigned long) sample, (unsigned long) td->td_samplesperpixel); - return (0); - } - strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowsperstrip; - } else - strip = row / td->td_rowsperstrip; + /* + ** Establish what strip we are working from. + */ + if (row >= td->td_imagelength) + { /* out of range */ + TIFFErrorExtR(tif, tif->tif_name, + "%" PRIu32 ": Row out of range, max %" PRIu32 "", row, + td->td_imagelength); + return (0); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + if (sample >= td->td_samplesperpixel) + { + TIFFErrorExtR(tif, tif->tif_name, + "%" PRIu16 ": Sample out of range, max %" PRIu16 "", + sample, td->td_samplesperpixel); + return (0); + } + strip = (uint32_t)sample * td->td_stripsperimage + + row / td->td_rowsperstrip; + } + else + strip = row / td->td_rowsperstrip; /* * Do we want to treat this strip as one whole chunk or * read it a few lines at a time? */ #if defined(CHUNKY_STRIP_READ_SUPPORT) - whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 - || isMapped(tif); - if( td->td_compression == COMPRESSION_LERC || - td->td_compression == COMPRESSION_JBIG ) - { - /* Ideally plugins should have a way to declare they don't support - * chunk strip */ - whole_strip = 1; - } -#else + whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif); + if (td->td_compression == COMPRESSION_LERC || + td->td_compression == COMPRESSION_JBIG) + { + /* Ideally plugins should have a way to declare they don't support + * chunk strip */ whole_strip = 1; + } +#else + whole_strip = 1; #endif - - if( !whole_strip ) - { - /* 16 is for YCbCr mode where we may need to read 16 */ - /* lines at a time to get a decompressed line, and 5000 */ - /* is some constant value, for example for JPEG tables */ - if( tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 && - tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000 ) - { - read_ahead = tif->tif_scanlinesize * 16 + 5000; - } - else - { - read_ahead = tif->tif_scanlinesize; - } - } + if (!whole_strip) + { + /* 16 is for YCbCr mode where we may need to read 16 */ + /* lines at a time to get a decompressed line, and 5000 */ + /* is some constant value, for example for JPEG tables */ + if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 && + tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000) + { + read_ahead = tif->tif_scanlinesize * 16 + 5000; + } + else + { + read_ahead = tif->tif_scanlinesize; + } + } + + /* + * If we haven't loaded this strip, do so now, possibly + * only reading the first part. + */ + if (strip != tif->tif_curstrip) + { /* different strip, refill */ + + if (whole_strip) + { + if (!TIFFFillStrip(tif, strip)) + return (0); + } + else + { + if (!TIFFFillStripPartial(tif, strip, read_ahead, 1)) + return 0; + } + } + + /* + ** If we already have some data loaded, do we need to read some more? + */ + else if (!whole_strip) + { + if (((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < + read_ahead && + (uint64_t)tif->tif_rawdataoff + tif->tif_rawdataloaded < + TIFFGetStrileByteCount(tif, strip)) + { + if (!TIFFFillStripPartial(tif, strip, read_ahead, 0)) + return 0; + } + } + + if (row < tif->tif_row) + { /* - * If we haven't loaded this strip, do so now, possibly - * only reading the first part. + * Moving backwards within the same strip: backup + * to the start and then decode forward (below). + * + * NB: If you're planning on lots of random access within a + * strip, it's better to just read and decode the entire + * strip, and then access the decoded data in a random fashion. */ - if (strip != tif->tif_curstrip) { /* different strip, refill */ - - if( whole_strip ) - { - if (!TIFFFillStrip(tif, strip)) - return (0); - } - else - { - if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) - return 0; - } - } - /* - ** If we already have some data loaded, do we need to read some more? - */ - else if( !whole_strip ) + if (tif->tif_rawdataoff != 0) { - if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead - && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < TIFFGetStrileByteCount(tif, strip) ) - { - if( !TIFFFillStripPartial(tif,strip,read_ahead,0) ) - return 0; - } + if (!TIFFFillStripPartial(tif, strip, read_ahead, 1)) + return 0; } + else + { + if (!TIFFStartStrip(tif, strip)) + return (0); + } + } - if (row < tif->tif_row) { - /* - * Moving backwards within the same strip: backup - * to the start and then decode forward (below). - * - * NB: If you're planning on lots of random access within a - * strip, it's better to just read and decode the entire - * strip, and then access the decoded data in a random fashion. - */ + if (row != tif->tif_row) + { + /* + * Seek forward to the desired row. + */ - if( tif->tif_rawdataoff != 0 ) - { - if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) - return 0; - } - else - { - if (!TIFFStartStrip(tif, strip)) - return (0); - } - } - - if (row != tif->tif_row) { - /* - * Seek forward to the desired row. - */ + /* TODO: Will this really work with partial buffers? */ - /* TODO: Will this really work with partial buffers? */ - - if (!(*tif->tif_seek)(tif, row - tif->tif_row)) - return (0); - tif->tif_row = row; - } + if (!(*tif->tif_seek)(tif, row - tif->tif_row)) + return (0); + tif->tif_row = row; + } - return (1); + return (1); } -int -TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) +int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) { - int e; + int e; - if (!TIFFCheckRead(tif, 0)) - return (-1); - if( (e = TIFFSeek(tif, row, sample)) != 0) { - /* - * Decompress desired row into user buffer. - */ - e = (*tif->tif_decoderow) - (tif, (uint8*) buf, tif->tif_scanlinesize, sample); + if (!TIFFCheckRead(tif, 0)) + return (-1); + if ((e = TIFFSeek(tif, row, sample)) != 0) + { + /* + * Decompress desired row into user buffer. + */ + e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize, + sample); - /* we are now poised at the beginning of the next row */ - tif->tif_row = row + 1; + /* we are now poised at the beginning of the next row */ + tif->tif_row = row + 1; - if (e) - (*tif->tif_postdecode)(tif, (uint8*) buf, - tif->tif_scanlinesize); - } - return (e > 0 ? 1 : -1); + if (e) + (*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize); + } + return (e > 0 ? 1 : -1); } /* @@ -485,471 +472,436 @@ TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) * rows in the strip (check for truncated last strip on any * of the separations). */ -static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF* tif, uint32 strip, uint16* pplane) +static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip, + uint16_t *pplane) { - static const char module[] = "TIFFReadEncodedStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint32 rowsperstrip; - uint32 stripsperplane; - uint32 stripinplane; - uint32 rows; - tmsize_t stripsize; - if (!TIFFCheckRead(tif,0)) - return((tmsize_t)(-1)); - if (strip>=td->td_nstrips) - { - TIFFErrorExt(tif->tif_clientdata,module, - "%lu: Strip out of range, max %lu",(unsigned long)strip, - (unsigned long)td->td_nstrips); - return((tmsize_t)(-1)); - } + static const char module[] = "TIFFReadEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint32_t rowsperstrip; + uint32_t stripsperplane; + uint32_t stripinplane; + uint32_t rows; + tmsize_t stripsize; + if (!TIFFCheckRead(tif, 0)) + return ((tmsize_t)(-1)); + if (strip >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Strip out of range, max %" PRIu32, strip, + td->td_nstrips); + return ((tmsize_t)(-1)); + } - rowsperstrip=td->td_rowsperstrip; - if (rowsperstrip>td->td_imagelength) - rowsperstrip=td->td_imagelength; - stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); - stripinplane=(strip%stripsperplane); - if( pplane ) *pplane=(uint16)(strip/stripsperplane); - rows=td->td_imagelength-stripinplane*rowsperstrip; - if (rows>rowsperstrip) - rows=rowsperstrip; - stripsize=TIFFVStripSize(tif,rows); - if (stripsize==0) - return((tmsize_t)(-1)); - return stripsize; + rowsperstrip = td->td_rowsperstrip; + if (rowsperstrip > td->td_imagelength) + rowsperstrip = td->td_imagelength; + stripsperplane = + TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); + stripinplane = (strip % stripsperplane); + if (pplane) + *pplane = (uint16_t)(strip / stripsperplane); + rows = td->td_imagelength - stripinplane * rowsperstrip; + if (rows > rowsperstrip) + rows = rowsperstrip; + stripsize = TIFFVStripSize(tif, rows); + if (stripsize == 0) + return ((tmsize_t)(-1)); + return stripsize; } /* * Read a strip of data and decompress the specified * amount into the user-supplied buffer. */ -tmsize_t -TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) +tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size) { - static const char module[] = "TIFFReadEncodedStrip"; - TIFFDirectory *td = &tif->tif_dir; - tmsize_t stripsize; - uint16 plane; + static const char module[] = "TIFFReadEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + tmsize_t stripsize; + uint16_t plane; - stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane); - if (stripsize==((tmsize_t)(-1))) - return((tmsize_t)(-1)); + stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane); + if (stripsize == ((tmsize_t)(-1))) + return ((tmsize_t)(-1)); /* shortcut to avoid an extra memcpy() */ - if( td->td_compression == COMPRESSION_NONE && - size!=(tmsize_t)(-1) && size >= stripsize && - !isMapped(tif) && - ((tif->tif_flags&TIFF_NOREADRAW)==0) ) + if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) && + size >= stripsize && !isMapped(tif) && + ((tif->tif_flags & TIFF_NOREADRAW) == 0)) { if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize) return ((tmsize_t)(-1)); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(buf,stripsize); + TIFFReverseBits(buf, stripsize); - (*tif->tif_postdecode)(tif,buf,stripsize); + (*tif->tif_postdecode)(tif, buf, stripsize); return (stripsize); } - if ((size!=(tmsize_t)(-1))&&(sizetif_decodestrip)(tif,buf,stripsize,plane)<=0) - return((tmsize_t)(-1)); - (*tif->tif_postdecode)(tif,buf,stripsize); - return(stripsize); + if ((size != (tmsize_t)(-1)) && (size < stripsize)) + stripsize = size; + if (!TIFFFillStrip(tif, strip)) + return ((tmsize_t)(-1)); + if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0) + return ((tmsize_t)(-1)); + (*tif->tif_postdecode)(tif, buf, stripsize); + return (stripsize); } -/* Variant of TIFFReadEncodedStrip() that does - * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillStrip() has - * succeeded. This avoid excessive memory allocation in case of truncated - * file. +/* Variant of TIFFReadEncodedStrip() that does + * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after + * TIFFFillStrip() has succeeded. This avoid excessive memory allocation in case + * of truncated file. * * calls regular TIFFReadEncodedStrip() if *buf != NULL */ -tmsize_t -_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip, - void **buf, tmsize_t bufsizetoalloc, - tmsize_t size_to_read) +tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip, + void **buf, + tmsize_t bufsizetoalloc, + tmsize_t size_to_read) { tmsize_t this_stripsize; - uint16 plane; + uint16_t plane; - if( *buf != NULL ) + if (*buf != NULL) { return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read); } - this_stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane); - if (this_stripsize==((tmsize_t)(-1))) - return((tmsize_t)(-1)); + this_stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane); + if (this_stripsize == ((tmsize_t)(-1))) + return ((tmsize_t)(-1)); - if ((size_to_read!=(tmsize_t)(-1))&&(size_to_readtif_clientdata, TIFFFileName(tif), "No space for strip buffer"); - return((tmsize_t)(-1)); + *buf = _TIFFmallocExt(tif, bufsizetoalloc); + if (*buf == NULL) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer"); + return ((tmsize_t)(-1)); } _TIFFmemset(*buf, 0, bufsizetoalloc); - if ((*tif->tif_decodestrip)(tif,*buf,this_stripsize,plane)<=0) - return((tmsize_t)(-1)); - (*tif->tif_postdecode)(tif,*buf,this_stripsize); - return(this_stripsize); - - + if ((*tif->tif_decodestrip)(tif, *buf, this_stripsize, plane) <= 0) + return ((tmsize_t)(-1)); + (*tif->tif_postdecode)(tif, *buf, this_stripsize); + return (this_stripsize); } -static tmsize_t -TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, - const char* module) +static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size, const char *module) { - assert((tif->tif_flags&TIFF_NOREADRAW)==0); - if (!isMapped(tif)) { - tmsize_t cc; + assert((tif->tif_flags & TIFF_NOREADRAW) == 0); + if (!isMapped(tif)) + { + tmsize_t cc; - if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Seek error at scanline %lu, strip %lu", - (unsigned long) tif->tif_row, (unsigned long) strip); - return ((tmsize_t)(-1)); - } - cc = TIFFReadFile(tif, buf, size); - if (cc != size) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at scanline %lu; got %I64u bytes, expected %I64u", - (unsigned long) tif->tif_row, - (unsigned __int64) cc, - (unsigned __int64) size); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at scanline %lu; got %llu bytes, expected %llu", - (unsigned long) tif->tif_row, - (unsigned long long) cc, - (unsigned long long) size); -#endif - return ((tmsize_t)(-1)); - } - } else { - tmsize_t ma = 0; - tmsize_t n; - if ((TIFFGetStrileOffset(tif, strip) > (uint64)TIFF_TMSIZE_T_MAX)|| - ((ma=(tmsize_t)TIFFGetStrileOffset(tif, strip))>tif->tif_size)) - { - n=0; - } - else if( ma > TIFF_TMSIZE_T_MAX - size ) - { - n=0; - } - else - { - tmsize_t mb=ma+size; - if (mb>tif->tif_size) - n=tif->tif_size-ma; - else - n=size; - } - if (n!=size) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u", - (unsigned long) tif->tif_row, - (unsigned long) strip, - (unsigned __int64) n, - (unsigned __int64) size); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu", - (unsigned long) tif->tif_row, - (unsigned long) strip, - (unsigned long long) n, - (unsigned long long) size); -#endif - return ((tmsize_t)(-1)); - } - _TIFFmemcpy(buf, tif->tif_base + ma, - size); - } - return (size); -} - -static tmsize_t -TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip, - tmsize_t size, const char* module) -{ - assert( !isMapped(tif) ); - assert((tif->tif_flags&TIFF_NOREADRAW)==0); - - if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) { - if( is_strip ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Seek error at scanline %lu, strip %lu", - (unsigned long) tif->tif_row, - (unsigned long) strip_or_tile); - } - else - { - TIFFErrorExt(tif->tif_clientdata, module, - "Seek error at row %lu, col %lu, tile %lu", - (unsigned long) tif->tif_row, - (unsigned long) tif->tif_col, - (unsigned long) strip_or_tile); - } - return ((tmsize_t)(-1)); - } - - if( !TIFFReadAndRealloc( tif, size, 0, is_strip, - strip_or_tile, module ) ) + if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) { + TIFFErrorExtR(tif, module, + "Seek error at scanline %" PRIu32 ", strip %" PRIu32, + tif->tif_row, strip); return ((tmsize_t)(-1)); } + cc = TIFFReadFile(tif, buf, size); + if (cc != size) + { + TIFFErrorExtR(tif, module, + "Read error at scanline %" PRIu32 + "; got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, cc, size); + return ((tmsize_t)(-1)); + } + } + else + { + tmsize_t ma = 0; + tmsize_t n; + if ((TIFFGetStrileOffset(tif, strip) > (uint64_t)TIFF_TMSIZE_T_MAX) || + ((ma = (tmsize_t)TIFFGetStrileOffset(tif, strip)) > tif->tif_size)) + { + n = 0; + } + else if (ma > TIFF_TMSIZE_T_MAX - size) + { + n = 0; + } + else + { + tmsize_t mb = ma + size; + if (mb > tif->tif_size) + n = tif->tif_size - ma; + else + n = size; + } + if (n != size) + { + TIFFErrorExtR(tif, module, + "Read error at scanline %" PRIu32 ", strip %" PRIu32 + "; got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, strip, n, size); + return ((tmsize_t)(-1)); + } + _TIFFmemcpy(buf, tif->tif_base + ma, size); + } + return (size); +} - return (size); +static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile, + int is_strip, tmsize_t size, + const char *module) +{ + assert(!isMapped(tif)); + assert((tif->tif_flags & TIFF_NOREADRAW) == 0); + + if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) + { + if (is_strip) + { + TIFFErrorExtR(tif, module, + "Seek error at scanline %" PRIu32 ", strip %" PRIu32, + tif->tif_row, strip_or_tile); + } + else + { + TIFFErrorExtR(tif, module, + "Seek error at row %" PRIu32 ", col %" PRIu32 + ", tile %" PRIu32, + tif->tif_row, tif->tif_col, strip_or_tile); + } + return ((tmsize_t)(-1)); + } + + if (!TIFFReadAndRealloc(tif, size, 0, is_strip, strip_or_tile, module)) + { + return ((tmsize_t)(-1)); + } + + return (size); } /* * Read a strip of data from the file. */ -tmsize_t -TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) +tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, tmsize_t size) { - static const char module[] = "TIFFReadRawStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint64 bytecount64; - tmsize_t bytecountm; + static const char module[] = "TIFFReadRawStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t bytecount64; + tmsize_t bytecountm; - if (!TIFFCheckRead(tif, 0)) - return ((tmsize_t)(-1)); - if (strip >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, - "%lu: Strip out of range, max %lu", - (unsigned long) strip, - (unsigned long) td->td_nstrips); - return ((tmsize_t)(-1)); - } - if (tif->tif_flags&TIFF_NOREADRAW) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Compression scheme does not support access to raw uncompressed data"); - return ((tmsize_t)(-1)); - } - bytecount64 = TIFFGetStrileByteCount(tif, strip); - if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64) - bytecountm = size; - else - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); - if( bytecountm == 0 ) { - return ((tmsize_t)(-1)); - } - return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module)); + if (!TIFFCheckRead(tif, 0)) + return ((tmsize_t)(-1)); + if (strip >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Strip out of range, max %" PRIu32, strip, + td->td_nstrips); + return ((tmsize_t)(-1)); + } + if (tif->tif_flags & TIFF_NOREADRAW) + { + TIFFErrorExtR(tif, module, + "Compression scheme does not support access to raw " + "uncompressed data"); + return ((tmsize_t)(-1)); + } + bytecount64 = TIFFGetStrileByteCount(tif, strip); + if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64) + bytecountm = size; + else + bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); + if (bytecountm == 0) + { + return ((tmsize_t)(-1)); + } + return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module)); } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static uint64 NoSanitizeSubUInt64(uint64 a, uint64 b) -{ - return a - b; -} +static uint64_t NoSanitizeSubUInt64(uint64_t a, uint64_t b) { return a - b; } /* * Read the specified strip and setup for decoding. The data buffer is * expanded, as necessary, to hold the strip's data. */ -int -TIFFFillStrip(TIFF* tif, uint32 strip) +int TIFFFillStrip(TIFF *tif, uint32_t strip) { - static const char module[] = "TIFFFillStrip"; - TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "TIFFFillStrip"; + TIFFDirectory *td = &tif->tif_dir; - if ((tif->tif_flags&TIFF_NOREADRAW)==0) - { - uint64 bytecount = TIFFGetStrileByteCount(tif, strip); - if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Invalid strip byte count %I64u, strip %lu", - (unsigned __int64) bytecount, - (unsigned long) strip); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Invalid strip byte count %llu, strip %lu", - (unsigned long long) bytecount, - (unsigned long) strip); -#endif - return (0); - } + if ((tif->tif_flags & TIFF_NOREADRAW) == 0) + { + uint64_t bytecount = TIFFGetStrileByteCount(tif, strip); + if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX) + { + TIFFErrorExtR(tif, module, + "Invalid strip byte count %" PRIu64 + ", strip %" PRIu32, + bytecount, strip); + return (0); + } - /* To avoid excessive memory allocations: */ - /* Byte count should normally not be larger than a number of */ - /* times the uncompressed size plus some margin */ - if( bytecount > 1024 * 1024 ) + /* To avoid excessive memory allocations: */ + /* Byte count should normally not be larger than a number of */ + /* times the uncompressed size plus some margin */ + if (bytecount > 1024 * 1024) + { + /* 10 and 4096 are just values that could be adjusted. */ + /* Hopefully they are safe enough for all codecs */ + tmsize_t stripsize = TIFFStripSize(tif); + if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize) + { + uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; + TIFFErrorExtR(tif, module, + "Too large strip byte count %" PRIu64 + ", strip %" PRIu32 ". Limiting to %" PRIu64, + bytecount, strip, newbytecount); + bytecount = newbytecount; + } + } + + if (isMapped(tif)) + { + /* + * We must check for overflow, potentially causing + * an OOB read. Instead of simple + * + * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size + * + * comparison (which can overflow) we do the following + * two comparisons: + */ + if (bytecount > (uint64_t)tif->tif_size || + TIFFGetStrileOffset(tif, strip) > + (uint64_t)tif->tif_size - bytecount) + { + /* + * This error message might seem strange, but + * it's what would happen if a read were done + * instead. + */ + TIFFErrorExtR( + tif, module, + + "Read error on strip %" PRIu32 "; " + "got %" PRIu64 " bytes, expected %" PRIu64, + strip, + NoSanitizeSubUInt64(tif->tif_size, + TIFFGetStrileOffset(tif, strip)), + bytecount); + tif->tif_curstrip = NOSTRIP; + return (0); + } + } + + if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || + (tif->tif_flags & TIFF_NOBITREV))) + { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is + * going to handle this operation itself. In this + * case, avoid copying the raw data and instead just + * reference the data from the memory mapped file + * image. This assumes that the decompression + * routines do not modify the contents of the raw data + * buffer (if they try to, the application will get a + * fault since the file is mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + tif->tif_flags &= ~TIFF_MYBUFFER; + tif->tif_rawdatasize = (tmsize_t)bytecount; + tif->tif_rawdata = + tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip); + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = (tmsize_t)bytecount; + + /* + * When we have tif_rawdata reference directly into the memory + * mapped file we need to be pretty careful about how we use the + * rawdata. It is not a general purpose working buffer as it + * normally otherwise is. So we keep track of this fact to avoid + * using it improperly. + */ + tif->tif_flags |= TIFF_BUFFERMMAP; + } + else + { + /* + * Expand raw data buffer, if needed, to hold data + * strip coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ + tmsize_t bytecountm; + bytecountm = (tmsize_t)bytecount; + if ((uint64_t)bytecountm != bytecount) + { + TIFFErrorExtR(tif, module, "Integer overflow"); + return (0); + } + if (bytecountm > tif->tif_rawdatasize) + { + tif->tif_curstrip = NOSTRIP; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - /* 10 and 4096 are just values that could be adjusted. */ - /* Hopefully they are safe enough for all codecs */ - tmsize_t stripsize = TIFFStripSize(tif); - if( stripsize != 0 && - (bytecount - 4096) / 10 > (uint64)stripsize ) - { - uint64 newbytecount = (uint64)stripsize * 10 + 4096; - if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX ) - { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFWarningExt(tif->tif_clientdata, module, - "Too large strip byte count %I64u, strip %lu. Limiting to %I64u", - (unsigned __int64) bytecount, - (unsigned long) strip, - (unsigned __int64) newbytecount); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Too large strip byte count %llu, strip %lu. Limiting to %llu", - (unsigned long long) bytecount, - (unsigned long) strip, - (unsigned long long) newbytecount); -#endif - bytecount = newbytecount; - } - } - } - - if (isMapped(tif)) { - /* - * We must check for overflow, potentially causing - * an OOB read. Instead of simple - * - * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size - * - * comparison (which can overflow) we do the following - * two comparisons: - */ - if (bytecount > (uint64)tif->tif_size || - TIFFGetStrileOffset(tif, strip) > (uint64)tif->tif_size - bytecount) { - /* - * This error message might seem strange, but - * it's what would happen if a read were done - * instead. - */ -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - - "Read error on strip %lu; " - "got %I64u bytes, expected %I64u", - (unsigned long) strip, - (unsigned __int64) NoSanitizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)), - (unsigned __int64) bytecount); -#else - TIFFErrorExt(tif->tif_clientdata, module, - - "Read error on strip %lu; " - "got %llu bytes, expected %llu", - (unsigned long) strip, - (unsigned long long) NoSanitizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)), - (unsigned long long) bytecount); -#endif - tif->tif_curstrip = NOSTRIP; - return (0); - } - } - - if (isMapped(tif) && - (isFillOrder(tif, td->td_fillorder) - || (tif->tif_flags & TIFF_NOBITREV))) { - /* - * The image is mapped into memory and we either don't - * need to flip bits or the compression routine is - * going to handle this operation itself. In this - * case, avoid copying the raw data and instead just - * reference the data from the memory mapped file - * image. This assumes that the decompression - * routines do not modify the contents of the raw data - * buffer (if they try to, the application will get a - * fault since the file is mapped read-only). - */ - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { - _TIFFfree(tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - tif->tif_flags &= ~TIFF_MYBUFFER; - tif->tif_rawdatasize = (tmsize_t)bytecount; - tif->tif_rawdata = tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip); - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = (tmsize_t) bytecount; - - /* - * When we have tif_rawdata reference directly into the memory mapped file - * we need to be pretty careful about how we use the rawdata. It is not - * a general purpose working buffer as it normally otherwise is. So we - * keep track of this fact to avoid using it improperly. - */ - tif->tif_flags |= TIFF_BUFFERMMAP; - } else { - /* - * Expand raw data buffer, if needed, to hold data - * strip coming from file (perhaps should set upper - * bound on the size of a buffer we'll use?). - */ - tmsize_t bytecountm; - bytecountm=(tmsize_t)bytecount; - if ((uint64)bytecountm!=bytecount) - { - TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); - return(0); - } - if (bytecountm > tif->tif_rawdatasize) { - tif->tif_curstrip = NOSTRIP; - if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Data buffer too small to hold strip %lu", - (unsigned long) strip); - return (0); - } - } - if (tif->tif_flags&TIFF_BUFFERMMAP) { - tif->tif_curstrip = NOSTRIP; - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - tif->tif_flags &= ~TIFF_BUFFERMMAP; - } - - if( isMapped(tif) ) - { - if (bytecountm > tif->tif_rawdatasize && - !TIFFReadBufferSetup(tif, 0, bytecountm)) - { - return (0); - } - if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, - bytecountm, module) != bytecountm) - { - return (0); - } - } - else - { - if (TIFFReadRawStripOrTile2(tif, strip, 1, - bytecountm, module) != bytecountm) - { - return (0); - } - } - - - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = bytecountm; - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, bytecountm); + TIFFErrorExtR( + tif, module, + "Data buffer too small to hold strip %" PRIu32, strip); + return (0); } - } - return (TIFFStartStrip(tif, strip)); + } + if (tif->tif_flags & TIFF_BUFFERMMAP) + { + tif->tif_curstrip = NOSTRIP; + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + tif->tif_flags &= ~TIFF_BUFFERMMAP; + } + + if (isMapped(tif)) + { + if (bytecountm > tif->tif_rawdatasize && + !TIFFReadBufferSetup(tif, 0, bytecountm)) + { + return (0); + } + if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecountm, + module) != bytecountm) + { + return (0); + } + } + else + { + if (TIFFReadRawStripOrTile2(tif, strip, 1, bytecountm, + module) != bytecountm) + { + return (0); + } + } + + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = bytecountm; + + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, bytecountm); + } + } + return (TIFFStartStrip(tif, strip)); } /* @@ -961,120 +913,162 @@ TIFFFillStrip(TIFF* tif, uint32 strip) * Read and decompress a tile of data. The * tile is selected by the (x,y,z,s) coordinates. */ -tmsize_t -TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) +tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z, + uint16_t s) { - if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) - return ((tmsize_t)(-1)); - return (TIFFReadEncodedTile(tif, - TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); + if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) + return ((tmsize_t)(-1)); + return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf, + (tmsize_t)(-1))); } /* * Read a tile of data and decompress the specified * amount into the user-supplied buffer. */ -tmsize_t -TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) +tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size) { - static const char module[] = "TIFFReadEncodedTile"; - TIFFDirectory *td = &tif->tif_dir; - tmsize_t tilesize = tif->tif_tilesize; + static const char module[] = "TIFFReadEncodedTile"; + TIFFDirectory *td = &tif->tif_dir; + tmsize_t tilesize = tif->tif_tilesize; - if (!TIFFCheckRead(tif, 1)) - return ((tmsize_t)(-1)); - if (tile >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, - "%lu: Tile out of range, max %lu", - (unsigned long) tile, (unsigned long) td->td_nstrips); - return ((tmsize_t)(-1)); - } + if (!TIFFCheckRead(tif, 1)) + return ((tmsize_t)(-1)); + if (tile >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Tile out of range, max %" PRIu32, tile, + td->td_nstrips); + return ((tmsize_t)(-1)); + } /* shortcut to avoid an extra memcpy() */ - if( td->td_compression == COMPRESSION_NONE && - size!=(tmsize_t)(-1) && size >= tilesize && - !isMapped(tif) && - ((tif->tif_flags&TIFF_NOREADRAW)==0) ) + if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) && + size >= tilesize && !isMapped(tif) && + ((tif->tif_flags & TIFF_NOREADRAW) == 0)) { if (TIFFReadRawTile1(tif, tile, buf, tilesize, module) != tilesize) return ((tmsize_t)(-1)); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(buf,tilesize); + TIFFReverseBits(buf, tilesize); - (*tif->tif_postdecode)(tif,buf,tilesize); + (*tif->tif_postdecode)(tif, buf, tilesize); return (tilesize); } - if (size == (tmsize_t)(-1)) - size = tilesize; - else if (size > tilesize) - size = tilesize; - if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif, - (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) { - (*tif->tif_postdecode)(tif, (uint8*) buf, size); - return (size); - } else - return ((tmsize_t)(-1)); + if (size == (tmsize_t)(-1)) + size = tilesize; + else if (size > tilesize) + size = tilesize; + if (TIFFFillTile(tif, tile) && + (*tif->tif_decodetile)(tif, (uint8_t *)buf, size, + (uint16_t)(tile / td->td_stripsperimage))) + { + (*tif->tif_postdecode)(tif, (uint8_t *)buf, size); + return (size); + } + else + return ((tmsize_t)(-1)); } -/* Variant of TIFFReadTile() that does - * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has - * succeeded. This avoid excessive memory allocation in case of truncated - * file. +/* Variant of TIFFReadTile() that does + * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after + * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case + * of truncated file. * * calls regular TIFFReadEncodedTile() if *buf != NULL */ -tmsize_t -_TIFFReadTileAndAllocBuffer(TIFF* tif, - void **buf, tmsize_t bufsizetoalloc, - uint32 x, uint32 y, uint32 z, uint16 s) +tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf, + tmsize_t bufsizetoalloc, uint32_t x, + uint32_t y, uint32_t z, uint16_t s) { if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) - return ((tmsize_t)(-1)); - return (_TIFFReadEncodedTileAndAllocBuffer(tif, - TIFFComputeTile(tif, x, y, z, s), - buf, bufsizetoalloc, - (tmsize_t)(-1))); + return ((tmsize_t)(-1)); + return (_TIFFReadEncodedTileAndAllocBuffer( + tif, TIFFComputeTile(tif, x, y, z, s), buf, bufsizetoalloc, + (tmsize_t)(-1))); } -/* Variant of TIFFReadEncodedTile() that does - * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has - * succeeded. This avoid excessive memory allocation in case of truncated - * file. +/* Variant of TIFFReadEncodedTile() that does + * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after + * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case + * of truncated file. * * calls regular TIFFReadEncodedTile() if *buf != NULL */ -tmsize_t -_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile, - void **buf, tmsize_t bufsizetoalloc, - tmsize_t size_to_read) +tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile, + void **buf, tmsize_t bufsizetoalloc, + tmsize_t size_to_read) { static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer"; TIFFDirectory *td = &tif->tif_dir; tmsize_t tilesize = tif->tif_tilesize; - if( *buf != NULL ) + if (*buf != NULL) { return TIFFReadEncodedTile(tif, tile, *buf, size_to_read); } if (!TIFFCheckRead(tif, 1)) - return ((tmsize_t)(-1)); - if (tile >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, - "%lu: Tile out of range, max %lu", - (unsigned long) tile, (unsigned long) td->td_nstrips); - return ((tmsize_t)(-1)); + return ((tmsize_t)(-1)); + if (tile >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Tile out of range, max %" PRIu32, tile, + td->td_nstrips); + return ((tmsize_t)(-1)); } - if (!TIFFFillTile(tif,tile)) - return((tmsize_t)(-1)); + if (!TIFFFillTile(tif, tile)) + return ((tmsize_t)(-1)); - *buf = _TIFFmalloc(bufsizetoalloc); - if (*buf == NULL) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), - "No space for tile buffer"); - return((tmsize_t)(-1)); + /* Sanity checks to avoid excessive memory allocation */ + /* Cf https://gitlab.com/libtiff/libtiff/-/issues/479 */ + if (td->td_compression == COMPRESSION_NONE) + { + if (tif->tif_rawdatasize != tilesize) + { + TIFFErrorExtR(tif, TIFFFileName(tif), + "Invalid tile byte count for tile %u. " + "Expected %" PRIu64 ", got %" PRIu64, + tile, (uint64_t)tilesize, + (uint64_t)tif->tif_rawdatasize); + return ((tmsize_t)(-1)); + } + } + else + { + /* Max compression ratio experimentally determined. Might be fragile... + * Only apply this heuristics to situations where the memory allocation + * would be big, to avoid breaking nominal use cases. + */ + const int maxCompressionRatio = + td->td_compression == COMPRESSION_ZSTD ? 33000 + : td->td_compression == COMPRESSION_JXL + ? + /* Evaluated on a 8000x8000 tile */ + 25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG + ? td->td_samplesperpixel + : 1) + : td->td_compression == COMPRESSION_LZMA ? 7000 : 1000; + if (bufsizetoalloc > 100 * 1000 * 1000 && + tif->tif_rawdatasize < tilesize / maxCompressionRatio) + { + TIFFErrorExtR(tif, TIFFFileName(tif), + "Likely invalid tile byte count for tile %u. " + "Uncompressed tile size is %" PRIu64 ", " + "compressed one is %" PRIu64, + tile, (uint64_t)tilesize, + (uint64_t)tif->tif_rawdatasize); + return ((tmsize_t)(-1)); + } + } + + *buf = _TIFFmallocExt(tif, bufsizetoalloc); + if (*buf == NULL) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer"); + return ((tmsize_t)(-1)); } _TIFFmemset(*buf, 0, bufsizetoalloc); @@ -1082,287 +1076,261 @@ _TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile, size_to_read = tilesize; else if (size_to_read > tilesize) size_to_read = tilesize; - if( (*tif->tif_decodetile)(tif, - (uint8*) *buf, size_to_read, (uint16)(tile/td->td_stripsperimage))) { - (*tif->tif_postdecode)(tif, (uint8*) *buf, size_to_read); + if ((*tif->tif_decodetile)(tif, (uint8_t *)*buf, size_to_read, + (uint16_t)(tile / td->td_stripsperimage))) + { + (*tif->tif_postdecode)(tif, (uint8_t *)*buf, size_to_read); return (size_to_read); - } else + } + else return ((tmsize_t)(-1)); } -static tmsize_t -TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module) +static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf, + tmsize_t size, const char *module) { - assert((tif->tif_flags&TIFF_NOREADRAW)==0); - if (!isMapped(tif)) { - tmsize_t cc; + assert((tif->tif_flags & TIFF_NOREADRAW) == 0); + if (!isMapped(tif)) + { + tmsize_t cc; - if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Seek error at row %lu, col %lu, tile %lu", - (unsigned long) tif->tif_row, - (unsigned long) tif->tif_col, - (unsigned long) tile); - return ((tmsize_t)(-1)); - } - cc = TIFFReadFile(tif, buf, size); - if (cc != size) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at row %lu, col %lu; got %I64u bytes, expected %I64u", - (unsigned long) tif->tif_row, - (unsigned long) tif->tif_col, - (unsigned __int64) cc, - (unsigned __int64) size); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at row %lu, col %lu; got %llu bytes, expected %llu", - (unsigned long) tif->tif_row, - (unsigned long) tif->tif_col, - (unsigned long long) cc, - (unsigned long long) size); -#endif - return ((tmsize_t)(-1)); - } - } else { - tmsize_t ma,mb; - tmsize_t n; - ma=(tmsize_t)TIFFGetStrileOffset(tif, tile); - mb=ma+size; - if ((TIFFGetStrileOffset(tif, tile) > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size)) - n=0; - else if ((mbtif->tif_size)) - n=tif->tif_size-ma; - else - n=size; - if (n!=size) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, -"Read error at row %lu, col %lu, tile %lu; got %I64u bytes, expected %I64u", - (unsigned long) tif->tif_row, - (unsigned long) tif->tif_col, - (unsigned long) tile, - (unsigned __int64) n, - (unsigned __int64) size); -#else - TIFFErrorExt(tif->tif_clientdata, module, -"Read error at row %lu, col %lu, tile %lu; got %llu bytes, expected %llu", - (unsigned long) tif->tif_row, - (unsigned long) tif->tif_col, - (unsigned long) tile, - (unsigned long long) n, - (unsigned long long) size); -#endif - return ((tmsize_t)(-1)); - } - _TIFFmemcpy(buf, tif->tif_base + ma, size); - } - return (size); + if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) + { + TIFFErrorExtR(tif, module, + "Seek error at row %" PRIu32 ", col %" PRIu32 + ", tile %" PRIu32, + tif->tif_row, tif->tif_col, tile); + return ((tmsize_t)(-1)); + } + cc = TIFFReadFile(tif, buf, size); + if (cc != size) + { + TIFFErrorExtR(tif, module, + "Read error at row %" PRIu32 ", col %" PRIu32 + "; got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, tif->tif_col, cc, size); + return ((tmsize_t)(-1)); + } + } + else + { + tmsize_t ma, mb; + tmsize_t n; + ma = (tmsize_t)TIFFGetStrileOffset(tif, tile); + mb = ma + size; + if ((TIFFGetStrileOffset(tif, tile) > (uint64_t)TIFF_TMSIZE_T_MAX) || + (ma > tif->tif_size)) + n = 0; + else if ((mb < ma) || (mb < size) || (mb > tif->tif_size)) + n = tif->tif_size - ma; + else + n = size; + if (n != size) + { + TIFFErrorExtR(tif, module, + "Read error at row %" PRIu32 ", col %" PRIu32 + ", tile %" PRIu32 "; got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, tif->tif_col, tile, n, size); + return ((tmsize_t)(-1)); + } + _TIFFmemcpy(buf, tif->tif_base + ma, size); + } + return (size); } /* * Read a tile of data from the file. */ -tmsize_t -TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) +tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size) { - static const char module[] = "TIFFReadRawTile"; - TIFFDirectory *td = &tif->tif_dir; - uint64 bytecount64; - tmsize_t bytecountm; + static const char module[] = "TIFFReadRawTile"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t bytecount64; + tmsize_t bytecountm; - if (!TIFFCheckRead(tif, 1)) - return ((tmsize_t)(-1)); - if (tile >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, - "%lu: Tile out of range, max %lu", - (unsigned long) tile, (unsigned long) td->td_nstrips); - return ((tmsize_t)(-1)); - } - if (tif->tif_flags&TIFF_NOREADRAW) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Compression scheme does not support access to raw uncompressed data"); - return ((tmsize_t)(-1)); - } - bytecount64 = TIFFGetStrileByteCount(tif, tile); - if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64) - bytecountm = size; - else - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); - if( bytecountm == 0 ) { - return ((tmsize_t)(-1)); - } - return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); + if (!TIFFCheckRead(tif, 1)) + return ((tmsize_t)(-1)); + if (tile >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Tile out of range, max %" PRIu32, tile, + td->td_nstrips); + return ((tmsize_t)(-1)); + } + if (tif->tif_flags & TIFF_NOREADRAW) + { + TIFFErrorExtR(tif, module, + "Compression scheme does not support access to raw " + "uncompressed data"); + return ((tmsize_t)(-1)); + } + bytecount64 = TIFFGetStrileByteCount(tif, tile); + if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64) + bytecountm = size; + else + bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); + if (bytecountm == 0) + { + return ((tmsize_t)(-1)); + } + return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); } /* * Read the specified tile and setup for decoding. The data buffer is * expanded, as necessary, to hold the tile's data. */ -int -TIFFFillTile(TIFF* tif, uint32 tile) +int TIFFFillTile(TIFF *tif, uint32_t tile) { - static const char module[] = "TIFFFillTile"; - TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "TIFFFillTile"; + TIFFDirectory *td = &tif->tif_dir; - if ((tif->tif_flags&TIFF_NOREADRAW)==0) - { - uint64 bytecount = TIFFGetStrileByteCount(tif, tile); - if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "%I64u: Invalid tile byte count, tile %lu", - (unsigned __int64) bytecount, - (unsigned long) tile); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "%llu: Invalid tile byte count, tile %lu", - (unsigned long long) bytecount, - (unsigned long) tile); -#endif - return (0); - } + if ((tif->tif_flags & TIFF_NOREADRAW) == 0) + { + uint64_t bytecount = TIFFGetStrileByteCount(tif, tile); + if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX) + { + TIFFErrorExtR(tif, module, + "%" PRIu64 ": Invalid tile byte count, tile %" PRIu32, + bytecount, tile); + return (0); + } - /* To avoid excessive memory allocations: */ - /* Byte count should normally not be larger than a number of */ - /* times the uncompressed size plus some margin */ - if( bytecount > 1024 * 1024 ) + /* To avoid excessive memory allocations: */ + /* Byte count should normally not be larger than a number of */ + /* times the uncompressed size plus some margin */ + if (bytecount > 1024 * 1024) + { + /* 10 and 4096 are just values that could be adjusted. */ + /* Hopefully they are safe enough for all codecs */ + tmsize_t stripsize = TIFFTileSize(tif); + if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize) + { + uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; + TIFFErrorExtR(tif, module, + "Too large tile byte count %" PRIu64 + ", tile %" PRIu32 ". Limiting to %" PRIu64, + bytecount, tile, newbytecount); + bytecount = newbytecount; + } + } + + if (isMapped(tif)) + { + /* + * We must check for overflow, potentially causing + * an OOB read. Instead of simple + * + * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size + * + * comparison (which can overflow) we do the following + * two comparisons: + */ + if (bytecount > (uint64_t)tif->tif_size || + TIFFGetStrileOffset(tif, tile) > + (uint64_t)tif->tif_size - bytecount) + { + tif->tif_curtile = NOTILE; + return (0); + } + } + + if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || + (tif->tif_flags & TIFF_NOBITREV))) + { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is + * going to handle this operation itself. In this + * case, avoid copying the raw data and instead just + * reference the data from the memory mapped file + * image. This assumes that the decompression + * routines do not modify the contents of the raw data + * buffer (if they try to, the application will get a + * fault since the file is mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + tif->tif_flags &= ~TIFF_MYBUFFER; + + tif->tif_rawdatasize = (tmsize_t)bytecount; + tif->tif_rawdata = + tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile); + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = (tmsize_t)bytecount; + tif->tif_flags |= TIFF_BUFFERMMAP; + } + else + { + /* + * Expand raw data buffer, if needed, to hold data + * tile coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ + tmsize_t bytecountm; + bytecountm = (tmsize_t)bytecount; + if ((uint64_t)bytecountm != bytecount) + { + TIFFErrorExtR(tif, module, "Integer overflow"); + return (0); + } + if (bytecountm > tif->tif_rawdatasize) + { + tif->tif_curtile = NOTILE; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - /* 10 and 4096 are just values that could be adjusted. */ - /* Hopefully they are safe enough for all codecs */ - tmsize_t stripsize = TIFFTileSize(tif); - if( stripsize != 0 && - (bytecount - 4096) / 10 > (uint64)stripsize ) - { - uint64 newbytecount = (uint64)stripsize * 10 + 4096; - if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX ) - { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFWarningExt(tif->tif_clientdata, module, - "Too large tile byte count %I64u, tile %lu. Limiting to %I64u", - (unsigned __int64) bytecount, - (unsigned long) tile, - (unsigned __int64) newbytecount); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Too large tile byte count %llu, tile %lu. Limiting to %llu", - (unsigned long long) bytecount, - (unsigned long) tile, - (unsigned long long) newbytecount); -#endif - bytecount = newbytecount; - } - } - } + TIFFErrorExtR(tif, module, + "Data buffer too small to hold tile %" PRIu32, + tile); + return (0); + } + } + if (tif->tif_flags & TIFF_BUFFERMMAP) + { + tif->tif_curtile = NOTILE; + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + tif->tif_flags &= ~TIFF_BUFFERMMAP; + } - if (isMapped(tif)) { - /* - * We must check for overflow, potentially causing - * an OOB read. Instead of simple - * - * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size - * - * comparison (which can overflow) we do the following - * two comparisons: - */ - if (bytecount > (uint64)tif->tif_size || - TIFFGetStrileOffset(tif, tile) > (uint64)tif->tif_size - bytecount) { - tif->tif_curtile = NOTILE; - return (0); - } - } + if (isMapped(tif)) + { + if (bytecountm > tif->tif_rawdatasize && + !TIFFReadBufferSetup(tif, 0, bytecountm)) + { + return (0); + } + if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, bytecountm, + module) != bytecountm) + { + return (0); + } + } + else + { + if (TIFFReadRawStripOrTile2(tif, tile, 0, bytecountm, module) != + bytecountm) + { + return (0); + } + } - if (isMapped(tif) && - (isFillOrder(tif, td->td_fillorder) - || (tif->tif_flags & TIFF_NOBITREV))) { - /* - * The image is mapped into memory and we either don't - * need to flip bits or the compression routine is - * going to handle this operation itself. In this - * case, avoid copying the raw data and instead just - * reference the data from the memory mapped file - * image. This assumes that the decompression - * routines do not modify the contents of the raw data - * buffer (if they try to, the application will get a - * fault since the file is mapped read-only). - */ - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { - _TIFFfree(tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - tif->tif_flags &= ~TIFF_MYBUFFER; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = bytecountm; - tif->tif_rawdatasize = (tmsize_t)bytecount; - tif->tif_rawdata = - tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile); - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = (tmsize_t) bytecount; - tif->tif_flags |= TIFF_BUFFERMMAP; - } else { - /* - * Expand raw data buffer, if needed, to hold data - * tile coming from file (perhaps should set upper - * bound on the size of a buffer we'll use?). - */ - tmsize_t bytecountm; - bytecountm=(tmsize_t)bytecount; - if ((uint64)bytecountm!=bytecount) - { - TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); - return(0); - } - if (bytecountm > tif->tif_rawdatasize) { - tif->tif_curtile = NOTILE; - if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Data buffer too small to hold tile %lu", - (unsigned long) tile); - return (0); - } - } - if (tif->tif_flags&TIFF_BUFFERMMAP) { - tif->tif_curtile = NOTILE; - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - tif->tif_flags &= ~TIFF_BUFFERMMAP; - } - - if( isMapped(tif) ) - { - if (bytecountm > tif->tif_rawdatasize && - !TIFFReadBufferSetup(tif, 0, bytecountm)) - { - return (0); - } - if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, - bytecountm, module) != bytecountm) - { - return (0); - } - } - else - { - if (TIFFReadRawStripOrTile2(tif, tile, 0, - bytecountm, module) != bytecountm) - { - return (0); - } - } - - - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = bytecountm; - - if (tif->tif_rawdata != NULL && - !isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, - tif->tif_rawdataloaded); - } - } - return (TIFFStartTile(tif, tile)); + if (tif->tif_rawdata != NULL && + !isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdataloaded); + } + } + return (TIFFStartTile(tif, tile)); } /* @@ -1374,180 +1342,191 @@ TIFFFillTile(TIFF* tif, uint32 tile) * large enough to hold any individual strip of * raw data. */ -int -TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size) +int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size) { - static const char module[] = "TIFFReadBufferSetup"; + static const char module[] = "TIFFReadBufferSetup"; - assert((tif->tif_flags&TIFF_NOREADRAW)==0); - tif->tif_flags &= ~TIFF_BUFFERMMAP; + assert((tif->tif_flags & TIFF_NOREADRAW) == 0); + tif->tif_flags &= ~TIFF_BUFFERMMAP; - if (tif->tif_rawdata) { - if (tif->tif_flags & TIFF_MYBUFFER) - _TIFFfree(tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - if (bp) { - tif->tif_rawdatasize = size; - tif->tif_rawdata = (uint8*) bp; - tif->tif_flags &= ~TIFF_MYBUFFER; - } else { - tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024); - if (tif->tif_rawdatasize==0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Invalid buffer size"); - return (0); - } - /* Initialize to zero to avoid uninitialized buffers in case of */ - /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */ - tif->tif_rawdata = (uint8*) _TIFFcalloc(1, tif->tif_rawdatasize); - tif->tif_flags |= TIFF_MYBUFFER; - } - if (tif->tif_rawdata == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, - "No space for data buffer at scanline %lu", - (unsigned long) tif->tif_row); - tif->tif_rawdatasize = 0; - return (0); - } - return (1); + if (tif->tif_rawdata) + { + if (tif->tif_flags & TIFF_MYBUFFER) + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + if (bp) + { + tif->tif_rawdatasize = size; + tif->tif_rawdata = (uint8_t *)bp; + tif->tif_flags &= ~TIFF_MYBUFFER; + } + else + { + tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64_t)size, 1024); + if (tif->tif_rawdatasize == 0) + { + TIFFErrorExtR(tif, module, "Invalid buffer size"); + return (0); + } + /* Initialize to zero to avoid uninitialized buffers in case of */ + /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */ + tif->tif_rawdata = + (uint8_t *)_TIFFcallocExt(tif, 1, tif->tif_rawdatasize); + tif->tif_flags |= TIFF_MYBUFFER; + } + if (tif->tif_rawdata == NULL) + { + TIFFErrorExtR(tif, module, + "No space for data buffer at scanline %" PRIu32, + tif->tif_row); + tif->tif_rawdatasize = 0; + return (0); + } + return (1); } /* * Set state to appear as if a * strip has just been read in. */ -static int -TIFFStartStrip(TIFF* tif, uint32 strip) +static int TIFFStartStrip(TIFF *tif, uint32_t strip) { - TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupdecode)(tif)) - return (0); - tif->tif_flags |= TIFF_CODERSETUP; - } - tif->tif_curstrip = strip; - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - tif->tif_flags &= ~TIFF_BUF4WRITE; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupdecode)(tif)) + return (0); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_curstrip = strip; + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_flags &= ~TIFF_BUF4WRITE; - if (tif->tif_flags&TIFF_NOREADRAW) - { - tif->tif_rawcp = NULL; - tif->tif_rawcc = 0; - } - else - { - tif->tif_rawcp = tif->tif_rawdata; - if( tif->tif_rawdataloaded > 0 ) - tif->tif_rawcc = tif->tif_rawdataloaded; - else - tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip); - } - if ((*tif->tif_predecode)(tif, - (uint16)(strip / td->td_stripsperimage)) == 0 ) { - /* Needed for example for scanline access, if tif_predecode */ - /* fails, and we try to read the same strip again. Without invalidating */ - /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */ - /* codec state. */ - tif->tif_curstrip = NOSTRIP; - return 0; - } - return 1; + if (tif->tif_flags & TIFF_NOREADRAW) + { + tif->tif_rawcp = NULL; + tif->tif_rawcc = 0; + } + else + { + tif->tif_rawcp = tif->tif_rawdata; + if (tif->tif_rawdataloaded > 0) + tif->tif_rawcc = tif->tif_rawdataloaded; + else + tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip); + } + if ((*tif->tif_predecode)(tif, (uint16_t)(strip / td->td_stripsperimage)) == + 0) + { + /* Needed for example for scanline access, if tif_predecode */ + /* fails, and we try to read the same strip again. Without invalidating + */ + /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */ + /* codec state. */ + tif->tif_curstrip = NOSTRIP; + return 0; + } + return 1; } /* * Set state to appear as if a * tile has just been read in. */ -static int -TIFFStartTile(TIFF* tif, uint32 tile) +static int TIFFStartTile(TIFF *tif, uint32_t tile) { - static const char module[] = "TIFFStartTile"; - TIFFDirectory *td = &tif->tif_dir; - uint32 howmany32; + static const char module[] = "TIFFStartTile"; + TIFFDirectory *td = &tif->tif_dir; + uint32_t howmany32; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupdecode)(tif)) - return (0); - tif->tif_flags |= TIFF_CODERSETUP; - } - tif->tif_curtile = tile; - howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); - if (howmany32 == 0) { - TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles"); - return 0; - } - tif->tif_row = (tile % howmany32) * td->td_tilelength; - howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength); - if (howmany32 == 0) { - TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles"); - return 0; - } - tif->tif_col = (tile % howmany32) * td->td_tilewidth; - tif->tif_flags &= ~TIFF_BUF4WRITE; - if (tif->tif_flags&TIFF_NOREADRAW) - { - tif->tif_rawcp = NULL; - tif->tif_rawcc = 0; - } - else - { - tif->tif_rawcp = tif->tif_rawdata; - if( tif->tif_rawdataloaded > 0 ) - tif->tif_rawcc = tif->tif_rawdataloaded; - else - tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile); - } - return ((*tif->tif_predecode)(tif, - (uint16)(tile/td->td_stripsperimage))); + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupdecode)(tif)) + return (0); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_curtile = tile; + howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); + if (howmany32 == 0) + { + TIFFErrorExtR(tif, module, "Zero tiles"); + return 0; + } + tif->tif_row = (tile % howmany32) * td->td_tilelength; + howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength); + if (howmany32 == 0) + { + TIFFErrorExtR(tif, module, "Zero tiles"); + return 0; + } + tif->tif_col = (tile % howmany32) * td->td_tilewidth; + tif->tif_flags &= ~TIFF_BUF4WRITE; + if (tif->tif_flags & TIFF_NOREADRAW) + { + tif->tif_rawcp = NULL; + tif->tif_rawcc = 0; + } + else + { + tif->tif_rawcp = tif->tif_rawdata; + if (tif->tif_rawdataloaded > 0) + tif->tif_rawcc = tif->tif_rawdataloaded; + else + tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile); + } + return ( + (*tif->tif_predecode)(tif, (uint16_t)(tile / td->td_stripsperimage))); } -static int -TIFFCheckRead(TIFF* tif, int tiles) +static int TIFFCheckRead(TIFF *tif, int tiles) { - if (tif->tif_mode == O_WRONLY) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading"); - return (0); - } - if (tiles ^ isTiled(tif)) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ? - "Can not read tiles from a striped image" : - "Can not read scanlines from a tiled image"); - return (0); - } - return (1); + if (tif->tif_mode == O_WRONLY) + { + TIFFErrorExtR(tif, tif->tif_name, "File not open for reading"); + return (0); + } + if (tiles ^ isTiled(tif)) + { + TIFFErrorExtR(tif, tif->tif_name, + tiles ? "Can not read tiles from a striped image" + : "Can not read scanlines from a tiled image"); + return (0); + } + return (1); } /* Use the provided input buffer (inbuf, insize) and decompress it into * (outbuf, outsize). - * This function replaces the use of TIFFReadEncodedStrip()/TIFFReadEncodedTile() - * when the user can provide the buffer for the input data, for example when - * he wants to avoid libtiff to read the strile offset/count values from the - * [Strip|Tile][Offsets/ByteCounts] array. - * inbuf content must be writable (if bit reversal is needed) - * Returns 1 in case of success, 0 otherwise. + * This function replaces the use of + * TIFFReadEncodedStrip()/TIFFReadEncodedTile() when the user can provide the + * buffer for the input data, for example when he wants to avoid libtiff to read + * the strile offset/count values from the [Strip|Tile][Offsets/ByteCounts] + * array. inbuf content must be writable (if bit reversal is needed) Returns 1 + * in case of success, 0 otherwise. */ -int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile, - void* inbuf, tmsize_t insize, - void* outbuf, tmsize_t outsize) +int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, + tmsize_t insize, void *outbuf, tmsize_t outsize) { static const char module[] = "TIFFReadFromUserBuffer"; TIFFDirectory *td = &tif->tif_dir; int ret = 1; - uint32 old_tif_flags = tif->tif_flags; + uint32_t old_tif_flags = tif->tif_flags; tmsize_t old_rawdatasize = tif->tif_rawdatasize; - void* old_rawdata = tif->tif_rawdata; + void *old_rawdata = tif->tif_rawdata; - if (tif->tif_mode == O_WRONLY) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading"); + if (tif->tif_mode == O_WRONLY) + { + TIFFErrorExtR(tif, tif->tif_name, "File not open for reading"); return 0; } - if (tif->tif_flags&TIFF_NOREADRAW) + if (tif->tif_flags & TIFF_NOREADRAW) { - TIFFErrorExt(tif->tif_clientdata, module, - "Compression scheme does not support access to raw uncompressed data"); + TIFFErrorExtR(tif, module, + "Compression scheme does not support access to raw " + "uncompressed data"); return 0; } @@ -1564,32 +1543,33 @@ int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile, TIFFReverseBits(inbuf, insize); } - if( TIFFIsTiled(tif) ) + if (TIFFIsTiled(tif)) { - if( !TIFFStartTile(tif, strile) || - !(*tif->tif_decodetile)(tif, (uint8*) outbuf, outsize, - (uint16)(strile/td->td_stripsperimage)) ) + if (!TIFFStartTile(tif, strile) || + !(*tif->tif_decodetile)(tif, (uint8_t *)outbuf, outsize, + (uint16_t)(strile / td->td_stripsperimage))) { ret = 0; } } else { - uint32 rowsperstrip=td->td_rowsperstrip; - uint32 stripsperplane; - if (rowsperstrip>td->td_imagelength) - rowsperstrip=td->td_imagelength; - stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); - if( !TIFFStartStrip(tif, strile) || - !(*tif->tif_decodestrip)(tif, (uint8*) outbuf, outsize, - (uint16)(strile/stripsperplane)) ) + uint32_t rowsperstrip = td->td_rowsperstrip; + uint32_t stripsperplane; + if (rowsperstrip > td->td_imagelength) + rowsperstrip = td->td_imagelength; + stripsperplane = + TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); + if (!TIFFStartStrip(tif, strile) || + !(*tif->tif_decodestrip)(tif, (uint8_t *)outbuf, outsize, + (uint16_t)(strile / stripsperplane))) { ret = 0; } } - if( ret ) + if (ret) { - (*tif->tif_postdecode)(tif, (uint8*) outbuf, outsize); + (*tif->tif_postdecode)(tif, (uint8_t *)outbuf, outsize); } if (!isFillOrder(tif, td->td_fillorder) && @@ -1598,7 +1578,8 @@ int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile, TIFFReverseBits(inbuf, insize); } - tif->tif_flags = old_tif_flags; + tif->tif_flags = (old_tif_flags & (TIFF_MYBUFFER | TIFF_BUFFERMMAP)) | + (tif->tif_flags & ~(TIFF_MYBUFFER | TIFF_BUFFERMMAP)); tif->tif_rawdatasize = old_rawdatasize; tif->tif_rawdata = old_rawdata; tif->tif_rawdataoff = 0; @@ -1607,49 +1588,37 @@ int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile, return ret; } -void -_TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc) +void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; (void) buf; (void) cc; + (void)tif; + (void)buf; + (void)cc; } -void -_TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc) +void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; + (void)tif; assert((cc & 1) == 0); - TIFFSwabArrayOfShort((uint16*) buf, cc/2); + TIFFSwabArrayOfShort((uint16_t *)buf, cc / 2); } -void -_TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc) +void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; + (void)tif; assert((cc % 3) == 0); - TIFFSwabArrayOfTriples((uint8*) buf, cc/3); + TIFFSwabArrayOfTriples((uint8_t *)buf, cc / 3); } -void -_TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc) +void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; + (void)tif; assert((cc & 3) == 0); - TIFFSwabArrayOfLong((uint32*) buf, cc/4); + TIFFSwabArrayOfLong((uint32_t *)buf, cc / 4); } -void -_TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc) +void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; + (void)tif; assert((cc & 7) == 0); - TIFFSwabArrayOfDouble((double*) buf, cc/8); + TIFFSwabArrayOfDouble((double *)buf, cc / 8); } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_stream.cxx b/3rdparty/libtiff/tif_stream.cxx index 7f640a9c0a..92ea273c56 100644 --- a/3rdparty/libtiff/tif_stream.cxx +++ b/3rdparty/libtiff/tif_stream.cxx @@ -2,23 +2,23 @@ * Copyright (c) 1988-1996 Sam Leffler * Copyright (c) 1991-1996 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -28,9 +28,7 @@ #include "tiffiop.h" #include -#ifndef __VMS using namespace std; -#endif /* ISO C++ uses a 'std::streamsize' type to define counts. This makes @@ -76,359 +74,331 @@ using namespace std; struct tiffis_data; struct tiffos_data; -extern "C" { - - static tmsize_t _tiffosReadProc(thandle_t, void*, tmsize_t); - static tmsize_t _tiffisReadProc(thandle_t fd, void* buf, tmsize_t size); - static tmsize_t _tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size); - static tmsize_t _tiffisWriteProc(thandle_t, void*, tmsize_t); - static uint64 _tiffosSeekProc(thandle_t fd, uint64 off, int whence); - static uint64 _tiffisSeekProc(thandle_t fd, uint64 off, int whence); - static uint64 _tiffosSizeProc(thandle_t fd); - static uint64 _tiffisSizeProc(thandle_t fd); - static int _tiffosCloseProc(thandle_t fd); - static int _tiffisCloseProc(thandle_t fd); - static int _tiffDummyMapProc(thandle_t , void** base, toff_t* size ); - static void _tiffDummyUnmapProc(thandle_t , void* base, toff_t size ); - static TIFF* _tiffStreamOpen(const char* name, const char* mode, void *fd); - -struct tiffis_data +extern "C" { - istream *stream; + + static tmsize_t _tiffosReadProc(thandle_t, void *, tmsize_t); + static tmsize_t _tiffisReadProc(thandle_t fd, void *buf, tmsize_t size); + static tmsize_t _tiffosWriteProc(thandle_t fd, void *buf, tmsize_t size); + static tmsize_t _tiffisWriteProc(thandle_t, void *, tmsize_t); + static uint64_t _tiffosSeekProc(thandle_t fd, uint64_t off, int whence); + static uint64_t _tiffisSeekProc(thandle_t fd, uint64_t off, int whence); + static uint64_t _tiffosSizeProc(thandle_t fd); + static uint64_t _tiffisSizeProc(thandle_t fd); + static int _tiffosCloseProc(thandle_t fd); + static int _tiffisCloseProc(thandle_t fd); + static int _tiffDummyMapProc(thandle_t, void **base, toff_t *size); + static void _tiffDummyUnmapProc(thandle_t, void *base, toff_t size); + static TIFF *_tiffStreamOpen(const char *name, const char *mode, void *fd); + + struct tiffis_data + { + istream *stream; ios::pos_type start_pos; -}; + }; -struct tiffos_data -{ - ostream *stream; - ios::pos_type start_pos; -}; + struct tiffos_data + { + ostream *stream; + ios::pos_type start_pos; + }; -static tmsize_t -_tiffosReadProc(thandle_t, void*, tmsize_t) -{ - return 0; -} + static tmsize_t _tiffosReadProc(thandle_t, void *, tmsize_t) { return 0; } -static tmsize_t -_tiffisReadProc(thandle_t fd, void* buf, tmsize_t size) -{ - tiffis_data *data = reinterpret_cast(fd); + static tmsize_t _tiffisReadProc(thandle_t fd, void *buf, tmsize_t size) + { + tiffis_data *data = reinterpret_cast(fd); // Verify that type does not overflow. streamsize request_size = size; if (static_cast(request_size) != size) - return static_cast(-1); + return static_cast(-1); - data->stream->read((char *) buf, request_size); + data->stream->read((char *)buf, request_size); return static_cast(data->stream->gcount()); -} + } -static tmsize_t -_tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size) -{ - tiffos_data *data = reinterpret_cast(fd); - ostream *os = data->stream; - ios::pos_type pos = os->tellp(); + static tmsize_t _tiffosWriteProc(thandle_t fd, void *buf, tmsize_t size) + { + tiffos_data *data = reinterpret_cast(fd); + ostream *os = data->stream; + ios::pos_type pos = os->tellp(); // Verify that type does not overflow. streamsize request_size = size; if (static_cast(request_size) != size) - return static_cast(-1); + return static_cast(-1); - os->write(reinterpret_cast(buf), request_size); + os->write(reinterpret_cast(buf), request_size); - return static_cast(os->tellp() - pos); -} + return static_cast(os->tellp() - pos); + } -static tmsize_t -_tiffisWriteProc(thandle_t, void*, tmsize_t) -{ - return 0; -} + static tmsize_t _tiffisWriteProc(thandle_t, void *, tmsize_t) { return 0; } -static uint64 -_tiffosSeekProc(thandle_t fd, uint64 off, int whence) -{ - tiffos_data *data = reinterpret_cast(fd); - ostream *os = data->stream; + static uint64_t _tiffosSeekProc(thandle_t fd, uint64_t off, int whence) + { + tiffos_data *data = reinterpret_cast(fd); + ostream *os = data->stream; - // if the stream has already failed, don't do anything - if( os->fail() ) - return static_cast(-1); + // if the stream has already failed, don't do anything + if (os->fail()) + return static_cast(-1); - switch(whence) { - case SEEK_SET: - { - // Compute 64-bit offset - uint64 new_offset = static_cast(data->start_pos) + off; + switch (whence) + { + case SEEK_SET: + { + // Compute 64-bit offset + uint64_t new_offset = + static_cast(data->start_pos) + off; - // Verify that value does not overflow - ios::off_type offset = static_cast(new_offset); - if (static_cast(offset) != new_offset) - return static_cast(-1); - - os->seekp(offset, ios::beg); - break; - } - case SEEK_CUR: - { - // Verify that value does not overflow - ios::off_type offset = static_cast(off); - if (static_cast(offset) != off) - return static_cast(-1); + // Verify that value does not overflow + ios::off_type offset = static_cast(new_offset); + if (static_cast(offset) != new_offset) + return static_cast(-1); - os->seekp(offset, ios::cur); - break; - } - case SEEK_END: - { - // Verify that value does not overflow - ios::off_type offset = static_cast(off); - if (static_cast(offset) != off) - return static_cast(-1); + os->seekp(offset, ios::beg); + break; + } + case SEEK_CUR: + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); - os->seekp(offset, ios::end); - break; - } - } + os->seekp(offset, ios::cur); + break; + } + case SEEK_END: + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); - // Attempt to workaround problems with seeking past the end of the - // stream. ofstream doesn't have a problem with this but - // ostrstream/ostringstream does. In that situation, add intermediate - // '\0' characters. - if( os->fail() ) { -#ifdef __VMS - int old_state; -#else - ios::iostate old_state; -#endif - ios::pos_type origin; + os->seekp(offset, ios::end); + break; + } + } - old_state = os->rdstate(); - // reset the fail bit or else tellp() won't work below - os->clear(os->rdstate() & ~ios::failbit); - switch( whence ) { - case SEEK_SET: - default: - origin = data->start_pos; - break; - case SEEK_CUR: - origin = os->tellp(); - break; - case SEEK_END: - os->seekp(0, ios::end); - origin = os->tellp(); - break; - } - // restore original stream state - os->clear(old_state); + // Attempt to workaround problems with seeking past the end of the + // stream. ofstream doesn't have a problem with this but + // ostrstream/ostringstream does. In that situation, add intermediate + // '\0' characters. + if (os->fail()) + { + ios::iostate old_state; + ios::pos_type origin; - // only do something if desired seek position is valid - if( (static_cast(origin) + off) > static_cast(data->start_pos) ) { - uint64 num_fill; + old_state = os->rdstate(); + // reset the fail bit or else tellp() won't work below + os->clear(os->rdstate() & ~ios::failbit); + switch (whence) + { + case SEEK_SET: + default: + origin = data->start_pos; + break; + case SEEK_CUR: + origin = os->tellp(); + break; + case SEEK_END: + os->seekp(0, ios::end); + origin = os->tellp(); + break; + } + // restore original stream state + os->clear(old_state); - // clear the fail bit - os->clear(os->rdstate() & ~ios::failbit); + // only do something if desired seek position is valid + if ((static_cast(origin) + off) > + static_cast(data->start_pos)) + { + uint64_t num_fill; - // extend the stream to the expected size - os->seekp(0, ios::end); - num_fill = (static_cast(origin)) + off - os->tellp(); - for( uint64 i = 0; i < num_fill; i++ ) - os->put('\0'); + // clear the fail bit + os->clear(os->rdstate() & ~ios::failbit); - // retry the seek - os->seekp(static_cast(static_cast(origin) + off), ios::beg); - } - } + // extend the stream to the expected size + os->seekp(0, ios::end); + num_fill = (static_cast(origin)) + off - os->tellp(); + for (uint64_t i = 0; i < num_fill; i++) + os->put('\0'); - return static_cast(os->tellp()); -} + // retry the seek + os->seekp(static_cast( + static_cast(origin) + off), + ios::beg); + } + } -static uint64 -_tiffisSeekProc(thandle_t fd, uint64 off, int whence) -{ - tiffis_data *data = reinterpret_cast(fd); + return static_cast(os->tellp()); + } - switch(whence) { - case SEEK_SET: - { - // Compute 64-bit offset - uint64 new_offset = static_cast(data->start_pos) + off; - - // Verify that value does not overflow - ios::off_type offset = static_cast(new_offset); - if (static_cast(offset) != new_offset) - return static_cast(-1); + static uint64_t _tiffisSeekProc(thandle_t fd, uint64_t off, int whence) + { + tiffis_data *data = reinterpret_cast(fd); - data->stream->seekg(offset, ios::beg); - break; - } - case SEEK_CUR: - { - // Verify that value does not overflow - ios::off_type offset = static_cast(off); - if (static_cast(offset) != off) - return static_cast(-1); + switch (whence) + { + case SEEK_SET: + { + // Compute 64-bit offset + uint64_t new_offset = + static_cast(data->start_pos) + off; - data->stream->seekg(offset, ios::cur); - break; - } - case SEEK_END: - { - // Verify that value does not overflow - ios::off_type offset = static_cast(off); - if (static_cast(offset) != off) - return static_cast(-1); + // Verify that value does not overflow + ios::off_type offset = static_cast(new_offset); + if (static_cast(offset) != new_offset) + return static_cast(-1); - data->stream->seekg(offset, ios::end); - break; - } - } + data->stream->seekg(offset, ios::beg); + break; + } + case SEEK_CUR: + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); - return (uint64) (data->stream->tellg() - data->start_pos); -} + data->stream->seekg(offset, ios::cur); + break; + } + case SEEK_END: + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); -static uint64 -_tiffosSizeProc(thandle_t fd) -{ - tiffos_data *data = reinterpret_cast(fd); - ostream *os = data->stream; - ios::pos_type pos = os->tellp(); - ios::pos_type len; + data->stream->seekg(offset, ios::end); + break; + } + } - os->seekp(0, ios::end); - len = os->tellp(); - os->seekp(pos); + return (uint64_t)(data->stream->tellg() - data->start_pos); + } - return (uint64) len; -} + static uint64_t _tiffosSizeProc(thandle_t fd) + { + tiffos_data *data = reinterpret_cast(fd); + ostream *os = data->stream; + ios::pos_type pos = os->tellp(); + ios::pos_type len; -static uint64 -_tiffisSizeProc(thandle_t fd) -{ - tiffis_data *data = reinterpret_cast(fd); - ios::pos_type pos = data->stream->tellg(); - ios::pos_type len; + os->seekp(0, ios::end); + len = os->tellp(); + os->seekp(pos); - data->stream->seekg(0, ios::end); - len = data->stream->tellg(); - data->stream->seekg(pos); + return (uint64_t)len; + } - return (uint64) len; -} + static uint64_t _tiffisSizeProc(thandle_t fd) + { + tiffis_data *data = reinterpret_cast(fd); + ios::pos_type pos = data->stream->tellg(); + ios::pos_type len; -static int -_tiffosCloseProc(thandle_t fd) -{ - // Our stream was not allocated by us, so it shouldn't be closed by us. - delete reinterpret_cast(fd); - return 0; -} + data->stream->seekg(0, ios::end); + len = data->stream->tellg(); + data->stream->seekg(pos); -static int -_tiffisCloseProc(thandle_t fd) -{ - // Our stream was not allocated by us, so it shouldn't be closed by us. - delete reinterpret_cast(fd); - return 0; -} + return (uint64_t)len; + } -static int -_tiffDummyMapProc(thandle_t , void** base, toff_t* size ) -{ - (void) base; - (void) size; - return (0); -} + static int _tiffosCloseProc(thandle_t fd) + { + // Our stream was not allocated by us, so it shouldn't be closed by us. + delete reinterpret_cast(fd); + return 0; + } -static void -_tiffDummyUnmapProc(thandle_t , void* base, toff_t size ) -{ - (void) base; - (void) size; -} + static int _tiffisCloseProc(thandle_t fd) + { + // Our stream was not allocated by us, so it shouldn't be closed by us. + delete reinterpret_cast(fd); + return 0; + } -/* - * Open a TIFF file descriptor for read/writing. - */ -static TIFF* -_tiffStreamOpen(const char* name, const char* mode, void *fd) -{ - TIFF* tif; + static int _tiffDummyMapProc(thandle_t, void **base, toff_t *size) + { + (void)base; + (void)size; + return (0); + } - if( strchr(mode, 'w') ) { - tiffos_data *data = new tiffos_data; - data->stream = reinterpret_cast(fd); - data->start_pos = data->stream->tellp(); + static void _tiffDummyUnmapProc(thandle_t, void *base, toff_t size) + { + (void)base; + (void)size; + } - // Open for writing. - tif = TIFFClientOpen(name, mode, - reinterpret_cast(data), - _tiffosReadProc, - _tiffosWriteProc, - _tiffosSeekProc, - _tiffosCloseProc, - _tiffosSizeProc, - _tiffDummyMapProc, - _tiffDummyUnmapProc); - if (!tif) { - delete data; - } - } else { - tiffis_data *data = new tiffis_data; - data->stream = reinterpret_cast(fd); - data->start_pos = data->stream->tellg(); - // Open for reading. - tif = TIFFClientOpen(name, mode, - reinterpret_cast(data), - _tiffisReadProc, - _tiffisWriteProc, - _tiffisSeekProc, - _tiffisCloseProc, - _tiffisSizeProc, - _tiffDummyMapProc, - _tiffDummyUnmapProc); - if (!tif) { - delete data; - } - } + /* + * Open a TIFF file descriptor for read/writing. + */ + static TIFF *_tiffStreamOpen(const char *name, const char *mode, void *fd) + { + TIFF *tif; - return (tif); -} + if (strchr(mode, 'w')) + { + tiffos_data *data = new tiffos_data; + data->stream = reinterpret_cast(fd); + data->start_pos = data->stream->tellp(); + + // Open for writing. + tif = TIFFClientOpen( + name, mode, reinterpret_cast(data), _tiffosReadProc, + _tiffosWriteProc, _tiffosSeekProc, _tiffosCloseProc, + _tiffosSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc); + if (!tif) + { + delete data; + } + } + else + { + tiffis_data *data = new tiffis_data; + data->stream = reinterpret_cast(fd); + data->start_pos = data->stream->tellg(); + // Open for reading. + tif = TIFFClientOpen( + name, mode, reinterpret_cast(data), _tiffisReadProc, + _tiffisWriteProc, _tiffisSeekProc, _tiffisCloseProc, + _tiffisSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc); + if (!tif) + { + delete data; + } + } + + return (tif); + } } /* extern "C" */ -TIFF* -TIFFStreamOpen(const char* name, ostream *os) +TIFF *TIFFStreamOpen(const char *name, ostream *os) { - // If os is either a ostrstream or ostringstream, and has no data - // written to it yet, then tellp() will return -1 which will break us. - // We workaround this by writing out a dummy character and - // then seek back to the beginning. - if( !os->fail() && static_cast(os->tellp()) < 0 ) { - *os << '\0'; - os->seekp(0); - } + // If os is either a ostrstream or ostringstream, and has no data + // written to it yet, then tellp() will return -1 which will break us. + // We workaround this by writing out a dummy character and + // then seek back to the beginning. + if (!os->fail() && static_cast(os->tellp()) < 0) + { + *os << '\0'; + os->seekp(0); + } - // NB: We don't support mapped files with streams so add 'm' - return _tiffStreamOpen(name, "wm", os); + // NB: We don't support mapped files with streams so add 'm' + return _tiffStreamOpen(name, "wm", os); } -TIFF* -TIFFStreamOpen(const char* name, istream *is) +TIFF *TIFFStreamOpen(const char *name, istream *is) { - // NB: We don't support mapped files with streams so add 'm' - return _tiffStreamOpen(name, "rm", is); + // NB: We don't support mapped files with streams so add 'm' + return _tiffStreamOpen(name, "rm", is); } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ - diff --git a/3rdparty/libtiff/tif_strip.c b/3rdparty/libtiff/tif_strip.c index c08c60a792..820a2544c3 100644 --- a/3rdparty/libtiff/tif_strip.c +++ b/3rdparty/libtiff/tif_strip.c @@ -2,23 +2,23 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,153 +32,145 @@ /* * Compute which strip a (row,sample) value is in. */ -uint32 -TIFFComputeStrip(TIFF* tif, uint32 row, uint16 sample) +uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample) { - static const char module[] = "TIFFComputeStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint32 strip; + static const char module[] = "TIFFComputeStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint32_t strip; - strip = row / td->td_rowsperstrip; - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - if (sample >= td->td_samplesperpixel) { - TIFFErrorExt(tif->tif_clientdata, module, - "%lu: Sample out of range, max %lu", - (unsigned long) sample, (unsigned long) td->td_samplesperpixel); - return (0); - } - strip += (uint32)sample*td->td_stripsperimage; - } - return (strip); + strip = row / td->td_rowsperstrip; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + if (sample >= td->td_samplesperpixel) + { + TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu", + (unsigned long)sample, + (unsigned long)td->td_samplesperpixel); + return (0); + } + strip += (uint32_t)sample * td->td_stripsperimage; + } + return (strip); } /* * Compute how many strips are in an image. */ -uint32 -TIFFNumberOfStrips(TIFF* tif) +uint32_t TIFFNumberOfStrips(TIFF *tif) { - TIFFDirectory *td = &tif->tif_dir; - uint32 nstrips; + TIFFDirectory *td = &tif->tif_dir; + uint32_t nstrips; - nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 : - TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel, - "TIFFNumberOfStrips"); - return (nstrips); + nstrips = (td->td_rowsperstrip == (uint32_t)-1 + ? 1 + : TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + nstrips = + _TIFFMultiply32(tif, nstrips, (uint32_t)td->td_samplesperpixel, + "TIFFNumberOfStrips"); + return (nstrips); } /* * Compute the # bytes in a variable height, row-aligned strip. */ -uint64 -TIFFVStripSize64(TIFF* tif, uint32 nrows) +uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows) { - static const char module[] = "TIFFVStripSize64"; - TIFFDirectory *td = &tif->tif_dir; - if (nrows==(uint32)(-1)) - nrows=td->td_imagelength; - if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& - (td->td_photometric == PHOTOMETRIC_YCBCR)&& - (!isUpSampled(tif))) - { - /* - * Packed YCbCr data contain one Cb+Cr for every - * HorizontalSampling*VerticalSampling Y values. - * Must also roundup width and height when calculating - * since images that are not a multiple of the - * horizontal/vertical subsampling area include - * YCbCr data for the extended image. - */ - uint16 ycbcrsubsampling[2]; - uint16 samplingblock_samples; - uint32 samplingblocks_hor; - uint32 samplingblocks_ver; - uint64 samplingrow_samples; - uint64 samplingrow_size; - if(td->td_samplesperpixel!=3) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Invalid td_samplesperpixel value"); - return 0; - } - TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, - ycbcrsubsampling+1); - if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) - ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Invalid YCbCr subsampling (%dx%d)", - ycbcrsubsampling[0], - ycbcrsubsampling[1] ); - return 0; - } - samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; - samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); - samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); - samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); - samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); - return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); - } - else - return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module)); + static const char module[] = "TIFFVStripSize64"; + TIFFDirectory *td = &tif->tif_dir; + if (nrows == (uint32_t)(-1)) + nrows = td->td_imagelength; + if ((td->td_planarconfig == PLANARCONFIG_CONTIG) && + (td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) + { + /* + * Packed YCbCr data contain one Cb+Cr for every + * HorizontalSampling*VerticalSampling Y values. + * Must also roundup width and height when calculating + * since images that are not a multiple of the + * horizontal/vertical subsampling area include + * YCbCr data for the extended image. + */ + uint16_t ycbcrsubsampling[2]; + uint16_t samplingblock_samples; + uint32_t samplingblocks_hor; + uint32_t samplingblocks_ver; + uint64_t samplingrow_samples; + uint64_t samplingrow_size; + if (td->td_samplesperpixel != 3) + { + TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value"); + return 0; + } + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, + ycbcrsubsampling + 0, ycbcrsubsampling + 1); + if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && + ycbcrsubsampling[0] != 4) || + (ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && + ycbcrsubsampling[1] != 4)) + { + TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)", + ycbcrsubsampling[0], ycbcrsubsampling[1]); + return 0; + } + samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2; + samplingblocks_hor = + TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]); + samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]); + samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor, + samplingblock_samples, module); + samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64( + tif, samplingrow_samples, td->td_bitspersample, module)); + return ( + _TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module)); + } + else + return (_TIFFMultiply64(tif, nrows, TIFFScanlineSize64(tif), module)); } -tmsize_t -TIFFVStripSize(TIFF* tif, uint32 nrows) +tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows) { - static const char module[] = "TIFFVStripSize"; - uint64 m; - m=TIFFVStripSize64(tif,nrows); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFVStripSize"; + uint64_t m; + m = TIFFVStripSize64(tif, nrows); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* * Compute the # bytes in a raw strip. */ -uint64 -TIFFRawStripSize64(TIFF* tif, uint32 strip) +uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip) { - static const char module[] = "TIFFRawStripSize64"; - uint64 bytecount = TIFFGetStrileByteCount(tif, strip); + static const char module[] = "TIFFRawStripSize64"; + uint64_t bytecount = TIFFGetStrileByteCount(tif, strip); - if (bytecount == 0) - { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "%I64u: Invalid strip byte count, strip %lu", - (unsigned __int64) bytecount, - (unsigned long) strip); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "%llu: Invalid strip byte count, strip %lu", - (unsigned long long) bytecount, - (unsigned long) strip); -#endif - bytecount = (uint64) -1; - } + if (bytecount == 0) + { + TIFFErrorExtR(tif, module, + "%" PRIu64 ": Invalid strip byte count, strip %lu", + (uint64_t)bytecount, (unsigned long)strip); + bytecount = (uint64_t)-1; + } - return bytecount; + return bytecount; } -tmsize_t -TIFFRawStripSize(TIFF* tif, uint32 strip) +tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip) { - static const char module[] = "TIFFRawStripSize"; - uint64 m; - tmsize_t n; - m=TIFFRawStripSize64(tif,strip); - if (m==(uint64)(-1)) - n=(tmsize_t)(-1); - else - { - n=(tmsize_t)m; - if ((uint64)n!=m) - { - TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); - n=0; - } - } - return(n); + static const char module[] = "TIFFRawStripSize"; + uint64_t m; + tmsize_t n; + m = TIFFRawStripSize64(tif, strip); + if (m == (uint64_t)(-1)) + n = (tmsize_t)(-1); + else + { + n = (tmsize_t)m; + if ((uint64_t)n != m) + { + TIFFErrorExtR(tif, module, "Integer overflow"); + n = 0; + } + } + return (n); } /* @@ -189,22 +181,20 @@ TIFFRawStripSize(TIFF* tif, uint32 strip) * truncated to reflect the actual space required * to hold the strip. */ -uint64 -TIFFStripSize64(TIFF* tif) +uint64_t TIFFStripSize64(TIFF *tif) { - TIFFDirectory* td = &tif->tif_dir; - uint32 rps = td->td_rowsperstrip; - if (rps > td->td_imagelength) - rps = td->td_imagelength; - return (TIFFVStripSize64(tif, rps)); + TIFFDirectory *td = &tif->tif_dir; + uint32_t rps = td->td_rowsperstrip; + if (rps > td->td_imagelength) + rps = td->td_imagelength; + return (TIFFVStripSize64(tif, rps)); } -tmsize_t -TIFFStripSize(TIFF* tif) +tmsize_t TIFFStripSize(TIFF *tif) { - static const char module[] = "TIFFStripSize"; - uint64 m; - m=TIFFStripSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFStripSize"; + uint64_t m; + m = TIFFStripSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* @@ -213,34 +203,33 @@ TIFFStripSize(TIFF* tif) * request is <1 then we choose a strip size according * to certain heuristics. */ -uint32 -TIFFDefaultStripSize(TIFF* tif, uint32 request) +uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request) { - return (*tif->tif_defstripsize)(tif, request); + return (*tif->tif_defstripsize)(tif, request); } -uint32 -_TIFFDefaultStripSize(TIFF* tif, uint32 s) +uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s) { - if ((int32) s < 1) { - /* - * If RowsPerStrip is unspecified, try to break the - * image up into strips that are approximately - * STRIP_SIZE_DEFAULT bytes long. - */ - uint64 scanlinesize; - uint64 rows; - scanlinesize=TIFFScanlineSize64(tif); - if (scanlinesize==0) - scanlinesize=1; - rows=(uint64)STRIP_SIZE_DEFAULT/scanlinesize; - if (rows==0) - rows=1; - else if (rows>0xFFFFFFFF) - rows=0xFFFFFFFF; - s=(uint32)rows; - } - return (s); + if ((int32_t)s < 1) + { + /* + * If RowsPerStrip is unspecified, try to break the + * image up into strips that are approximately + * STRIP_SIZE_DEFAULT bytes long. + */ + uint64_t scanlinesize; + uint64_t rows; + scanlinesize = TIFFScanlineSize64(tif); + if (scanlinesize == 0) + scanlinesize = 1; + rows = (uint64_t)STRIP_SIZE_DEFAULT / scanlinesize; + if (rows == 0) + rows = 1; + else if (rows > 0xFFFFFFFF) + rows = 0xFFFFFFFF; + s = (uint32_t)rows; + } + return (s); } /* @@ -253,70 +242,79 @@ _TIFFDefaultStripSize(TIFF* tif, uint32 s) * subsampling lines divided by vertical subsampling. It should thus make * sense when multiplied by a multiple of vertical subsampling. */ -uint64 -TIFFScanlineSize64(TIFF* tif) +uint64_t TIFFScanlineSize64(TIFF *tif) { - static const char module[] = "TIFFScanlineSize64"; - TIFFDirectory *td = &tif->tif_dir; - uint64 scanline_size; - if (td->td_planarconfig==PLANARCONFIG_CONTIG) - { - if ((td->td_photometric==PHOTOMETRIC_YCBCR)&& - (td->td_samplesperpixel==3)&& - (!isUpSampled(tif))) - { - uint16 ycbcrsubsampling[2]; - uint16 samplingblock_samples; - uint32 samplingblocks_hor; - uint64 samplingrow_samples; - uint64 samplingrow_size; - if(td->td_samplesperpixel!=3) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Invalid td_samplesperpixel value"); - return 0; - } - TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING, - ycbcrsubsampling+0, - ycbcrsubsampling+1); - if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) || - ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4))) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Invalid YCbCr subsampling"); - return 0; - } - samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; - samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); - samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); - samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8); - scanline_size = (samplingrow_size/ycbcrsubsampling[1]); - } - else - { - uint64 scanline_samples; - scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module); - scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8); - } - } - else + static const char module[] = "TIFFScanlineSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t scanline_size; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + if ((td->td_photometric == PHOTOMETRIC_YCBCR) && + (td->td_samplesperpixel == 3) && (!isUpSampled(tif))) { - scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8); - } - if (scanline_size == 0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Computed scanline size is zero"); + uint16_t ycbcrsubsampling[2]; + uint16_t samplingblock_samples; + uint32_t samplingblocks_hor; + uint64_t samplingrow_samples; + uint64_t samplingrow_size; + if (td->td_samplesperpixel != 3) + { + TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value"); return 0; + } + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, + ycbcrsubsampling + 0, ycbcrsubsampling + 1); + if (((ycbcrsubsampling[0] != 1) && (ycbcrsubsampling[0] != 2) && + (ycbcrsubsampling[0] != 4)) || + ((ycbcrsubsampling[1] != 1) && (ycbcrsubsampling[1] != 2) && + (ycbcrsubsampling[1] != 4))) + { + TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling"); + return 0; + } + samplingblock_samples = + ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2; + samplingblocks_hor = + TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]); + samplingrow_samples = _TIFFMultiply64( + tif, samplingblocks_hor, samplingblock_samples, module); + samplingrow_size = + TIFFhowmany_64(_TIFFMultiply64(tif, samplingrow_samples, + td->td_bitspersample, module), + 8); + scanline_size = (samplingrow_size / ycbcrsubsampling[1]); } - return(scanline_size); + else + { + uint64_t scanline_samples; + scanline_samples = _TIFFMultiply64(tif, td->td_imagewidth, + td->td_samplesperpixel, module); + scanline_size = + TIFFhowmany_64(_TIFFMultiply64(tif, scanline_samples, + td->td_bitspersample, module), + 8); + } + } + else + { + scanline_size = + TIFFhowmany_64(_TIFFMultiply64(tif, td->td_imagewidth, + td->td_bitspersample, module), + 8); + } + if (scanline_size == 0) + { + TIFFErrorExtR(tif, module, "Computed scanline size is zero"); + return 0; + } + return (scanline_size); } -tmsize_t -TIFFScanlineSize(TIFF* tif) +tmsize_t TIFFScanlineSize(TIFF *tif) { - static const char module[] = "TIFFScanlineSize"; - uint64 m; - m=TIFFScanlineSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFScanlineSize"; + uint64_t m; + m = TIFFScanlineSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* @@ -325,35 +323,28 @@ TIFFScanlineSize(TIFF* tif) * I/O size returned by TIFFScanlineSize which may be less * if data is store as separate planes). */ -uint64 -TIFFRasterScanlineSize64(TIFF* tif) +uint64_t TIFFRasterScanlineSize64(TIFF *tif) { - static const char module[] = "TIFFRasterScanlineSize64"; - TIFFDirectory *td = &tif->tif_dir; - uint64 scanline; + static const char module[] = "TIFFRasterScanlineSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t scanline; - scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module); - return (TIFFhowmany8_64(scanline)); - } else - return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline), - td->td_samplesperpixel, module)); + scanline = + _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module); + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + scanline = + _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module); + return (TIFFhowmany8_64(scanline)); + } + else + return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline), + td->td_samplesperpixel, module)); } -tmsize_t -TIFFRasterScanlineSize(TIFF* tif) +tmsize_t TIFFRasterScanlineSize(TIFF *tif) { - static const char module[] = "TIFFRasterScanlineSize"; - uint64 m; - m=TIFFRasterScanlineSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFRasterScanlineSize"; + uint64_t m; + m = TIFFRasterScanlineSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_swab.c b/3rdparty/libtiff/tif_swab.c index b174ba69c0..827b025ce7 100644 --- a/3rdparty/libtiff/tif_swab.c +++ b/3rdparty/libtiff/tif_swab.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -30,169 +30,218 @@ #include "tiffiop.h" #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort) -void -TIFFSwabShort(uint16* wp) +void TIFFSwabShort(uint16_t *wp) { - register unsigned char* cp = (unsigned char*) wp; - unsigned char t; - assert(sizeof(uint16)==2); - t = cp[1]; cp[1] = cp[0]; cp[0] = t; + register unsigned char *cp = (unsigned char *)wp; + unsigned char t; + assert(sizeof(uint16_t) == 2); + t = cp[1]; + cp[1] = cp[0]; + cp[0] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong) -void -TIFFSwabLong(uint32* lp) +void TIFFSwabLong(uint32_t *lp) { - register unsigned char* cp = (unsigned char*) lp; - unsigned char t; - assert(sizeof(uint32)==4); - t = cp[3]; cp[3] = cp[0]; cp[0] = t; - t = cp[2]; cp[2] = cp[1]; cp[1] = t; + register unsigned char *cp = (unsigned char *)lp; + unsigned char t; + assert(sizeof(uint32_t) == 4); + t = cp[3]; + cp[3] = cp[0]; + cp[0] = t; + t = cp[2]; + cp[2] = cp[1]; + cp[1] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8) -void -TIFFSwabLong8(uint64* lp) +void TIFFSwabLong8(uint64_t *lp) { - register unsigned char* cp = (unsigned char*) lp; - unsigned char t; - assert(sizeof(uint64)==8); - t = cp[7]; cp[7] = cp[0]; cp[0] = t; - t = cp[6]; cp[6] = cp[1]; cp[1] = t; - t = cp[5]; cp[5] = cp[2]; cp[2] = t; - t = cp[4]; cp[4] = cp[3]; cp[3] = t; + register unsigned char *cp = (unsigned char *)lp; + unsigned char t; + assert(sizeof(uint64_t) == 8); + t = cp[7]; + cp[7] = cp[0]; + cp[0] = t; + t = cp[6]; + cp[6] = cp[1]; + cp[1] = t; + t = cp[5]; + cp[5] = cp[2]; + cp[2] = t; + t = cp[4]; + cp[4] = cp[3]; + cp[3] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort) -void -TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n) +void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n) { - register unsigned char* cp; - register unsigned char t; - assert(sizeof(uint16)==2); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char*) wp; - t = cp[1]; cp[1] = cp[0]; cp[0] = t; - wp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(uint16_t) == 2); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)wp; + t = cp[1]; + cp[1] = cp[0]; + cp[0] = t; + wp++; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples) -void -TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n) +void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n) { - unsigned char* cp; - unsigned char t; + unsigned char *cp; + unsigned char t; - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char*) tp; - t = cp[2]; cp[2] = cp[0]; cp[0] = t; - tp += 3; - } + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)tp; + t = cp[2]; + cp[2] = cp[0]; + cp[0] = t; + tp += 3; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong) -void -TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n) +void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; - assert(sizeof(uint32)==4); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char *)lp; - t = cp[3]; cp[3] = cp[0]; cp[0] = t; - t = cp[2]; cp[2] = cp[1]; cp[1] = t; - lp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(uint32_t) == 4); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)lp; + t = cp[3]; + cp[3] = cp[0]; + cp[0] = t; + t = cp[2]; + cp[2] = cp[1]; + cp[1] = t; + lp++; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8) -void -TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n) +void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; - assert(sizeof(uint64)==8); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char *)lp; - t = cp[7]; cp[7] = cp[0]; cp[0] = t; - t = cp[6]; cp[6] = cp[1]; cp[1] = t; - t = cp[5]; cp[5] = cp[2]; cp[2] = t; - t = cp[4]; cp[4] = cp[3]; cp[3] = t; - lp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(uint64_t) == 8); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)lp; + t = cp[7]; + cp[7] = cp[0]; + cp[0] = t; + t = cp[6]; + cp[6] = cp[1]; + cp[1] = t; + t = cp[5]; + cp[5] = cp[2]; + cp[2] = t; + t = cp[4]; + cp[4] = cp[3]; + cp[3] = t; + lp++; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat) -void -TIFFSwabFloat(float* fp) +void TIFFSwabFloat(float *fp) { - register unsigned char* cp = (unsigned char*) fp; - unsigned char t; - assert(sizeof(float)==4); - t = cp[3]; cp[3] = cp[0]; cp[0] = t; - t = cp[2]; cp[2] = cp[1]; cp[1] = t; + register unsigned char *cp = (unsigned char *)fp; + unsigned char t; + assert(sizeof(float) == 4); + t = cp[3]; + cp[3] = cp[0]; + cp[0] = t; + t = cp[2]; + cp[2] = cp[1]; + cp[1] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat) -void -TIFFSwabArrayOfFloat(register float* fp, tmsize_t n) +void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; - assert(sizeof(float)==4); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char *)fp; - t = cp[3]; cp[3] = cp[0]; cp[0] = t; - t = cp[2]; cp[2] = cp[1]; cp[1] = t; - fp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(float) == 4); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)fp; + t = cp[3]; + cp[3] = cp[0]; + cp[0] = t; + t = cp[2]; + cp[2] = cp[1]; + cp[1] = t; + fp++; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble) -void -TIFFSwabDouble(double *dp) +void TIFFSwabDouble(double *dp) { - register unsigned char* cp = (unsigned char*) dp; - unsigned char t; - assert(sizeof(double)==8); - t = cp[7]; cp[7] = cp[0]; cp[0] = t; - t = cp[6]; cp[6] = cp[1]; cp[1] = t; - t = cp[5]; cp[5] = cp[2]; cp[2] = t; - t = cp[4]; cp[4] = cp[3]; cp[3] = t; + register unsigned char *cp = (unsigned char *)dp; + unsigned char t; + assert(sizeof(double) == 8); + t = cp[7]; + cp[7] = cp[0]; + cp[0] = t; + t = cp[6]; + cp[6] = cp[1]; + cp[1] = t; + t = cp[5]; + cp[5] = cp[2]; + cp[2] = t; + t = cp[4]; + cp[4] = cp[3]; + cp[3] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble) -void -TIFFSwabArrayOfDouble(double* dp, tmsize_t n) +void TIFFSwabArrayOfDouble(double *dp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; - assert(sizeof(double)==8); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char *)dp; - t = cp[7]; cp[7] = cp[0]; cp[0] = t; - t = cp[6]; cp[6] = cp[1]; cp[1] = t; - t = cp[5]; cp[5] = cp[2]; cp[2] = t; - t = cp[4]; cp[4] = cp[3]; cp[3] = t; - dp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(double) == 8); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)dp; + t = cp[7]; + cp[7] = cp[0]; + cp[0] = t; + t = cp[6]; + cp[6] = cp[1]; + cp[1] = t; + t = cp[5]; + cp[5] = cp[2]; + cp[2] = t; + t = cp[4]; + cp[4] = cp[3]; + cp[3] = t; + dp++; + } } #endif @@ -206,105 +255,75 @@ TIFFSwabArrayOfDouble(double* dp, tmsize_t n) * do not reverse bit values. */ static const unsigned char TIFFBitRevTable[256] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -}; + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, + 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, + 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, + 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, + 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, + 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, + 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, + 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, + 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, + 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, + 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, + 0x3f, 0xbf, 0x7f, 0xff}; static const unsigned char TIFFNoBitRevTable[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0xff, }; -const unsigned char* -TIFFGetBitRevTable(int reversed) +const unsigned char *TIFFGetBitRevTable(int reversed) { - return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable); + return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable); } -void -TIFFReverseBits(uint8* cp, tmsize_t n) +void TIFFReverseBits(uint8_t *cp, tmsize_t n) { - for (; n > 8; n -= 8) { - cp[0] = TIFFBitRevTable[cp[0]]; - cp[1] = TIFFBitRevTable[cp[1]]; - cp[2] = TIFFBitRevTable[cp[2]]; - cp[3] = TIFFBitRevTable[cp[3]]; - cp[4] = TIFFBitRevTable[cp[4]]; - cp[5] = TIFFBitRevTable[cp[5]]; - cp[6] = TIFFBitRevTable[cp[6]]; - cp[7] = TIFFBitRevTable[cp[7]]; - cp += 8; - } - while (n-- > 0) { - *cp = TIFFBitRevTable[*cp]; - cp++; - } + for (; n > 8; n -= 8) + { + cp[0] = TIFFBitRevTable[cp[0]]; + cp[1] = TIFFBitRevTable[cp[1]]; + cp[2] = TIFFBitRevTable[cp[2]]; + cp[3] = TIFFBitRevTable[cp[3]]; + cp[4] = TIFFBitRevTable[cp[4]]; + cp[5] = TIFFBitRevTable[cp[5]]; + cp[6] = TIFFBitRevTable[cp[6]]; + cp[7] = TIFFBitRevTable[cp[7]]; + cp += 8; + } + while (n-- > 0) + { + *cp = TIFFBitRevTable[*cp]; + cp++; + } } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_thunder.c b/3rdparty/libtiff/tif_thunder.c index db6383a81a..1f97362ca3 100644 --- a/3rdparty/libtiff/tif_thunder.c +++ b/3rdparty/libtiff/tif_thunder.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -41,166 +41,158 @@ * or 3-bit delta values are used, with the deltas packed * into a single byte. */ -#define THUNDER_DATA 0x3f /* mask for 6-bit data */ -#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */ +#define THUNDER_DATA 0x3f /* mask for 6-bit data */ +#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */ /* code values */ -#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */ -#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */ -#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */ -#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */ -#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */ -#define THUNDER_RAW 0xc0 /* raw data encoded */ +#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */ +#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */ +#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */ +#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */ +#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */ +#define THUNDER_RAW 0xc0 /* raw data encoded */ -static const int twobitdeltas[4] = { 0, 1, 0, -1 }; -static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 }; +static const int twobitdeltas[4] = {0, 1, 0, -1}; +static const int threebitdeltas[8] = {0, 1, 2, 3, 0, -3, -2, -1}; -#define SETPIXEL(op, v) { \ - lastpixel = (v) & 0xf; \ - if ( npixels < maxpixels ) \ - { \ - if (npixels++ & 1) \ - *op++ |= lastpixel; \ - else \ - op[0] = (uint8) (lastpixel << 4); \ - } \ +#define SETPIXEL(op, v) \ + { \ + lastpixel = (v)&0xf; \ + if (npixels < maxpixels) \ + { \ + if (npixels++ & 1) \ + *op++ |= lastpixel; \ + else \ + op[0] = (uint8_t)(lastpixel << 4); \ + } \ + } + +static int ThunderSetupDecode(TIFF *tif) +{ + static const char module[] = "ThunderSetupDecode"; + + if (tif->tif_dir.td_bitspersample != 4) + { + TIFFErrorExtR(tif, module, + "Wrong bitspersample value (%d), Thunder decoder only " + "supports 4bits per sample.", + (int)tif->tif_dir.td_bitspersample); + return 0; + } + + return (1); } -static int -ThunderSetupDecode(TIFF* tif) +static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels) { - static const char module[] = "ThunderSetupDecode"; + static const char module[] = "ThunderDecode"; + register unsigned char *bp; + register tmsize_t cc; + unsigned int lastpixel; + tmsize_t npixels; - if( tif->tif_dir.td_bitspersample != 4 ) + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + lastpixel = 0; + npixels = 0; + while (cc > 0 && npixels < maxpixels) + { + int n, delta; + + n = *bp++; + cc--; + switch (n & THUNDER_CODE) { - TIFFErrorExt(tif->tif_clientdata, module, - "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.", - (int) tif->tif_dir.td_bitspersample ); - return 0; + case THUNDER_RUN: /* pixel run */ + /* + * Replicate the last pixel n times, + * where n is the lower-order 6 bits. + */ + if (npixels & 1) + { + op[0] |= lastpixel; + lastpixel = *op++; + npixels++; + n--; + } + else + lastpixel |= lastpixel << 4; + npixels += n; + if (npixels < maxpixels) + { + for (; n > 0; n -= 2) + *op++ = (uint8_t)lastpixel; + } + if (n == -1) + *--op &= 0xf0; + lastpixel &= 0xf; + break; + case THUNDER_2BITDELTAS: /* 2-bit deltas */ + if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) + SETPIXEL(op, + (unsigned)((int)lastpixel + twobitdeltas[delta])); + if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) + SETPIXEL(op, + (unsigned)((int)lastpixel + twobitdeltas[delta])); + if ((delta = (n & 3)) != DELTA2_SKIP) + SETPIXEL(op, + (unsigned)((int)lastpixel + twobitdeltas[delta])); + break; + case THUNDER_3BITDELTAS: /* 3-bit deltas */ + if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) + SETPIXEL( + op, (unsigned)((int)lastpixel + threebitdeltas[delta])); + if ((delta = (n & 7)) != DELTA3_SKIP) + SETPIXEL( + op, (unsigned)((int)lastpixel + threebitdeltas[delta])); + break; + case THUNDER_RAW: /* raw data */ + SETPIXEL(op, n); + break; } - + } + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + if (npixels != maxpixels) + { + TIFFErrorExtR(tif, module, + "%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")", + npixels < maxpixels ? "Not enough" : "Too much", + (unsigned long)tif->tif_row, (uint64_t)npixels, + (uint64_t)maxpixels); + return (0); + } - return (1); + return (1); } -static int -ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels) +static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - static const char module[] = "ThunderDecode"; - register unsigned char *bp; - register tmsize_t cc; - unsigned int lastpixel; - tmsize_t npixels; + static const char module[] = "ThunderDecodeRow"; + uint8_t *row = buf; - bp = (unsigned char *)tif->tif_rawcp; - cc = tif->tif_rawcc; - lastpixel = 0; - npixels = 0; - while (cc > 0 && npixels < maxpixels) { - int n, delta; - - n = *bp++; - cc--; - switch (n & THUNDER_CODE) { - case THUNDER_RUN: /* pixel run */ - /* - * Replicate the last pixel n times, - * where n is the lower-order 6 bits. - */ - if (npixels & 1) { - op[0] |= lastpixel; - lastpixel = *op++; npixels++; n--; - } else - lastpixel |= lastpixel << 4; - npixels += n; - if (npixels < maxpixels) { - for (; n > 0; n -= 2) - *op++ = (uint8) lastpixel; - } - if (n == -1) - *--op &= 0xf0; - lastpixel &= 0xf; - break; - case THUNDER_2BITDELTAS: /* 2-bit deltas */ - if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta])); - if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta])); - if ((delta = (n & 3)) != DELTA2_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta])); - break; - case THUNDER_3BITDELTAS: /* 3-bit deltas */ - if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta])); - if ((delta = (n & 7)) != DELTA3_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta])); - break; - case THUNDER_RAW: /* raw data */ - SETPIXEL(op, n); - break; - } - } - tif->tif_rawcp = (uint8*) bp; - tif->tif_rawcc = cc; - if (npixels != maxpixels) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "%s data at scanline %lu (%I64u != %I64u)", - npixels < maxpixels ? "Not enough" : "Too much", - (unsigned long) tif->tif_row, - (unsigned __int64) npixels, - (unsigned __int64) maxpixels); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "%s data at scanline %lu (%llu != %llu)", - npixels < maxpixels ? "Not enough" : "Too much", - (unsigned long) tif->tif_row, - (unsigned long long) npixels, - (unsigned long long) maxpixels); -#endif - return (0); - } - - return (1); + (void)s; + if (occ % tif->tif_scanlinesize) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (0); + } + while (occ > 0) + { + if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) + return (0); + occ -= tif->tif_scanlinesize; + row += tif->tif_scanlinesize; + } + return (1); } -static int -ThunderDecodeRow(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) +int TIFFInitThunderScan(TIFF *tif, int scheme) { - static const char module[] = "ThunderDecodeRow"; - uint8* row = buf; - - (void) s; - if (occ % tif->tif_scanlinesize) - { - TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); - return (0); - } - while (occ > 0) { - if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) - return (0); - occ -= tif->tif_scanlinesize; - row += tif->tif_scanlinesize; - } - return (1); -} + (void)scheme; -int -TIFFInitThunderScan(TIFF* tif, int scheme) -{ - (void) scheme; - - tif->tif_setupdecode = ThunderSetupDecode; - tif->tif_decoderow = ThunderDecodeRow; - tif->tif_decodestrip = ThunderDecodeRow; - return (1); + tif->tif_setupdecode = ThunderSetupDecode; + tif->tif_decoderow = ThunderDecodeRow; + tif->tif_decodestrip = ThunderDecodeRow; + return (1); } #endif /* THUNDER_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_tile.c b/3rdparty/libtiff/tif_tile.c index 661cc77154..f07032f731 100644 --- a/3rdparty/libtiff/tif_tile.c +++ b/3rdparty/libtiff/tif_tile.c @@ -2,23 +2,23 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,234 +32,230 @@ /* * Compute which tile an (x,y,z,s) value is in. */ -uint32 -TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) +uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, + uint16_t s) { - TIFFDirectory *td = &tif->tif_dir; - uint32 dx = td->td_tilewidth; - uint32 dy = td->td_tilelength; - uint32 dz = td->td_tiledepth; - uint32 tile = 1; + TIFFDirectory *td = &tif->tif_dir; + uint32_t dx = td->td_tilewidth; + uint32_t dy = td->td_tilelength; + uint32_t dz = td->td_tiledepth; + uint32_t tile = 1; - if (td->td_imagedepth == 1) - z = 0; - if (dx == (uint32) -1) - dx = td->td_imagewidth; - if (dy == (uint32) -1) - dy = td->td_imagelength; - if (dz == (uint32) -1) - dz = td->td_imagedepth; - if (dx != 0 && dy != 0 && dz != 0) { - uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx); - uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy); - uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz); + if (td->td_imagedepth == 1) + z = 0; + if (dx == (uint32_t)-1) + dx = td->td_imagewidth; + if (dy == (uint32_t)-1) + dy = td->td_imagelength; + if (dz == (uint32_t)-1) + dz = td->td_imagedepth; + if (dx != 0 && dy != 0 && dz != 0) + { + uint32_t xpt = TIFFhowmany_32(td->td_imagewidth, dx); + uint32_t ypt = TIFFhowmany_32(td->td_imagelength, dy); + uint32_t zpt = TIFFhowmany_32(td->td_imagedepth, dz); - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - tile = (xpt*ypt*zpt)*s + - (xpt*ypt)*(z/dz) + - xpt*(y/dy) + - x/dx; - else - tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx; - } - return (tile); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + tile = (xpt * ypt * zpt) * s + (xpt * ypt) * (z / dz) + + xpt * (y / dy) + x / dx; + else + tile = (xpt * ypt) * (z / dz) + xpt * (y / dy) + x / dx; + } + return (tile); } /* * Check an (x,y,z,s) coordinate * against the image bounds. */ -int -TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) +int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, uint16_t s) { - TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; - if (x >= td->td_imagewidth) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Col out of range, max %lu", - (unsigned long) x, - (unsigned long) (td->td_imagewidth - 1)); - return (0); - } - if (y >= td->td_imagelength) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Row out of range, max %lu", - (unsigned long) y, - (unsigned long) (td->td_imagelength - 1)); - return (0); - } - if (z >= td->td_imagedepth) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Depth out of range, max %lu", - (unsigned long) z, - (unsigned long) (td->td_imagedepth - 1)); - return (0); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE && - s >= td->td_samplesperpixel) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Sample out of range, max %lu", - (unsigned long) s, - (unsigned long) (td->td_samplesperpixel - 1)); - return (0); - } - return (1); + if (x >= td->td_imagewidth) + { + TIFFErrorExtR(tif, tif->tif_name, "%lu: Col out of range, max %lu", + (unsigned long)x, (unsigned long)(td->td_imagewidth - 1)); + return (0); + } + if (y >= td->td_imagelength) + { + TIFFErrorExtR(tif, tif->tif_name, "%lu: Row out of range, max %lu", + (unsigned long)y, + (unsigned long)(td->td_imagelength - 1)); + return (0); + } + if (z >= td->td_imagedepth) + { + TIFFErrorExtR(tif, tif->tif_name, "%lu: Depth out of range, max %lu", + (unsigned long)z, (unsigned long)(td->td_imagedepth - 1)); + return (0); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && + s >= td->td_samplesperpixel) + { + TIFFErrorExtR(tif, tif->tif_name, "%lu: Sample out of range, max %lu", + (unsigned long)s, + (unsigned long)(td->td_samplesperpixel - 1)); + return (0); + } + return (1); } /* * Compute how many tiles are in an image. */ -uint32 -TIFFNumberOfTiles(TIFF* tif) +uint32_t TIFFNumberOfTiles(TIFF *tif) { - TIFFDirectory *td = &tif->tif_dir; - uint32 dx = td->td_tilewidth; - uint32 dy = td->td_tilelength; - uint32 dz = td->td_tiledepth; - uint32 ntiles; + TIFFDirectory *td = &tif->tif_dir; + uint32_t dx = td->td_tilewidth; + uint32_t dy = td->td_tilelength; + uint32_t dz = td->td_tiledepth; + uint32_t ntiles; - if (dx == (uint32) -1) - dx = td->td_imagewidth; - if (dy == (uint32) -1) - dy = td->td_imagelength; - if (dz == (uint32) -1) - dz = td->td_imagedepth; - ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 : - _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx), - TIFFhowmany_32(td->td_imagelength, dy), - "TIFFNumberOfTiles"), - TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles"); - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel, - "TIFFNumberOfTiles"); - return (ntiles); + if (dx == (uint32_t)-1) + dx = td->td_imagewidth; + if (dy == (uint32_t)-1) + dy = td->td_imagelength; + if (dz == (uint32_t)-1) + dz = td->td_imagedepth; + ntiles = + (dx == 0 || dy == 0 || dz == 0) + ? 0 + : _TIFFMultiply32( + tif, + _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx), + TIFFhowmany_32(td->td_imagelength, dy), + "TIFFNumberOfTiles"), + TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles"); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel, + "TIFFNumberOfTiles"); + return (ntiles); } /* * Compute the # bytes in each row of a tile. */ -uint64 -TIFFTileRowSize64(TIFF* tif) +uint64_t TIFFTileRowSize64(TIFF *tif) { - static const char module[] = "TIFFTileRowSize64"; - TIFFDirectory *td = &tif->tif_dir; - uint64 rowsize; - uint64 tilerowsize; + static const char module[] = "TIFFTileRowSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t rowsize; + uint64_t tilerowsize; - if (td->td_tilelength == 0) + if (td->td_tilelength == 0) + { + TIFFErrorExtR(tif, module, "Tile length is zero"); + return 0; + } + if (td->td_tilewidth == 0) + { + TIFFErrorExtR(tif, module, "Tile width is zero"); + return (0); + } + rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth, + "TIFFTileRowSize"); + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + if (td->td_samplesperpixel == 0) { - TIFFErrorExt(tif->tif_clientdata,module,"Tile length is zero"); - return 0; + TIFFErrorExtR(tif, module, "Samples per pixel is zero"); + return 0; } - if (td->td_tilewidth == 0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Tile width is zero"); - return (0); - } - rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth, - "TIFFTileRowSize"); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - if (td->td_samplesperpixel == 0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Samples per pixel is zero"); - return 0; - } - rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel, - "TIFFTileRowSize"); - } - tilerowsize=TIFFhowmany8_64(rowsize); - if (tilerowsize == 0) - { - TIFFErrorExt(tif->tif_clientdata,module,"Computed tile row size is zero"); - return 0; - } - return (tilerowsize); + rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel, + "TIFFTileRowSize"); + } + tilerowsize = TIFFhowmany8_64(rowsize); + if (tilerowsize == 0) + { + TIFFErrorExtR(tif, module, "Computed tile row size is zero"); + return 0; + } + return (tilerowsize); } -tmsize_t -TIFFTileRowSize(TIFF* tif) +tmsize_t TIFFTileRowSize(TIFF *tif) { - static const char module[] = "TIFFTileRowSize"; - uint64 m; - m=TIFFTileRowSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFTileRowSize"; + uint64_t m; + m = TIFFTileRowSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* * Compute the # bytes in a variable length, row-aligned tile. */ -uint64 -TIFFVTileSize64(TIFF* tif, uint32 nrows) +uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows) { - static const char module[] = "TIFFVTileSize64"; - TIFFDirectory *td = &tif->tif_dir; - if (td->td_tilelength == 0 || td->td_tilewidth == 0 || - td->td_tiledepth == 0) - return (0); - if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& - (td->td_photometric==PHOTOMETRIC_YCBCR)&& - (td->td_samplesperpixel==3)&& - (!isUpSampled(tif))) - { - /* - * Packed YCbCr data contain one Cb+Cr for every - * HorizontalSampling*VerticalSampling Y values. - * Must also roundup width and height when calculating - * since images that are not a multiple of the - * horizontal/vertical subsampling area include - * YCbCr data for the extended image. - */ - uint16 ycbcrsubsampling[2]; - uint16 samplingblock_samples; - uint32 samplingblocks_hor; - uint32 samplingblocks_ver; - uint64 samplingrow_samples; - uint64 samplingrow_size; - TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, - ycbcrsubsampling+1); - if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) - ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) - { - TIFFErrorExt(tif->tif_clientdata,module, - "Invalid YCbCr subsampling (%dx%d)", - ycbcrsubsampling[0], - ycbcrsubsampling[1] ); - return 0; - } - samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; - samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]); - samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); - samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); - samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); - return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); - } - else - return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module)); + static const char module[] = "TIFFVTileSize64"; + TIFFDirectory *td = &tif->tif_dir; + if (td->td_tilelength == 0 || td->td_tilewidth == 0 || + td->td_tiledepth == 0) + return (0); + if ((td->td_planarconfig == PLANARCONFIG_CONTIG) && + (td->td_photometric == PHOTOMETRIC_YCBCR) && + (td->td_samplesperpixel == 3) && (!isUpSampled(tif))) + { + /* + * Packed YCbCr data contain one Cb+Cr for every + * HorizontalSampling*VerticalSampling Y values. + * Must also roundup width and height when calculating + * since images that are not a multiple of the + * horizontal/vertical subsampling area include + * YCbCr data for the extended image. + */ + uint16_t ycbcrsubsampling[2]; + uint16_t samplingblock_samples; + uint32_t samplingblocks_hor; + uint32_t samplingblocks_ver; + uint64_t samplingrow_samples; + uint64_t samplingrow_size; + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, + ycbcrsubsampling + 0, ycbcrsubsampling + 1); + if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && + ycbcrsubsampling[0] != 4) || + (ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && + ycbcrsubsampling[1] != 4)) + { + TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)", + ycbcrsubsampling[0], ycbcrsubsampling[1]); + return 0; + } + samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2; + samplingblocks_hor = + TIFFhowmany_32(td->td_tilewidth, ycbcrsubsampling[0]); + samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]); + samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor, + samplingblock_samples, module); + samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64( + tif, samplingrow_samples, td->td_bitspersample, module)); + return ( + _TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module)); + } + else + return (_TIFFMultiply64(tif, nrows, TIFFTileRowSize64(tif), module)); } -tmsize_t -TIFFVTileSize(TIFF* tif, uint32 nrows) +tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows) { - static const char module[] = "TIFFVTileSize"; - uint64 m; - m=TIFFVTileSize64(tif,nrows); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFVTileSize"; + uint64_t m; + m = TIFFVTileSize64(tif, nrows); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* * Compute the # bytes in a row-aligned tile. */ -uint64 -TIFFTileSize64(TIFF* tif) +uint64_t TIFFTileSize64(TIFF *tif) { - return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength)); + return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength)); } -tmsize_t -TIFFTileSize(TIFF* tif) +tmsize_t TIFFTileSize(TIFF *tif) { - static const char module[] = "TIFFTileSize"; - uint64 m; - m=TIFFTileSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFTileSize"; + uint64_t m; + m = TIFFTileSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* @@ -268,32 +264,21 @@ TIFFTileSize(TIFF* tif) * request is <1 then we choose a size according * to certain heuristics. */ -void -TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) +void TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) { - (*tif->tif_deftilesize)(tif, tw, th); + (*tif->tif_deftilesize)(tif, tw, th); } -void -_TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) +void _TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) { - (void) tif; - if (*(int32*) tw < 1) - *tw = 256; - if (*(int32*) th < 1) - *th = 256; - /* roundup to a multiple of 16 per the spec */ - if (*tw & 0xf) - *tw = TIFFroundup_32(*tw, 16); - if (*th & 0xf) - *th = TIFFroundup_32(*th, 16); + (void)tif; + if (*(int32_t *)tw < 1) + *tw = 256; + if (*(int32_t *)th < 1) + *th = 256; + /* roundup to a multiple of 16 per the spec */ + if (*tw & 0xf) + *tw = TIFFroundup_32(*tw, 16); + if (*th & 0xf) + *th = TIFFroundup_32(*th, 16); } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_unix.c b/3rdparty/libtiff/tif_unix.c index bea1ef7802..34dd53b98c 100644 --- a/3rdparty/libtiff/tif_unix.c +++ b/3rdparty/libtiff/tif_unix.c @@ -30,7 +30,7 @@ #include "tif_config.h" #ifdef HAVE_SYS_TYPES_H -# include +#include #endif #include @@ -40,215 +40,222 @@ #include #ifdef HAVE_UNISTD_H -# include +#include #endif #ifdef HAVE_FCNTL_H -# include +#include #endif #ifdef HAVE_IO_H -# include +#include #endif #include "tiffiop.h" - #define TIFF_IO_MAX 2147483647U - typedef union fd_as_handle_union { - int fd; - thandle_t h; + int fd; + thandle_t h; } fd_as_handle_union_t; -static tmsize_t -_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) +static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size) { - fd_as_handle_union_t fdh; - const size_t bytes_total = (size_t) size; - size_t bytes_read; - tmsize_t count = -1; - if ((tmsize_t) bytes_total != size) - { - errno=EINVAL; - return (tmsize_t) -1; - } - fdh.h = fd; - for (bytes_read=0; bytes_read < bytes_total; bytes_read+=count) - { - char *buf_offset = (char *) buf+bytes_read; - size_t io_size = bytes_total-bytes_read; - if (io_size > TIFF_IO_MAX) - io_size = TIFF_IO_MAX; - count=read(fdh.fd, buf_offset, (TIFFIOSize_t) io_size); - if (count <= 0) - break; - } - if (count < 0) - return (tmsize_t)-1; - return (tmsize_t) bytes_read; + fd_as_handle_union_t fdh; + const size_t bytes_total = (size_t)size; + size_t bytes_read; + tmsize_t count = -1; + if ((tmsize_t)bytes_total != size) + { + errno = EINVAL; + return (tmsize_t)-1; + } + fdh.h = fd; + for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count) + { + char *buf_offset = (char *)buf + bytes_read; + size_t io_size = bytes_total - bytes_read; + if (io_size > TIFF_IO_MAX) + io_size = TIFF_IO_MAX; + count = read(fdh.fd, buf_offset, (TIFFIOSize_t)io_size); + if (count <= 0) + break; + } + if (count < 0) + return (tmsize_t)-1; + return (tmsize_t)bytes_read; } -static tmsize_t -_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) +static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size) { - fd_as_handle_union_t fdh; - const size_t bytes_total = (size_t) size; - size_t bytes_written; - tmsize_t count = -1; - if ((tmsize_t) bytes_total != size) - { - errno=EINVAL; - return (tmsize_t) -1; - } - fdh.h = fd; - for (bytes_written=0; bytes_written < bytes_total; bytes_written+=count) - { - const char *buf_offset = (char *) buf+bytes_written; - size_t io_size = bytes_total-bytes_written; - if (io_size > TIFF_IO_MAX) - io_size = TIFF_IO_MAX; - count=write(fdh.fd, buf_offset, (TIFFIOSize_t) io_size); - if (count <= 0) - break; - } - if (count < 0) - return (tmsize_t)-1; - return (tmsize_t) bytes_written; - /* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */ + fd_as_handle_union_t fdh; + const size_t bytes_total = (size_t)size; + size_t bytes_written; + tmsize_t count = -1; + if ((tmsize_t)bytes_total != size) + { + errno = EINVAL; + return (tmsize_t)-1; + } + fdh.h = fd; + for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count) + { + const char *buf_offset = (char *)buf + bytes_written; + size_t io_size = bytes_total - bytes_written; + if (io_size > TIFF_IO_MAX) + io_size = TIFF_IO_MAX; + count = write(fdh.fd, buf_offset, (TIFFIOSize_t)io_size); + if (count <= 0) + break; + } + if (count < 0) + return (tmsize_t)-1; + return (tmsize_t)bytes_written; + /* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */ } -static uint64 -_tiffSeekProc(thandle_t fd, uint64 off, int whence) +static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence) { - fd_as_handle_union_t fdh; - _TIFF_off_t off_io = (_TIFF_off_t) off; - if ((uint64) off_io != off) - { - errno=EINVAL; - return (uint64) -1; /* this is really gross */ - } - fdh.h = fd; - return((uint64)_TIFF_lseek_f(fdh.fd,off_io,whence)); + fd_as_handle_union_t fdh; + _TIFF_off_t off_io = (_TIFF_off_t)off; + if ((uint64_t)off_io != off) + { + errno = EINVAL; + return (uint64_t)-1; /* this is really gross */ + } + fdh.h = fd; + return ((uint64_t)_TIFF_lseek_f(fdh.fd, off_io, whence)); } -static int -_tiffCloseProc(thandle_t fd) +static int _tiffCloseProc(thandle_t fd) { - fd_as_handle_union_t fdh; - fdh.h = fd; - return(close(fdh.fd)); + fd_as_handle_union_t fdh; + fdh.h = fd; + return (close(fdh.fd)); } -static uint64 -_tiffSizeProc(thandle_t fd) +static uint64_t _tiffSizeProc(thandle_t fd) { - _TIFF_stat_s sb; - fd_as_handle_union_t fdh; - fdh.h = fd; - if (_TIFF_fstat_f(fdh.fd,&sb)<0) - return(0); - else - return((uint64)sb.st_size); + _TIFF_stat_s sb; + fd_as_handle_union_t fdh; + fdh.h = fd; + if (_TIFF_fstat_f(fdh.fd, &sb) < 0) + return (0); + else + return ((uint64_t)sb.st_size); } #ifdef HAVE_MMAP #include -static int -_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) +static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) { - uint64 size64 = _tiffSizeProc(fd); - tmsize_t sizem = (tmsize_t)size64; - if (size64 && (uint64)sizem==size64) { - fd_as_handle_union_t fdh; - fdh.h = fd; - *pbase = (void*) - mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0); - if (*pbase != (void*) -1) { - *psize = (tmsize_t)sizem; - return (1); - } - } - return (0); + uint64_t size64 = _tiffSizeProc(fd); + tmsize_t sizem = (tmsize_t)size64; + if (size64 && (uint64_t)sizem == size64) + { + fd_as_handle_union_t fdh; + fdh.h = fd; + *pbase = + (void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0); + if (*pbase != (void *)-1) + { + *psize = (tmsize_t)sizem; + return (1); + } + } + return (0); } -static void -_tiffUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; - (void) munmap(base, (off_t) size); + (void)fd; + (void)munmap(base, (off_t)size); } -#else /* !HAVE_MMAP */ -static int -_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) +#else /* !HAVE_MMAP */ +static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) { - (void) fd; (void) pbase; (void) psize; - return (0); + (void)fd; + (void)pbase; + (void)psize; + return (0); } -static void -_tiffUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; (void) base; (void) size; + (void)fd; + (void)base; + (void)size; } #endif /* !HAVE_MMAP */ /* * Open a TIFF file descriptor for read/writing. */ -TIFF* -TIFFFdOpen(int fd, const char* name, const char* mode) +TIFF *TIFFFdOpen(int fd, const char *name, const char *mode) { - TIFF* tif; + return TIFFFdOpenExt(fd, name, mode, NULL); +} - fd_as_handle_union_t fdh; - fdh.fd = fd; - tif = TIFFClientOpen(name, mode, - fdh.h, - _tiffReadProc, _tiffWriteProc, - _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, - _tiffMapProc, _tiffUnmapProc); - if (tif) - tif->tif_fd = fd; - return (tif); +TIFF *TIFFFdOpenExt(int fd, const char *name, const char *mode, + TIFFOpenOptions *opts) +{ + TIFF *tif; + + fd_as_handle_union_t fdh; + fdh.fd = fd; + tif = TIFFClientOpenExt(name, mode, fdh.h, _tiffReadProc, _tiffWriteProc, + _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, + _tiffMapProc, _tiffUnmapProc, opts); + if (tif) + tif->tif_fd = fd; + return (tif); } /* * Open a TIFF file for read/writing. */ -TIFF* -TIFFOpen(const char* name, const char* mode) +TIFF *TIFFOpen(const char *name, const char *mode) { - static const char module[] = "TIFFOpen"; - int m, fd; - TIFF* tif; + return TIFFOpenExt(name, mode, NULL); +} - m = _TIFFgetMode(mode, module); - if (m == -1) - return ((TIFF*)0); +TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts) +{ + static const char module[] = "TIFFOpen"; + int m, fd; + TIFF *tif; + + m = _TIFFgetMode(opts, NULL, mode, module); + if (m == -1) + return ((TIFF *)0); /* for cygwin and mingw */ #ifdef O_BINARY - m |= O_BINARY; + m |= O_BINARY; #endif - fd = open(name, m, 0666); - if (fd < 0) { - if (errno > 0 && strerror(errno) != NULL ) { - TIFFErrorExt(0, module, "%s: %s", name, strerror(errno) ); - } else { - TIFFErrorExt(0, module, "%s: Cannot open", name); - } - return ((TIFF *)0); - } + fd = open(name, m, 0666); + if (fd < 0) + { + if (errno > 0 && strerror(errno) != NULL) + { + _TIFFErrorEarly(opts, NULL, module, "%s: %s", name, + strerror(errno)); + } + else + { + _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name); + } + return ((TIFF *)0); + } - tif = TIFFFdOpen((int)fd, name, mode); - if(!tif) - close(fd); - return tif; + tif = TIFFFdOpenExt((int)fd, name, mode, opts); + if (!tif) + close(fd); + return tif; } #ifdef __WIN32__ @@ -256,129 +263,108 @@ TIFFOpen(const char* name, const char* mode) /* * Open a TIFF file with a Unicode filename, for read/writing. */ -TIFF* -TIFFOpenW(const wchar_t* name, const char* mode) +TIFF *TIFFOpenW(const wchar_t *name, const char *mode) { - static const char module[] = "TIFFOpenW"; - int m, fd; - int mbsize; - char *mbname; - TIFF* tif; + return TIFFOpenWExt(name, mode, NULL); +} +TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts) +{ + static const char module[] = "TIFFOpenW"; + int m, fd; + int mbsize; + char *mbname; + TIFF *tif; - m = _TIFFgetMode(mode, module); - if (m == -1) - return ((TIFF*)0); + m = _TIFFgetMode(opts, NULL, mode, module); + if (m == -1) + return ((TIFF *)0); /* for cygwin and mingw */ #ifdef O_BINARY - m |= O_BINARY; + m |= O_BINARY; #endif - fd = _wopen(name, m, 0666); - if (fd < 0) { - TIFFErrorExt(0, module, "%ls: Cannot open", name); - return ((TIFF *)0); - } + fd = _wopen(name, m, 0666); + if (fd < 0) + { + _TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name); + return ((TIFF *)0); + } - mbname = NULL; - mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); - if (mbsize > 0) { - mbname = _TIFFmalloc(mbsize); - if (!mbname) { - TIFFErrorExt(0, module, - "Can't allocate space for filename conversion buffer"); - return ((TIFF*)0); - } + mbname = NULL; + mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); + if (mbsize > 0) + { + mbname = _TIFFmalloc(mbsize); + if (!mbname) + { + _TIFFErrorEarly( + opts, NULL, module, + "Can't allocate space for filename conversion buffer"); + return ((TIFF *)0); + } - WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, - NULL, NULL); - } + WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL); + } - tif = TIFFFdOpen((int)fd, (mbname != NULL) ? mbname : "", - mode); - - _TIFFfree(mbname); - - if(!tif) - close(fd); - return tif; + tif = TIFFFdOpenExt((int)fd, (mbname != NULL) ? mbname : "", mode, + opts); + + _TIFFfree(mbname); + + if (!tif) + close(fd); + return tif; } #endif -void* -_TIFFmalloc(tmsize_t s) +void *_TIFFmalloc(tmsize_t s) { - if (s == 0) - return ((void *) NULL); + if (s == 0) + return ((void *)NULL); - return (malloc((size_t) s)); + return (malloc((size_t)s)); } -void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) +void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz) { - if( nmemb == 0 || siz == 0 ) - return ((void *) NULL); + if (nmemb == 0 || siz == 0) + return ((void *)NULL); - return calloc((size_t) nmemb, (size_t)siz); + return calloc((size_t)nmemb, (size_t)siz); } -void -_TIFFfree(void* p) +void _TIFFfree(void *p) { free(p); } + +void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); } + +void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); } + +void _TIFFmemcpy(void *d, const void *s, tmsize_t c) { - free(p); + memcpy(d, s, (size_t)c); } -void* -_TIFFrealloc(void* p, tmsize_t s) +int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c) { - return (realloc(p, (size_t) s)); + return (memcmp(p1, p2, (size_t)c)); } -void -_TIFFmemset(void* p, int v, tmsize_t c) +static void unixWarningHandler(const char *module, const char *fmt, va_list ap) { - memset(p, v, (size_t) c); -} - -void -_TIFFmemcpy(void* d, const void* s, tmsize_t c) -{ - memcpy(d, s, (size_t) c); -} - -int -_TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) -{ - return (memcmp(p1, p2, (size_t) c)); -} - -static void -unixWarningHandler(const char* module, const char* fmt, va_list ap) -{ - if (module != NULL) - fprintf(stderr, "%s: ", module); - fprintf(stderr, "Warning, "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); } TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler; -static void -unixErrorHandler(const char* module, const char* fmt, va_list ap) +static void unixErrorHandler(const char *module, const char *fmt, va_list ap) { - if (module != NULL) - fprintf(stderr, "%s: ", module); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); } TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler; - -/* vim: set ts=8 sts=8 sw=8 noet: */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_version.c b/3rdparty/libtiff/tif_version.c index 60875bbf09..0b6c9bc00a 100644 --- a/3rdparty/libtiff/tif_version.c +++ b/3rdparty/libtiff/tif_version.c @@ -2,38 +2,27 @@ * Copyright (c) 1992-1997 Sam Leffler * Copyright (c) 1992-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "tiffiop.h" static const char TIFFVersion[] = TIFFLIB_VERSION_STR; -const char* -TIFFGetVersion(void) -{ - return (TIFFVersion); -} -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ +const char *TIFFGetVersion(void) { return (TIFFVersion); } diff --git a/3rdparty/libtiff/tif_warning.c b/3rdparty/libtiff/tif_warning.c index c482785c29..5468de55f2 100644 --- a/3rdparty/libtiff/tif_warning.c +++ b/3rdparty/libtiff/tif_warning.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,59 +29,77 @@ TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL; -TIFFErrorHandler -TIFFSetWarningHandler(TIFFErrorHandler handler) +TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler handler) { - TIFFErrorHandler prev = _TIFFwarningHandler; - _TIFFwarningHandler = handler; - return (prev); + TIFFErrorHandler prev = _TIFFwarningHandler; + _TIFFwarningHandler = handler; + return (prev); } -TIFFErrorHandlerExt -TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler) +TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler) { - TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt; - _TIFFwarningHandlerExt = handler; - return (prev); + TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt; + _TIFFwarningHandlerExt = handler; + return (prev); } -void -TIFFWarning(const char* module, const char* fmt, ...) +void TIFFWarning(const char *module, const char *fmt, ...) { - va_list ap; - if (_TIFFwarningHandler) { - va_start(ap, fmt); - (*_TIFFwarningHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFwarningHandlerExt) { - va_start(ap, fmt); - (*_TIFFwarningHandlerExt)(0, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (_TIFFwarningHandler) + { + va_start(ap, fmt); + (*_TIFFwarningHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFwarningHandlerExt) + { + va_start(ap, fmt); + (*_TIFFwarningHandlerExt)(0, module, fmt, ap); + va_end(ap); + } } -void -TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...) +void TIFFWarningExt(thandle_t fd, const char *module, const char *fmt, ...) { - va_list ap; - if (_TIFFwarningHandler) { - va_start(ap, fmt); - (*_TIFFwarningHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFwarningHandlerExt) { - va_start(ap, fmt); - (*_TIFFwarningHandlerExt)(fd, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (_TIFFwarningHandler) + { + va_start(ap, fmt); + (*_TIFFwarningHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFwarningHandlerExt) + { + va_start(ap, fmt); + (*_TIFFwarningHandlerExt)(fd, module, fmt, ap); + va_end(ap); + } } - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ +void TIFFWarningExtR(TIFF *tif, const char *module, const char *fmt, ...) +{ + va_list ap; + if (tif && tif->tif_warnhandler) + { + va_start(ap, fmt); + int stop = (*tif->tif_warnhandler)(tif, tif->tif_warnhandler_user_data, + module, fmt, ap); + va_end(ap); + if (stop) + return; + } + if (_TIFFwarningHandler) + { + va_start(ap, fmt); + (*_TIFFwarningHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFwarningHandlerExt) + { + va_start(ap, fmt); + (*_TIFFwarningHandlerExt)(tif ? tif->tif_clientdata : 0, module, fmt, + ap); + va_end(ap); + } +} diff --git a/3rdparty/libtiff/tif_webp.c b/3rdparty/libtiff/tif_webp.c index a00478f6b9..bf9d77eb9b 100644 --- a/3rdparty/libtiff/tif_webp.c +++ b/3rdparty/libtiff/tif_webp.c @@ -1,26 +1,26 @@ /* -* Copyright (c) 2018, Mapbox -* Author: -* -* Permission to use, copy, modify, distribute, and sell this software and -* its documentation for any purpose is hereby granted without fee, provided -* that (i) the above copyright notices and this permission notice appear in -* all copies of the software and related documentation, and (ii) the names of -* Sam Leffler and Silicon Graphics may not be used in any advertising or -* publicity relating to the software without the specific, prior written -* permission of Sam Leffler and Silicon Graphics. -* -* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -* -* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR -* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, -* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF -* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -* OF THIS SOFTWARE. -*/ + * Copyright (c) 2018, Mapbox + * Author: + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ #include "tiffiop.h" #ifdef WEBP_SUPPORT @@ -34,6 +34,7 @@ #include "webp/decode.h" #include "webp/encode.h" +#include #include #define LSTATE_INIT_DECODE 0x01 @@ -42,661 +43,839 @@ * State block for each open TIFF * file using WEBP compression/decompression. */ -typedef struct { - uint16 nSamples; /* number of samples per pixel */ - - int lossless; /* lossy/lossless compression */ - int quality_level; /* compression level */ - WebPPicture sPicture; /* WebP Picture */ - WebPConfig sEncoderConfig; /* WebP encoder config */ - uint8* pBuffer; /* buffer to hold raw data on encoding */ - unsigned int buffer_offset; /* current offset into the buffer */ - unsigned int buffer_size; - - WebPIDecoder* psDecoder; /* WebPIDecoder */ - WebPDecBuffer sDecBuffer; /* Decoder buffer */ - int last_y; /* Last row decoded */ - - int state; /* state flags */ - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ +typedef struct +{ + uint16_t nSamples; /* number of samples per pixel */ + + int lossless; /* lossy/lossless compression */ + int lossless_exact; /* lossless exact mode. If TRUE, R,G,B values in areas + with alpha = 0 will be preserved */ + int quality_level; /* compression level */ + WebPPicture sPicture; /* WebP Picture */ + WebPConfig sEncoderConfig; /* WebP encoder config */ + uint8_t *pBuffer; /* buffer to hold raw data on encoding */ + unsigned int buffer_offset; /* current offset into the buffer */ + unsigned int buffer_size; + + WebPIDecoder *psDecoder; /* WebPIDecoder */ + WebPDecBuffer sDecBuffer; /* Decoder buffer */ + int last_y; /* Last row decoded */ + + int state; /* state flags */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } WebPState; -#define LState(tif) ((WebPState*) (tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) +#define LState(tif) ((WebPState *)(tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) -static int TWebPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); -static int TWebPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); +static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -static -int TWebPDatasetWriter(const uint8_t* data, size_t data_size, - const WebPPicture* const picture) +static int TWebPDatasetWriter(const uint8_t *data, size_t data_size, + const WebPPicture *const picture) { - static const char module[] = "TWebPDatasetWriter"; - TIFF* tif = (TIFF*)(picture->custom_ptr); - - if ( (tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Buffer too small by " TIFF_SIZE_FORMAT " bytes.", - (size_t) (tif->tif_rawcc + data_size - tif->tif_rawdatasize)); - return 0; - } else { - _TIFFmemcpy(tif->tif_rawcp, data, data_size); - tif->tif_rawcc += data_size; - tif->tif_rawcp += data_size; - return 1; - } + static const char module[] = "TWebPDatasetWriter"; + TIFF *tif = (TIFF *)(picture->custom_ptr); + + if ((tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize) + { + TIFFErrorExtR( + tif, module, "Buffer too small by %" TIFF_SIZE_FORMAT " bytes.", + (size_t)(tif->tif_rawcc + data_size - tif->tif_rawdatasize)); + return 0; + } + else + { + _TIFFmemcpy(tif->tif_rawcp, data, data_size); + tif->tif_rawcc += data_size; + tif->tif_rawcp += data_size; + return 1; + } } /* * Encode a chunk of pixels. */ -static int -TWebPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "TWebPEncode"; - WebPState *sp = EncoderState(tif); - (void) s; + static const char module[] = "TWebPEncode"; + WebPState *sp = EncoderState(tif); + (void)s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); - - if( (uint64)sp->buffer_offset + - (uint64)cc > sp->buffer_size ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Too many bytes to be written"); - return 0; - } + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); - memcpy(sp->pBuffer + sp->buffer_offset, - bp, cc); - sp->buffer_offset += (unsigned)cc; - - return 1; - -} - -static int -TWebPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) -{ - static const char module[] = "WebPDecode"; - VP8StatusCode status = VP8_STATUS_OK; - WebPState *sp = DecoderState(tif); - (void) s; - - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); - - if (occ % sp->sDecBuffer.u.RGBA.stride) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Fractional scanlines cannot be read"); - return 0; - } - - status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc); - - if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { - if (status == VP8_STATUS_INVALID_PARAM) { - TIFFErrorExt(tif->tif_clientdata, module, - "Invalid parameter used."); - } else if (status == VP8_STATUS_OUT_OF_MEMORY) { - TIFFErrorExt(tif->tif_clientdata, module, - "Out of memory."); - } else { - TIFFErrorExt(tif->tif_clientdata, module, - "Unrecognized error."); + if ((uint64_t)sp->buffer_offset + (uint64_t)cc > sp->buffer_size) + { + TIFFErrorExtR(tif, module, "Too many bytes to be written"); + return 0; } - return 0; - } else { - int current_y, stride; - uint8_t* buf; - /* Returns the RGB/A image decoded so far */ - buf = WebPIDecGetRGB(sp->psDecoder, ¤t_y, NULL, NULL, &stride); - - if ((buf != NULL) && - (occ <= stride * (current_y - sp->last_y))) { - memcpy(op, - buf + (sp->last_y * stride), - occ); + memcpy(sp->pBuffer + sp->buffer_offset, bp, cc); + sp->buffer_offset += (unsigned)cc; - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; - sp->last_y += occ / sp->sDecBuffer.u.RGBA.stride; - return 1; - } else { - TIFFErrorExt(tif->tif_clientdata, module, "Unable to decode WebP data."); - return 0; + return 1; +} + +static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) +{ + static const char module[] = "WebPDecode"; + VP8StatusCode status = VP8_STATUS_OK; + WebPState *sp = DecoderState(tif); + uint32_t segment_width, segment_height; + bool decode_whole_strile = false; + + (void)s; + + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + if (sp->psDecoder == NULL) + { + TIFFDirectory *td = &tif->tif_dir; + uint32_t buffer_size; + + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + } + + int webp_width, webp_height; + if (!WebPGetInfo(tif->tif_rawcp, + (uint64_t)tif->tif_rawcc > UINT32_MAX + ? UINT32_MAX + : (uint32_t)tif->tif_rawcc, + &webp_width, &webp_height)) + { + TIFFErrorExtR(tif, module, "WebPGetInfo() failed"); + return 0; + } + if ((uint32_t)webp_width != segment_width || + (uint32_t)webp_height != segment_height) + { + TIFFErrorExtR( + tif, module, "WebP blob dimension is %dx%d. Expected %ux%u", + webp_width, webp_height, segment_width, segment_height); + return 0; + } + +#if WEBP_DECODER_ABI_VERSION >= 0x0002 + WebPDecoderConfig config; + if (!WebPInitDecoderConfig(&config)) + { + TIFFErrorExtR(tif, module, "WebPInitDecoderConfig() failed"); + return 0; + } + + const bool bWebPGetFeaturesOK = + WebPGetFeatures(tif->tif_rawcp, + (uint64_t)tif->tif_rawcc > UINT32_MAX + ? UINT32_MAX + : (uint32_t)tif->tif_rawcc, + &config.input) == VP8_STATUS_OK; + + WebPFreeDecBuffer(&config.output); + + if (!bWebPGetFeaturesOK) + { + TIFFErrorExtR(tif, module, "WebPInitDecoderConfig() failed"); + return 0; + } + + const int webp_bands = config.input.has_alpha ? 4 : 3; + if (webp_bands != sp->nSamples && + /* We accept the situation where the WebP blob has only 3 bands, + * whereas the raster is 4 bands. This can happen when the alpha + * channel is fully opaque, and WebP decoding works fine in that + * situation. + */ + !(webp_bands == 3 && sp->nSamples == 4)) + { + TIFFErrorExtR(tif, module, + "WebP blob band count is %d. Expected %d", webp_bands, + sp->nSamples); + return 0; + } +#endif + + buffer_size = segment_width * segment_height * sp->nSamples; + if (occ == (tmsize_t)buffer_size) + { + /* If decoding the whole strip/tile, we can directly use the */ + /* output buffer */ + decode_whole_strile = true; + } + else if (sp->pBuffer == NULL || buffer_size > sp->buffer_size) + { + if (sp->pBuffer != NULL) + { + _TIFFfreeExt(tif, sp->pBuffer); + sp->pBuffer = NULL; + } + + sp->pBuffer = _TIFFmallocExt(tif, buffer_size); + if (!sp->pBuffer) + { + TIFFErrorExtR(tif, module, "Cannot allocate buffer"); + return 0; + } + sp->buffer_size = buffer_size; + } + + sp->last_y = 0; + + WebPInitDecBuffer(&sp->sDecBuffer); + + sp->sDecBuffer.is_external_memory = 1; + sp->sDecBuffer.width = segment_width; + sp->sDecBuffer.height = segment_height; + sp->sDecBuffer.u.RGBA.rgba = decode_whole_strile ? op : sp->pBuffer; + sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples; + sp->sDecBuffer.u.RGBA.size = buffer_size; + + if (sp->nSamples > 3) + { + sp->sDecBuffer.colorspace = MODE_RGBA; + } + else + { + sp->sDecBuffer.colorspace = MODE_RGB; + } + + sp->psDecoder = WebPINewDecoder(&sp->sDecBuffer); + + if (sp->psDecoder == NULL) + { + TIFFErrorExtR(tif, module, "Unable to allocate WebP decoder."); + return 0; + } + } + + if (occ % sp->sDecBuffer.u.RGBA.stride) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return 0; + } + + status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc); + + if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) + { + if (status == VP8_STATUS_INVALID_PARAM) + { + TIFFErrorExtR(tif, module, "Invalid parameter used."); + } + else if (status == VP8_STATUS_OUT_OF_MEMORY) + { + TIFFErrorExtR(tif, module, "Out of memory."); + } + else + { + TIFFErrorExtR(tif, module, "Unrecognized error."); + } + return 0; + } + else + { + int current_y, stride; + uint8_t *buf; + + /* Returns the RGB/A image decoded so far */ + buf = WebPIDecGetRGB(sp->psDecoder, ¤t_y, NULL, NULL, &stride); + + if ((buf != NULL) && + (occ <= (tmsize_t)stride * (current_y - sp->last_y))) + { + const int numberOfExpectedLines = + (int)(occ / sp->sDecBuffer.u.RGBA.stride); + if (decode_whole_strile) + { + if (current_y != numberOfExpectedLines) + { + TIFFErrorExtR(tif, module, + "Unable to decode WebP data: less lines than " + "expected."); + return 0; + } + } + else + { + memcpy(op, buf + (sp->last_y * stride), occ); + } + + tif->tif_rawcp += tif->tif_rawcc; + tif->tif_rawcc = 0; + sp->last_y += numberOfExpectedLines; + + if (decode_whole_strile) + { + /* We can now free the decoder as we're completely done */ + if (sp->psDecoder != NULL) + { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + } + } + return 1; + } + else + { + TIFFErrorExtR(tif, module, "Unable to decode WebP data."); + return 0; + } } - } } -static int -TWebPFixupTags(TIFF* tif) +static int TWebPFixupTags(TIFF *tif) { - (void) tif; - if (tif->tif_dir.td_planarconfig != PLANARCONFIG_CONTIG) { - static const char module[] = "TWebPFixupTags"; - TIFFErrorExt(tif->tif_clientdata, module, - "TIFF WEBP requires data to be stored contiguously in RGB e.g. RGBRGBRGB " + (void)tif; + if (tif->tif_dir.td_planarconfig != PLANARCONFIG_CONTIG) + { + static const char module[] = "TWebPFixupTags"; + TIFFErrorExtR(tif, module, + "TIFF WEBP requires data to be stored contiguously in " + "RGB e.g. RGBRGBRGB " #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - "or RGBARGBARGBA" + "or RGBARGBARGBA" #endif - ); - return 0; - } - return 1; + ); + return 0; + } + return 1; } -static int -TWebPSetupDecode(TIFF* tif) +static int TWebPSetupDecode(TIFF *tif) { - static const char module[] = "WebPSetupDecode"; - uint16 nBitsPerSample = tif->tif_dir.td_bitspersample; - uint16 sampleFormat = tif->tif_dir.td_sampleformat; + static const char module[] = "WebPSetupDecode"; + uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample; + uint16_t sampleFormat = tif->tif_dir.td_sampleformat; - WebPState* sp = DecoderState(tif); - assert(sp != NULL); + WebPState *sp = DecoderState(tif); + assert(sp != NULL); - sp->nSamples = tif->tif_dir.td_samplesperpixel; + sp->nSamples = tif->tif_dir.td_samplesperpixel; - /* check band count */ - if ( sp->nSamples != 3 + /* check band count */ + if (sp->nSamples != 3 #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - && sp->nSamples != 4 + && sp->nSamples != 4 #endif - ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "WEBP driver doesn't support %d bands. Must be 3 (RGB) " - #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - "or 4 (RGBA) " - #endif - "bands.", - sp->nSamples ); - return 0; - } + ) + { + TIFFErrorExtR(tif, module, + "WEBP driver doesn't support %d bands. Must be 3 (RGB) " +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + "or 4 (RGBA) " +#endif + "bands.", + sp->nSamples); + return 0; + } - /* check bits per sample and data type */ - if ((nBitsPerSample != 8) && (sampleFormat != 1)) { - TIFFErrorExt(tif->tif_clientdata, module, - "WEBP driver requires 8 bit unsigned data"); - return 0; - } - - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) { - WebPPictureFree(&sp->sPicture); - if (sp->pBuffer != NULL) { - _TIFFfree(sp->pBuffer); - sp->pBuffer = NULL; - } - sp->buffer_offset = 0; - sp->state = 0; - } + /* check bits per sample and data type */ + if ((nBitsPerSample != 8) && (sampleFormat != 1)) + { + TIFFErrorExtR(tif, module, "WEBP driver requires 8 bit unsigned data"); + return 0; + } - sp->state |= LSTATE_INIT_DECODE; + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) + { + WebPPictureFree(&sp->sPicture); + if (sp->pBuffer != NULL) + { + _TIFFfreeExt(tif, sp->pBuffer); + sp->pBuffer = NULL; + } + sp->buffer_offset = 0; + sp->state = 0; + } - return 1; + sp->state |= LSTATE_INIT_DECODE; + + return 1; } /* -* Setup state for decoding a strip. -*/ -static int -TWebPPreDecode(TIFF* tif, uint16 s) + * Setup state for decoding a strip. + */ +static int TWebPPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "TWebPPreDecode"; - uint32 segment_width, segment_height; - WebPState* sp = DecoderState(tif); - TIFFDirectory* td = &tif->tif_dir; - (void) s; - assert(sp != NULL); - - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - } + static const char module[] = "TWebPPreDecode"; + uint32_t segment_width, segment_height; + WebPState *sp = DecoderState(tif); + TIFFDirectory *td = &tif->tif_dir; + (void)s; + assert(sp != NULL); - if( segment_width > 16383 || segment_height > 16383 ) { - TIFFErrorExt(tif->tif_clientdata, module, - "WEBP maximum image dimensions are 16383 x 16383."); - return 0; - } + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + } - if( (sp->state & LSTATE_INIT_DECODE) == 0 ) - tif->tif_setupdecode(tif); - - if (sp->psDecoder != NULL) { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - } + if (segment_width > 16383 || segment_height > 16383) + { + TIFFErrorExtR(tif, module, + "WEBP maximum image dimensions are 16383 x 16383."); + return 0; + } - sp->last_y = 0; - - WebPInitDecBuffer(&sp->sDecBuffer); - - sp->sDecBuffer.is_external_memory = 0; - sp->sDecBuffer.width = segment_width; - sp->sDecBuffer.height = segment_height; - sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples; - sp->sDecBuffer.u.RGBA.size = segment_width * sp->nSamples * segment_height; - - if (sp->nSamples > 3) { - sp->sDecBuffer.colorspace = MODE_RGBA; - } else { - sp->sDecBuffer.colorspace = MODE_RGB; - } - - sp->psDecoder = WebPINewDecoder(&sp->sDecBuffer); - - if (sp->psDecoder == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, - "Unable to allocate WebP decoder."); - return 0; - } - - return 1; + if ((sp->state & LSTATE_INIT_DECODE) == 0) + tif->tif_setupdecode(tif); + + if (sp->psDecoder != NULL) + { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + } + + return 1; } -static int -TWebPSetupEncode(TIFF* tif) +static int TWebPSetupEncode(TIFF *tif) { - static const char module[] = "WebPSetupEncode"; - uint16 nBitsPerSample = tif->tif_dir.td_bitspersample; - uint16 sampleFormat = tif->tif_dir.td_sampleformat; - - WebPState* sp = EncoderState(tif); - assert(sp != NULL); + static const char module[] = "WebPSetupEncode"; + uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample; + uint16_t sampleFormat = tif->tif_dir.td_sampleformat; - sp->nSamples = tif->tif_dir.td_samplesperpixel; + WebPState *sp = EncoderState(tif); + assert(sp != NULL); - /* check band count */ - if ( sp->nSamples != 3 + sp->nSamples = tif->tif_dir.td_samplesperpixel; + + /* check band count */ + if (sp->nSamples != 3 #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - && sp->nSamples != 4 + && sp->nSamples != 4 #endif - ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "WEBP driver doesn't support %d bands. Must be 3 (RGB) " + ) + { + TIFFErrorExtR(tif, module, + "WEBP driver doesn't support %d bands. Must be 3 (RGB) " #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - "or 4 (RGBA) " + "or 4 (RGBA) " #endif - "bands.", - sp->nSamples ); - return 0; - } - - /* check bits per sample and data type */ - if ((nBitsPerSample != 8) || (sampleFormat != SAMPLEFORMAT_UINT)) { - TIFFErrorExt(tif->tif_clientdata, module, - "WEBP driver requires 8 bit unsigned data"); - return 0; - } - - if (sp->state & LSTATE_INIT_DECODE) { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - sp->last_y = 0; - sp->state = 0; - } + "bands.", + sp->nSamples); + return 0; + } - sp->state |= LSTATE_INIT_ENCODE; + /* check bits per sample and data type */ + if ((nBitsPerSample != 8) || (sampleFormat != SAMPLEFORMAT_UINT)) + { + TIFFErrorExtR(tif, module, "WEBP driver requires 8 bit unsigned data"); + return 0; + } - if (!WebPPictureInit(&sp->sPicture)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error initializing WebP picture."); - return 0; - } + if (sp->state & LSTATE_INIT_DECODE) + { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + sp->last_y = 0; + sp->state = 0; + } - if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT, - (float)sp->quality_level, - WEBP_ENCODER_ABI_VERSION)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error creating WebP encoder configuration."); - return 0; - } + sp->state |= LSTATE_INIT_ENCODE; - // WebPConfigInitInternal above sets lossless to false - #if WEBP_ENCODER_ABI_VERSION >= 0x0100 + if (!WebPPictureInit(&sp->sPicture)) + { + TIFFErrorExtR(tif, module, "Error initializing WebP picture."); + return 0; + } + + if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT, + (float)sp->quality_level, + WEBP_ENCODER_ABI_VERSION)) + { + TIFFErrorExtR(tif, module, + "Error creating WebP encoder configuration."); + return 0; + } + +// WebPConfigInitInternal above sets lossless to false +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 sp->sEncoderConfig.lossless = sp->lossless; - if (sp->lossless) { - sp->sPicture.use_argb = 1; - } - #endif - - if (!WebPValidateConfig(&sp->sEncoderConfig)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error with WebP encoder configuration."); - return 0; - } - - return 1; -} - -/* -* Reset encoding state at the start of a strip. -*/ -static int -TWebPPreEncode(TIFF* tif, uint16 s) -{ - static const char module[] = "TWebPPreEncode"; - uint32 segment_width, segment_height; - WebPState *sp = EncoderState(tif); - TIFFDirectory* td = &tif->tif_dir; - - (void) s; - - assert(sp != NULL); - if( sp->state != LSTATE_INIT_ENCODE ) - tif->tif_setupencode(tif); - - /* - * Set encoding parameters for this strip/tile. - */ - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - } - - if( segment_width > 16383 || segment_height > 16383 ) { - TIFFErrorExt(tif->tif_clientdata, module, - "WEBP maximum image dimensions are 16383 x 16383."); - return 0; - } - - /* set up buffer for raw data */ - /* given above check and that nSamples <= 4, buffer_size is <= 1 GB */ - sp->buffer_size = segment_width * segment_height * sp->nSamples; - - if (sp->pBuffer != NULL) { - _TIFFfree(sp->pBuffer); - sp->pBuffer = NULL; - } - - sp->pBuffer = _TIFFmalloc(sp->buffer_size); - if( !sp->pBuffer) { - TIFFErrorExt(tif->tif_clientdata, module, "Cannot allocate buffer"); - return 0; - } - sp->buffer_offset = 0; - - sp->sPicture.width = segment_width; - sp->sPicture.height = segment_height; - sp->sPicture.writer = TWebPDatasetWriter; - sp->sPicture.custom_ptr = tif; - - return 1; -} - -/* -* Finish off an encoded strip by flushing it. -*/ -static int -TWebPPostEncode(TIFF* tif) -{ - static const char module[] = "WebPPostEncode"; - int64_t stride; - WebPState *sp = EncoderState(tif); - assert(sp != NULL); - - assert(sp->state == LSTATE_INIT_ENCODE); - - stride = (int64_t)sp->sPicture.width * sp->nSamples; - -#if WEBP_ENCODER_ABI_VERSION >= 0x0100 - if (sp->nSamples == 4) { - if (!WebPPictureImportRGBA(&sp->sPicture, sp->pBuffer, (int)stride)) { - TIFFErrorExt(tif->tif_clientdata, module, - "WebPPictureImportRGBA() failed" ); - return 0; - } - } - else + if (sp->lossless) + { + sp->sPicture.use_argb = 1; +#if WEBP_ENCODER_ABI_VERSION >= 0x0209 + sp->sEncoderConfig.exact = sp->lossless_exact; #endif - if (!WebPPictureImportRGB(&sp->sPicture, sp->pBuffer, (int)stride)) { - TIFFErrorExt(tif->tif_clientdata, module, - "WebPPictureImportRGB() failed"); - return 0; - } - - if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) { + } +#endif + + if (!WebPValidateConfig(&sp->sEncoderConfig)) + { + TIFFErrorExtR(tif, module, "Error with WebP encoder configuration."); + return 0; + } + + return 1; +} + +/* + * Reset encoding state at the start of a strip. + */ +static int TWebPPreEncode(TIFF *tif, uint16_t s) +{ + static const char module[] = "TWebPPreEncode"; + uint32_t segment_width, segment_height; + WebPState *sp = EncoderState(tif); + TIFFDirectory *td = &tif->tif_dir; + + (void)s; + + assert(sp != NULL); + if (sp->state != LSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); + + /* + * Set encoding parameters for this strip/tile. + */ + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + } + + if (segment_width > 16383 || segment_height > 16383) + { + TIFFErrorExtR(tif, module, + "WEBP maximum image dimensions are 16383 x 16383."); + return 0; + } + + /* set up buffer for raw data */ + /* given above check and that nSamples <= 4, buffer_size is <= 1 GB */ + sp->buffer_size = segment_width * segment_height * sp->nSamples; + + if (sp->pBuffer != NULL) + { + _TIFFfreeExt(tif, sp->pBuffer); + sp->pBuffer = NULL; + } + + sp->pBuffer = _TIFFmallocExt(tif, sp->buffer_size); + if (!sp->pBuffer) + { + TIFFErrorExtR(tif, module, "Cannot allocate buffer"); + return 0; + } + sp->buffer_offset = 0; + + sp->sPicture.width = segment_width; + sp->sPicture.height = segment_height; + sp->sPicture.writer = TWebPDatasetWriter; + sp->sPicture.custom_ptr = tif; + + return 1; +} + +/* + * Finish off an encoded strip by flushing it. + */ +static int TWebPPostEncode(TIFF *tif) +{ + static const char module[] = "WebPPostEncode"; + int64_t stride; + WebPState *sp = EncoderState(tif); + assert(sp != NULL); + + assert(sp->state == LSTATE_INIT_ENCODE); + + stride = (int64_t)sp->sPicture.width * sp->nSamples; #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - const char* pszErrorMsg = NULL; - switch(sp->sPicture.error_code) { - case VP8_ENC_ERROR_OUT_OF_MEMORY: - pszErrorMsg = "Out of memory"; break; - case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: - pszErrorMsg = "Out of memory while flushing bits"; break; - case VP8_ENC_ERROR_NULL_PARAMETER: - pszErrorMsg = "A pointer parameter is NULL"; break; - case VP8_ENC_ERROR_INVALID_CONFIGURATION: - pszErrorMsg = "Configuration is invalid"; break; - case VP8_ENC_ERROR_BAD_DIMENSION: - pszErrorMsg = "Picture has invalid width/height"; break; - case VP8_ENC_ERROR_PARTITION0_OVERFLOW: - pszErrorMsg = "Partition is bigger than 512k. Try using less " - "SEGMENTS, or increase PARTITION_LIMIT value"; - break; - case VP8_ENC_ERROR_PARTITION_OVERFLOW: - pszErrorMsg = "Partition is bigger than 16M"; - break; - case VP8_ENC_ERROR_BAD_WRITE: - pszErrorMsg = "Error while fludshing bytes"; break; - case VP8_ENC_ERROR_FILE_TOO_BIG: - pszErrorMsg = "File is bigger than 4G"; break; - case VP8_ENC_ERROR_USER_ABORT: - pszErrorMsg = "User interrupted"; - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "WebPEncode returned an unknown error code: %d", - sp->sPicture.error_code); - pszErrorMsg = "Unknown WebP error type."; - break; + if (sp->nSamples == 4) + { + if (!WebPPictureImportRGBA(&sp->sPicture, sp->pBuffer, (int)stride)) + { + TIFFErrorExtR(tif, module, "WebPPictureImportRGBA() failed"); + return 0; + } } - TIFFErrorExt(tif->tif_clientdata, module, - "WebPEncode() failed : %s", pszErrorMsg); + else +#endif + if (!WebPPictureImportRGB(&sp->sPicture, sp->pBuffer, (int)stride)) + { + TIFFErrorExtR(tif, module, "WebPPictureImportRGB() failed"); + return 0; + } + + if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) + { + +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + const char *pszErrorMsg = NULL; + switch (sp->sPicture.error_code) + { + case VP8_ENC_ERROR_OUT_OF_MEMORY: + pszErrorMsg = "Out of memory"; + break; + case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: + pszErrorMsg = "Out of memory while flushing bits"; + break; + case VP8_ENC_ERROR_NULL_PARAMETER: + pszErrorMsg = "A pointer parameter is NULL"; + break; + case VP8_ENC_ERROR_INVALID_CONFIGURATION: + pszErrorMsg = "Configuration is invalid"; + break; + case VP8_ENC_ERROR_BAD_DIMENSION: + pszErrorMsg = "Picture has invalid width/height"; + break; + case VP8_ENC_ERROR_PARTITION0_OVERFLOW: + pszErrorMsg = "Partition is bigger than 512k. Try using less " + "SEGMENTS, or increase PARTITION_LIMIT value"; + break; + case VP8_ENC_ERROR_PARTITION_OVERFLOW: + pszErrorMsg = "Partition is bigger than 16M"; + break; + case VP8_ENC_ERROR_BAD_WRITE: + pszErrorMsg = "Error while fludshing bytes"; + break; + case VP8_ENC_ERROR_FILE_TOO_BIG: + pszErrorMsg = "File is bigger than 4G"; + break; + case VP8_ENC_ERROR_USER_ABORT: + pszErrorMsg = "User interrupted"; + break; + default: + TIFFErrorExtR(tif, module, + "WebPEncode returned an unknown error code: %d", + sp->sPicture.error_code); + pszErrorMsg = "Unknown WebP error type."; + break; + } + TIFFErrorExtR(tif, module, "WebPEncode() failed : %s", pszErrorMsg); #else - TIFFErrorExt(tif->tif_clientdata, module, - "Error in WebPEncode()"); + TIFFErrorExtR(tif, module, "Error in WebPEncode()"); #endif - return 0; - } + return 0; + } - sp->sPicture.custom_ptr = NULL; + sp->sPicture.custom_ptr = NULL; - if (!TIFFFlushData1(tif)) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Error flushing TIFF WebP encoder."); - return 0; - } + if (!TIFFFlushData1(tif)) + { + TIFFErrorExtR(tif, module, "Error flushing TIFF WebP encoder."); + return 0; + } - return 1; + return 1; } -static void -TWebPCleanup(TIFF* tif) +static void TWebPCleanup(TIFF *tif) { - WebPState* sp = LState(tif); + WebPState *sp = LState(tif); - assert(sp != 0); + assert(sp != 0); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; - if (sp->state & LSTATE_INIT_ENCODE) { - WebPPictureFree(&sp->sPicture); - } + if (sp->state & LSTATE_INIT_ENCODE) + { + WebPPictureFree(&sp->sPicture); + } - if (sp->psDecoder != NULL) { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - sp->last_y = 0; - } - - if (sp->pBuffer != NULL) { - _TIFFfree(sp->pBuffer); - sp->pBuffer = NULL; - } + if (sp->psDecoder != NULL) + { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + sp->last_y = 0; + } - _TIFFfree(tif->tif_data); - tif->tif_data = NULL; + if (sp->pBuffer != NULL) + { + _TIFFfreeExt(tif, sp->pBuffer); + sp->pBuffer = NULL; + } - _TIFFSetDefaultCompressionState(tif); + _TIFFfreeExt(tif, tif->tif_data); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); } -static int -TWebPVSetField(TIFF* tif, uint32 tag, va_list ap) +static int TWebPVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "WebPVSetField"; - WebPState* sp = LState(tif); + static const char module[] = "WebPVSetField"; + WebPState *sp = LState(tif); - switch (tag) { - case TIFFTAG_WEBP_LEVEL: - sp->quality_level = (int) va_arg(ap, int); - if( sp->quality_level <= 0 || - sp->quality_level > 100.0f ) { - TIFFWarningExt(tif->tif_clientdata, module, - "WEBP_LEVEL should be between 1 and 100"); + switch (tag) + { + case TIFFTAG_WEBP_LEVEL: + sp->quality_level = (int)va_arg(ap, int); + if (sp->quality_level <= 0 || sp->quality_level > 100.0f) + { + TIFFWarningExtR(tif, module, + "WEBP_LEVEL should be between 1 and 100"); + } + return 1; + case TIFFTAG_WEBP_LOSSLESS: +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + sp->lossless = va_arg(ap, int); + if (sp->lossless) + { + sp->quality_level = 100; + } + return 1; +#else + TIFFErrorExtR( + tif, module, + "Need to upgrade WEBP driver, this version doesn't support " + "lossless compression."); + return 0; +#endif + case TIFFTAG_WEBP_LOSSLESS_EXACT: +#if WEBP_ENCODER_ABI_VERSION >= 0x0209 + sp->lossless_exact = va_arg(ap, int); + return 1; +#else + TIFFErrorExtR( + tif, module, + "Need to upgrade WEBP driver, this version doesn't support " + "lossless compression."); + return 0; +#endif + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ +} + +static int TWebPVGetField(TIFF *tif, uint32_t tag, va_list ap) +{ + WebPState *sp = LState(tif); + + switch (tag) + { + case TIFFTAG_WEBP_LEVEL: + *va_arg(ap, int *) = sp->quality_level; + break; + case TIFFTAG_WEBP_LOSSLESS: + *va_arg(ap, int *) = sp->lossless; + break; + case TIFFTAG_WEBP_LOSSLESS_EXACT: + *va_arg(ap, int *) = sp->lossless_exact; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); } return 1; - case TIFFTAG_WEBP_LOSSLESS: - #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - sp->lossless = va_arg(ap, int); - if (sp->lossless){ - sp->quality_level = 100; - } - return 1; - #else - TIFFErrorExt(tif->tif_clientdata, module, - "Need to upgrade WEBP driver, this version doesn't support " - "lossless compression."); - return 0; - #endif - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ -} - -static int -TWebPVGetField(TIFF* tif, uint32 tag, va_list ap) -{ - WebPState* sp = LState(tif); - - switch (tag) { - case TIFFTAG_WEBP_LEVEL: - *va_arg(ap, int*) = sp->quality_level; - break; - case TIFFTAG_WEBP_LOSSLESS: - *va_arg(ap, int*) = sp->lossless; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; } static const TIFFField TWebPFields[] = { - { TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "WEBP quality", NULL }, - { TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "WEBP lossless/lossy", NULL - }, + {TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP quality", NULL}, + {TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP lossless/lossy", + NULL}, + {TIFFTAG_WEBP_LOSSLESS_EXACT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP exact lossless", + NULL}, }; -int -TIFFInitWebP(TIFF* tif, int scheme) +int TIFFInitWebP(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitWebP"; - WebPState* sp; + static const char module[] = "TIFFInitWebP"; + WebPState *sp; - (void)scheme; - assert( scheme == COMPRESSION_WEBP ); + (void)scheme; + assert(scheme == COMPRESSION_WEBP); - /* - * Merge codec-specific tag information. - */ - if ( !_TIFFMergeFields(tif, TWebPFields, TIFFArrayCount(TWebPFields)) ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Merging WebP codec-specific tags failed"); - return 0; - } + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, TWebPFields, TIFFArrayCount(TWebPFields))) + { + TIFFErrorExtR(tif, module, "Merging WebP codec-specific tags failed"); + return 0; + } - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8*) _TIFFmalloc(sizeof(WebPState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(WebPState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = TWebPVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */ + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = TWebPVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */ - /* Default values for codec-specific fields */ - sp->quality_level = 75; /* default comp. level */ - sp->lossless = 0; /* default to false */ - sp->state = 0; - sp->nSamples = 0; - sp->psDecoder = NULL; - sp->last_y = 0; - - sp->buffer_offset = 0; - sp->pBuffer = NULL; + /* Default values for codec-specific fields */ + sp->quality_level = 75; /* default comp. level */ + sp->lossless = 0; /* default to false */ + sp->lossless_exact = 1; /* exact lossless mode (if lossless enabled) */ + sp->state = 0; + sp->nSamples = 0; + sp->psDecoder = NULL; + sp->last_y = 0; - /* - * Install codec methods. - * Notes: - * encoderow is not supported - */ - tif->tif_fixuptags = TWebPFixupTags; - tif->tif_setupdecode = TWebPSetupDecode; - tif->tif_predecode = TWebPPreDecode; - tif->tif_decoderow = TWebPDecode; - tif->tif_decodestrip = TWebPDecode; - tif->tif_decodetile = TWebPDecode; - tif->tif_setupencode = TWebPSetupEncode; - tif->tif_preencode = TWebPPreEncode; - tif->tif_postencode = TWebPPostEncode; - tif->tif_encoderow = TWebPEncode; - tif->tif_encodestrip = TWebPEncode; - tif->tif_encodetile = TWebPEncode; - tif->tif_cleanup = TWebPCleanup; + sp->buffer_offset = 0; + sp->pBuffer = NULL; - return 1; + /* + * Install codec methods. + * Notes: + * encoderow is not supported + */ + tif->tif_fixuptags = TWebPFixupTags; + tif->tif_setupdecode = TWebPSetupDecode; + tif->tif_predecode = TWebPPreDecode; + tif->tif_decoderow = TWebPDecode; + tif->tif_decodestrip = TWebPDecode; + tif->tif_decodetile = TWebPDecode; + tif->tif_setupencode = TWebPSetupEncode; + tif->tif_preencode = TWebPPreEncode; + tif->tif_postencode = TWebPPostEncode; + tif->tif_encoderow = TWebPEncode; + tif->tif_encodestrip = TWebPEncode; + tif->tif_encodetile = TWebPEncode; + tif->tif_cleanup = TWebPCleanup; + + return 1; bad: - TIFFErrorExt(tif->tif_clientdata, module, - "No space for WebP state block"); - return 0; + TIFFErrorExtR(tif, module, "No space for WebP state block"); + return 0; } #endif /* WEBP_SUPPORT */ diff --git a/3rdparty/libtiff/tif_win32.c b/3rdparty/libtiff/tif_win32.c index 8964569394..1a6b86dffb 100644 --- a/3rdparty/libtiff/tif_win32.c +++ b/3rdparty/libtiff/tif_win32.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -28,6 +28,7 @@ */ #include "tiffiop.h" +#include #include @@ -54,121 +55,111 @@ static inline thandle_t thandle_from_int(int ifd) return (thandle_t)(intptr_t)ifd; } -static inline int thandle_to_int(thandle_t fd) +static inline int thandle_to_int(thandle_t fd) { return (int)(intptr_t)fd; } + +static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size) { - return (int)(intptr_t)fd; + /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes + * 32bit sizes, so we loop through the data in suitable 32bit sized + * chunks */ + uint8_t *ma; + uint64_t mb; + DWORD n; + DWORD o; + tmsize_t p; + ma = (uint8_t *)buf; + mb = size; + p = 0; + while (mb > 0) + { + n = 0x80000000UL; + if ((uint64_t)n > mb) + n = (DWORD)mb; + if (!ReadFile(fd, (LPVOID)ma, n, &o, NULL)) + return (0); + ma += o; + mb -= o; + p += o; + if (o != n) + break; + } + return (p); } -static tmsize_t -_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) +static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size) { - /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes - * 32bit sizes, so we loop through the data in suitable 32bit sized - * chunks */ - uint8* ma; - uint64 mb; - DWORD n; - DWORD o; - tmsize_t p; - ma=(uint8*)buf; - mb=size; - p=0; - while (mb>0) - { - n=0x80000000UL; - if ((uint64)n>mb) - n=(DWORD)mb; - if (!ReadFile(fd,(LPVOID)ma,n,&o,NULL)) - return(0); - ma+=o; - mb-=o; - p+=o; - if (o!=n) - break; - } - return(p); + /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes + * 32bit sizes, so we loop through the data in suitable 32bit sized + * chunks */ + uint8_t *ma; + uint64_t mb; + DWORD n; + DWORD o; + tmsize_t p; + ma = (uint8_t *)buf; + mb = size; + p = 0; + while (mb > 0) + { + n = 0x80000000UL; + if ((uint64_t)n > mb) + n = (DWORD)mb; + if (!WriteFile(fd, (LPVOID)ma, n, &o, NULL)) + return (0); + ma += o; + mb -= o; + p += o; + if (o != n) + break; + } + return (p); } -static tmsize_t -_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) +static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence) { - /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes - * 32bit sizes, so we loop through the data in suitable 32bit sized - * chunks */ - uint8* ma; - uint64 mb; - DWORD n; - DWORD o; - tmsize_t p; - ma=(uint8*)buf; - mb=size; - p=0; - while (mb>0) - { - n=0x80000000UL; - if ((uint64)n>mb) - n=(DWORD)mb; - if (!WriteFile(fd,(LPVOID)ma,n,&o,NULL)) - return(0); - ma+=o; - mb-=o; - p+=o; - if (o!=n) - break; - } - return(p); + LARGE_INTEGER offli; + DWORD dwMoveMethod; + offli.QuadPart = off; + switch (whence) + { + case SEEK_SET: + dwMoveMethod = FILE_BEGIN; + break; + case SEEK_CUR: + dwMoveMethod = FILE_CURRENT; + break; + case SEEK_END: + dwMoveMethod = FILE_END; + break; + default: + dwMoveMethod = FILE_BEGIN; + break; + } + offli.LowPart = + SetFilePointer(fd, offli.LowPart, &offli.HighPart, dwMoveMethod); + if ((offli.LowPart == INVALID_SET_FILE_POINTER) && + (GetLastError() != NO_ERROR)) + offli.QuadPart = 0; + return (offli.QuadPart); } -static uint64 -_tiffSeekProc(thandle_t fd, uint64 off, int whence) +static int _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); } + +static uint64_t _tiffSizeProc(thandle_t fd) { - LARGE_INTEGER offli; - DWORD dwMoveMethod; - offli.QuadPart = off; - switch(whence) - { - case SEEK_SET: - dwMoveMethod = FILE_BEGIN; - break; - case SEEK_CUR: - dwMoveMethod = FILE_CURRENT; - break; - case SEEK_END: - dwMoveMethod = FILE_END; - break; - default: - dwMoveMethod = FILE_BEGIN; - break; - } - offli.LowPart=SetFilePointer(fd,offli.LowPart,&offli.HighPart,dwMoveMethod); - if ((offli.LowPart==INVALID_SET_FILE_POINTER)&&(GetLastError()!=NO_ERROR)) - offli.QuadPart=0; - return(offli.QuadPart); + LARGE_INTEGER m; + if (GetFileSizeEx(fd, &m)) + return (m.QuadPart); + else + return (0); } -static int -_tiffCloseProc(thandle_t fd) +static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize) { - return (CloseHandle(fd) ? 0 : -1); -} - -static uint64 -_tiffSizeProc(thandle_t fd) -{ - LARGE_INTEGER m; - if (GetFileSizeEx(fd,&m)) - return(m.QuadPart); - else - return(0); -} - -static int -_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) -{ - (void) fd; - (void) pbase; - (void) psize; - return (0); + (void)fd; + (void)pbase; + (void)psize; + return (0); } /* @@ -182,45 +173,42 @@ _tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) * This removes a nasty OS dependency and cures a problem * with Visual C++ 5.0 */ -static int -_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) +static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) { - uint64 size; - tmsize_t sizem; - HANDLE hMapFile; + uint64_t size; + tmsize_t sizem; + HANDLE hMapFile; - size = _tiffSizeProc(fd); - sizem = (tmsize_t)size; - if (!size || (uint64)sizem!=size) - return (0); + size = _tiffSizeProc(fd); + sizem = (tmsize_t)size; + if (!size || (uint64_t)sizem != size) + return (0); - /* By passing in 0 for the maximum file size, it specifies that we - create a file mapping object for the full file size. */ - hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); - if (hMapFile == NULL) - return (0); - *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); - CloseHandle(hMapFile); - if (*pbase == NULL) - return (0); - *psize = size; - return(1); + /* By passing in 0 for the maximum file size, it specifies that we + create a file mapping object for the full file size. */ + hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); + if (hMapFile == NULL) + return (0); + *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); + CloseHandle(hMapFile); + if (*pbase == NULL) + return (0); + *psize = size; + return (1); } -static void -_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; - (void) base; - (void) size; + (void)fd; + (void)base; + (void)size; } -static void -_tiffUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; - (void) size; - UnmapViewOfFile(base); + (void)fd; + (void)size; + UnmapViewOfFile(base); } /* @@ -228,29 +216,36 @@ _tiffUnmapProc(thandle_t fd, void* base, toff_t size) * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode * string, which forces the file to be opened unmapped. */ -TIFF* -TIFFFdOpen(int ifd, const char* name, const char* mode) +TIFF *TIFFFdOpen(int ifd, const char *name, const char *mode) { - TIFF* tif; - int fSuppressMap; - int m; - fSuppressMap=0; - for (m=0; mode[m]!=0; m++) - { - if (mode[m]=='u') - { - fSuppressMap=1; - break; - } - } - tif = TIFFClientOpen(name, mode, thandle_from_int(ifd), - _tiffReadProc, _tiffWriteProc, - _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, - fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, - fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc); - if (tif) - tif->tif_fd = ifd; - return (tif); + return TIFFFdOpenExt(ifd, name, mode, NULL); +} + +TIFF *TIFFFdOpenExt(int ifd, const char *name, const char *mode, + TIFFOpenOptions *opts) +{ + TIFF *tif; + int fSuppressMap; + int m; + + fSuppressMap = 0; + for (m = 0; mode[m] != 0; m++) + { + if (mode[m] == 'u') + { + fSuppressMap = 1; + break; + } + } + + tif = TIFFClientOpenExt( + name, mode, thandle_from_int(ifd), _tiffReadProc, _tiffWriteProc, + _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, + fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, + fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc, opts); + if (tif) + tif->tif_fd = ifd; + return (tif); } #ifndef _WIN32_WCE @@ -258,184 +253,190 @@ TIFFFdOpen(int ifd, const char* name, const char* mode) /* * Open a TIFF file for read/writing. */ -TIFF* -TIFFOpen(const char* name, const char* mode) +TIFF *TIFFOpen(const char *name, const char *mode) { - static const char module[] = "TIFFOpen"; - thandle_t fd; - int m; - DWORD dwMode; - TIFF* tif; + return TIFFOpenExt(name, mode, NULL); +} - m = _TIFFgetMode(mode, module); +TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts) +{ + static const char module[] = "TIFFOpen"; + thandle_t fd; + int m; + DWORD dwMode; + TIFF *tif; - switch(m) { - case O_RDONLY: dwMode = OPEN_EXISTING; break; - case O_RDWR: dwMode = OPEN_ALWAYS; break; - case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; - case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; - case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; - default: return ((TIFF*)0); - } - - fd = (thandle_t)CreateFileA(name, - (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE), - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, - (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, - NULL); - if (fd == INVALID_HANDLE_VALUE) { - TIFFErrorExt(0, module, "%s: Cannot open", name); - return ((TIFF *)0); - } + m = _TIFFgetMode(opts, NULL, mode, module); - tif = TIFFFdOpen(thandle_to_int(fd), name, mode); - if(!tif) - CloseHandle(fd); - return tif; + switch (m) + { + case O_RDONLY: + dwMode = OPEN_EXISTING; + break; + case O_RDWR: + dwMode = OPEN_EXISTING; + break; + case O_RDWR | O_CREAT: + dwMode = OPEN_ALWAYS; + break; + case O_RDWR | O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + case O_RDWR | O_CREAT | O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + default: + return ((TIFF *)0); + } + + fd = (thandle_t)CreateFileA( + name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, + (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL, + NULL); + if (fd == INVALID_HANDLE_VALUE) + { + _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name); + return ((TIFF *)0); + } + + tif = TIFFFdOpenExt(thandle_to_int(fd), name, mode, opts); + if (!tif) + CloseHandle(fd); + return tif; } /* * Open a TIFF file with a Unicode filename, for read/writing. */ -TIFF* -TIFFOpenW(const wchar_t* name, const char* mode) +TIFF *TIFFOpenW(const wchar_t *name, const char *mode) { - static const char module[] = "TIFFOpenW"; - thandle_t fd; - int m; - DWORD dwMode; - int mbsize; - char *mbname; - TIFF *tif; + return TIFFOpenWExt(name, mode, NULL); +} - m = _TIFFgetMode(mode, module); +TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts) +{ + static const char module[] = "TIFFOpenW"; + thandle_t fd; + int m; + DWORD dwMode; + int mbsize; + char *mbname; + TIFF *tif; - switch(m) { - case O_RDONLY: dwMode = OPEN_EXISTING; break; - case O_RDWR: dwMode = OPEN_ALWAYS; break; - case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; - case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; - case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; - default: return ((TIFF*)0); - } + m = _TIFFgetMode(opts, NULL, mode, module); - fd = (thandle_t)CreateFileW(name, - (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE), - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, - (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, - NULL); - if (fd == INVALID_HANDLE_VALUE) { - TIFFErrorExt(0, module, "%S: Cannot open", name); - return ((TIFF *)0); - } + switch (m) + { + case O_RDONLY: + dwMode = OPEN_EXISTING; + break; + case O_RDWR: + dwMode = OPEN_EXISTING; + break; + case O_RDWR | O_CREAT: + dwMode = OPEN_ALWAYS; + break; + case O_RDWR | O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + case O_RDWR | O_CREAT | O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + default: + return ((TIFF *)0); + } - mbname = NULL; - mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); - if (mbsize > 0) { - mbname = (char *)_TIFFmalloc(mbsize); - if (!mbname) { - TIFFErrorExt(0, module, - "Can't allocate space for filename conversion buffer"); - return ((TIFF*)0); - } + fd = (thandle_t)CreateFileW( + name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, + (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL, + NULL); + if (fd == INVALID_HANDLE_VALUE) + { + _TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name); + return ((TIFF *)0); + } - WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, - NULL, NULL); - } + mbname = NULL; + mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); + if (mbsize > 0) + { + mbname = (char *)_TIFFmalloc(mbsize); + if (!mbname) + { + _TIFFErrorEarly( + opts, NULL, module, + "Can't allocate space for filename conversion buffer"); + return ((TIFF *)0); + } - tif = TIFFFdOpen(thandle_to_int(fd), - (mbname != NULL) ? mbname : "", mode); - if(!tif) - CloseHandle(fd); + WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL); + } - _TIFFfree(mbname); + tif = TIFFFdOpenExt(thandle_to_int(fd), + (mbname != NULL) ? mbname : "", mode, opts); + if (!tif) + CloseHandle(fd); - return tif; + _TIFFfree(mbname); + + return tif; } #endif /* ndef _WIN32_WCE */ -void* -_TIFFmalloc(tmsize_t s) +void *_TIFFmalloc(tmsize_t s) { - if (s == 0) - return ((void *) NULL); + if (s == 0) + return ((void *)NULL); - return (malloc((size_t) s)); + return (malloc((size_t)s)); } -void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) +void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz) { - if( nmemb == 0 || siz == 0 ) - return ((void *) NULL); + if (nmemb == 0 || siz == 0) + return ((void *)NULL); - return calloc((size_t) nmemb, (size_t)siz); + return calloc((size_t)nmemb, (size_t)siz); } -void -_TIFFfree(void* p) +void _TIFFfree(void *p) { free(p); } + +void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); } + +void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); } + +void _TIFFmemcpy(void *d, const void *s, tmsize_t c) { - free(p); + memcpy(d, s, (size_t)c); } -void* -_TIFFrealloc(void* p, tmsize_t s) +int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c) { - return (realloc(p, (size_t) s)); -} - -void -_TIFFmemset(void* p, int v, tmsize_t c) -{ - memset(p, v, (size_t) c); -} - -void -_TIFFmemcpy(void* d, const void* s, tmsize_t c) -{ - memcpy(d, s, (size_t) c); -} - -int -_TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) -{ - return (memcmp(p1, p2, (size_t) c)); + return (memcmp(p1, p2, (size_t)c)); } #ifndef _WIN32_WCE -#if (_MSC_VER < 1500) -# define vsnprintf _vsnprintf -#endif - -static void -Win32WarningHandler(const char* module, const char* fmt, va_list ap) +static void Win32WarningHandler(const char *module, const char *fmt, va_list ap) { - if (module != NULL) - fprintf(stderr, "%s: ", module); - fprintf(stderr, "Warning, "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); } TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler; -static void -Win32ErrorHandler(const char* module, const char* fmt, va_list ap) +static void Win32ErrorHandler(const char *module, const char *fmt, va_list ap) { - if (module != NULL) - fprintf(stderr, "%s: ", module); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); } TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler; #endif /* ndef _WIN32_WCE */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_write.c b/3rdparty/libtiff/tif_write.c index 3af69ab4e7..6631a782fd 100644 --- a/3rdparty/libtiff/tif_write.c +++ b/3rdparty/libtiff/tif_write.c @@ -30,174 +30,178 @@ #include "tiffiop.h" #include -#define STRIPINCR 20 /* expansion factor on strip array */ +#define STRIPINCR 20 /* expansion factor on strip array */ -#define WRITECHECKSTRIPS(tif, module) \ - (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module)) -#define WRITECHECKTILES(tif, module) \ - (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module)) -#define BUFFERCHECK(tif) \ - ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \ - TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1)) +#define WRITECHECKSTRIPS(tif, module) \ + (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module)) +#define WRITECHECKTILES(tif, module) \ + (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module)) +#define BUFFERCHECK(tif) \ + ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \ + TIFFWriteBufferSetup((tif), NULL, (tmsize_t)-1)) -static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module); -static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc); +static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module); +static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, + tmsize_t cc); -int -TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) +int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) { - static const char module[] = "TIFFWriteScanline"; - register TIFFDirectory *td; - int status, imagegrew = 0; - uint32 strip; + static const char module[] = "TIFFWriteScanline"; + register TIFFDirectory *td; + int status, imagegrew = 0; + uint32_t strip; - if (!WRITECHECKSTRIPS(tif, module)) - return (-1); - /* - * Handle delayed allocation of data buffer. This - * permits it to be sized more intelligently (using - * directory information). - */ - if (!BUFFERCHECK(tif)) - return (-1); - tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/ + if (!WRITECHECKSTRIPS(tif, module)) + return (-1); + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized more intelligently (using + * directory information). + */ + if (!BUFFERCHECK(tif)) + return (-1); + tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/ - td = &tif->tif_dir; - /* - * Extend image length if needed - * (but only for PlanarConfig=1). - */ - if (row >= td->td_imagelength) { /* extend image */ - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not change \"ImageLength\" when using separate planes"); - return (-1); - } - td->td_imagelength = row+1; - imagegrew = 1; - } - /* - * Calculate strip and check for crossings. - */ - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - if (sample >= td->td_samplesperpixel) { - TIFFErrorExt(tif->tif_clientdata, module, - "%lu: Sample out of range, max %lu", - (unsigned long) sample, (unsigned long) td->td_samplesperpixel); - return (-1); - } - strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; - } else - strip = row / td->td_rowsperstrip; - /* - * Check strip array to make sure there's space. We don't support - * dynamically growing files that have data organized in separate - * bitplanes because it's too painful. In that case we require that - * the imagelength be set properly before the first write (so that the - * strips array will be fully allocated above). - */ - if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) - return (-1); - if (strip != tif->tif_curstrip) { - /* - * Changing strips -- flush any data present. - */ - if (!TIFFFlushData(tif)) - return (-1); - tif->tif_curstrip = strip; - /* - * Watch out for a growing image. The value of strips/image - * will initially be 1 (since it can't be deduced until the - * imagelength is known). - */ - if (strip >= td->td_stripsperimage && imagegrew) - td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); - if (td->td_stripsperimage == 0) { - TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image"); - return (-1); - } - tif->tif_row = - (strip % td->td_stripsperimage) * td->td_rowsperstrip; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupencode)(tif)) - return (-1); - tif->tif_flags |= TIFF_CODERSETUP; - } - - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; + td = &tif->tif_dir; + /* + * Extend image length if needed + * (but only for PlanarConfig=1). + */ + if (row >= td->td_imagelength) + { /* extend image */ + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + TIFFErrorExtR( + tif, module, + "Can not change \"ImageLength\" when using separate planes"); + return (-1); + } + td->td_imagelength = row + 1; + imagegrew = 1; + } + /* + * Calculate strip and check for crossings. + */ + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + if (sample >= td->td_samplesperpixel) + { + TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu", + (unsigned long)sample, + (unsigned long)td->td_samplesperpixel); + return (-1); + } + strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip; + } + else + strip = row / td->td_rowsperstrip; + /* + * Check strip array to make sure there's space. We don't support + * dynamically growing files that have data organized in separate + * bitplanes because it's too painful. In that case we require that + * the imagelength be set properly before the first write (so that the + * strips array will be fully allocated above). + */ + if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) + return (-1); + if (strip != tif->tif_curstrip) + { + /* + * Changing strips -- flush any data present. + */ + if (!TIFFFlushData(tif)) + return (-1); + tif->tif_curstrip = strip; + /* + * Watch out for a growing image. The value of strips/image + * will initially be 1 (since it can't be deduced until the + * imagelength is known). + */ + if (strip >= td->td_stripsperimage && imagegrew) + td->td_stripsperimage = + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); + if (td->td_stripsperimage == 0) + { + TIFFErrorExtR(tif, module, "Zero strips per image"); + return (-1); + } + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupencode)(tif)) + return (-1); + tif->tif_flags |= TIFF_CODERSETUP; + } - if( td->td_stripbytecount_p[strip] > 0 ) - { - /* if we are writing over existing tiles, zero length */ - td->td_stripbytecount_p[strip] = 0; + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; - /* this forces TIFFAppendToStrip() to do a seek */ - tif->tif_curoff = 0; - } + /* this informs TIFFAppendToStrip() we have changed strip */ + tif->tif_curoff = 0; - if (!(*tif->tif_preencode)(tif, sample)) - return (-1); - tif->tif_flags |= TIFF_POSTENCODE; - } - /* - * Ensure the write is either sequential or at the - * beginning of a strip (or that we can randomly - * access the data -- i.e. no encoding). - */ - if (row != tif->tif_row) { - if (row < tif->tif_row) { - /* - * Moving backwards within the same strip: - * backup to the start and then decode - * forward (below). - */ - tif->tif_row = (strip % td->td_stripsperimage) * - td->td_rowsperstrip; - tif->tif_rawcp = tif->tif_rawdata; - } - /* - * Seek forward to the desired row. - */ - if (!(*tif->tif_seek)(tif, row - tif->tif_row)) - return (-1); - tif->tif_row = row; - } + if (!(*tif->tif_preencode)(tif, sample)) + return (-1); + tif->tif_flags |= TIFF_POSTENCODE; + } + /* + * Ensure the write is either sequential or at the + * beginning of a strip (or that we can randomly + * access the data -- i.e. no encoding). + */ + if (row != tif->tif_row) + { + if (row < tif->tif_row) + { + /* + * Moving backwards within the same strip: + * backup to the start and then decode + * forward (below). + */ + tif->tif_row = + (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_rawcp = tif->tif_rawdata; + } + /* + * Seek forward to the desired row. + */ + if (!(*tif->tif_seek)(tif, row - tif->tif_row)) + return (-1); + tif->tif_row = row; + } - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize ); + /* swab if needed - note that source buffer will be altered */ + tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize); - status = (*tif->tif_encoderow)(tif, (uint8*) buf, - tif->tif_scanlinesize, sample); + status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize, + sample); - /* we are now poised at the beginning of the next row */ - tif->tif_row = row + 1; - return (status); + /* we are now poised at the beginning of the next row */ + tif->tif_row = row + 1; + return (status); } -/* Make sure that at the first attempt of rewriting a tile/strip, we will have */ +/* Make sure that at the first attempt of rewriting a tile/strip, we will have + */ /* more bytes available in the output buffer than the previous byte count, */ -/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */ +/* so that TIFFAppendToStrip() will detect the overflow when it is called the + * first */ /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */ -static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32 strip_or_tile) +static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile) { TIFFDirectory *td = &tif->tif_dir; - if( td->td_stripbytecount_p[strip_or_tile] > 0 ) + if (td->td_stripbytecount_p[strip_or_tile] > 0) { /* The +1 is to ensure at least one extra bytes */ /* The +4 is because the LZW encoder flushes 4 bytes before the limit */ - uint64 safe_buffer_size = (uint64)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4); - if( tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size ) + uint64_t safe_buffer_size = + (uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4); + if (tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size) { - if( !(TIFFWriteBufferSetup(tif, NULL, - (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) ) + if (!(TIFFWriteBufferSetup( + tif, NULL, + (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024)))) return 0; } - - /* Force TIFFAppendToStrip() to consider placing data at end - of file. */ - tif->tif_curoff = 0; } return 1; } @@ -208,103 +212,112 @@ static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32 strip_or_tile) * * NB: Image length must be setup before writing. */ -tmsize_t -TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) +tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data, + tmsize_t cc) { - static const char module[] = "TIFFWriteEncodedStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint16 sample; + static const char module[] = "TIFFWriteEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint16_t sample; - if (!WRITECHECKSTRIPS(tif, module)) - return ((tmsize_t) -1); - /* - * Check strip array to make sure there's space. - * We don't support dynamically growing files that - * have data organized in separate bitplanes because - * it's too painful. In that case we require that - * the imagelength be set properly before the first - * write (so that the strips array will be fully - * allocated above). - */ - if (strip >= td->td_nstrips) { - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not grow image by strips when using separate planes"); - return ((tmsize_t) -1); - } - if (!TIFFGrowStrips(tif, 1, module)) - return ((tmsize_t) -1); - td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); - } - /* - * Handle delayed allocation of data buffer. This - * permits it to be sized according to the directory - * info. - */ - if (!BUFFERCHECK(tif)) - return ((tmsize_t) -1); - - tif->tif_flags |= TIFF_BUF4WRITE; - tif->tif_curstrip = strip; - - if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) { - return ((tmsize_t)(-1)); + if (!WRITECHECKSTRIPS(tif, module)) + return ((tmsize_t)-1); + /* + * Check strip array to make sure there's space. + * We don't support dynamically growing files that + * have data organized in separate bitplanes because + * it's too painful. In that case we require that + * the imagelength be set properly before the first + * write (so that the strips array will be fully + * allocated above). + */ + if (strip >= td->td_nstrips) + { + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + TIFFErrorExtR( + tif, module, + "Can not grow image by strips when using separate planes"); + return ((tmsize_t)-1); } + if (!TIFFGrowStrips(tif, 1, module)) + return ((tmsize_t)-1); + td->td_stripsperimage = + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); + } + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized according to the directory + * info. + */ + if (!BUFFERCHECK(tif)) + return ((tmsize_t)-1); - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; + tif->tif_flags |= TIFF_BUF4WRITE; - if (td->td_stripsperimage == 0) { - TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image"); - return ((tmsize_t) -1); - } + tif->tif_curstrip = strip; - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupencode)(tif)) - return ((tmsize_t) -1); - tif->tif_flags |= TIFF_CODERSETUP; - } + /* this informs TIFFAppendToStrip() we have changed or reset strip */ + tif->tif_curoff = 0; - tif->tif_flags &= ~TIFF_POSTENCODE; + if (!_TIFFReserveLargeEnoughWriteBuffer(tif, strip)) + { + return ((tmsize_t)(-1)); + } + + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + + if (td->td_stripsperimage == 0) + { + TIFFErrorExtR(tif, module, "Zero strips per image"); + return ((tmsize_t)-1); + } + + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupencode)(tif)) + return ((tmsize_t)-1); + tif->tif_flags |= TIFF_CODERSETUP; + } + + tif->tif_flags &= ~TIFF_POSTENCODE; /* shortcut to avoid an extra memcpy() */ - if( td->td_compression == COMPRESSION_NONE ) + if (td->td_compression == COMPRESSION_NONE) { /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode( tif, (uint8*) data, cc ); + tif->tif_postdecode(tif, (uint8_t *)data, cc); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8*) data, cc); + TIFFReverseBits((uint8_t *)data, cc); - if (cc > 0 && - !TIFFAppendToStrip(tif, strip, (uint8*) data, cc)) - return ((tmsize_t) -1); + if (cc > 0 && !TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc)) + return ((tmsize_t)-1); return (cc); } - sample = (uint16)(strip / td->td_stripsperimage); - if (!(*tif->tif_preencode)(tif, sample)) - return ((tmsize_t) -1); + sample = (uint16_t)(strip / td->td_stripsperimage); + if (!(*tif->tif_preencode)(tif, sample)) + return ((tmsize_t)-1); - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode( tif, (uint8*) data, cc ); + /* swab if needed - note that source buffer will be altered */ + tif->tif_postdecode(tif, (uint8_t *)data, cc); - if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample)) - return ((tmsize_t) -1); - if (!(*tif->tif_postencode)(tif)) - return ((tmsize_t) -1); - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); - if (tif->tif_rawcc > 0 && - !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) - return ((tmsize_t) -1); - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - return (cc); + if (!(*tif->tif_encodestrip)(tif, (uint8_t *)data, cc, sample)) + return ((tmsize_t)-1); + if (!(*tif->tif_postencode)(tif)) + return ((tmsize_t)-1); + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); + if (tif->tif_rawcc > 0 && + !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) + return ((tmsize_t)-1); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + return (cc); } /* @@ -312,67 +325,78 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) * * NB: Image length must be setup before writing. */ -tmsize_t -TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) +tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc) { - static const char module[] = "TIFFWriteRawStrip"; - TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "TIFFWriteRawStrip"; + TIFFDirectory *td = &tif->tif_dir; - if (!WRITECHECKSTRIPS(tif, module)) - return ((tmsize_t) -1); - /* - * Check strip array to make sure there's space. - * We don't support dynamically growing files that - * have data organized in separate bitplanes because - * it's too painful. In that case we require that - * the imagelength be set properly before the first - * write (so that the strips array will be fully - * allocated above). - */ - if (strip >= td->td_nstrips) { - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - TIFFErrorExt(tif->tif_clientdata, module, - "Can not grow image by strips when using separate planes"); - return ((tmsize_t) -1); - } - /* - * Watch out for a growing image. The value of - * strips/image will initially be 1 (since it - * can't be deduced until the imagelength is known). - */ - if (strip >= td->td_stripsperimage) - td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); - if (!TIFFGrowStrips(tif, 1, module)) - return ((tmsize_t) -1); - } - tif->tif_curstrip = strip; - if (td->td_stripsperimage == 0) { - TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image"); - return ((tmsize_t) -1); + if (!WRITECHECKSTRIPS(tif, module)) + return ((tmsize_t)-1); + /* + * Check strip array to make sure there's space. + * We don't support dynamically growing files that + * have data organized in separate bitplanes because + * it's too painful. In that case we require that + * the imagelength be set properly before the first + * write (so that the strips array will be fully + * allocated above). + */ + if (strip >= td->td_nstrips) + { + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + TIFFErrorExtR( + tif, module, + "Can not grow image by strips when using separate planes"); + return ((tmsize_t)-1); } - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ? - cc : (tmsize_t) -1); + /* + * Watch out for a growing image. The value of + * strips/image will initially be 1 (since it + * can't be deduced until the imagelength is known). + */ + if (strip >= td->td_stripsperimage) + td->td_stripsperimage = + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); + if (!TIFFGrowStrips(tif, 1, module)) + return ((tmsize_t)-1); + } + + if (tif->tif_curstrip != strip) + { + tif->tif_curstrip = strip; + + /* this informs TIFFAppendToStrip() we have changed or reset strip */ + tif->tif_curoff = 0; + } + + if (td->td_stripsperimage == 0) + { + TIFFErrorExtR(tif, module, "Zero strips per image"); + return ((tmsize_t)-1); + } + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc + : (tmsize_t)-1); } /* * Write and compress a tile of data. The * tile is selected by the (x,y,z,s) coordinates. */ -tmsize_t -TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) +tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z, + uint16_t s) { - if (!TIFFCheckTile(tif, x, y, z, s)) - return ((tmsize_t)(-1)); - /* - * NB: A tile size of -1 is used instead of tif_tilesize knowing - * that TIFFWriteEncodedTile will clamp this to the tile size. - * This is done because the tile size may not be defined until - * after the output buffer is setup in TIFFWriteBufferSetup. - */ - return (TIFFWriteEncodedTile(tif, - TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); + if (!TIFFCheckTile(tif, x, y, z, s)) + return ((tmsize_t)(-1)); + /* + * NB: A tile size of -1 is used instead of tif_tilesize knowing + * that TIFFWriteEncodedTile will clamp this to the tile size. + * This is done because the tile size may not be defined until + * after the output buffer is setup in TIFFWriteBufferSetup. + */ + return (TIFFWriteEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf, + (tmsize_t)(-1))); } /* @@ -387,104 +411,111 @@ TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) * interface does not support automatically growing * the image on each write (as TIFFWriteScanline does). */ -tmsize_t -TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) +tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc) { - static const char module[] = "TIFFWriteEncodedTile"; - TIFFDirectory *td; - uint16 sample; - uint32 howmany32; + static const char module[] = "TIFFWriteEncodedTile"; + TIFFDirectory *td; + uint16_t sample; + uint32_t howmany32; - if (!WRITECHECKTILES(tif, module)) - return ((tmsize_t)(-1)); - td = &tif->tif_dir; - if (tile >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", - (unsigned long) tile, (unsigned long) td->td_nstrips); - return ((tmsize_t)(-1)); - } - /* - * Handle delayed allocation of data buffer. This - * permits it to be sized more intelligently (using - * directory information). - */ - if (!BUFFERCHECK(tif)) - return ((tmsize_t)(-1)); + if (!WRITECHECKTILES(tif, module)) + return ((tmsize_t)(-1)); + td = &tif->tif_dir; + if (tile >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu", + (unsigned long)tile, (unsigned long)td->td_nstrips); + return ((tmsize_t)(-1)); + } + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized more intelligently (using + * directory information). + */ + if (!BUFFERCHECK(tif)) + return ((tmsize_t)(-1)); - tif->tif_flags |= TIFF_BUF4WRITE; - tif->tif_curtile = tile; + tif->tif_flags |= TIFF_BUF4WRITE; - if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) { + tif->tif_curtile = tile; + + /* this informs TIFFAppendToStrip() we have changed or reset tile */ + tif->tif_curoff = 0; + + if (!_TIFFReserveLargeEnoughWriteBuffer(tif, tile)) + { + return ((tmsize_t)(-1)); + } + + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + + /* + * Compute tiles per row & per column to compute + * current row and column + */ + howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength); + if (howmany32 == 0) + { + TIFFErrorExtR(tif, module, "Zero tiles"); + return ((tmsize_t)(-1)); + } + tif->tif_row = (tile % howmany32) * td->td_tilelength; + howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); + if (howmany32 == 0) + { + TIFFErrorExtR(tif, module, "Zero tiles"); + return ((tmsize_t)(-1)); + } + tif->tif_col = (tile % howmany32) * td->td_tilewidth; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupencode)(tif)) return ((tmsize_t)(-1)); - } + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_flags &= ~TIFF_POSTENCODE; - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - - /* - * Compute tiles per row & per column to compute - * current row and column - */ - howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength); - if (howmany32 == 0) { - TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles"); - return ((tmsize_t)(-1)); - } - tif->tif_row = (tile % howmany32) * td->td_tilelength; - howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); - if (howmany32 == 0) { - TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles"); - return ((tmsize_t)(-1)); - } - tif->tif_col = (tile % howmany32) * td->td_tilewidth; - - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupencode)(tif)) - return ((tmsize_t)(-1)); - tif->tif_flags |= TIFF_CODERSETUP; - } - tif->tif_flags &= ~TIFF_POSTENCODE; - - /* - * Clamp write amount to the tile size. This is mostly - * done so that callers can pass in some large number - * (e.g. -1) and have the tile size used instead. - */ - if ( cc < 1 || cc > tif->tif_tilesize) - cc = tif->tif_tilesize; + /* + * Clamp write amount to the tile size. This is mostly + * done so that callers can pass in some large number + * (e.g. -1) and have the tile size used instead. + */ + if (cc < 1 || cc > tif->tif_tilesize) + cc = tif->tif_tilesize; /* shortcut to avoid an extra memcpy() */ - if( td->td_compression == COMPRESSION_NONE ) + if (td->td_compression == COMPRESSION_NONE) { /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode( tif, (uint8*) data, cc ); + tif->tif_postdecode(tif, (uint8_t *)data, cc); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8*) data, cc); + TIFFReverseBits((uint8_t *)data, cc); - if (cc > 0 && - !TIFFAppendToStrip(tif, tile, (uint8*) data, cc)) - return ((tmsize_t) -1); + if (cc > 0 && !TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc)) + return ((tmsize_t)-1); return (cc); } - sample = (uint16)(tile/td->td_stripsperimage); + sample = (uint16_t)(tile / td->td_stripsperimage); if (!(*tif->tif_preencode)(tif, sample)) return ((tmsize_t)(-1)); /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode( tif, (uint8*) data, cc ); + tif->tif_postdecode(tif, (uint8_t *)data, cc); - if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample)) - return ((tmsize_t) -1); + if (!(*tif->tif_encodetile)(tif, (uint8_t *)data, cc, sample)) + return ((tmsize_t)-1); if (!(*tif->tif_postencode)(tif)) - return ((tmsize_t)(-1)); + return ((tmsize_t)(-1)); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc); - if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile, - tif->tif_rawdata, tif->tif_rawcc)) - return ((tmsize_t)(-1)); + TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc); + if (tif->tif_rawcc > 0 && + !TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc)) + return ((tmsize_t)(-1)); tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; return (cc); @@ -499,66 +530,64 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) * interface does not support automatically growing * the image on each write (as TIFFWriteScanline does). */ -tmsize_t -TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) +tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc) { - static const char module[] = "TIFFWriteRawTile"; + static const char module[] = "TIFFWriteRawTile"; - if (!WRITECHECKTILES(tif, module)) - return ((tmsize_t)(-1)); - if (tile >= tif->tif_dir.td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", - (unsigned long) tile, - (unsigned long) tif->tif_dir.td_nstrips); - return ((tmsize_t)(-1)); - } - return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ? - cc : (tmsize_t)(-1)); + if (!WRITECHECKTILES(tif, module)) + return ((tmsize_t)(-1)); + if (tile >= tif->tif_dir.td_nstrips) + { + TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu", + (unsigned long)tile, + (unsigned long)tif->tif_dir.td_nstrips); + return ((tmsize_t)(-1)); + } + return (TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc) ? cc + : (tmsize_t)(-1)); } -#define isUnspecified(tif, f) \ - (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0) +#define isUnspecified(tif, f) \ + (TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0) -int -TIFFSetupStrips(TIFF* tif) +int TIFFSetupStrips(TIFF *tif) { - TIFFDirectory* td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; - if (isTiled(tif)) - td->td_stripsperimage = - isUnspecified(tif, FIELD_TILEDIMENSIONS) ? - td->td_samplesperpixel : TIFFNumberOfTiles(tif); - else - td->td_stripsperimage = - isUnspecified(tif, FIELD_ROWSPERSTRIP) ? - td->td_samplesperpixel : TIFFNumberOfStrips(tif); - td->td_nstrips = td->td_stripsperimage; - /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */ - if( td->td_nstrips >= 0x80000000U / ((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U) ) - { - TIFFErrorExt(tif->tif_clientdata, "TIFFSetupStrips", - "Too large Strip/Tile Offsets/ByteCounts arrays"); - return 0; - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - td->td_stripsperimage /= td->td_samplesperpixel; - td->td_stripoffset_p = (uint64 *) - _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), - "for \"StripOffsets\" array"); - td->td_stripbytecount_p = (uint64 *) - _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), - "for \"StripByteCounts\" array"); - if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL) - return (0); - /* - * Place data at the end-of-file - * (by setting offsets to zero). - */ - _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips*sizeof (uint64)); - _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips*sizeof (uint64)); - TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); - TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); - return (1); + if (isTiled(tif)) + td->td_stripsperimage = isUnspecified(tif, FIELD_TILEDIMENSIONS) + ? td->td_samplesperpixel + : TIFFNumberOfTiles(tif); + else + td->td_stripsperimage = isUnspecified(tif, FIELD_ROWSPERSTRIP) + ? td->td_samplesperpixel + : TIFFNumberOfStrips(tif); + td->td_nstrips = td->td_stripsperimage; + /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */ + if (td->td_nstrips >= + 0x80000000U / ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U)) + { + TIFFErrorExtR(tif, "TIFFSetupStrips", + "Too large Strip/Tile Offsets/ByteCounts arrays"); + return 0; + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + td->td_stripsperimage /= td->td_samplesperpixel; + td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc( + tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array"); + td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc( + tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array"); + if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL) + return (0); + /* + * Place data at the end-of-file + * (by setting offsets to zero). + */ + _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips * sizeof(uint64_t)); + _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips * sizeof(uint64_t)); + TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); + TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); + return (1); } #undef isUnspecified @@ -568,241 +597,325 @@ TIFFSetupStrips(TIFF* tif) * we also "freeze" the state of the directory so * that important information is not changed. */ -int -TIFFWriteCheck(TIFF* tif, int tiles, const char* module) +int TIFFWriteCheck(TIFF *tif, int tiles, const char *module) { - if (tif->tif_mode == O_RDONLY) { - TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing"); - return (0); - } - if (tiles ^ isTiled(tif)) { - TIFFErrorExt(tif->tif_clientdata, module, tiles ? - "Can not write tiles to a striped image" : - "Can not write scanlines to a tiled image"); - return (0); - } + if (tif->tif_mode == O_RDONLY) + { + TIFFErrorExtR(tif, module, "File not open for writing"); + return (0); + } + if (tiles ^ isTiled(tif)) + { + TIFFErrorExtR(tif, module, + tiles ? "Can not write tiles to a striped image" + : "Can not write scanlines to a tiled image"); + return (0); + } - _TIFFFillStriles( tif ); - - /* - * On the first write verify all the required information - * has been setup and initialize any data structures that - * had to wait until directory information was set. - * Note that a lot of our work is assumed to remain valid - * because we disallow any of the important parameters - * from changing after we start writing (i.e. once - * TIFF_BEENWRITING is set, TIFFSetField will only allow - * the image's length to be changed). - */ - if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Must set \"ImageWidth\" before writing data"); - return (0); - } - if (tif->tif_dir.td_samplesperpixel == 1) { - /* - * Planarconfiguration is irrelevant in case of single band - * images and need not be included. We will set it anyway, - * because this field is used in other parts of library even - * in the single band case. - */ - if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) - tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG; - } else { - if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) { - TIFFErrorExt(tif->tif_clientdata, module, - "Must set \"PlanarConfiguration\" before writing data"); - return (0); - } - } - if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) { - tif->tif_dir.td_nstrips = 0; - TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays", - isTiled(tif) ? "tile" : "strip"); - return (0); - } - if (isTiled(tif)) - { - tif->tif_tilesize = TIFFTileSize(tif); - if (tif->tif_tilesize == 0) - return (0); - } - else - tif->tif_tilesize = (tmsize_t)(-1); - tif->tif_scanlinesize = TIFFScanlineSize(tif); - if (tif->tif_scanlinesize == 0) - return (0); - tif->tif_flags |= TIFF_BEENWRITING; + _TIFFFillStriles(tif); - if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 && - !(tif->tif_flags & TIFF_DIRTYDIRECT) ) - { - TIFFForceStrileArrayWriting(tif); - } + /* + * On the first write verify all the required information + * has been setup and initialize any data structures that + * had to wait until directory information was set. + * Note that a lot of our work is assumed to remain valid + * because we disallow any of the important parameters + * from changing after we start writing (i.e. once + * TIFF_BEENWRITING is set, TIFFSetField will only allow + * the image's length to be changed). + */ + if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) + { + TIFFErrorExtR(tif, module, + "Must set \"ImageWidth\" before writing data"); + return (0); + } + if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) + { + tif->tif_dir.td_nstrips = 0; + TIFFErrorExtR(tif, module, "No space for %s arrays", + isTiled(tif) ? "tile" : "strip"); + return (0); + } + if (isTiled(tif)) + { + tif->tif_tilesize = TIFFTileSize(tif); + if (tif->tif_tilesize == 0) + return (0); + } + else + tif->tif_tilesize = (tmsize_t)(-1); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + if (tif->tif_scanlinesize == 0) + return (0); + tif->tif_flags |= TIFF_BEENWRITING; - return (1); + if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && + tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 && + !(tif->tif_flags & TIFF_DIRTYDIRECT)) + { + TIFFForceStrileArrayWriting(tif); + } + + return (1); } /* * Setup the raw data buffer used for encoding. */ -int -TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size) +int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size) { - static const char module[] = "TIFFWriteBufferSetup"; + static const char module[] = "TIFFWriteBufferSetup"; - if (tif->tif_rawdata) { - if (tif->tif_flags & TIFF_MYBUFFER) { - _TIFFfree(tif->tif_rawdata); - tif->tif_flags &= ~TIFF_MYBUFFER; - } - tif->tif_rawdata = NULL; - } - if (size == (tmsize_t)(-1)) { - size = (isTiled(tif) ? - tif->tif_tilesize : TIFFStripSize(tif)); + if (tif->tif_rawdata) + { + if (tif->tif_flags & TIFF_MYBUFFER) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_flags &= ~TIFF_MYBUFFER; + } + tif->tif_rawdata = NULL; + } + if (size == (tmsize_t)(-1)) + { + size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif)); - /* Adds 10% margin for cases where compression would expand a bit */ - if( size < TIFF_TMSIZE_T_MAX - size / 10 ) - size += size / 10; - /* - * Make raw data buffer at least 8K - */ - if (size < 8*1024) - size = 8*1024; - bp = NULL; /* NB: force malloc */ - } - if (bp == NULL) { - bp = _TIFFmalloc(size); - if (bp == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer"); - return (0); - } - tif->tif_flags |= TIFF_MYBUFFER; - } else - tif->tif_flags &= ~TIFF_MYBUFFER; - tif->tif_rawdata = (uint8*) bp; - tif->tif_rawdatasize = size; - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - tif->tif_flags |= TIFF_BUFFERSETUP; - return (1); + /* Adds 10% margin for cases where compression would expand a bit */ + if (size < TIFF_TMSIZE_T_MAX - size / 10) + size += size / 10; + /* + * Make raw data buffer at least 8K + */ + if (size < 8 * 1024) + size = 8 * 1024; + bp = NULL; /* NB: force malloc */ + } + if (bp == NULL) + { + bp = _TIFFmallocExt(tif, size); + if (bp == NULL) + { + TIFFErrorExtR(tif, module, "No space for output buffer"); + return (0); + } + tif->tif_flags |= TIFF_MYBUFFER; + } + else + tif->tif_flags &= ~TIFF_MYBUFFER; + tif->tif_rawdata = (uint8_t *)bp; + tif->tif_rawdatasize = size; + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + tif->tif_flags |= TIFF_BUFFERSETUP; + return (1); } /* * Grow the strip data structures by delta strips. */ -static int -TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module) +static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module) { - TIFFDirectory *td = &tif->tif_dir; - uint64* new_stripoffset; - uint64* new_stripbytecount; + TIFFDirectory *td = &tif->tif_dir; + uint64_t *new_stripoffset; + uint64_t *new_stripbytecount; - assert(td->td_planarconfig == PLANARCONFIG_CONTIG); - new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset_p, - (td->td_nstrips + delta) * sizeof (uint64)); - new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount_p, - (td->td_nstrips + delta) * sizeof (uint64)); - if (new_stripoffset == NULL || new_stripbytecount == NULL) { - if (new_stripoffset) - _TIFFfree(new_stripoffset); - if (new_stripbytecount) - _TIFFfree(new_stripbytecount); - td->td_nstrips = 0; - TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays"); - return (0); - } - td->td_stripoffset_p = new_stripoffset; - td->td_stripbytecount_p = new_stripbytecount; - _TIFFmemset(td->td_stripoffset_p + td->td_nstrips, - 0, delta*sizeof (uint64)); - _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, - 0, delta*sizeof (uint64)); - td->td_nstrips += delta; - tif->tif_flags |= TIFF_DIRTYDIRECT; + assert(td->td_planarconfig == PLANARCONFIG_CONTIG); + new_stripoffset = (uint64_t *)_TIFFreallocExt( + tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t)); + new_stripbytecount = (uint64_t *)_TIFFreallocExt( + tif, td->td_stripbytecount_p, + (td->td_nstrips + delta) * sizeof(uint64_t)); + if (new_stripoffset == NULL || new_stripbytecount == NULL) + { + if (new_stripoffset) + _TIFFfreeExt(tif, new_stripoffset); + if (new_stripbytecount) + _TIFFfreeExt(tif, new_stripbytecount); + td->td_nstrips = 0; + TIFFErrorExtR(tif, module, "No space to expand strip arrays"); + return (0); + } + td->td_stripoffset_p = new_stripoffset; + td->td_stripbytecount_p = new_stripbytecount; + _TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0, + delta * sizeof(uint64_t)); + _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0, + delta * sizeof(uint64_t)); + td->td_nstrips += delta; + tif->tif_flags |= TIFF_DIRTYDIRECT; - return (1); + return (1); } /* * Append the data to the specified strip. */ -static int -TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc) +static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, + tmsize_t cc) { - static const char module[] = "TIFFAppendToStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint64 m; - int64 old_byte_count = -1; + static const char module[] = "TIFFAppendToStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t m; + int64_t old_byte_count = -1; - if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) { - assert(td->td_nstrips > 0); + if (tif->tif_curoff == 0) + tif->tif_lastvalidoff = 0; - if( td->td_stripbytecount_p[strip] != 0 - && td->td_stripoffset_p[strip] != 0 - && td->td_stripbytecount_p[strip] >= (uint64) cc ) - { - /* - * There is already tile data on disk, and the new tile - * data we have will fit in the same space. The only - * aspect of this that is risky is that there could be - * more data to append to this strip before we are done - * depending on how we are getting called. - */ - if (!SeekOK(tif, td->td_stripoffset_p[strip])) { - TIFFErrorExt(tif->tif_clientdata, module, - "Seek error at scanline %lu", - (unsigned long)tif->tif_row); - return (0); - } - } - else - { - /* - * Seek to end of file, and set that as our location to - * write this strip. - */ - td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END); - tif->tif_flags |= TIFF_DIRTYSTRIP; - } - - tif->tif_curoff = td->td_stripoffset_p[strip]; + if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) + { + assert(td->td_nstrips > 0); + if (td->td_stripbytecount_p[strip] != 0 && + td->td_stripoffset_p[strip] != 0 && + td->td_stripbytecount_p[strip] >= (uint64_t)cc) + { /* - * We are starting a fresh strip/tile, so set the size to zero. + * There is already tile data on disk, and the new tile + * data we have will fit in the same space. The only + * aspect of this that is risky is that there could be + * more data to append to this strip before we are done + * depending on how we are getting called. */ - old_byte_count = td->td_stripbytecount_p[strip]; - td->td_stripbytecount_p[strip] = 0; - } + if (!SeekOK(tif, td->td_stripoffset_p[strip])) + { + TIFFErrorExtR(tif, module, "Seek error at scanline %lu", + (unsigned long)tif->tif_row); + return (0); + } - m = tif->tif_curoff+cc; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - m = (uint32)m; - if ((mtif_curoff)||(m<(uint64)cc)) - { - TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded"); - return (0); - } - if (!WriteOK(tif, data, cc)) { - TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu", - (unsigned long) tif->tif_row); - return (0); - } - tif->tif_curoff = m; - td->td_stripbytecount_p[strip] += cc; - - if( (int64) td->td_stripbytecount_p[strip] != old_byte_count ) + tif->tif_lastvalidoff = + td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip]; + } + else + { + /* + * Seek to end of file, and set that as our location to + * write this strip. + */ + td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END); tif->tif_flags |= TIFF_DIRTYSTRIP; - - return (1); + } + + tif->tif_curoff = td->td_stripoffset_p[strip]; + + /* + * We are starting a fresh strip/tile, so set the size to zero. + */ + old_byte_count = td->td_stripbytecount_p[strip]; + td->td_stripbytecount_p[strip] = 0; + } + + m = tif->tif_curoff + cc; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + m = (uint32_t)m; + if ((m < tif->tif_curoff) || (m < (uint64_t)cc)) + { + TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); + return (0); + } + + if (tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff && + td->td_stripbytecount_p[strip] > 0) + { + /* Ouch: we have detected that we are rewriting in place a strip/tile */ + /* with several calls to TIFFAppendToStrip(). The first call was with */ + /* a size smaller than the previous size of the strip/tile, so we */ + /* opted to rewrite in place, but a following call causes us to go */ + /* outsize of the strip/tile area, so we have to finally go for a */ + /* append-at-end-of-file strategy, and start by moving what we already + */ + /* wrote. */ + tmsize_t tempSize; + void *temp; + uint64_t offsetRead; + uint64_t offsetWrite; + uint64_t toCopy = td->td_stripbytecount_p[strip]; + + if (toCopy < 1024 * 1024) + tempSize = (tmsize_t)toCopy; + else + tempSize = 1024 * 1024; + + offsetRead = td->td_stripoffset_p[strip]; + offsetWrite = TIFFSeekFile(tif, 0, SEEK_END); + + m = offsetWrite + toCopy + cc; + if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m) + { + TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); + return (0); + } + + temp = _TIFFmallocExt(tif, tempSize); + if (temp == NULL) + { + TIFFErrorExtR(tif, module, "No space for output buffer"); + return (0); + } + + tif->tif_flags |= TIFF_DIRTYSTRIP; + + td->td_stripoffset_p[strip] = offsetWrite; + td->td_stripbytecount_p[strip] = 0; + + /* Move data written by previous calls to us at end of file */ + while (toCopy > 0) + { + if (!SeekOK(tif, offsetRead)) + { + TIFFErrorExtR(tif, module, "Seek error"); + _TIFFfreeExt(tif, temp); + return (0); + } + if (!ReadOK(tif, temp, tempSize)) + { + TIFFErrorExtR(tif, module, "Cannot read"); + _TIFFfreeExt(tif, temp); + return (0); + } + if (!SeekOK(tif, offsetWrite)) + { + TIFFErrorExtR(tif, module, "Seek error"); + _TIFFfreeExt(tif, temp); + return (0); + } + if (!WriteOK(tif, temp, tempSize)) + { + TIFFErrorExtR(tif, module, "Cannot write"); + _TIFFfreeExt(tif, temp); + return (0); + } + offsetRead += tempSize; + offsetWrite += tempSize; + td->td_stripbytecount_p[strip] += tempSize; + toCopy -= tempSize; + } + _TIFFfreeExt(tif, temp); + + /* Append the data of this call */ + offsetWrite += cc; + m = offsetWrite; + } + + if (!WriteOK(tif, data, cc)) + { + TIFFErrorExtR(tif, module, "Write error at scanline %lu", + (unsigned long)tif->tif_row); + return (0); + } + tif->tif_curoff = m; + td->td_stripbytecount_p[strip] += cc; + + if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count) + tif->tif_flags |= TIFF_DIRTYSTRIP; + + return (1); } /* @@ -810,29 +923,28 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc) * called by ``encodestrip routines'' w/o concern * for infinite recursion. */ -int -TIFFFlushData1(TIFF* tif) +int TIFFFlushData1(TIFF *tif) { - if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) { - if (!isFillOrder(tif, tif->tif_dir.td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8*)tif->tif_rawdata, - tif->tif_rawcc); - if (!TIFFAppendToStrip(tif, - isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, - tif->tif_rawdata, tif->tif_rawcc)) + if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE) + { + if (!isFillOrder(tif, tif->tif_dir.td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc); + if (!TIFFAppendToStrip( + tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, + tif->tif_rawdata, tif->tif_rawcc)) { /* We update those variables even in case of error since there's */ /* code that doesn't really check the return code of this */ /* function */ tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; - return (0); + return (0); } - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - } - return (1); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + } + return (1); } /* @@ -841,17 +953,8 @@ TIFFFlushData1(TIFF* tif) * (very carefully), or to 0 so that the next write gets * appended to the end of the file. */ -void -TIFFSetWriteOffset(TIFF* tif, toff_t off) +void TIFFSetWriteOffset(TIFF *tif, toff_t off) { - tif->tif_curoff = off; + tif->tif_curoff = off; + tif->tif_lastvalidoff = 0; } - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_zip.c b/3rdparty/libtiff/tif_zip.c index e71c312c80..fcf510044c 100644 --- a/3rdparty/libtiff/tif_zip.c +++ b/3rdparty/libtiff/tif_zip.c @@ -2,23 +2,23 @@ * Copyright (c) 1995-1997 Sam Leffler * Copyright (c) 1995-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -57,644 +57,675 @@ #error "Antiquated ZLIB software; you must use version 1.0 or later" #endif -#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg) +#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg) /* * State block for each open TIFF * file using ZIP compression/decompression. */ -typedef struct { - TIFFPredictorState predict; - z_stream stream; - int zipquality; /* compression level */ - int state; /* state flags */ - int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */ +typedef struct +{ + TIFFPredictorState predict; + z_stream stream; + int zipquality; /* compression level */ + int state; /* state flags */ + int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */ #if LIBDEFLATE_SUPPORT - int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is called, 0 = use zlib, 1 = use libdeflate */ - struct libdeflate_decompressor* libdeflate_dec; - struct libdeflate_compressor* libdeflate_enc; + int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is + called, 0 = use zlib, 1 = use libdeflate */ + struct libdeflate_decompressor *libdeflate_dec; + struct libdeflate_compressor *libdeflate_enc; #endif #define ZSTATE_INIT_DECODE 0x01 #define ZSTATE_INIT_ENCODE 0x02 - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } ZIPState; -#define ZState(tif) ((ZIPState*) (tif)->tif_data) -#define DecoderState(tif) ZState(tif) -#define EncoderState(tif) ZState(tif) +#define ZState(tif) ((ZIPState *)(tif)->tif_data) +#define DecoderState(tif) ZState(tif) +#define EncoderState(tif) ZState(tif) -static int ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); -static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); +static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -static int -ZIPFixupTags(TIFF* tif) +static int ZIPFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } -static int -ZIPSetupDecode(TIFF* tif) +static int ZIPSetupDecode(TIFF *tif) { - static const char module[] = "ZIPSetupDecode"; - ZIPState* sp = DecoderState(tif); + static const char module[] = "ZIPSetupDecode"; + ZIPState *sp = DecoderState(tif); - assert(sp != NULL); - - /* if we were last encoding, terminate this mode */ - if (sp->state & ZSTATE_INIT_ENCODE) { - deflateEnd(&sp->stream); - sp->state = 0; - } + assert(sp != NULL); - /* This function can possibly be called several times by */ - /* PredictorSetupDecode() if this function succeeds but */ - /* PredictorSetup() fails */ - if ((sp->state & ZSTATE_INIT_DECODE) == 0 && - inflateInit(&sp->stream) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp)); - return (0); - } else { - sp->state |= ZSTATE_INIT_DECODE; - return (1); - } + /* if we were last encoding, terminate this mode */ + if (sp->state & ZSTATE_INIT_ENCODE) + { + deflateEnd(&sp->stream); + sp->state = 0; + } + + /* This function can possibly be called several times by */ + /* PredictorSetupDecode() if this function succeeds but */ + /* PredictorSetup() fails */ + if ((sp->state & ZSTATE_INIT_DECODE) == 0 && + inflateInit(&sp->stream) != Z_OK) + { + TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp)); + return (0); + } + else + { + sp->state |= ZSTATE_INIT_DECODE; + return (1); + } } /* * Setup state for decoding a strip. */ -static int -ZIPPreDecode(TIFF* tif, uint16 s) +static int ZIPPreDecode(TIFF *tif, uint16_t s) { - ZIPState* sp = DecoderState(tif); + ZIPState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); + (void)s; + assert(sp != NULL); - if( (sp->state & ZSTATE_INIT_DECODE) == 0 ) - tif->tif_setupdecode( tif ); + if ((sp->state & ZSTATE_INIT_DECODE) == 0) + tif->tif_setupdecode(tif); #if LIBDEFLATE_SUPPORT - sp->libdeflate_state = -1; + sp->libdeflate_state = -1; #endif - sp->stream.next_in = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_in = (uint64)tif->tif_rawcc < 0xFFFFFFFFU ? (uInt) tif->tif_rawcc : 0xFFFFFFFFU; - return (inflateReset(&sp->stream) == Z_OK); + sp->stream.next_in = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU + ? (uInt)tif->tif_rawcc + : 0xFFFFFFFFU; + return (inflateReset(&sp->stream) == Z_OK); } -static int -ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "ZIPDecode"; - ZIPState* sp = DecoderState(tif); + static const char module[] = "ZIPDecode"; + ZIPState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); - assert(sp->state == ZSTATE_INIT_DECODE); + (void)s; + assert(sp != NULL); + assert(sp->state == ZSTATE_INIT_DECODE); #if LIBDEFLATE_SUPPORT - if( sp->libdeflate_state == 1 ) - return 0; + if (sp->libdeflate_state == 1) + return 0; - /* If we have libdeflate support and we are asked to read a whole */ - /* strip/tile, then go for using it */ - do { - TIFFDirectory *td = &tif->tif_dir; + /* If we have libdeflate support and we are asked to read a whole */ + /* strip/tile, then go for using it */ + do + { + TIFFDirectory *td = &tif->tif_dir; - if( sp->libdeflate_state == 0 ) + if (sp->libdeflate_state == 0) + break; + if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB) + break; + + /* Check if we are in the situation where we can use libdeflate */ + if (isTiled(tif)) + { + if (TIFFTileSize64(tif) != (uint64_t)occ) break; - if( sp->subcodec == DEFLATE_SUBCODEC_ZLIB ) + } + else + { + uint32_t strip_height = td->td_imagelength - tif->tif_row; + if (strip_height > td->td_rowsperstrip) + strip_height = td->td_rowsperstrip; + if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ) break; + } - /* Check if we are in the situation where we can use libdeflate */ - if (isTiled(tif)) { - if( TIFFTileSize64(tif) != (uint64)occ ) - break; - } else { - uint32 strip_height = td->td_imagelength - tif->tif_row; - if (strip_height > td->td_rowsperstrip) - strip_height = td->td_rowsperstrip; - if( TIFFVStripSize64(tif, strip_height) != (uint64)occ ) - break; - } + /* Check for overflow */ + if ((size_t)tif->tif_rawcc != (uint64_t)tif->tif_rawcc) + break; + if ((size_t)occ != (uint64_t)occ) + break; - /* Check for overflow */ - if( (size_t)tif->tif_rawcc != (uint64)tif->tif_rawcc ) - break; - if( (size_t)occ != (uint64)occ ) - break; - - /* Go for decompression using libdeflate */ + /* Go for decompression using libdeflate */ + { + enum libdeflate_result res; + if (sp->libdeflate_dec == NULL) { - enum libdeflate_result res; - if( sp->libdeflate_dec == NULL ) + sp->libdeflate_dec = libdeflate_alloc_decompressor(); + if (sp->libdeflate_dec == NULL) { - sp->libdeflate_dec = libdeflate_alloc_decompressor(); - if( sp->libdeflate_dec == NULL ) - { - break; - } + break; } - - sp->libdeflate_state = 1; - - res = libdeflate_zlib_decompress( - sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc, op, (size_t)occ, NULL); - - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; - - /* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */ - /* There are odd files in the wild where the last strip, when */ - /* it is smaller in height than td_rowsperstrip, actually contains */ - /* data for td_rowsperstrip lines. Just ignore that silently. */ - if( res != LIBDEFLATE_SUCCESS && - res != LIBDEFLATE_INSUFFICIENT_SPACE ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Decoding error at scanline %lu", - (unsigned long) tif->tif_row); - return 0; - } - - return 1; } - } while(0); - sp->libdeflate_state = 0; + + sp->libdeflate_state = 1; + + res = libdeflate_zlib_decompress(sp->libdeflate_dec, tif->tif_rawcp, + (size_t)tif->tif_rawcc, op, + (size_t)occ, NULL); + + tif->tif_rawcp += tif->tif_rawcc; + tif->tif_rawcc = 0; + + /* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */ + /* There are odd files in the wild where the last strip, when */ + /* it is smaller in height than td_rowsperstrip, actually contains + */ + /* data for td_rowsperstrip lines. Just ignore that silently. */ + if (res != LIBDEFLATE_SUCCESS && + res != LIBDEFLATE_INSUFFICIENT_SPACE) + { + TIFFErrorExtR(tif, module, "Decoding error at scanline %lu", + (unsigned long)tif->tif_row); + return 0; + } + + return 1; + } + } while (0); + sp->libdeflate_state = 0; #endif /* LIBDEFLATE_SUPPORT */ - sp->stream.next_in = tif->tif_rawcp; - - sp->stream.next_out = op; - assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - do { - int state; - uInt avail_in_before = (uint64)tif->tif_rawcc <= 0xFFFFFFFFU ? (uInt)tif->tif_rawcc : 0xFFFFFFFFU; - uInt avail_out_before = (uint64)occ < 0xFFFFFFFFU ? (uInt) occ : 0xFFFFFFFFU; - sp->stream.avail_in = avail_in_before; - sp->stream.avail_out = avail_out_before; - state = inflate(&sp->stream, Z_PARTIAL_FLUSH); - tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in); - occ -= (avail_out_before - sp->stream.avail_out); - if (state == Z_STREAM_END) - break; - if (state == Z_DATA_ERROR) { - TIFFErrorExt(tif->tif_clientdata, module, - "Decoding error at scanline %lu, %s", - (unsigned long) tif->tif_row, SAFE_MSG(sp)); - return (0); - } - if (state != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, - "ZLib error: %s", SAFE_MSG(sp)); - return (0); - } - } while (occ > 0); - if (occ != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", - (unsigned long) tif->tif_row, (TIFF_UINT64_T) occ); - return (0); - } + sp->stream.next_in = tif->tif_rawcp; - tif->tif_rawcp = sp->stream.next_in; + sp->stream.next_out = op; + assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + do + { + int state; + uInt avail_in_before = (uint64_t)tif->tif_rawcc <= 0xFFFFFFFFU + ? (uInt)tif->tif_rawcc + : 0xFFFFFFFFU; + uInt avail_out_before = + (uint64_t)occ < 0xFFFFFFFFU ? (uInt)occ : 0xFFFFFFFFU; + sp->stream.avail_in = avail_in_before; + sp->stream.avail_out = avail_out_before; + /* coverity[overrun-buffer-arg] */ + state = inflate(&sp->stream, Z_PARTIAL_FLUSH); + tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in); + occ -= (avail_out_before - sp->stream.avail_out); + if (state == Z_STREAM_END) + break; + if (state == Z_DATA_ERROR) + { + TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s", + (unsigned long)tif->tif_row, SAFE_MSG(sp)); + return (0); + } + if (state != Z_OK) + { + TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp)); + return (0); + } + } while (occ > 0); + if (occ != 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %lu (short %" PRIu64 + " bytes)", + (unsigned long)tif->tif_row, (uint64_t)occ); + return (0); + } - return (1); + tif->tif_rawcp = sp->stream.next_in; + + return (1); } -static int -ZIPSetupEncode(TIFF* tif) +static int ZIPSetupEncode(TIFF *tif) { - static const char module[] = "ZIPSetupEncode"; - ZIPState* sp = EncoderState(tif); - int cappedQuality; + static const char module[] = "ZIPSetupEncode"; + ZIPState *sp = EncoderState(tif); + int cappedQuality; - assert(sp != NULL); - if (sp->state & ZSTATE_INIT_DECODE) { - inflateEnd(&sp->stream); - sp->state = 0; - } + assert(sp != NULL); + if (sp->state & ZSTATE_INIT_DECODE) + { + inflateEnd(&sp->stream); + sp->state = 0; + } - cappedQuality = sp->zipquality; - if( cappedQuality > Z_BEST_COMPRESSION ) - cappedQuality = Z_BEST_COMPRESSION; + cappedQuality = sp->zipquality; + if (cappedQuality > Z_BEST_COMPRESSION) + cappedQuality = Z_BEST_COMPRESSION; - if (deflateInit(&sp->stream, cappedQuality) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp)); - return (0); - } else { - sp->state |= ZSTATE_INIT_ENCODE; - return (1); - } + if (deflateInit(&sp->stream, cappedQuality) != Z_OK) + { + TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp)); + return (0); + } + else + { + sp->state |= ZSTATE_INIT_ENCODE; + return (1); + } } /* * Reset encoding state at the start of a strip. */ -static int -ZIPPreEncode(TIFF* tif, uint16 s) +static int ZIPPreEncode(TIFF *tif, uint16_t s) { - ZIPState *sp = EncoderState(tif); + ZIPState *sp = EncoderState(tif); - (void) s; - assert(sp != NULL); - if( sp->state != ZSTATE_INIT_ENCODE ) - tif->tif_setupencode( tif ); + (void)s; + assert(sp != NULL); + if (sp->state != ZSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); #if LIBDEFLATE_SUPPORT - sp->libdeflate_state = -1; + sp->libdeflate_state = -1; #endif - sp->stream.next_out = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU; - return (deflateReset(&sp->stream) == Z_OK); + sp->stream.next_out = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU + ? (uInt)tif->tif_rawdatasize + : 0xFFFFFFFFU; + return (deflateReset(&sp->stream) == Z_OK); } /* * Encode a chunk of pixels. */ -static int -ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "ZIPEncode"; - ZIPState *sp = EncoderState(tif); + static const char module[] = "ZIPEncode"; + ZIPState *sp = EncoderState(tif); - assert(sp != NULL); - assert(sp->state == ZSTATE_INIT_ENCODE); + assert(sp != NULL); + assert(sp->state == ZSTATE_INIT_ENCODE); - (void) s; + (void)s; #if LIBDEFLATE_SUPPORT - if( sp->libdeflate_state == 1 ) - return 0; + if (sp->libdeflate_state == 1) + return 0; - /* If we have libdeflate support and we are asked to write a whole */ - /* strip/tile, then go for using it */ - do { - TIFFDirectory *td = &tif->tif_dir; + /* If we have libdeflate support and we are asked to write a whole */ + /* strip/tile, then go for using it */ + do + { + TIFFDirectory *td = &tif->tif_dir; - if( sp->libdeflate_state == 0 ) + if (sp->libdeflate_state == 0) + break; + if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB) + break; + + /* Libdeflate does not support the 0-compression level */ + if (sp->zipquality == Z_NO_COMPRESSION) + break; + + /* Check if we are in the situation where we can use libdeflate */ + if (isTiled(tif)) + { + if (TIFFTileSize64(tif) != (uint64_t)cc) break; - if( sp->subcodec == DEFLATE_SUBCODEC_ZLIB ) + } + else + { + uint32_t strip_height = td->td_imagelength - tif->tif_row; + if (strip_height > td->td_rowsperstrip) + strip_height = td->td_rowsperstrip; + if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc) break; + } - /* Libdeflate does not support the 0-compression level */ - if( sp->zipquality == Z_NO_COMPRESSION ) - break; + /* Check for overflow */ + if ((size_t)tif->tif_rawdatasize != (uint64_t)tif->tif_rawdatasize) + break; + if ((size_t)cc != (uint64_t)cc) + break; - /* Check if we are in the situation where we can use libdeflate */ - if (isTiled(tif)) { - if( TIFFTileSize64(tif) != (uint64)cc ) - break; - } else { - uint32 strip_height = td->td_imagelength - tif->tif_row; - if (strip_height > td->td_rowsperstrip) - strip_height = td->td_rowsperstrip; - if( TIFFVStripSize64(tif, strip_height) != (uint64)cc ) - break; - } - - /* Check for overflow */ - if( (size_t)tif->tif_rawdatasize != (uint64)tif->tif_rawdatasize ) - break; - if( (size_t)cc != (uint64)cc ) - break; - - /* Go for compression using libdeflate */ + /* Go for compression using libdeflate */ + { + size_t nCompressedBytes; + if (sp->libdeflate_enc == NULL) { - size_t nCompressedBytes; - if( sp->libdeflate_enc == NULL ) - { - /* To get results as good as zlib, we asked for an extra */ - /* level of compression */ - sp->libdeflate_enc = libdeflate_alloc_compressor( - sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 : - sp->zipquality >= 6 && sp->zipquality <= 9 ? sp->zipquality + 1 : - sp->zipquality); - if( sp->libdeflate_enc == NULL ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot allocate compressor"); - break; - } - } - - /* Make sure the output buffer is large enough for the worse case. */ - /* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */ - /* we've taken a 10% margin over the uncompressed size, which should */ - /* be large enough even for the the worse case scenario. */ - if( libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) > - (size_t)tif->tif_rawdatasize) + /* To get results as good as zlib, we asked for an extra */ + /* level of compression */ + sp->libdeflate_enc = libdeflate_alloc_compressor( + sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 + : sp->zipquality >= 6 && sp->zipquality <= 9 + ? sp->zipquality + 1 + : sp->zipquality); + if (sp->libdeflate_enc == NULL) { + TIFFErrorExtR(tif, module, "Cannot allocate compressor"); break; } - - sp->libdeflate_state = 1; - nCompressedBytes = libdeflate_zlib_compress( - sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata, (size_t)tif->tif_rawdatasize); - - if( nCompressedBytes == 0 ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Encoder error at scanline %lu", - (unsigned long) tif->tif_row); - return 0; - } - - tif->tif_rawcc = nCompressedBytes; - - if( !TIFFFlushData1(tif) ) - return 0; - - return 1; } - } while(0); - sp->libdeflate_state = 0; + + /* Make sure the output buffer is large enough for the worse case. + */ + /* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */ + /* we've taken a 10% margin over the uncompressed size, which should + */ + /* be large enough even for the the worse case scenario. */ + if (libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) > + (size_t)tif->tif_rawdatasize) + { + break; + } + + sp->libdeflate_state = 1; + nCompressedBytes = libdeflate_zlib_compress( + sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata, + (size_t)tif->tif_rawdatasize); + + if (nCompressedBytes == 0) + { + TIFFErrorExtR(tif, module, "Encoder error at scanline %lu", + (unsigned long)tif->tif_row); + return 0; + } + + tif->tif_rawcc = nCompressedBytes; + + if (!TIFFFlushData1(tif)) + return 0; + + return 1; + } + } while (0); + sp->libdeflate_state = 0; #endif /* LIBDEFLATE_SUPPORT */ - sp->stream.next_in = bp; - assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - do { - uInt avail_in_before = (uint64)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU; - sp->stream.avail_in = avail_in_before; - if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, - "Encoder error: %s", - SAFE_MSG(sp)); - return (0); - } - if (sp->stream.avail_out == 0) { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU; - } - cc -= (avail_in_before - sp->stream.avail_in); - } while (cc > 0); - return (1); + sp->stream.next_in = bp; + assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + do + { + uInt avail_in_before = + (uint64_t)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU; + sp->stream.avail_in = avail_in_before; + /* coverity[overrun-buffer-arg] */ + if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) + { + TIFFErrorExtR(tif, module, "Encoder error: %s", SAFE_MSG(sp)); + return (0); + } + if (sp->stream.avail_out == 0) + { + tif->tif_rawcc = tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU + ? (uInt)tif->tif_rawdatasize + : 0xFFFFFFFFU; + } + cc -= (avail_in_before - sp->stream.avail_in); + } while (cc > 0); + return (1); } /* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ -static int -ZIPPostEncode(TIFF* tif) +static int ZIPPostEncode(TIFF *tif) { - static const char module[] = "ZIPPostEncode"; - ZIPState *sp = EncoderState(tif); - int state; + static const char module[] = "ZIPPostEncode"; + ZIPState *sp = EncoderState(tif); + int state; #if LIBDEFLATE_SUPPORT - if( sp->libdeflate_state == 1 ) - return 1; + if (sp->libdeflate_state == 1) + return 1; #endif - sp->stream.avail_in = 0; - do { - state = deflate(&sp->stream, Z_FINISH); - switch (state) { - case Z_STREAM_END: - case Z_OK: - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) - { - tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU; - } - break; - default: - TIFFErrorExt(tif->tif_clientdata, module, - "ZLib error: %s", SAFE_MSG(sp)); - return (0); - } - } while (state != Z_STREAM_END); - return (1); -} - -static void -ZIPCleanup(TIFF* tif) -{ - ZIPState* sp = ZState(tif); - - assert(sp != 0); - - (void)TIFFPredictorCleanup(tif); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->state & ZSTATE_INIT_ENCODE) { - deflateEnd(&sp->stream); - sp->state = 0; - } else if( sp->state & ZSTATE_INIT_DECODE) { - inflateEnd(&sp->stream); - sp->state = 0; - } - -#if LIBDEFLATE_SUPPORT - if( sp->libdeflate_dec ) - libdeflate_free_decompressor(sp->libdeflate_dec); - if( sp->libdeflate_enc ) - libdeflate_free_compressor(sp->libdeflate_enc); -#endif - - _TIFFfree(sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static int -ZIPVSetField(TIFF* tif, uint32 tag, va_list ap) -{ - static const char module[] = "ZIPVSetField"; - ZIPState* sp = ZState(tif); - - switch (tag) { - case TIFFTAG_ZIPQUALITY: - sp->zipquality = (int) va_arg(ap, int); - if( sp->zipquality < Z_DEFAULT_COMPRESSION || - sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Invalid ZipQuality value. Should be in [-1,%d] range", - LIBDEFLATE_MAX_COMPRESSION_LEVEL); - return 0; - } - - if ( sp->state&ZSTATE_INIT_ENCODE ) { - int cappedQuality = sp->zipquality; - if( cappedQuality > Z_BEST_COMPRESSION ) - cappedQuality = Z_BEST_COMPRESSION; - if (deflateParams(&sp->stream, - cappedQuality, Z_DEFAULT_STRATEGY) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", - SAFE_MSG(sp)); - return (0); - } - } - -#if LIBDEFLATE_SUPPORT - if( sp->libdeflate_enc ) + sp->stream.avail_in = 0; + do + { + state = deflate(&sp->stream, Z_FINISH); + switch (state) + { + case Z_STREAM_END: + case Z_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { - libdeflate_free_compressor(sp->libdeflate_enc); - sp->libdeflate_enc = NULL; + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU + ? (uInt)tif->tif_rawdatasize + : 0xFFFFFFFFU; } + break; + default: + TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp)); + return (0); + } + } while (state != Z_STREAM_END); + return (1); +} + +static void ZIPCleanup(TIFF *tif) +{ + ZIPState *sp = ZState(tif); + + assert(sp != 0); + + (void)TIFFPredictorCleanup(tif); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->state & ZSTATE_INIT_ENCODE) + { + deflateEnd(&sp->stream); + sp->state = 0; + } + else if (sp->state & ZSTATE_INIT_DECODE) + { + inflateEnd(&sp->stream); + sp->state = 0; + } + +#if LIBDEFLATE_SUPPORT + if (sp->libdeflate_dec) + libdeflate_free_decompressor(sp->libdeflate_dec); + if (sp->libdeflate_enc) + libdeflate_free_compressor(sp->libdeflate_enc); #endif - return (1); + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap) +{ + static const char module[] = "ZIPVSetField"; + ZIPState *sp = ZState(tif); + + switch (tag) + { + case TIFFTAG_ZIPQUALITY: + sp->zipquality = (int)va_arg(ap, int); + if (sp->zipquality < Z_DEFAULT_COMPRESSION || + sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL) + { + TIFFErrorExtR( + tif, module, + "Invalid ZipQuality value. Should be in [-1,%d] range", + LIBDEFLATE_MAX_COMPRESSION_LEVEL); + return 0; + } + + if (sp->state & ZSTATE_INIT_ENCODE) + { + int cappedQuality = sp->zipquality; + if (cappedQuality > Z_BEST_COMPRESSION) + cappedQuality = Z_BEST_COMPRESSION; + if (deflateParams(&sp->stream, cappedQuality, + Z_DEFAULT_STRATEGY) != Z_OK) + { + TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp)); + return (0); + } + } + +#if LIBDEFLATE_SUPPORT + if (sp->libdeflate_enc) + { + libdeflate_free_compressor(sp->libdeflate_enc); + sp->libdeflate_enc = NULL; + } +#endif + + return (1); case TIFFTAG_DEFLATE_SUBCODEC: - sp->subcodec = (int) va_arg(ap, int); - if( sp->subcodec != DEFLATE_SUBCODEC_ZLIB && - sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Invalid DeflateCodec value."); - return 0; - } + sp->subcodec = (int)va_arg(ap, int); + if (sp->subcodec != DEFLATE_SUBCODEC_ZLIB && + sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE) + { + TIFFErrorExtR(tif, module, "Invalid DeflateCodec value."); + return 0; + } #if !LIBDEFLATE_SUPPORT - if( sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE unsupported in this build"); - return 0; - } + if (sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE) + { + TIFFErrorExtR(tif, module, + "DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE " + "unsupported in this build"); + return 0; + } #endif - return 1; + return 1; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ } -static int -ZIPVGetField(TIFF* tif, uint32 tag, va_list ap) +static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap) { - ZIPState* sp = ZState(tif); + ZIPState *sp = ZState(tif); - switch (tag) { - case TIFFTAG_ZIPQUALITY: - *va_arg(ap, int*) = sp->zipquality; - break; + switch (tag) + { + case TIFFTAG_ZIPQUALITY: + *va_arg(ap, int *) = sp->zipquality; + break; case TIFFTAG_DEFLATE_SUBCODEC: - *va_arg(ap, int*) = sp->subcodec; - break; + *va_arg(ap, int *) = sp->subcodec; + break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); } static const TIFFField zipFields[] = { - { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, - { TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, + {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, + {TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, }; -int -TIFFInitZIP(TIFF* tif, int scheme) +int TIFFInitZIP(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitZIP"; - ZIPState* sp; + static const char module[] = "TIFFInitZIP"; + ZIPState *sp; - assert( (scheme == COMPRESSION_DEFLATE) - || (scheme == COMPRESSION_ADOBE_DEFLATE)); + assert((scheme == COMPRESSION_DEFLATE) || + (scheme == COMPRESSION_ADOBE_DEFLATE)); #ifdef NDEBUG - (void)scheme; + (void)scheme; #endif - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Merging Deflate codec-specific tags failed"); - return 0; - } + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) + { + TIFFErrorExtR(tif, module, + "Merging Deflate codec-specific tags failed"); + return 0; + } - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8*) _TIFFcalloc(sizeof (ZIPState), 1); - if (tif->tif_data == NULL) - goto bad; - sp = ZState(tif); - sp->stream.zalloc = NULL; - sp->stream.zfree = NULL; - sp->stream.opaque = NULL; - sp->stream.data_type = Z_BINARY; + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1); + if (tif->tif_data == NULL) + goto bad; + sp = ZState(tif); + sp->stream.zalloc = NULL; + sp->stream.zfree = NULL; + sp->stream.opaque = NULL; + sp->stream.data_type = Z_BINARY; - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */ + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */ - /* Default values for codec-specific fields */ - sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ - sp->state = 0; + /* Default values for codec-specific fields */ + sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; #if LIBDEFLATE_SUPPORT - sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE; + sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE; #else - sp->subcodec = DEFLATE_SUBCODEC_ZLIB; + sp->subcodec = DEFLATE_SUBCODEC_ZLIB; #endif - /* - * Install codec methods. - */ - tif->tif_fixuptags = ZIPFixupTags; - tif->tif_setupdecode = ZIPSetupDecode; - tif->tif_predecode = ZIPPreDecode; - tif->tif_decoderow = ZIPDecode; - tif->tif_decodestrip = ZIPDecode; - tif->tif_decodetile = ZIPDecode; - tif->tif_setupencode = ZIPSetupEncode; - tif->tif_preencode = ZIPPreEncode; - tif->tif_postencode = ZIPPostEncode; - tif->tif_encoderow = ZIPEncode; - tif->tif_encodestrip = ZIPEncode; - tif->tif_encodetile = ZIPEncode; - tif->tif_cleanup = ZIPCleanup; - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - return (1); + /* + * Install codec methods. + */ + tif->tif_fixuptags = ZIPFixupTags; + tif->tif_setupdecode = ZIPSetupDecode; + tif->tif_predecode = ZIPPreDecode; + tif->tif_decoderow = ZIPDecode; + tif->tif_decodestrip = ZIPDecode; + tif->tif_decodetile = ZIPDecode; + tif->tif_setupencode = ZIPSetupEncode; + tif->tif_preencode = ZIPPreEncode; + tif->tif_postencode = ZIPPostEncode; + tif->tif_encoderow = ZIPEncode; + tif->tif_encodestrip = ZIPEncode; + tif->tif_encodetile = ZIPEncode; + tif->tif_cleanup = ZIPCleanup; + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + return (1); bad: - TIFFErrorExt(tif->tif_clientdata, module, - "No space for ZIP state block"); - return (0); + TIFFErrorExtR(tif, module, "No space for ZIP state block"); + return (0); } #endif /* ZIP_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tif_zstd.c b/3rdparty/libtiff/tif_zstd.c index 66135e03c1..646993103d 100644 --- a/3rdparty/libtiff/tif_zstd.c +++ b/3rdparty/libtiff/tif_zstd.c @@ -1,35 +1,35 @@ /* -* Copyright (c) 2017, Planet Labs -* Author: -* -* Permission to use, copy, modify, distribute, and sell this software and -* its documentation for any purpose is hereby granted without fee, provided -* that (i) the above copyright notices and this permission notice appear in -* all copies of the software and related documentation, and (ii) the names of -* Sam Leffler and Silicon Graphics may not be used in any advertising or -* publicity relating to the software without the specific, prior written -* permission of Sam Leffler and Silicon Graphics. -* -* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -* -* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR -* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, -* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF -* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -* OF THIS SOFTWARE. -*/ + * Copyright (c) 2017, Planet Labs + * Author: + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ #include "tiffiop.h" #ifdef ZSTD_SUPPORT /* -* TIFF Library. -* -* ZSTD Compression Support -* -*/ + * TIFF Library. + * + * ZSTD Compression Support + * + */ #include "tif_predict.h" #include "zstd.h" @@ -37,406 +37,400 @@ #include /* -* State block for each open TIFF file using ZSTD compression/decompression. -*/ -typedef struct { - TIFFPredictorState predict; - ZSTD_DStream* dstream; - ZSTD_CStream* cstream; - int compression_level; /* compression level */ - ZSTD_outBuffer out_buffer; - int state; /* state flags */ + * State block for each open TIFF file using ZSTD compression/decompression. + */ +typedef struct +{ + TIFFPredictorState predict; + ZSTD_DStream *dstream; + ZSTD_CStream *cstream; + int compression_level; /* compression level */ + ZSTD_outBuffer out_buffer; + int state; /* state flags */ #define LSTATE_INIT_DECODE 0x01 #define LSTATE_INIT_ENCODE 0x02 - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } ZSTDState; -#define LState(tif) ((ZSTDState*) (tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) +#define LState(tif) ((ZSTDState *)(tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) -static int ZSTDEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); -static int ZSTDDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); +static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -static int -ZSTDFixupTags(TIFF* tif) +static int ZSTDFixupTags(TIFF *tif) { - (void) tif; - return 1; + (void)tif; + return 1; } -static int -ZSTDSetupDecode(TIFF* tif) +static int ZSTDSetupDecode(TIFF *tif) { - ZSTDState* sp = DecoderState(tif); + ZSTDState *sp = DecoderState(tif); - assert(sp != NULL); + assert(sp != NULL); - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) { - ZSTD_freeCStream(sp->cstream); - sp->cstream = NULL; - sp->state = 0; - } + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) + { + ZSTD_freeCStream(sp->cstream); + sp->cstream = NULL; + sp->state = 0; + } - sp->state |= LSTATE_INIT_DECODE; - return 1; + sp->state |= LSTATE_INIT_DECODE; + return 1; } /* -* Setup state for decoding a strip. -*/ -static int -ZSTDPreDecode(TIFF* tif, uint16 s) + * Setup state for decoding a strip. + */ +static int ZSTDPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "ZSTDPreDecode"; - ZSTDState* sp = DecoderState(tif); - size_t zstd_ret; + static const char module[] = "ZSTDPreDecode"; + ZSTDState *sp = DecoderState(tif); + size_t zstd_ret; - (void) s; - assert(sp != NULL); + (void)s; + assert(sp != NULL); - if( (sp->state & LSTATE_INIT_DECODE) == 0 ) - tif->tif_setupdecode(tif); - - if( sp->dstream ) - { - ZSTD_freeDStream(sp->dstream); - sp->dstream = NULL; - } + if ((sp->state & LSTATE_INIT_DECODE) == 0) + tif->tif_setupdecode(tif); + if (sp->dstream == NULL) + { sp->dstream = ZSTD_createDStream(); - if( sp->dstream == NULL ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot allocate decompression stream"); + if (sp->dstream == NULL) + { + TIFFErrorExtR(tif, module, "Cannot allocate decompression stream"); return 0; } - zstd_ret = ZSTD_initDStream(sp->dstream); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error in ZSTD_initDStream(): %s", - ZSTD_getErrorName(zstd_ret)); + } + + zstd_ret = ZSTD_initDStream(sp->dstream); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_initDStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + + return 1; +} + +static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) +{ + static const char module[] = "ZSTDDecode"; + ZSTDState *sp = DecoderState(tif); + ZSTD_inBuffer in_buffer; + ZSTD_outBuffer out_buffer; + size_t zstd_ret; + + (void)s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + in_buffer.src = tif->tif_rawcp; + in_buffer.size = (size_t)tif->tif_rawcc; + in_buffer.pos = 0; + + out_buffer.dst = op; + out_buffer.size = (size_t)occ; + out_buffer.pos = 0; + + do + { + zstd_ret = ZSTD_decompressStream(sp->dstream, &out_buffer, &in_buffer); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_decompressStream(): %s", + ZSTD_getErrorName(zstd_ret)); return 0; } + } while (zstd_ret != 0 && in_buffer.pos < in_buffer.size && + out_buffer.pos < out_buffer.size); - return 1; + if (out_buffer.pos < (size_t)occ) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %lu (short %lu bytes)", + (unsigned long)tif->tif_row, + (unsigned long)((size_t)occ - out_buffer.pos)); + return 0; + } + + tif->tif_rawcp += in_buffer.pos; + tif->tif_rawcc -= in_buffer.pos; + + return 1; } -static int -ZSTDDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +static int ZSTDSetupEncode(TIFF *tif) { - static const char module[] = "ZSTDDecode"; - ZSTDState* sp = DecoderState(tif); - ZSTD_inBuffer in_buffer; - ZSTD_outBuffer out_buffer; - size_t zstd_ret; + ZSTDState *sp = EncoderState(tif); - (void) s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); + assert(sp != NULL); + if (sp->state & LSTATE_INIT_DECODE) + { + ZSTD_freeDStream(sp->dstream); + sp->dstream = NULL; + sp->state = 0; + } - in_buffer.src = tif->tif_rawcp; - in_buffer.size = (size_t) tif->tif_rawcc; - in_buffer.pos = 0; - - out_buffer.dst = op; - out_buffer.size = (size_t) occ; - out_buffer.pos = 0; - - do { - zstd_ret = ZSTD_decompressStream(sp->dstream, &out_buffer, - &in_buffer); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error in ZSTD_decompressStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - } while( zstd_ret != 0 && - in_buffer.pos < in_buffer.size && - out_buffer.pos < out_buffer.size ); - - if (out_buffer.pos < (size_t)occ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %lu (short %lu bytes)", - (unsigned long) tif->tif_row, - (unsigned long) (size_t)occ - out_buffer.pos); - return 0; - } - - tif->tif_rawcp += in_buffer.pos; - tif->tif_rawcc -= in_buffer.pos; - - return 1; -} - -static int -ZSTDSetupEncode(TIFF* tif) -{ - ZSTDState* sp = EncoderState(tif); - - assert(sp != NULL); - if (sp->state & LSTATE_INIT_DECODE) { - ZSTD_freeDStream(sp->dstream); - sp->dstream = NULL; - sp->state = 0; - } - - sp->state |= LSTATE_INIT_ENCODE; - return 1; + sp->state |= LSTATE_INIT_ENCODE; + return 1; } /* -* Reset encoding state at the start of a strip. -*/ -static int -ZSTDPreEncode(TIFF* tif, uint16 s) + * Reset encoding state at the start of a strip. + */ +static int ZSTDPreEncode(TIFF *tif, uint16_t s) { - static const char module[] = "ZSTDPreEncode"; - ZSTDState *sp = EncoderState(tif); - size_t zstd_ret; + static const char module[] = "ZSTDPreEncode"; + ZSTDState *sp = EncoderState(tif); + size_t zstd_ret; - (void) s; - assert(sp != NULL); - if( sp->state != LSTATE_INIT_ENCODE ) - tif->tif_setupencode(tif); + (void)s; + assert(sp != NULL); + if (sp->state != LSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); - if (sp->cstream) { - ZSTD_freeCStream(sp->cstream); - sp->cstream = NULL; - } + if (sp->cstream == NULL) + { sp->cstream = ZSTD_createCStream(); - if( sp->cstream == NULL ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot allocate compression stream"); + if (sp->cstream == NULL) + { + TIFFErrorExtR(tif, module, "Cannot allocate compression stream"); return 0; } + } - zstd_ret = ZSTD_initCStream(sp->cstream, sp->compression_level); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error in ZSTD_initCStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } + zstd_ret = ZSTD_initCStream(sp->cstream, sp->compression_level); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_initCStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } - sp->out_buffer.dst = tif->tif_rawdata; - sp->out_buffer.size = (size_t)tif->tif_rawdatasize; - sp->out_buffer.pos = 0; + sp->out_buffer.dst = tif->tif_rawdata; + sp->out_buffer.size = (size_t)tif->tif_rawdatasize; + sp->out_buffer.pos = 0; - return 1; + return 1; } /* -* Encode a chunk of pixels. -*/ -static int -ZSTDEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) + * Encode a chunk of pixels. + */ +static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "ZSTDEncode"; - ZSTDState *sp = EncoderState(tif); - ZSTD_inBuffer in_buffer; - size_t zstd_ret; + static const char module[] = "ZSTDEncode"; + ZSTDState *sp = EncoderState(tif); + ZSTD_inBuffer in_buffer; + size_t zstd_ret; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); - (void) s; + (void)s; - in_buffer.src = bp; - in_buffer.size = (size_t)cc; - in_buffer.pos = 0; + in_buffer.src = bp; + in_buffer.size = (size_t)cc; + in_buffer.pos = 0; - do { - zstd_ret = ZSTD_compressStream(sp->cstream, &sp->out_buffer, - &in_buffer); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error in ZSTD_compressStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - if( sp->out_buffer.pos == sp->out_buffer.size ) { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->out_buffer.dst = tif->tif_rawcp; - sp->out_buffer.pos = 0; - } - } while( in_buffer.pos < in_buffer.size ); + do + { + zstd_ret = + ZSTD_compressStream(sp->cstream, &sp->out_buffer, &in_buffer); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_compressStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + if (sp->out_buffer.pos == sp->out_buffer.size) + { + tif->tif_rawcc = tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return 0; + sp->out_buffer.dst = tif->tif_rawcp; + sp->out_buffer.pos = 0; + } + } while (in_buffer.pos < in_buffer.size); - return 1; + return 1; } /* -* Finish off an encoded strip by flushing it. -*/ -static int -ZSTDPostEncode(TIFF* tif) + * Finish off an encoded strip by flushing it. + */ +static int ZSTDPostEncode(TIFF *tif) { - static const char module[] = "ZSTDPostEncode"; - ZSTDState *sp = EncoderState(tif); - size_t zstd_ret; + static const char module[] = "ZSTDPostEncode"; + ZSTDState *sp = EncoderState(tif); + size_t zstd_ret; - do { - zstd_ret = ZSTD_endStream(sp->cstream, &sp->out_buffer); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error in ZSTD_endStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - if( sp->out_buffer.pos > 0 ) { - tif->tif_rawcc = sp->out_buffer.pos; - if (!TIFFFlushData1(tif)) - return 0; - sp->out_buffer.dst = tif->tif_rawcp; - sp->out_buffer.pos = 0; - } - } while (zstd_ret != 0); - return 1; + do + { + zstd_ret = ZSTD_endStream(sp->cstream, &sp->out_buffer); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_endStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + if (sp->out_buffer.pos > 0) + { + tif->tif_rawcc = sp->out_buffer.pos; + if (!TIFFFlushData1(tif)) + return 0; + sp->out_buffer.dst = tif->tif_rawcp; + sp->out_buffer.pos = 0; + } + } while (zstd_ret != 0); + return 1; } -static void -ZSTDCleanup(TIFF* tif) +static void ZSTDCleanup(TIFF *tif) { - ZSTDState* sp = LState(tif); + ZSTDState *sp = LState(tif); - assert(sp != 0); + assert(sp != 0); - (void)TIFFPredictorCleanup(tif); + (void)TIFFPredictorCleanup(tif); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; - if (sp->dstream) { - ZSTD_freeDStream(sp->dstream); - sp->dstream = NULL; - } - if (sp->cstream) { - ZSTD_freeCStream(sp->cstream); - sp->cstream = NULL; - } - _TIFFfree(sp); - tif->tif_data = NULL; + if (sp->dstream) + { + ZSTD_freeDStream(sp->dstream); + sp->dstream = NULL; + } + if (sp->cstream) + { + ZSTD_freeCStream(sp->cstream); + sp->cstream = NULL; + } + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -static int -ZSTDVSetField(TIFF* tif, uint32 tag, va_list ap) +static int ZSTDVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "ZSTDVSetField"; - ZSTDState* sp = LState(tif); + static const char module[] = "ZSTDVSetField"; + ZSTDState *sp = LState(tif); - switch (tag) { + switch (tag) + { case TIFFTAG_ZSTD_LEVEL: - sp->compression_level = (int) va_arg(ap, int); - if( sp->compression_level <= 0 || - sp->compression_level > ZSTD_maxCLevel() ) - { - TIFFWarningExt(tif->tif_clientdata, module, - "ZSTD_LEVEL should be between 1 and %d", - ZSTD_maxCLevel()); - } - return 1; + sp->compression_level = (int)va_arg(ap, int); + if (sp->compression_level <= 0 || + sp->compression_level > ZSTD_maxCLevel()) + { + TIFFWarningExtR(tif, module, + "ZSTD_LEVEL should be between 1 and %d", + ZSTD_maxCLevel()); + } + return 1; default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ } -static int -ZSTDVGetField(TIFF* tif, uint32 tag, va_list ap) +static int ZSTDVGetField(TIFF *tif, uint32_t tag, va_list ap) { - ZSTDState* sp = LState(tif); + ZSTDState *sp = LState(tif); - switch (tag) { + switch (tag) + { case TIFFTAG_ZSTD_LEVEL: - *va_arg(ap, int*) = sp->compression_level; - break; + *va_arg(ap, int *) = sp->compression_level; + break; default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; } static const TIFFField ZSTDFields[] = { - { TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "ZSTD compression_level", NULL }, + {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "ZSTD compression_level", + NULL}, }; -int -TIFFInitZSTD(TIFF* tif, int scheme) +int TIFFInitZSTD(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitZSTD"; - ZSTDState* sp; + static const char module[] = "TIFFInitZSTD"; + ZSTDState *sp; - assert( scheme == COMPRESSION_ZSTD ); + (void)scheme; + assert(scheme == COMPRESSION_ZSTD); - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, ZSTDFields, TIFFArrayCount(ZSTDFields))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Merging ZSTD codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8*) _TIFFmalloc(sizeof(ZSTDState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = ZSTDVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = ZSTDVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->compression_level = 9; /* default comp. level */ - sp->state = 0; - sp->dstream = 0; - sp->cstream = 0; - sp->out_buffer.dst = NULL; - sp->out_buffer.size = 0; - sp->out_buffer.pos = 0; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = ZSTDFixupTags; - tif->tif_setupdecode = ZSTDSetupDecode; - tif->tif_predecode = ZSTDPreDecode; - tif->tif_decoderow = ZSTDDecode; - tif->tif_decodestrip = ZSTDDecode; - tif->tif_decodetile = ZSTDDecode; - tif->tif_setupencode = ZSTDSetupEncode; - tif->tif_preencode = ZSTDPreEncode; - tif->tif_postencode = ZSTDPostEncode; - tif->tif_encoderow = ZSTDEncode; - tif->tif_encodestrip = ZSTDEncode; - tif->tif_encodetile = ZSTDEncode; - tif->tif_cleanup = ZSTDCleanup; - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - return 1; -bad: - TIFFErrorExt(tif->tif_clientdata, module, - "No space for ZSTD state block"); + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, ZSTDFields, TIFFArrayCount(ZSTDFields))) + { + TIFFErrorExtR(tif, module, "Merging ZSTD codec-specific tags failed"); return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(ZSTDState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = ZSTDVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = ZSTDVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->compression_level = 9; /* default comp. level */ + sp->state = 0; + sp->dstream = 0; + sp->cstream = 0; + sp->out_buffer.dst = NULL; + sp->out_buffer.size = 0; + sp->out_buffer.pos = 0; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = ZSTDFixupTags; + tif->tif_setupdecode = ZSTDSetupDecode; + tif->tif_predecode = ZSTDPreDecode; + tif->tif_decoderow = ZSTDDecode; + tif->tif_decodestrip = ZSTDDecode; + tif->tif_decodetile = ZSTDDecode; + tif->tif_setupencode = ZSTDSetupEncode; + tif->tif_preencode = ZSTDPreEncode; + tif->tif_postencode = ZSTDPostEncode; + tif->tif_encoderow = ZSTDEncode; + tif->tif_encodestrip = ZSTDEncode; + tif->tif_encodetile = ZSTDEncode; + tif->tif_cleanup = ZSTDCleanup; + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + return 1; +bad: + TIFFErrorExtR(tif, module, "No space for ZSTD state block"); + return 0; } #endif /* ZSTD_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/3rdparty/libtiff/tiff.h b/3rdparty/libtiff/tiff.h index 2d4a47679d..d8da33dc38 100644 --- a/3rdparty/libtiff/tiff.h +++ b/3rdparty/libtiff/tiff.h @@ -2,28 +2,28 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _TIFF_ -#define _TIFF_ +#define _TIFF_ #include "tiffconf.h" @@ -48,32 +48,46 @@ #define TIFF_VERSION_CLASSIC 42 #define TIFF_VERSION_BIG 43 -#define TIFF_BIGENDIAN 0x4d4d -#define TIFF_LITTLEENDIAN 0x4949 -#define MDI_LITTLEENDIAN 0x5045 -#define MDI_BIGENDIAN 0x4550 +#define TIFF_BIGENDIAN 0x4d4d +#define TIFF_LITTLEENDIAN 0x4949 +#define MDI_LITTLEENDIAN 0x5045 +#define MDI_BIGENDIAN 0x4550 /* * Intrinsic data types required by the file format: * - * 8-bit quantities int8/uint8 - * 16-bit quantities int16/uint16 - * 32-bit quantities int32/uint32 - * 64-bit quantities int64/uint64 + * 8-bit quantities int8_t/uint_8_t + * 16-bit quantities int16_t/uint_16_t + * 32-bit quantities int32_t/uint_32_t + * 64-bit quantities int64_t/uint_64_t * strings unsigned char* */ +#ifdef __GNUC__ +#define TIFF_GCC_DEPRECATED __attribute__((deprecated)) +#else +#define TIFF_GCC_DEPRECATED +#endif +#ifdef _MSC_VER +#define TIFF_MSC_DEPRECATED \ + __declspec(deprecated("libtiff type deprecated; please use corresponding " \ + "C99 stdint.h type")) +#else +#define TIFF_MSC_DEPRECATED +#endif -typedef TIFF_INT8_T int8; -typedef TIFF_UINT8_T uint8; +#ifndef TIFF_DISABLE_DEPRECATED +typedef TIFF_MSC_DEPRECATED int8_t int8 TIFF_GCC_DEPRECATED; +typedef TIFF_MSC_DEPRECATED uint8_t uint8 TIFF_GCC_DEPRECATED; -typedef TIFF_INT16_T int16; -typedef TIFF_UINT16_T uint16; +typedef TIFF_MSC_DEPRECATED int16_t int16 TIFF_GCC_DEPRECATED; +typedef TIFF_MSC_DEPRECATED uint16_t uint16 TIFF_GCC_DEPRECATED; -typedef TIFF_INT32_T int32; -typedef TIFF_UINT32_T uint32; +typedef TIFF_MSC_DEPRECATED int32_t int32 TIFF_GCC_DEPRECATED; +typedef TIFF_MSC_DEPRECATED uint32_t uint32 TIFF_GCC_DEPRECATED; -typedef TIFF_INT64_T int64; -typedef TIFF_UINT64_T uint64; +typedef TIFF_MSC_DEPRECATED int64_t int64 TIFF_GCC_DEPRECATED; +typedef TIFF_MSC_DEPRECATED uint64_t uint64 TIFF_GCC_DEPRECATED; +#endif /* TIFF_DISABLE_DEPRECATED */ /* * Some types as promoted in a variable argument list @@ -88,24 +102,26 @@ typedef int uint16_vap; /* * TIFF header. */ -typedef struct { - uint16 tiff_magic; /* magic number (defines byte order) */ - uint16 tiff_version; /* TIFF version number */ +typedef struct +{ + uint16_t tiff_magic; /* magic number (defines byte order) */ + uint16_t tiff_version; /* TIFF version number */ } TIFFHeaderCommon; -typedef struct { - uint16 tiff_magic; /* magic number (defines byte order) */ - uint16 tiff_version; /* TIFF version number */ - uint32 tiff_diroff; /* byte offset to first directory */ +typedef struct +{ + uint16_t tiff_magic; /* magic number (defines byte order) */ + uint16_t tiff_version; /* TIFF version number */ + uint32_t tiff_diroff; /* byte offset to first directory */ } TIFFHeaderClassic; -typedef struct { - uint16 tiff_magic; /* magic number (defines byte order) */ - uint16 tiff_version; /* TIFF version number */ - uint16 tiff_offsetsize; /* size of offsets, should be 8 */ - uint16 tiff_unused; /* unused word, should be 0 */ - uint64 tiff_diroff; /* byte offset to first directory */ +typedef struct +{ + uint16_t tiff_magic; /* magic number (defines byte order) */ + uint16_t tiff_version; /* TIFF version number */ + uint16_t tiff_offsetsize; /* size of offsets, should be 8 */ + uint16_t tiff_unused; /* unused word, should be 0 */ + uint64_t tiff_diroff; /* byte offset to first directory */ } TIFFHeaderBig; - /* * NB: In the comments below, * - items marked with a + are obsoleted by revision 5.0, @@ -120,464 +136,551 @@ typedef struct { * * Note: RATIONALs are the ratio of two 32-bit integer values. *--: - * Note2: TIFF_IFD8 data type is used in tiffFields[]-tag definition in order to distinguish the write-handling - of those tags between ClassicTIFF and BigTiff: - For ClassicTIFF libtiff writes a 32-bit value and the TIFF_IFD type-id into the file - For BigTIFF libtiff writes a 64-bit value and the TIFF_IFD8 type-id into the file + * Note2: TIFF_IFD8 data type is used in tiffFields[]-tag definition in order to + distinguish the write-handling of those tags between ClassicTIFF and BigTiff: + For ClassicTIFF libtiff writes a 32-bit value and the TIFF_IFD + type-id into the file For BigTIFF libtiff writes a 64-bit value and the + TIFF_IFD8 type-id into the file */ -typedef enum { - TIFF_NOTYPE = 0, /* placeholder */ - TIFF_BYTE = 1, /* 8-bit unsigned integer */ - TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ - TIFF_SHORT = 3, /* 16-bit unsigned integer */ - TIFF_LONG = 4, /* 32-bit unsigned integer */ - TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ - TIFF_SBYTE = 6, /* !8-bit signed integer */ - TIFF_UNDEFINED = 7, /* !8-bit untyped data */ - TIFF_SSHORT = 8, /* !16-bit signed integer */ - TIFF_SLONG = 9, /* !32-bit signed integer */ - TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ - TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ - TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ - TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */ - TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */ - TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */ - TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */ +typedef enum +{ + TIFF_NOTYPE = 0, /* placeholder */ + TIFF_BYTE = 1, /* 8-bit unsigned integer */ + TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ + TIFF_SHORT = 3, /* 16-bit unsigned integer */ + TIFF_LONG = 4, /* 32-bit unsigned integer */ + TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ + TIFF_SBYTE = 6, /* !8-bit signed integer */ + TIFF_UNDEFINED = 7, /* !8-bit untyped data */ + TIFF_SSHORT = 8, /* !16-bit signed integer */ + TIFF_SLONG = 9, /* !32-bit signed integer */ + TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ + TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ + TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ + TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */ + TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */ + TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */ + TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */ } TIFFDataType; /* * TIFF Tag Definitions. */ -#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ -#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ -#define FILETYPE_PAGE 0x2 /* one page of many */ -#define FILETYPE_MASK 0x4 /* transparency mask */ -#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ -#define OFILETYPE_IMAGE 1 /* full resolution image data */ -#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ -#define OFILETYPE_PAGE 3 /* one page of many */ -#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ -#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ -#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ -#define TIFFTAG_COMPRESSION 259 /* data compression technique */ -#define COMPRESSION_NONE 1 /* dump mode */ -#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ -#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ -#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */ -#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ -#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */ -#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ -#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ -#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ -#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */ -#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */ -#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ -#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ -#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ -#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ +/* clang-format off */ /* for better readability of tag comments */ +#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ +#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ +#define FILETYPE_PAGE 0x2 /* one page of many */ +#define FILETYPE_MASK 0x4 /* transparency mask */ +#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ +#define OFILETYPE_IMAGE 1 /* full resolution image data */ +#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ +#define OFILETYPE_PAGE 3 /* one page of many */ +#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ +#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ +#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ +#define TIFFTAG_COMPRESSION 259 /* data compression technique */ +#define COMPRESSION_NONE 1 /* dump mode */ +#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ +#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ +#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */ +#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ +#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */ +#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ +#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ +#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ +#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */ +#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */ +#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ +#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ +#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ +#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ /* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT */ -#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ -#define COMPRESSION_JBIG 34661 /* ISO JBIG */ -#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ -#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ -#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ -#define COMPRESSION_LERC 34887 /* ESRI Lerc codec: https://github.com/Esri/lerc */ +#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ +#define COMPRESSION_JBIG 34661 /* ISO JBIG */ +#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ +#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ +#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ +#define COMPRESSION_LERC 34887 /* ESRI Lerc codec: https://github.com/Esri/lerc */ /* compression codes 34887-34889 are reserved for ESRI */ -#define COMPRESSION_LZMA 34925 /* LZMA2 */ -#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */ -#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */ -#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ -#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ -#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ -#define PHOTOMETRIC_RGB 2 /* RGB color model */ -#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ -#define PHOTOMETRIC_MASK 4 /* $holdout mask */ -#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ -#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ -#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ -#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ -#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ -#define PHOTOMETRIC_CFA 32803 /* color filter array */ -#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ -#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ -#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ -#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ -#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ -#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ -#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ -#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ -#define TIFFTAG_FILLORDER 266 /* data order within a byte */ -#define FILLORDER_MSB2LSB 1 /* most significant -> least */ -#define FILLORDER_LSB2MSB 2 /* least significant -> most */ -#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ -#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ -#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ -#define TIFFTAG_MODEL 272 /* scanner model name/number */ -#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ -#define TIFFTAG_ORIENTATION 274 /* +image orientation */ -#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ -#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ -#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ -#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ -#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ -#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ -#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ -#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ -#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ -#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ -#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ -#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ -#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ -#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ -#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ -#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ -#define PLANARCONFIG_CONTIG 1 /* single image plane */ -#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ -#define TIFFTAG_PAGENAME 285 /* page name image is from */ -#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ -#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ -#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ -#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ -#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ -#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ -#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ -#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ -#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ -#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ -#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ -#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ -#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */ -#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ -#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ -#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ -#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ -#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */ -#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ -#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ -#define RESUNIT_NONE 1 /* no meaningful units */ -#define RESUNIT_INCH 2 /* english */ -#define RESUNIT_CENTIMETER 3 /* metric */ -#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ -#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ -#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ -#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ -#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ -#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ -#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ -#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ -#define TIFFTAG_SOFTWARE 305 /* name & release */ -#define TIFFTAG_DATETIME 306 /* creation date and time */ -#define TIFFTAG_ARTIST 315 /* creator of image */ -#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ -#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ -#define PREDICTOR_NONE 1 /* no prediction scheme used */ -#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */ -#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */ -#define TIFFTAG_WHITEPOINT 318 /* image white point */ -#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ -#define TIFFTAG_COLORMAP 320 /* RGB map for palette image */ -#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ -#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */ -#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */ -#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ -#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ -#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ -#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ -#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ -#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ -#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ -#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ -#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ -#define TIFFTAG_INKSET 332 /* !inks in separated image */ -#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */ -#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */ -#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ -#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ -#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ -#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ -#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ -#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ -#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ -#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ -#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ -#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ -#define SAMPLEFORMAT_INT 2 /* !signed integer data */ -#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ -#define SAMPLEFORMAT_VOID 4 /* !untyped data */ -#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */ -#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */ -#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ -#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ -#define TIFFTAG_CLIPPATH 343 /* %ClipPath - [Adobe TIFF technote 2] */ -#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits - [Adobe TIFF technote 2] */ -#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits - [Adobe TIFF technote 2] */ -#define TIFFTAG_INDEXED 346 /* %Indexed - [Adobe TIFF Technote 3] */ -#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ -#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ +#define COMPRESSION_LZMA 34925 /* LZMA2 */ +#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */ +#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */ +#define COMPRESSION_JXL 50002 /* JPEGXL: WARNING not registered in Adobe-maintained registry */ +#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ +#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ +#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ +#define PHOTOMETRIC_RGB 2 /* RGB color model */ +#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ +#define PHOTOMETRIC_MASK 4 /* $holdout mask */ +#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ +#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ +#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ +#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ +#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ +#define PHOTOMETRIC_CFA 32803 /* color filter array */ +#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ +#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ +#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ +#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ +#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ +#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ +#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ +#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ +#define TIFFTAG_FILLORDER 266 /* data order within a byte */ +#define FILLORDER_MSB2LSB 1 /* most significant -> least */ +#define FILLORDER_LSB2MSB 2 /* least significant -> most */ +#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ +#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ +#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ +#define TIFFTAG_MODEL 272 /* scanner model name/number */ +#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ +#define TIFFTAG_ORIENTATION 274 /* +image orientation */ +#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ +#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ +#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ +#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ +#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ +#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ +#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ +#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ +#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ +#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ +#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ +#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ +#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ +#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ +#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ +#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ +#define PLANARCONFIG_CONTIG 1 /* single image plane */ +#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ +#define TIFFTAG_PAGENAME 285 /* page name image is from */ +#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ +#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ +#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ +#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ +#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ +#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ +#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ +#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */ +#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ +#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ +#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ +#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */ +#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ +#define RESUNIT_NONE 1 /* no meaningful units */ +#define RESUNIT_INCH 2 /* english */ +#define RESUNIT_CENTIMETER 3 /* metric */ +#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ +#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ +#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ +#define TIFFTAG_SOFTWARE 305 /* name & release */ +#define TIFFTAG_DATETIME 306 /* creation date and time */ +#define TIFFTAG_ARTIST 315 /* creator of image */ +#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ +#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ +#define PREDICTOR_NONE 1 /* no prediction scheme used */ +#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */ +#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */ +#define TIFFTAG_WHITEPOINT 318 /* image white point */ +#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ +#define TIFFTAG_COLORMAP 320 /* RGB map for palette image */ +#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ +#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */ +#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */ +#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ +#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ +#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ +#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ +#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ +#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ +#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ +#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ +#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ +#define TIFFTAG_INKSET 332 /* !inks in separated image */ +#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */ +#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */ +#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ +#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ +#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ +#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ +#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ +#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ +#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ +#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ +#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ +#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ +#define SAMPLEFORMAT_INT 2 /* !signed integer data */ +#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ +#define SAMPLEFORMAT_VOID 4 /* !untyped data */ +#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */ +#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */ +#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ +#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ +#define TIFFTAG_CLIPPATH 343 /* %ClipPath [Adobe TIFF technote 2] */ +#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits [Adobe TIFF technote 2] */ +#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits [Adobe TIFF technote 2] */ +#define TIFFTAG_INDEXED 346 /* %Indexed [Adobe TIFF Technote 3] */ +#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ +#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ /* Tags 400-435 are from the TIFF/FX spec */ -#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */ -#define TIFFTAG_PROFILETYPE 401 /* ! */ -#define PROFILETYPE_UNSPECIFIED 0 /* ! */ -#define PROFILETYPE_G3_FAX 1 /* ! */ -#define TIFFTAG_FAXPROFILE 402 /* ! */ -#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */ -#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */ -#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */ -#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */ -#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */ -#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */ -#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */ -#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */ -#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */ -#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */ -#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */ -#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */ -#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */ -#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */ -#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */ -#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */ -#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */ -#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */ +#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */ +#define TIFFTAG_PROFILETYPE 401 /* ! */ +#define PROFILETYPE_UNSPECIFIED 0 /* ! */ +#define PROFILETYPE_G3_FAX 1 /* ! */ +#define TIFFTAG_FAXPROFILE 402 /* ! */ +#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */ +#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */ +#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */ +#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */ +#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */ +#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */ +#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */ +#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */ +#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */ +#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */ +#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */ +#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */ +#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */ +#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */ +#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */ +#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */ +#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */ +#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */ /* * Tags 512-521 are obsoleted by Technical Note #2 which specifies a * revised JPEG-in-TIFF scheme. */ -#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ -#define JPEGPROC_BASELINE 1 /* !baseline sequential */ -#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ -#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ -#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ -#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ -#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ -#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ -#define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */ -#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ -#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ -#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ -#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ -#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ -#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ -#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ -#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ -#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */ -#define TIFFTAG_XMLPACKET 700 /* %XML packet - [Adobe XMP Specification, - January 2004 */ -#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID - [Adobe TIFF technote] */ -#define TIFFTAG_TIFFANNOTATIONDATA 32932 /* http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm */ +#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ +#define JPEGPROC_BASELINE 1 /* !baseline sequential */ +#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ +#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ +#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ +#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ +#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ +#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ +#define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */ +#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ +#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ +#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ +#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ +#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ +#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ +#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ +#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ +#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */ +#define TIFFTAG_XMLPACKET 700 /* %XML packet [Adobe XMP Specification, January 2004 */ +#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID [Adobe TIFF technote] */ +/* For eiStream Annotation Specification, Version 1.00.06 see + * http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm */ +#define TIFFTAG_TIFFANNOTATIONDATA 32932 /* tags 32952-32956 are private tags registered to Island Graphics */ -#define TIFFTAG_REFPTS 32953 /* image reference points */ -#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ -#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ -#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ +#define TIFFTAG_REFPTS 32953 /* image reference points */ +#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ +#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ +#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ /* tags 32995-32999 are private tags registered to SGI */ -#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ -#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ -#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ -#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ +#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ +#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ +#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ +#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ /* tags 33300-33309 are private tags registered to Pixar */ /* * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH - * are set when an image has been cropped out of a larger image. + * are set when an image has been cropped out of a larger image. * They reflect the size of the original uncropped image. * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used * to determine the position of the smaller image in the larger one. */ -#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ -#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ - /* Tags 33302-33306 are used to identify special image modes and data - * used by Pixar's texture formats. - */ -#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ -#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ -#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ +#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ +#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ +/* Tags 33302-33306 are used to identify special image modes and data + * used by Pixar's texture formats. + */ +#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ +#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ +#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ #define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305 #define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 /* tag 33405 is a private tag registered to Eastman Kodak */ -#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ -#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */ -#define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */ +#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ +#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* (alias for TIFFTAG_EP_CFAREPEATPATTERNDIM)*/ +#define TIFFTAG_CFAPATTERN 33422 /* (alias for TIFFTAG_EP_CFAPATTERN) */ +#define TIFFTAG_BATTERYLEVEL 33423 /* (alias for TIFFTAG_EP_BATTERYLEVEL) */ /* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ -#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ -/* Tags 33445-33452 are used for GEL fileformat, see - * http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf +#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ +/* Tags 33445-33452 are used for Molecular Dynamics GEL fileformat, + * see http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf + * (2023: the above web site is unavailable but tags are explained briefly at + * https://www.awaresystems.be/imaging/tiff/tifftags/docs/gel.html */ -#define TIFFTAG_MD_FILETAG 33445 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_SCALEPIXEL 33446 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_COLORTABLE 33447 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_LABNAME 33448 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_SAMPLEINFO 33449 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_PREPDATE 33450 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_PREPTIME 33451 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_FILEUNITS 33452 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ +#define TIFFTAG_MD_FILETAG 33445 /* Specifies the pixel data format encoding in the GEL file format. */ +#define TIFFTAG_MD_SCALEPIXEL 33446 /* scale factor */ +#define TIFFTAG_MD_COLORTABLE 33447 /* conversion from 16bit to 8bit */ +#define TIFFTAG_MD_LABNAME 33448 /* name of the lab that scanned this file. */ +#define TIFFTAG_MD_SAMPLEINFO 33449 /* information about the scanned GEL sample */ +#define TIFFTAG_MD_PREPDATE 33450 /* information about the date the sample was prepared YY/MM/DD */ +#define TIFFTAG_MD_PREPTIME 33451 /* information about the time the sample was prepared HH:MM*/ +#define TIFFTAG_MD_FILEUNITS 33452 /* Units for data in this file, as used in the GEL file format. */ /* IPTC TAG from RichTIFF specifications */ -#define TIFFTAG_RICHTIFFIPTC 33723 -#define TIFFTAG_INGR_PACKET_DATA_TAG 33918 /* Intergraph Application specific storage. */ -#define TIFFTAG_INGR_FLAG_REGISTERS 33919 /* Intergraph Application specific flags. */ -#define TIFFTAG_IRASB_TRANSORMATION_MATRIX 33920 /* Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. */ -#define TIFFTAG_MODELTIEPOINTTAG 33922 /* GeoTIFF */ +#define TIFFTAG_RICHTIFFIPTC 33723 +#define TIFFTAG_INGR_PACKET_DATA_TAG 33918 /* Intergraph Application specific storage. */ +#define TIFFTAG_INGR_FLAG_REGISTERS 33919 /* Intergraph Application specific flags. */ +#define TIFFTAG_IRASB_TRANSORMATION_MATRIX 33920 /* Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. */ +#define TIFFTAG_MODELTIEPOINTTAG 33922 /* GeoTIFF */ /* 34016-34029 are reserved for ANSI IT8 TIFF/IT */ -#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ +#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ /* tag 34929 is a private tag registered to FedEx */ -#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ -#define TIFFTAG_IMAGESOURCEDATA 37724 /* http://justsolve.archiveteam.org/wiki/PSD, http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/ */ -#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */ -#define TIFFTAG_GDAL_METADATA 42112 /* Used by the GDAL library */ -#define TIFFTAG_GDAL_NODATA 42113 /* Used by the GDAL library */ -#define TIFFTAG_OCE_SCANJOB_DESCRIPTION 50215 /* Used in the Oce scanning process */ -#define TIFFTAG_OCE_APPLICATION_SELECTOR 50216 /* Used in the Oce scanning process. */ -#define TIFFTAG_OCE_IDENTIFICATION_NUMBER 50217 -#define TIFFTAG_OCE_IMAGELOGIC_CHARACTERISTICS 50218 - +#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ +#define TIFFTAG_IMAGESOURCEDATA 37724 /* http://justsolve.archiveteam.org/wiki/PSD, http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/ */ +#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to EXIF Interoperability private directory */ +#define TIFFTAG_GDAL_METADATA 42112 /* Used by the GDAL library */ +#define TIFFTAG_GDAL_NODATA 42113 /* Used by the GDAL library */ +#define TIFFTAG_OCE_SCANJOB_DESCRIPTION 50215 /* Used in the Oce scanning process */ +#define TIFFTAG_OCE_APPLICATION_SELECTOR 50216 /* Used in the Oce scanning process. */ +#define TIFFTAG_OCE_IDENTIFICATION_NUMBER 50217 +#define TIFFTAG_OCE_IMAGELOGIC_CHARACTERISTICS 50218 /* tags 50674 to 50677 are reserved for ESRI */ -#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */ +#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */ + /* Adobe Digital Negative (DNG) format tags */ -#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ -#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ -#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */ -#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model - name */ -#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space - mapping */ -#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */ -#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */ -#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for - the BlackLevel tag */ -#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */ -#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level - differences (columns) */ -#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level - differences (rows) */ -#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding - level */ -#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */ -#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image - area */ -#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image - area */ -#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space - transformation matrix 1 */ -#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space - transformation matrix 2 */ -#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */ -#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */ -#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction - matrix 1 */ -#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction - matrix 2 */ -#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw - values*/ -#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in - linear reference space */ -#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in - x-y chromaticity - coordinates */ -#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero - point */ -#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */ -#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of - sharpening */ -#define TIFFTAG_BAYERGREENSPLIT 50733 /* &how closely the values of - the green pixels in the - blue/green rows track the - values of the green pixels - in the red/green rows */ -#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */ -#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */ -#define TIFFTAG_LENSINFO 50736 /* info about the lens */ -#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */ -#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the - camera's anti-alias filter */ -#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */ -#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */ -#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote - tag is safe to preserve - along with the rest of the - EXIF data */ -#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */ -#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */ -#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */ -#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for - the raw image data */ -#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original - raw file */ -#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original - raw file */ -#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels - of the sensor */ -#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates - of fully masked pixels */ -#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */ -#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space - into ICC profile space */ -#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */ -#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */ +#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ +#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ +#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */ +#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model name (UTF-8) */ +#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space mapping */ +#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */ +#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */ +#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for the BlackLevel tag */ +#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */ +#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level differences (columns) */ +#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level differences (rows) */ +#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding level */ +#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */ +#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image area */ +#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image area */ +#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space transformation matrix 1 */ +#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space transformation matrix 2 */ +#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */ +#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */ +#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction matrix 1 */ +#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction matrix 2 */ +#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw values*/ +#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in linear reference space */ +#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in x-y chromaticity coordinates */ +#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero point */ +#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */ +#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of sharpening */ +/* TIFFTAG_BAYERGREENSPLIT: &how closely the values of the green pixels in the blue/green rows + * track the values of the green pixels in the red/green rows */ +#define TIFFTAG_BAYERGREENSPLIT 50733 +#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */ +#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */ +#define TIFFTAG_LENSINFO 50736 /* info about the lens */ +#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */ +#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the camera's anti-alias filter */ +#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */ +#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */ +#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote tag is safe to preserve along with the rest of the EXIF data */ +#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */ +#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */ +#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */ +#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for the raw image data */ +#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original raw file (UTF-8) */ +#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original raw file */ +#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels of the sensor */ +#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates of fully masked pixels */ +#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */ +#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space into ICC profile space */ +#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */ +#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */ -#define TIFFTAG_RPCCOEFFICIENT 50844 /* Define by GDAL for geospatial georeferencing through RPC: http://geotiff.maptools.org/rpc_prop.html */ +/* DNG 1.2.0.0 */ +#define TIFFTAG_COLORIMETRICREFERENCE 50879 /* &colorimetric reference */ +#define TIFFTAG_CAMERACALIBRATIONSIGNATURE 50931 /* &camera calibration signature (UTF-8) */ +#define TIFFTAG_PROFILECALIBRATIONSIGNATURE 50932 /* &profile calibration signature (UTF-8) */ +/* TIFFTAG_EXTRACAMERAPROFILES 50933 &extra camera profiles : is already defined for GeoTIFF DGIWG */ +#define TIFFTAG_ASSHOTPROFILENAME 50934 /* &as shot profile name (UTF-8) */ +#define TIFFTAG_NOISEREDUCTIONAPPLIED 50935 /* &amount of applied noise reduction */ +#define TIFFTAG_PROFILENAME 50936 /* &camera profile name (UTF-8) */ +#define TIFFTAG_PROFILEHUESATMAPDIMS 50937 /* &dimensions of HSV mapping */ +#define TIFFTAG_PROFILEHUESATMAPDATA1 50938 /* &first HSV mapping table */ +#define TIFFTAG_PROFILEHUESATMAPDATA2 50939 /* &second HSV mapping table */ +#define TIFFTAG_PROFILETONECURVE 50940 /* &default tone curve */ +#define TIFFTAG_PROFILEEMBEDPOLICY 50941 /* &profile embedding policy */ +#define TIFFTAG_PROFILECOPYRIGHT 50942 /* &profile copyright information (UTF-8) */ +#define TIFFTAG_FORWARDMATRIX1 50964 /* &matrix for mapping white balanced camera colors to XYZ D50 */ +#define TIFFTAG_FORWARDMATRIX2 50965 /* &matrix for mapping white balanced camera colors to XYZ D50 */ +#define TIFFTAG_PREVIEWAPPLICATIONNAME 50966 /* &name of application that created preview (UTF-8) */ +#define TIFFTAG_PREVIEWAPPLICATIONVERSION 50967 /* &version of application that created preview (UTF-8) */ +#define TIFFTAG_PREVIEWSETTINGSNAME 50968 /* &name of conversion settings (UTF-8) */ +#define TIFFTAG_PREVIEWSETTINGSDIGEST 50969 /* &unique id of conversion settings */ +#define TIFFTAG_PREVIEWCOLORSPACE 50970 /* &preview color space */ +#define TIFFTAG_PREVIEWDATETIME 50971 /* &date/time preview was rendered */ +#define TIFFTAG_RAWIMAGEDIGEST 50972 /* &md5 of raw image data */ +#define TIFFTAG_ORIGINALRAWFILEDIGEST 50973 /* &md5 of the data stored in the OriginalRawFileData tag */ +#define TIFFTAG_SUBTILEBLOCKSIZE 50974 /* &subtile block size */ +#define TIFFTAG_ROWINTERLEAVEFACTOR 50975 /* &number of interleaved fields */ +#define TIFFTAG_PROFILELOOKTABLEDIMS 50981 /* &num of input samples in each dim of default "look" table */ +#define TIFFTAG_PROFILELOOKTABLEDATA 50982 /* &default "look" table for use as starting point */ -#define TIFFTAG_ALIAS_LAYER_METADATA 50784 /* Alias Sketchbook Pro layer usage description. */ +/* DNG 1.3.0.0 */ +#define TIFFTAG_OPCODELIST1 51008 /* &opcodes that should be applied to raw image after reading */ +#define TIFFTAG_OPCODELIST2 51009 /* &opcodes that should be applied after mapping to linear reference */ +#define TIFFTAG_OPCODELIST3 51022 /* &opcodes that should be applied after demosaicing */ +#define TIFFTAG_NOISEPROFILE 51041 /* &noise profile */ + +/* DNG 1.4.0.0 */ +#define TIFFTAG_DEFAULTUSERCROP 51125 /* &default user crop rectangle in relative coords */ +#define TIFFTAG_DEFAULTBLACKRENDER 51110 /* &black rendering hint */ +#define TIFFTAG_BASELINEEXPOSUREOFFSET 51109 /* &baseline exposure offset */ +#define TIFFTAG_PROFILELOOKTABLEENCODING 51108 /* &3D LookTable indexing conversion */ +#define TIFFTAG_PROFILEHUESATMAPENCODING 51107 /* &3D HueSatMap indexing conversion */ +#define TIFFTAG_ORIGINALDEFAULTFINALSIZE 51089 /* &default final size of larger original file for this proxy */ +#define TIFFTAG_ORIGINALBESTQUALITYFINALSIZE 51090 /* &best quality final size of larger original file for this proxy */ +#define TIFFTAG_ORIGINALDEFAULTCROPSIZE 51091 /* &the default crop size of larger original file for this proxy */ +#define TIFFTAG_NEWRAWIMAGEDIGEST 51111 /* &modified MD5 digest of the raw image data */ +#define TIFFTAG_RAWTOPREVIEWGAIN 51112 /* &The gain between the main raw FD and the preview IFD containing this tag */ + +/* DNG 1.5.0.0 */ +#define TIFFTAG_DEPTHFORMAT 51177 /* &encoding of the depth data in the file */ +#define TIFFTAG_DEPTHNEAR 51178 /* &distance from the camera represented by value 0 in the depth map */ +#define TIFFTAG_DEPTHFAR 51179 /* &distance from the camera represented by the maximum value in the depth map */ +#define TIFFTAG_DEPTHUNITS 51180 /* &measurement units for DepthNear and DepthFar */ +#define TIFFTAG_DEPTHMEASURETYPE 51181 /* &measurement geometry for the depth map */ +#define TIFFTAG_ENHANCEPARAMS 51182 /* &a string that documents how the enhanced image data was processed. */ + +/* DNG 1.6.0.0 */ +#define TIFFTAG_PROFILEGAINTABLEMAP 52525 /* &spatially varying gain tables that can be applied as starting point */ +#define TIFFTAG_SEMANTICNAME 52526 /* &a string that identifies the semantic mask */ +#define TIFFTAG_SEMANTICINSTANCEID 52528 /* &a string that identifies a specific instance in a semantic mask */ +#define TIFFTAG_MASKSUBAREA 52536 /* &the crop rectangle of this IFD's mask, relative to the main image */ +#define TIFFTAG_RGBTABLES 52543 /* &color transforms to apply to masked image regions */ +#define TIFFTAG_CALIBRATIONILLUMINANT3 52529 /* &the illuminant used for the third set of color calibration tags */ +#define TIFFTAG_COLORMATRIX3 52531 /* &matrix to convert XYZ values to reference camera native color space under CalibrationIlluminant3 */ +#define TIFFTAG_CAMERACALIBRATION3 52530 /* &matrix to transform reference camera native space values to individual camera native space values under CalibrationIlluminant3 */ +#define TIFFTAG_REDUCTIONMATRIX3 52538 /* &dimensionality reduction matrix for use in color conversion to XYZ under CalibrationIlluminant3 */ +#define TIFFTAG_PROFILEHUESATMAPDATA3 52537 /* &the data for the third HSV table */ +#define TIFFTAG_FORWARDMATRIX3 52532 /* &matrix to map white balanced camera colors to XYZ D50 */ +#define TIFFTAG_ILLUMINANTDATA1 52533 /* &data for the first calibration illuminant */ +#define TIFFTAG_ILLUMINANTDATA2 52534 /* &data for the second calibration illuminant */ +#define TIFFTAG_ILLUMINANTDATA3 53535 /* &data for the third calibration illuminant */ + +/* TIFF/EP */ +#define TIFFTAG_EP_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */ +#define TIFFTAG_EP_CFAPATTERN 33422 /* color filter array pattern */ +#define TIFFTAG_EP_BATTERYLEVEL 33423 /* battery level (rational or ASCII) */ +#define TIFFTAG_EP_INTERLACE 34857 /* Number of multi-field images */ +/* TIFFTAG_EP_IPTC_NAA and TIFFTAG_RICHTIFFIPTC share the same tag number (33723) + * LibTIFF type is UNDEFINED or BYTE, but often times incorrectly specified as LONG, + * because TIFF/EP (ISO/DIS 12234-2) specifies type LONG or ASCII. */ +#define TIFFTAG_EP_IPTC_NAA 33723 /* Alias IPTC/NAA Newspaper Association RichTIFF */ +#define TIFFTAG_EP_TIMEZONEOFFSET 34858 /* Time zone offset relative to UTC */ +#define TIFFTAG_EP_SELFTIMERMODE 34859 /* Number of seconds capture was delayed from button press */ +#define TIFFTAG_EP_FLASHENERGY 37387 /* Flash energy, or range if there is uncertainty */ +#define TIFFTAG_EP_SPATIALFREQUENCYRESPONSE 37388 /* Spatial frequency response */ +#define TIFFTAG_EP_NOISE 37389 /* Camera noise measurement values */ +#define TIFFTAG_EP_FOCALPLANEXRESOLUTION 37390 /* Focal plane X resolution */ +#define TIFFTAG_EP_FOCALPLANEYRESOLUTION 37391 /* Focal plane Y resolution */ +#define TIFFTAG_EP_FOCALPLANERESOLUTIONUNIT 37392 /* Focal plane resolution unit */ +#define TIFFTAG_EP_IMAGENUMBER 37393 /* Number of image when several of burst shot stored in same TIFF/EP */ +#define TIFFTAG_EP_SECURITYCLASSIFICATION 37394 /* Security classification */ +#define TIFFTAG_EP_IMAGEHISTORY 37395 /* Record of what has been done to the image */ +#define TIFFTAG_EP_EXPOSUREINDEX 37397 /* Exposure index */ +#define TIFFTAG_EP_STANDARDID 37398 /* TIFF/EP standard version, n.n.n.n */ +#define TIFFTAG_EP_SENSINGMETHOD 37399 /* Type of image sensor */ +/* + * TIFF/EP tags equivalent to EXIF tags + * Note that TIFF-EP and EXIF use nearly the same metadata tag set, but TIFF-EP stores the tags in IFD 0, + * while EXIF store the tags in a separate IFD. Either location is allowed by DNG, but the EXIF location is preferred. + */ +#define TIFFTAG_EP_EXPOSURETIME 33434 /* Exposure time */ +#define TIFFTAG_EP_FNUMBER 33437 /* F number */ +#define TIFFTAG_EP_EXPOSUREPROGRAM 34850 /* Exposure program */ +#define TIFFTAG_EP_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ +#define TIFFTAG_EP_ISOSPEEDRATINGS 34855 /* ISO speed rating */ +#define TIFFTAG_EP_OECF 34856 /* Optoelectric conversion factor */ +#define TIFFTAG_EP_DATETIMEORIGINAL 36867 /* Date and time of original data generation */ +#define TIFFTAG_EP_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ +#define TIFFTAG_EP_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ +#define TIFFTAG_EP_APERTUREVALUE 37378 /* Aperture */ +#define TIFFTAG_EP_BRIGHTNESSVALUE 37379 /* Brightness */ +#define TIFFTAG_EP_EXPOSUREBIASVALUE 37380 /* Exposure bias */ +#define TIFFTAG_EP_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ +#define TIFFTAG_EP_SUBJECTDISTANCE 37382 /* Subject distance */ +#define TIFFTAG_EP_METERINGMODE 37383 /* Metering mode */ +#define TIFFTAG_EP_LIGHTSOURCE 37384 /* Light source */ +#define TIFFTAG_EP_FLASH 37385 /* Flash */ +#define TIFFTAG_EP_FOCALLENGTH 37386 /* Lens focal length */ +#define TIFFTAG_EP_SUBJECTLOCATION 37396 /* Subject location (area) */ + +#define TIFFTAG_RPCCOEFFICIENT 50844 /* Define by GDAL for geospatial georeferencing through RPC: http://geotiff.maptools.org/rpc_prop.html */ +#define TIFFTAG_ALIAS_LAYER_METADATA 50784 /* Alias Sketchbook Pro layer usage description. */ /* GeoTIFF DGIWG */ -#define TIFFTAG_TIFF_RSID 50908 /* https://www.awaresystems.be/imaging/tiff/tifftags/tiff_rsid.html */ -#define TIFFTAG_GEO_METADATA 50909 /* https://www.awaresystems.be/imaging/tiff/tifftags/geo_metadata.html */ - -#define TIFFTAG_EXTRACAMERAPROFILES 50933 /* http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf */ +#define TIFFTAG_TIFF_RSID 50908 /* https://www.awaresystems.be/imaging/tiff/tifftags/tiff_rsid.html */ +#define TIFFTAG_GEO_METADATA 50909 /* https://www.awaresystems.be/imaging/tiff/tifftags/geo_metadata.html */ +#define TIFFTAG_EXTRACAMERAPROFILES 50933 /* http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf */ /* tag 65535 is an undefined tag used by Eastman Kodak */ -#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ +#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ /* * The following are ``pseudo tags'' that can be used to control @@ -590,211 +693,207 @@ typedef enum { * http://www.remotesensing.org/libtiff/bugs.html with the appropriate * C definitions to add. */ -#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ -#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ -#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ -#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ -#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ -#define FAXMODE_WORDALIGN 0x0008 /* word align row */ -#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ -#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ +#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ +#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ +#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ +#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ +#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ +#define FAXMODE_WORDALIGN 0x0008 /* word align row */ +#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ +#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ /* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ -#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ -#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ -#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ -#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ -#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ -#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ +#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ +#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ +#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ +#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ +#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ +#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ /* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ -#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ -#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ -#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ -#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ -#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ -#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ -#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ -#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ +#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ +#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ +#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ +#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ +#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ +#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ +#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ +#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ /* 65550-65556 are allocated to Oceana Matrix */ -#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ -#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ -#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ -#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ -#define DCSIMAGERFILTER_IR 0 /* infrared filter */ -#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ -#define DCSIMAGERFILTER_CFA 2 /* color filter array */ -#define DCSIMAGERFILTER_OTHER 3 /* other filter */ -#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ -#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ -#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ -#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ -#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ -#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ -#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ -#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ +#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ +#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ +#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ +#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ +#define DCSIMAGERFILTER_IR 0 /* infrared filter */ +#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ +#define DCSIMAGERFILTER_CFA 2 /* color filter array */ +#define DCSIMAGERFILTER_OTHER 3 /* other filter */ +#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ +#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ +#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ +#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ +#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ +#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ +#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ +#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ /* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ -#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ -#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ +#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ +#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ /* 65559 is allocated to Oceana Matrix */ -#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ -#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ -#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ -#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ -#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ -#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ -#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ -#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ -#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ -#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */ -#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ -#define PERSAMPLE_MERGED 0 /* present as a single value */ -#define PERSAMPLE_MULTI 1 /* present as multiple values */ -#define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */ -#define TIFFTAG_LERC_VERSION 65565 /* LERC version */ -#define LERC_VERSION_2_4 4 -#define TIFFTAG_LERC_ADD_COMPRESSION 65566 /* LERC additional compression */ -#define LERC_ADD_COMPRESSION_NONE 0 -#define LERC_ADD_COMPRESSION_DEFLATE 1 -#define LERC_ADD_COMPRESSION_ZSTD 2 -#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */ -#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level */ -#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy */ -#define TIFFTAG_DEFLATE_SUBCODEC 65570 /* ZIP codec: to get/set the sub-codec to use. Will default to libdeflate when available */ -#define DEFLATE_SUBCODEC_ZLIB 0 -#define DEFLATE_SUBCODEC_LIBDEFLATE 1 +#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ +#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ +#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ +#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ +#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ +#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ +#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ +#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ +#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ +#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */ +#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ +#define PERSAMPLE_MERGED 0 /* present as a single value */ +#define PERSAMPLE_MULTI 1 /* present as multiple values */ +#define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */ +#define TIFFTAG_LERC_VERSION 65565 /* LERC version */ +#define LERC_VERSION_2_4 4 +#define TIFFTAG_LERC_ADD_COMPRESSION 65566 /* LERC additional compression */ +#define LERC_ADD_COMPRESSION_NONE 0 +#define LERC_ADD_COMPRESSION_DEFLATE 1 +#define LERC_ADD_COMPRESSION_ZSTD 2 +#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */ +#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level */ +#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy */ +#define TIFFTAG_WEBP_LOSSLESS_EXACT 65571 /* WebP lossless exact mode. Set-only mode. Default is 1. Can be set to 0 to increase compression rate, but R,G,B in areas where alpha = 0 will not be preserved */ +#define TIFFTAG_DEFLATE_SUBCODEC 65570 /* ZIP codec: to get/set the sub-codec to use. Will default to libdeflate when available */ +#define DEFLATE_SUBCODEC_ZLIB 0 +#define DEFLATE_SUBCODEC_LIBDEFLATE 1 /* * EXIF tags */ -#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */ -#define EXIFTAG_FNUMBER 33437 /* F number */ -#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */ -#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ -#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */ -#define EXIFTAG_PHOTOGRAPHICSENSITIVITY 34855 /* Photographic Sensitivity (new name for tag 34855) */ -#define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */ -#define EXIFTAG_EXIFVERSION 36864 /* Exif version */ -#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original - data generation */ -#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital - data generation */ -#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */ -#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ -#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ -#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */ -#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */ -#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */ -#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ -#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */ -#define EXIFTAG_METERINGMODE 37383 /* Metering mode */ -#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */ -#define EXIFTAG_FLASH 37385 /* Flash */ -#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */ -#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */ -#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */ -#define EXIFTAG_USERCOMMENT 37510 /* User comments */ -#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */ -#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */ -#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */ -#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */ -#define EXIFTAG_COLORSPACE 40961 /* Color space information */ -#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */ -#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */ -#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */ -#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */ -#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */ -#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */ -#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */ -#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */ -#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */ -#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */ -#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */ -#define EXIFTAG_FILESOURCE 41728 /* File source */ -#define EXIFTAG_SCENETYPE 41729 /* Scene type */ -#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */ -#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */ -#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */ -#define EXIFTAG_WHITEBALANCE 41987 /* White balance */ -#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */ -#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */ -#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */ -#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ -#define EXIFTAG_CONTRAST 41992 /* Contrast */ -#define EXIFTAG_SATURATION 41993 /* Saturation */ -#define EXIFTAG_SHARPNESS 41994 /* Sharpness */ -#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */ -#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */ -#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */ +#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */ +#define EXIFTAG_FNUMBER 33437 /* F number */ +#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */ +#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ +/* After EXIF 2.2.1 ISOSpeedRatings is named PhotographicSensitivity. + In addition, while "Count=Any", only 1 count should be used. */ +#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */ +#define EXIFTAG_PHOTOGRAPHICSENSITIVITY 34855 /* Photographic Sensitivity (new name for tag 34855) */ +#define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */ +#define EXIFTAG_EXIFVERSION 36864 /* Exif version */ +#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original data generation */ +#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital data generation */ +#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */ +#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ +#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ +#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */ +#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */ +#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */ +#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ +#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */ +#define EXIFTAG_METERINGMODE 37383 /* Metering mode */ +#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */ +#define EXIFTAG_FLASH 37385 /* Flash */ +#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */ +#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */ +#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */ +#define EXIFTAG_USERCOMMENT 37510 /* User comments */ +#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */ +#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */ +#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */ +#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */ +#define EXIFTAG_COLORSPACE 40961 /* Color space information */ +#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */ +#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */ +#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */ +#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */ +#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */ +#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */ +#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */ +#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */ +#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */ +#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */ +#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */ +#define EXIFTAG_FILESOURCE 41728 /* File source */ +#define EXIFTAG_SCENETYPE 41729 /* Scene type */ +#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */ +#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */ +#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */ +#define EXIFTAG_WHITEBALANCE 41987 /* White balance */ +#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */ +#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */ +#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */ +#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ +#define EXIFTAG_CONTRAST 41992 /* Contrast */ +#define EXIFTAG_SATURATION 41993 /* Saturation */ +#define EXIFTAG_SHARPNESS 41994 /* Sharpness */ +#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */ +#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */ +#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */ /*--: New for EXIF-Version 2.32, May 2019 ... */ -#define EXIFTAG_SENSITIVITYTYPE 34864 /* The SensitivityType tag indicates which one of the parameters of ISO12232 is the PhotographicSensitivity tag. */ -#define EXIFTAG_STANDARDOUTPUTSENSITIVITY 34865 /* This tag indicates the standard output sensitivity value of a camera or input device defined in ISO 12232. */ -#define EXIFTAG_RECOMMENDEDEXPOSUREINDEX 34866 /* recommended exposure index */ -#define EXIFTAG_ISOSPEED 34867 /* ISO speed value */ -#define EXIFTAG_ISOSPEEDLATITUDEYYY 34868 /* ISO speed latitude yyy */ -#define EXIFTAG_ISOSPEEDLATITUDEZZZ 34869 /* ISO speed latitude zzz */ -#define EXIFTAG_OFFSETTIME 36880 /* offset from UTC of the time of DateTime tag. */ -#define EXIFTAG_OFFSETTIMEORIGINAL 36881 /* offset from UTC of the time of DateTimeOriginal tag. */ -#define EXIFTAG_OFFSETTIMEDIGITIZED 36882 /* offset from UTC of the time of DateTimeDigitized tag. */ -#define EXIFTAG_TEMPERATURE 37888 /* Temperature as the ambient situation at the shot in dergee Celsius */ -#define EXIFTAG_HUMIDITY 37889 /* Humidity as the ambient situation at the shot in percent */ -#define EXIFTAG_PRESSURE 37890 /* Pressure as the ambient situation at the shot hecto-Pascal (hPa) */ -#define EXIFTAG_WATERDEPTH 37891 /* WaterDepth as the ambient situation at the shot in meter (m) */ -#define EXIFTAG_ACCELERATION 37892 /* Acceleration (a scalar regardless of direction) as the ambient situation at the shot in units of mGal (10-5 m/s^2) */ -#define EXIFTAG_CAMERAELEVATIONANGLE 37893 /* Elevation/depression. angle of the orientation of the camera(imaging optical axis) as the ambient situation at the shot in degree from -180deg to +180deg. */ -#define EXIFTAG_CAMERAOWNERNAME 42032 /* owner of a camera */ -#define EXIFTAG_BODYSERIALNUMBER 42033 /* serial number of the body of the camera */ -#define EXIFTAG_LENSSPECIFICATION 42034 /* minimum focal length (in mm), maximum focal length (in mm), minimum F number in the minimum focal length, and minimum F number in the maximum focal length, */ -#define EXIFTAG_LENSMAKE 42035 /* the lens manufacturer */ -#define EXIFTAG_LENSMODEL 42036 /* the lens model name and model number */ -#define EXIFTAG_LENSSERIALNUMBER 42037 /* the serial number of the interchangeable lens */ -#define EXIFTAG_GAMMA 42240 /* value of coefficient gamma */ -#define EXIFTAG_COMPOSITEIMAGE 42080 /* composite image */ -#define EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE 42081 /* source image number of composite image */ -#define EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE 42082 /* source exposure times of composite image */ +#define EXIFTAG_SENSITIVITYTYPE 34864 /* The SensitivityType tag indicates which one of the parameters of ISO12232 is the PhotographicSensitivity tag. */ +#define EXIFTAG_STANDARDOUTPUTSENSITIVITY 34865 /* This tag indicates the standard output sensitivity value of a camera or input device defined in ISO 12232. */ +#define EXIFTAG_RECOMMENDEDEXPOSUREINDEX 34866 /* recommended exposure index */ +#define EXIFTAG_ISOSPEED 34867 /* ISO speed value */ +#define EXIFTAG_ISOSPEEDLATITUDEYYY 34868 /* ISO speed latitude yyy */ +#define EXIFTAG_ISOSPEEDLATITUDEZZZ 34869 /* ISO speed latitude zzz */ +#define EXIFTAG_OFFSETTIME 36880 /* offset from UTC of the time of DateTime tag. */ +#define EXIFTAG_OFFSETTIMEORIGINAL 36881 /* offset from UTC of the time of DateTimeOriginal tag. */ +#define EXIFTAG_OFFSETTIMEDIGITIZED 36882 /* offset from UTC of the time of DateTimeDigitized tag. */ +#define EXIFTAG_TEMPERATURE 37888 /* Temperature as the ambient situation at the shot in dergee Celsius */ +#define EXIFTAG_HUMIDITY 37889 /* Humidity as the ambient situation at the shot in percent */ +#define EXIFTAG_PRESSURE 37890 /* Pressure as the ambient situation at the shot hecto-Pascal (hPa) */ +#define EXIFTAG_WATERDEPTH 37891 /* WaterDepth as the ambient situation at the shot in meter (m) */ +#define EXIFTAG_ACCELERATION 37892 /* Acceleration (a scalar regardless of direction) as the ambientsituation at the shot in units of mGal (10-5 m/s^2) */ +/* EXIFTAG_CAMERAELEVATIONANGLE: Elevation/depression. angle of the orientation of the camera(imaging optical axis) + * as the ambient situation at the shot in degree from -180deg to +180deg. */ +#define EXIFTAG_CAMERAELEVATIONANGLE 37893 +#define EXIFTAG_CAMERAOWNERNAME 42032 /* owner of a camera */ +#define EXIFTAG_BODYSERIALNUMBER 42033 /* serial number of the body of the camera */ +/* EXIFTAG_LENSSPECIFICATION: minimum focal length (in mm), maximum focal length (in mm),minimum F number in the minimum focal length, + * and minimum F number in the maximum focal length, */ +#define EXIFTAG_LENSSPECIFICATION 42034 +#define EXIFTAG_LENSMAKE 42035 /* the lens manufacturer */ +#define EXIFTAG_LENSMODEL 42036 /* the lens model name and model number */ +#define EXIFTAG_LENSSERIALNUMBER 42037 /* the serial number of the interchangeable lens */ +#define EXIFTAG_GAMMA 42240 /* value of coefficient gamma */ +#define EXIFTAG_COMPOSITEIMAGE 42080 /* composite image */ +#define EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE 42081 /* source image number of composite image */ +#define EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE 42082 /* source exposure times of composite image */ /* * EXIF-GPS tags (Version 2.31, July 2016) */ -#define GPSTAG_VERSIONID 0 /* Indicates the version of GPSInfoIFD. */ -#define GPSTAG_LATITUDEREF 1 /* Indicates whether the latitude is north or south latitude. */ -#define GPSTAG_LATITUDE 2 /* Indicates the latitude. */ -#define GPSTAG_LONGITUDEREF 3 /* Indicates whether the longitude is east or west longitude. */ -#define GPSTAG_LONGITUDE 4 /* Indicates the longitude. */ -#define GPSTAG_ALTITUDEREF 5 /* Indicates the altitude used as the reference altitude. */ -#define GPSTAG_ALTITUDE 6 /* Indicates the altitude based on the reference in GPSAltitudeRef. */ -#define GPSTAG_TIMESTAMP 7 /* Indicates the time as UTC (Coordinated Universal Time). */ -#define GPSTAG_SATELLITES 8 /* Indicates the GPS satellites used for measurements. */ -#define GPSTAG_STATUS 9 /* Indicates the status of the GPS receiver when the image is recorded. */ -#define GPSTAG_MEASUREMODE 10 /* Indicates the GPS measurement mode. */ -#define GPSTAG_DOP 11 /* Indicates the GPS DOP (data degree of precision). */ -#define GPSTAG_SPEEDREF 12 /* Indicates the unit used to express the GPS receiver speed of movement. */ -#define GPSTAG_SPEED 13 /* Indicates the speed of GPS receiver movement. */ -#define GPSTAG_TRACKREF 14 /* Indicates the reference for giving the direction of GPS receiver movement. */ -#define GPSTAG_TRACK 15 /* Indicates the direction of GPS receiver movement. */ -#define GPSTAG_IMGDIRECTIONREF 16 /* Indicates the reference for giving the direction of the image when it is captured. */ -#define GPSTAG_IMGDIRECTION 17 /* Indicates the direction of the image when it was captured. */ -#define GPSTAG_MAPDATUM 18 /* Indicates the geodetic survey data used by the GPS receiver. (e.g. WGS-84) */ -#define GPSTAG_DESTLATITUDEREF 19 /* Indicates whether the latitude of the destination point is north or south latitude. */ -#define GPSTAG_DESTLATITUDE 20 /* Indicates the latitude of the destination point. */ -#define GPSTAG_DESTLONGITUDEREF 21 /* Indicates whether the longitude of the destination point is east or west longitude. */ -#define GPSTAG_DESTLONGITUDE 22 /* Indicates the longitude of the destination point. */ -#define GPSTAG_DESTBEARINGREF 23 /* Indicates the reference used for giving the bearing to the destination point. */ -#define GPSTAG_DESTBEARING 24 /* Indicates the bearing to the destination point. */ -#define GPSTAG_DESTDISTANCEREF 25 /* Indicates the unit used to express the distance to the destination point. */ -#define GPSTAG_DESTDISTANCE 26 /* Indicates the distance to the destination point. */ -#define GPSTAG_PROCESSINGMETHOD 27 /* A character string recording the name of the method used for location finding. */ -#define GPSTAG_AREAINFORMATION 28 /* A character string recording the name of the GPS area. */ -#define GPSTAG_DATESTAMP 29 /* A character string recording date and time information relative to UTC (Coordinated Universal Time). */ -#define GPSTAG_DIFFERENTIAL 30 /* Indicates whether differential correction is applied to the GPS receiver. */ -#define GPSTAG_GPSHPOSITIONINGERROR 31 /* Indicates horizontal positioning errors in meters. */ +#define GPSTAG_VERSIONID 0 /* Indicates the version of GPSInfoIFD. */ +#define GPSTAG_LATITUDEREF 1 /* Indicates whether the latitude is north or south latitude. */ +#define GPSTAG_LATITUDE 2 /* Indicates the latitude. */ +#define GPSTAG_LONGITUDEREF 3 /* Indicates whether the longitude is east or west longitude. */ +#define GPSTAG_LONGITUDE 4 /* Indicates the longitude. */ +#define GPSTAG_ALTITUDEREF 5 /* Indicates the altitude used as the reference altitude. */ +#define GPSTAG_ALTITUDE 6 /* Indicates the altitude based on the reference in GPSAltitudeRef. */ +#define GPSTAG_TIMESTAMP 7 /*Indicates the time as UTC (Coordinated Universal Time). */ +#define GPSTAG_SATELLITES 8 /*Indicates the GPS satellites used for measurements. */ +#define GPSTAG_STATUS 9 /* Indicates the status of the GPS receiver when the image is recorded. */ +#define GPSTAG_MEASUREMODE 10 /* Indicates the GPS measurement mode. */ +#define GPSTAG_DOP 11 /* Indicates the GPS DOP (data degree of precision). */ +#define GPSTAG_SPEEDREF 12 /* Indicates the unit used to express the GPS receiver speed of movement. */ +#define GPSTAG_SPEED 13 /* Indicates the speed of GPS receiver movement. */ +#define GPSTAG_TRACKREF 14 /* Indicates the reference for giving the direction of GPS receiver movement. */ +#define GPSTAG_TRACK 15 /* Indicates the direction of GPS receiver movement. */ +#define GPSTAG_IMGDIRECTIONREF 16 /* Indicates the reference for giving the direction of the image when it is captured. */ +#define GPSTAG_IMGDIRECTION 17 /* Indicates the direction of the image when it was captured. */ +#define GPSTAG_MAPDATUM 18 /* Indicates the geodetic survey data used by the GPS receiver. (e.g. WGS-84) */ +#define GPSTAG_DESTLATITUDEREF 19 /* Indicates whether the latitude of the destination point is north or south latitude. */ +#define GPSTAG_DESTLATITUDE 20 /* Indicates the latitude of the destination point. */ +#define GPSTAG_DESTLONGITUDEREF 21 /* Indicates whether the longitude of the destination point is east or west longitude. */ +#define GPSTAG_DESTLONGITUDE 22 /* Indicates the longitude of the destination point. */ +#define GPSTAG_DESTBEARINGREF 23 /* Indicates the reference used for giving the bearing to the destination point. */ +#define GPSTAG_DESTBEARING 24 /* Indicates the bearing to the destination point. */ +#define GPSTAG_DESTDISTANCEREF 25 /* Indicates the unit used to express the distance to the destination point. */ +#define GPSTAG_DESTDISTANCE 26 /* Indicates the distance to the destination point. */ +#define GPSTAG_PROCESSINGMETHOD 27 /* A character string recording the name of the method used for location finding. */ +#define GPSTAG_AREAINFORMATION 28 /* A character string recording the name of the GPS area. */ +#define GPSTAG_DATESTAMP 29 /* A character string recording date and time information relative to UTC (Coordinated Universal Time). */ +#define GPSTAG_DIFFERENTIAL 30 /* Indicates whether differential correction is applied to the GPS receiver. */ +#define GPSTAG_GPSHPOSITIONINGERROR 31 /* Indicates horizontal positioning errors in meters. */ #endif /* _TIFF_ */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tiffconf.h.cmake.in b/3rdparty/libtiff/tiffconf.h.cmake.in index 9b4b032820..306874f5a7 100644 --- a/3rdparty/libtiff/tiffconf.h.cmake.in +++ b/3rdparty/libtiff/tiffconf.h.cmake.in @@ -4,9 +4,21 @@ from this file in your programs. */ +/* clang-format off */ +/* clang-format disabled because CMake scripts are very sensitive to the + * formatting of this file. configure_file variables of type "@VAR@" are + * modified by clang-format and won't be substituted. + */ + #ifndef _TIFFCONF_ #define _TIFFCONF_ + +#include +#include +#include + + /* Signed 16-bit type */ #define TIFF_INT16_T @TIFF_INT16_T@ @@ -31,23 +43,26 @@ /* Unsigned 8-bit type */ #define TIFF_UINT8_T @TIFF_UINT8_T@ -/* Unsigned size type */ -#define TIFF_SIZE_T @TIFF_SIZE_T@ - /* Signed size type */ #define TIFF_SSIZE_T @TIFF_SSIZE_T@ -/* Pointer difference type */ -#define TIFF_PTRDIFF_T @TIFF_PTRDIFF_T@ - /* Compatibility stuff. */ -/* Define as 0 or 1 according to the floating point format suported by the +/* Define as 0 or 1 according to the floating point format supported by the machine */ #cmakedefine HAVE_IEEEFP 1 -/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ -#define HOST_FILLORDER @HOST_FILLORDER@ +/* The concept of HOST_FILLORDER is broken. Since libtiff 4.5.1 + * this macro will always be hardcoded to FILLORDER_LSB2MSB on all + * architectures, to reflect past long behavior of doing so on x86 architecture. + * Note however that the default FillOrder used by libtiff is FILLORDER_MSB2LSB, + * as mandated per the TIFF specification. + * The influence of HOST_FILLORDER is only when passing the 'H' mode in + * TIFFOpen(). + * You should NOT rely on this macro to decide the CPU endianness! + * This macro will be removed in libtiff 4.6 + */ +#define HOST_FILLORDER FILLORDER_LSB2MSB /* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */ @@ -62,6 +77,9 @@ /* Support JBIG compression (requires JBIG-KIT library) */ #cmakedefine JBIG_SUPPORT +/* Support LERC compression */ +#cmakedefine LERC_SUPPORT 1 + /* Support LogLuv high dynamic range encoding */ #cmakedefine LOGLUV_SUPPORT 1 @@ -91,8 +109,8 @@ #cmakedefine LIBDEFLATE_SUPPORT 1 /* Support strip chopping (whether or not to convert single-strip uncompressed - images to mutiple strips of ~8Kb to reduce memory usage) */ -#cmakedefine STRIPCHOP_DEFAULT 1 + images to multiple strips of ~8Kb to reduce memory usage) */ +#cmakedefine STRIPCHOP_DEFAULT TIFF_STRIPCHOP /* Enable SubIFD tag (330) support */ #cmakedefine SUBIFD_SUPPORT 1 @@ -122,3 +140,5 @@ #define IPTC_SUPPORT #endif /* _TIFFCONF_ */ + +/* clang-format on */ diff --git a/3rdparty/libtiff/tiffio.h b/3rdparty/libtiff/tiffio.h index 6274f0989e..20460542f6 100644 --- a/3rdparty/libtiff/tiffio.h +++ b/3rdparty/libtiff/tiffio.h @@ -23,7 +23,7 @@ */ #ifndef _TIFFIO_ -#define _TIFFIO_ +#define _TIFFIO_ /* * TIFF I/O Library Definitions. @@ -60,20 +60,22 @@ typedef struct tiff TIFF; */ /* * this is the machine addressing size type, only it's signed, so make it - * int32 on 32bit machines, int64 on 64bit machines + * int32_t on 32bit machines, int64_t on 64bit machines */ typedef TIFF_SSIZE_T tmsize_t; -typedef uint64 toff_t; /* file offset */ +#define TIFF_TMSIZE_T_MAX (tmsize_t)(SIZE_MAX >> 1) + +typedef uint64_t toff_t; /* file offset */ /* the following are deprecated and should be replaced by their defining counterparts */ -typedef uint32 ttag_t; /* directory tag */ -typedef uint16 tdir_t; /* directory index */ -typedef uint16 tsample_t; /* sample number */ -typedef uint32 tstrile_t; /* strip or tile number */ -typedef tstrile_t tstrip_t; /* strip number */ -typedef tstrile_t ttile_t; /* tile number */ -typedef tmsize_t tsize_t; /* i/o size in bytes */ -typedef void* tdata_t; /* image data ref */ +typedef uint32_t ttag_t; /* directory tag */ +typedef uint32_t tdir_t; /* directory index */ +typedef uint16_t tsample_t; /* sample number */ +typedef uint32_t tstrile_t; /* strip or tile number */ +typedef tstrile_t tstrip_t; /* strip number */ +typedef tstrile_t ttile_t; /* tile number */ +typedef tmsize_t tsize_t; /* i/o size in bytes */ +typedef void *tdata_t; /* image data ref */ #if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32)) #define __WIN32__ @@ -87,21 +89,22 @@ typedef void* tdata_t; /* image data ref */ */ #if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows) -# if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && !defined(USE_WIN32_FILEIO) -# define AVOID_WIN32_FILEIO -# endif +#if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && \ + !defined(USE_WIN32_FILEIO) +#define AVOID_WIN32_FILEIO +#endif #endif #if defined(USE_WIN32_FILEIO) -# define VC_EXTRALEAN -# include -# ifdef __WIN32__ -DECLARE_HANDLE(thandle_t); /* Win32 file handle */ -# else -typedef HFILE thandle_t; /* client data handle */ -# endif /* __WIN32__ */ +#define VC_EXTRALEAN +#include +#ifdef __WIN32__ +DECLARE_HANDLE(thandle_t); /* Win32 file handle */ #else -typedef void* thandle_t; /* client data handle */ +typedef HFILE thandle_t; /* client data handle */ +#endif /* __WIN32__ */ +#else +typedef void *thandle_t; /* client data handle */ #endif /* USE_WIN32_FILEIO */ /* @@ -110,15 +113,15 @@ typedef void* thandle_t; /* client data handle */ * very large. Bit-or these flags to enable printing * multiple items. */ -#define TIFFPRINT_NONE 0x0 /* no extra info */ -#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ -#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ -#define TIFFPRINT_COLORMAP 0x4 /* colormap */ -#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ -#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ -#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ +#define TIFFPRINT_NONE 0x0 /* no extra info */ +#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ +#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ +#define TIFFPRINT_COLORMAP 0x4 /* colormap */ +#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ +#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ +#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ -/* +/* * Colour conversion stuff */ @@ -133,42 +136,45 @@ typedef void* thandle_t; /* client data handle */ /* Structure for holding information about a display device. */ -typedef unsigned char TIFFRGBValue; /* 8-bit samples */ +typedef unsigned char TIFFRGBValue; /* 8-bit samples */ -typedef struct { - float d_mat[3][3]; /* XYZ -> luminance matrix */ - float d_YCR; /* Light o/p for reference white */ - float d_YCG; - float d_YCB; - uint32 d_Vrwr; /* Pixel values for ref. white */ - uint32 d_Vrwg; - uint32 d_Vrwb; - float d_Y0R; /* Residual light for black pixel */ - float d_Y0G; - float d_Y0B; - float d_gammaR; /* Gamma values for the three guns */ - float d_gammaG; - float d_gammaB; +typedef struct +{ + float d_mat[3][3]; /* XYZ -> luminance matrix */ + float d_YCR; /* Light o/p for reference white */ + float d_YCG; + float d_YCB; + uint32_t d_Vrwr; /* Pixel values for ref. white */ + uint32_t d_Vrwg; + uint32_t d_Vrwb; + float d_Y0R; /* Residual light for black pixel */ + float d_Y0G; + float d_Y0B; + float d_gammaR; /* Gamma values for the three guns */ + float d_gammaG; + float d_gammaB; } TIFFDisplay; -typedef struct { /* YCbCr->RGB support */ - TIFFRGBValue* clamptab; /* range clamping table */ - int* Cr_r_tab; - int* Cb_b_tab; - int32* Cr_g_tab; - int32* Cb_g_tab; - int32* Y_tab; +typedef struct +{ /* YCbCr->RGB support */ + TIFFRGBValue *clamptab; /* range clamping table */ + int *Cr_r_tab; + int *Cb_b_tab; + int32_t *Cr_g_tab; + int32_t *Cb_g_tab; + int32_t *Y_tab; } TIFFYCbCrToRGB; -typedef struct { /* CIE Lab 1976->RGB support */ - int range; /* Size of conversion table */ +typedef struct +{ /* CIE Lab 1976->RGB support */ + int range; /* Size of conversion table */ #define CIELABTORGB_TABLE_RANGE 1500 - float rstep, gstep, bstep; - float X0, Y0, Z0; /* Reference white point */ - TIFFDisplay display; - float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ - float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ - float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ + float rstep, gstep, bstep; + float X0, Y0, Z0; /* Reference white point */ + TIFFDisplay display; + float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ + float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ + float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ } TIFFCIELabToRGB; /* @@ -178,63 +184,66 @@ typedef struct _TIFFRGBAImage TIFFRGBAImage; /* * The image reading and conversion routines invoke * ``put routines'' to copy/image/whatever tiles of - * raw image data. A default set of routines are + * raw image data. A default set of routines are * provided to convert/copy raw image data to 8-bit * packed ABGR format rasters. Applications can supply * alternate routines that unpack the data into a * different format or, for example, unpack the data * and draw the unpacked raster on the display. */ -typedef void (*tileContigRoutine) - (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, - unsigned char*); -typedef void (*tileSeparateRoutine) - (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, - unsigned char*, unsigned char*, unsigned char*, unsigned char*); +typedef void (*tileContigRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t, + uint32_t, uint32_t, uint32_t, int32_t, + int32_t, unsigned char *); +typedef void (*tileSeparateRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t, + uint32_t, uint32_t, uint32_t, int32_t, + int32_t, unsigned char *, unsigned char *, + unsigned char *, unsigned char *); /* * RGBA-reader state. */ -struct _TIFFRGBAImage { - TIFF* tif; /* image handle */ - int stoponerr; /* stop on read error */ - int isContig; /* data is packed/separate */ - int alpha; /* type of alpha data present */ - uint32 width; /* image width */ - uint32 height; /* image height */ - uint16 bitspersample; /* image bits/sample */ - uint16 samplesperpixel; /* image samples/pixel */ - uint16 orientation; /* image orientation */ - uint16 req_orientation; /* requested orientation */ - uint16 photometric; /* image photometric interp */ - uint16* redcmap; /* colormap palette */ - uint16* greencmap; - uint16* bluecmap; - /* get image data routine */ - int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32); - /* put decoded strip/tile */ - union { - void (*any)(TIFFRGBAImage*); - tileContigRoutine contig; - tileSeparateRoutine separate; - } put; - TIFFRGBValue* Map; /* sample mapping array */ - uint32** BWmap; /* black&white map */ - uint32** PALmap; /* palette image map */ - TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */ - TIFFCIELabToRGB* cielab; /* CIE L*a*b conversion state */ +struct _TIFFRGBAImage +{ + TIFF *tif; /* image handle */ + int stoponerr; /* stop on read error */ + int isContig; /* data is packed/separate */ + int alpha; /* type of alpha data present */ + uint32_t width; /* image width */ + uint32_t height; /* image height */ + uint16_t bitspersample; /* image bits/sample */ + uint16_t samplesperpixel; /* image samples/pixel */ + uint16_t orientation; /* image orientation */ + uint16_t req_orientation; /* requested orientation */ + uint16_t photometric; /* image photometric interp */ + uint16_t *redcmap; /* colormap palette */ + uint16_t *greencmap; + uint16_t *bluecmap; + /* get image data routine */ + int (*get)(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); + /* put decoded strip/tile */ + union + { + void (*any)(TIFFRGBAImage *); + tileContigRoutine contig; + tileSeparateRoutine separate; + } put; + TIFFRGBValue *Map; /* sample mapping array */ + uint32_t **BWmap; /* black&white map */ + uint32_t **PALmap; /* palette image map */ + TIFFYCbCrToRGB *ycbcr; /* YCbCr conversion state */ + TIFFCIELabToRGB *cielab; /* CIE L*a*b conversion state */ - uint8* UaToAa; /* Unassociated alpha to associated alpha conversion LUT */ - uint8* Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */ + uint8_t *UaToAa; /* Unassociated alpha to associated alpha conversion LUT */ + uint8_t *Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */ - int row_offset; - int col_offset; + int row_offset; + int col_offset; }; /* * Macros for extracting components from the * packed ABGR form returned by TIFFReadRGBAImage. */ -#define TIFFGetR(abgr) ((abgr) & 0xff) +#define TIFFGetR(abgr) ((abgr)&0xff) #define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) #define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) #define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) @@ -246,327 +255,399 @@ struct _TIFFRGBAImage { * More codecs may be registered through calls to the library * and/or the builtin implementations may be overridden. */ -typedef int (*TIFFInitMethod)(TIFF*, int); -typedef struct { - char* name; - uint16 scheme; - TIFFInitMethod init; +typedef int (*TIFFInitMethod)(TIFF *, int); +typedef struct +{ + char *name; + uint16_t scheme; + TIFFInitMethod init; } TIFFCodec; -#include +typedef struct +{ + uint32_t uNum; + uint32_t uDenom; +} TIFFRational_t; + #include +#include /* share internal LogLuv conversion routines? */ #ifndef LOGLUV_PUBLIC #define LOGLUV_PUBLIC 1 #endif -#if defined(__GNUC__) || defined(__attribute__) -# define TIFF_ATTRIBUTE(x) __attribute__(x) +#if defined(__GNUC__) || defined(__clang__) || defined(__attribute__) +#define TIFF_ATTRIBUTE(x) __attribute__(x) #else -# define TIFF_ATTRIBUTE(x) /*nothing*/ +#define TIFF_ATTRIBUTE(x) /*nothing*/ #endif #if defined(c_plusplus) || defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -typedef void (*TIFFErrorHandler)(const char*, const char*, va_list); -typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list); -typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void*, tmsize_t); -typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); -typedef int (*TIFFCloseProc)(thandle_t); -typedef toff_t (*TIFFSizeProc)(thandle_t); -typedef int (*TIFFMapFileProc)(thandle_t, void** base, toff_t* size); -typedef void (*TIFFUnmapFileProc)(thandle_t, void* base, toff_t size); -typedef void (*TIFFExtendProc)(TIFF*); + typedef void (*TIFFErrorHandler)(const char *, const char *, va_list); + typedef void (*TIFFErrorHandlerExt)(thandle_t, const char *, const char *, + va_list); + typedef int (*TIFFErrorHandlerExtR)(TIFF *, void *user_data, const char *, + const char *, va_list); + typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void *, tmsize_t); + typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); + typedef int (*TIFFCloseProc)(thandle_t); + typedef toff_t (*TIFFSizeProc)(thandle_t); + typedef int (*TIFFMapFileProc)(thandle_t, void **base, toff_t *size); + typedef void (*TIFFUnmapFileProc)(thandle_t, void *base, toff_t size); + typedef void (*TIFFExtendProc)(TIFF *); -extern const char* TIFFGetVersion(void); + extern const char *TIFFGetVersion(void); -extern const TIFFCodec* TIFFFindCODEC(uint16); -extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod); -extern void TIFFUnRegisterCODEC(TIFFCodec*); -extern int TIFFIsCODECConfigured(uint16); -extern TIFFCodec* TIFFGetConfiguredCODECs(void); + extern const TIFFCodec *TIFFFindCODEC(uint16_t); + extern TIFFCodec *TIFFRegisterCODEC(uint16_t, const char *, TIFFInitMethod); + extern void TIFFUnRegisterCODEC(TIFFCodec *); + extern int TIFFIsCODECConfigured(uint16_t); + extern TIFFCodec *TIFFGetConfiguredCODECs(void); -/* - * Auxiliary functions. - */ + /* + * Auxiliary functions. + */ -extern void* _TIFFmalloc(tmsize_t s); -extern void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz); -extern void* _TIFFrealloc(void* p, tmsize_t s); -extern void _TIFFmemset(void* p, int v, tmsize_t c); -extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c); -extern int _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c); -extern void _TIFFfree(void* p); + extern void *_TIFFmalloc(tmsize_t s); + extern void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz); + extern void *_TIFFrealloc(void *p, tmsize_t s); + extern void _TIFFmemset(void *p, int v, tmsize_t c); + extern void _TIFFmemcpy(void *d, const void *s, tmsize_t c); + extern int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c); + extern void _TIFFfree(void *p); -/* -** Stuff, related to tag handling and creating custom tags. -*/ -extern int TIFFGetTagListCount( TIFF * ); -extern uint32 TIFFGetTagListEntry( TIFF *, int tag_index ); - -#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ -#define TIFF_VARIABLE -1 /* marker for variable length tags */ -#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ -#define TIFF_VARIABLE2 -3 /* marker for uint32 var-length tags */ + /* + ** Stuff, related to tag handling and creating custom tags. + */ + extern int TIFFGetTagListCount(TIFF *); + extern uint32_t TIFFGetTagListEntry(TIFF *, int tag_index); -#define FIELD_CUSTOM 65 +#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ +#define TIFF_VARIABLE -1 /* marker for variable length tags */ +#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ +#define TIFF_VARIABLE2 -3 /* marker for uint32_t var-length tags */ -typedef struct _TIFFField TIFFField; -typedef struct _TIFFFieldArray TIFFFieldArray; +#define FIELD_CUSTOM 65 -extern const TIFFField* TIFFFindField(TIFF *, uint32, TIFFDataType); -extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32); -extern const TIFFField* TIFFFieldWithName(TIFF*, const char *); + typedef struct _TIFFField TIFFField; + typedef struct _TIFFFieldArray TIFFFieldArray; -extern uint32 TIFFFieldTag(const TIFFField*); -extern const char* TIFFFieldName(const TIFFField*); -extern TIFFDataType TIFFFieldDataType(const TIFFField*); -extern int TIFFFieldPassCount(const TIFFField*); -extern int TIFFFieldReadCount(const TIFFField*); -extern int TIFFFieldWriteCount(const TIFFField*); + extern const TIFFField *TIFFFindField(TIFF *, uint32_t, TIFFDataType); + extern const TIFFField *TIFFFieldWithTag(TIFF *, uint32_t); + extern const TIFFField *TIFFFieldWithName(TIFF *, const char *); -typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list); -typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list); -typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long); + extern uint32_t TIFFFieldTag(const TIFFField *); + extern const char *TIFFFieldName(const TIFFField *); + extern TIFFDataType TIFFFieldDataType(const TIFFField *); + extern int TIFFFieldPassCount(const TIFFField *); + extern int TIFFFieldReadCount(const TIFFField *); + extern int TIFFFieldWriteCount(const TIFFField *); + extern int + TIFFFieldSetGetSize(const TIFFField *); /* returns internal storage size of + TIFFSetGetFieldType in bytes. */ + extern int TIFFFieldSetGetCountSize( + const TIFFField *); /* returns size of count parameter 0=none, + 2=uint16_t, 4=uint32_t */ + extern int TIFFFieldIsAnonymous(const TIFFField *); -typedef struct { - TIFFVSetMethod vsetfield; /* tag set routine */ - TIFFVGetMethod vgetfield; /* tag get routine */ - TIFFPrintMethod printdir; /* directory print routine */ -} TIFFTagMethods; + typedef int (*TIFFVSetMethod)(TIFF *, uint32_t, va_list); + typedef int (*TIFFVGetMethod)(TIFF *, uint32_t, va_list); + typedef void (*TIFFPrintMethod)(TIFF *, FILE *, long); -extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *); -extern void *TIFFGetClientInfo(TIFF *, const char *); -extern void TIFFSetClientInfo(TIFF *, void *, const char *); + typedef struct + { + TIFFVSetMethod vsetfield; /* tag set routine */ + TIFFVGetMethod vgetfield; /* tag get routine */ + TIFFPrintMethod printdir; /* directory print routine */ + } TIFFTagMethods; -extern void TIFFCleanup(TIFF* tif); -extern void TIFFClose(TIFF* tif); -extern int TIFFFlush(TIFF* tif); -extern int TIFFFlushData(TIFF* tif); -extern int TIFFGetField(TIFF* tif, uint32 tag, ...); -extern int TIFFVGetField(TIFF* tif, uint32 tag, va_list ap); -extern int TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...); -extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap); -extern int TIFFReadDirectory(TIFF* tif); -extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray); -extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff); -extern int TIFFReadGPSDirectory(TIFF* tif, toff_t diroff); -extern uint64 TIFFScanlineSize64(TIFF* tif); -extern tmsize_t TIFFScanlineSize(TIFF* tif); -extern uint64 TIFFRasterScanlineSize64(TIFF* tif); -extern tmsize_t TIFFRasterScanlineSize(TIFF* tif); -extern uint64 TIFFStripSize64(TIFF* tif); -extern tmsize_t TIFFStripSize(TIFF* tif); -extern uint64 TIFFRawStripSize64(TIFF* tif, uint32 strip); -extern tmsize_t TIFFRawStripSize(TIFF* tif, uint32 strip); -extern uint64 TIFFVStripSize64(TIFF* tif, uint32 nrows); -extern tmsize_t TIFFVStripSize(TIFF* tif, uint32 nrows); -extern uint64 TIFFTileRowSize64(TIFF* tif); -extern tmsize_t TIFFTileRowSize(TIFF* tif); -extern uint64 TIFFTileSize64(TIFF* tif); -extern tmsize_t TIFFTileSize(TIFF* tif); -extern uint64 TIFFVTileSize64(TIFF* tif, uint32 nrows); -extern tmsize_t TIFFVTileSize(TIFF* tif, uint32 nrows); -extern uint32 TIFFDefaultStripSize(TIFF* tif, uint32 request); -extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*); -extern int TIFFFileno(TIFF*); -extern int TIFFSetFileno(TIFF*, int); -extern thandle_t TIFFClientdata(TIFF*); -extern thandle_t TIFFSetClientdata(TIFF*, thandle_t); -extern int TIFFGetMode(TIFF*); -extern int TIFFSetMode(TIFF*, int); -extern int TIFFIsTiled(TIFF*); -extern int TIFFIsByteSwapped(TIFF*); -extern int TIFFIsUpSampled(TIFF*); -extern int TIFFIsMSB2LSB(TIFF*); -extern int TIFFIsBigEndian(TIFF*); -extern TIFFReadWriteProc TIFFGetReadProc(TIFF*); -extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*); -extern TIFFSeekProc TIFFGetSeekProc(TIFF*); -extern TIFFCloseProc TIFFGetCloseProc(TIFF*); -extern TIFFSizeProc TIFFGetSizeProc(TIFF*); -extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*); -extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*); -extern uint32 TIFFCurrentRow(TIFF*); -extern uint16 TIFFCurrentDirectory(TIFF*); -extern uint16 TIFFNumberOfDirectories(TIFF*); -extern uint64 TIFFCurrentDirOffset(TIFF*); -extern uint32 TIFFCurrentStrip(TIFF*); -extern uint32 TIFFCurrentTile(TIFF* tif); -extern int TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size); -extern int TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size); -extern int TIFFSetupStrips(TIFF *); -extern int TIFFWriteCheck(TIFF*, int, const char *); -extern void TIFFFreeDirectory(TIFF*); -extern int TIFFCreateDirectory(TIFF*); -extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*); -extern int TIFFCreateEXIFDirectory(TIFF*); -extern int TIFFCreateGPSDirectory(TIFF*); -extern int TIFFLastDirectory(TIFF*); -extern int TIFFSetDirectory(TIFF*, uint16); -extern int TIFFSetSubDirectory(TIFF*, uint64); -extern int TIFFUnlinkDirectory(TIFF*, uint16); -extern int TIFFSetField(TIFF*, uint32, ...); -extern int TIFFVSetField(TIFF*, uint32, va_list); -extern int TIFFUnsetField(TIFF*, uint32); -extern int TIFFWriteDirectory(TIFF *); -extern int TIFFWriteCustomDirectory(TIFF *, uint64 *); -extern int TIFFCheckpointDirectory(TIFF *); -extern int TIFFRewriteDirectory(TIFF *); -extern int TIFFDeferStrileArrayWriting(TIFF *); -extern int TIFFForceStrileArrayWriting(TIFF* ); + extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *); + extern void *TIFFGetClientInfo(TIFF *, const char *); + extern void TIFFSetClientInfo(TIFF *, void *, const char *); + + extern void TIFFCleanup(TIFF *tif); + extern void TIFFClose(TIFF *tif); + extern int TIFFFlush(TIFF *tif); + extern int TIFFFlushData(TIFF *tif); + extern int TIFFGetField(TIFF *tif, uint32_t tag, ...); + extern int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap); + extern int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...); + extern int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap); + extern int TIFFReadDirectory(TIFF *tif); + extern int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, + const TIFFFieldArray *infoarray); + extern int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff); + extern int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff); + extern uint64_t TIFFScanlineSize64(TIFF *tif); + extern tmsize_t TIFFScanlineSize(TIFF *tif); + extern uint64_t TIFFRasterScanlineSize64(TIFF *tif); + extern tmsize_t TIFFRasterScanlineSize(TIFF *tif); + extern uint64_t TIFFStripSize64(TIFF *tif); + extern tmsize_t TIFFStripSize(TIFF *tif); + extern uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip); + extern tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip); + extern uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows); + extern tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows); + extern uint64_t TIFFTileRowSize64(TIFF *tif); + extern tmsize_t TIFFTileRowSize(TIFF *tif); + extern uint64_t TIFFTileSize64(TIFF *tif); + extern tmsize_t TIFFTileSize(TIFF *tif); + extern uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows); + extern tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows); + extern uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request); + extern void TIFFDefaultTileSize(TIFF *, uint32_t *, uint32_t *); + extern int TIFFFileno(TIFF *); + extern int TIFFSetFileno(TIFF *, int); + extern thandle_t TIFFClientdata(TIFF *); + extern thandle_t TIFFSetClientdata(TIFF *, thandle_t); + extern int TIFFGetMode(TIFF *); + extern int TIFFSetMode(TIFF *, int); + extern int TIFFIsTiled(TIFF *); + extern int TIFFIsByteSwapped(TIFF *); + extern int TIFFIsUpSampled(TIFF *); + extern int TIFFIsMSB2LSB(TIFF *); + extern int TIFFIsBigEndian(TIFF *); + extern int TIFFIsBigTIFF(TIFF *); + extern TIFFReadWriteProc TIFFGetReadProc(TIFF *); + extern TIFFReadWriteProc TIFFGetWriteProc(TIFF *); + extern TIFFSeekProc TIFFGetSeekProc(TIFF *); + extern TIFFCloseProc TIFFGetCloseProc(TIFF *); + extern TIFFSizeProc TIFFGetSizeProc(TIFF *); + extern TIFFMapFileProc TIFFGetMapFileProc(TIFF *); + extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *); + extern uint32_t TIFFCurrentRow(TIFF *); + extern tdir_t TIFFCurrentDirectory(TIFF *); + extern tdir_t TIFFNumberOfDirectories(TIFF *); + extern uint64_t TIFFCurrentDirOffset(TIFF *); + extern uint32_t TIFFCurrentStrip(TIFF *); + extern uint32_t TIFFCurrentTile(TIFF *tif); + extern int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size); + extern int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size); + extern int TIFFSetupStrips(TIFF *); + extern int TIFFWriteCheck(TIFF *, int, const char *); + extern void TIFFFreeDirectory(TIFF *); + extern int TIFFCreateDirectory(TIFF *); + extern int TIFFCreateCustomDirectory(TIFF *, const TIFFFieldArray *); + extern int TIFFCreateEXIFDirectory(TIFF *); + extern int TIFFCreateGPSDirectory(TIFF *); + extern int TIFFLastDirectory(TIFF *); + extern int TIFFSetDirectory(TIFF *, tdir_t); + extern int TIFFSetSubDirectory(TIFF *, uint64_t); + extern int TIFFUnlinkDirectory(TIFF *, tdir_t); + extern int TIFFSetField(TIFF *, uint32_t, ...); + extern int TIFFVSetField(TIFF *, uint32_t, va_list); + extern int TIFFUnsetField(TIFF *, uint32_t); + extern int TIFFWriteDirectory(TIFF *); + extern int TIFFWriteCustomDirectory(TIFF *, uint64_t *); + extern int TIFFCheckpointDirectory(TIFF *); + extern int TIFFRewriteDirectory(TIFF *); + extern int TIFFDeferStrileArrayWriting(TIFF *); + extern int TIFFForceStrileArrayWriting(TIFF *); #if defined(c_plusplus) || defined(__cplusplus) -extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0); -extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0); -extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0); -extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0); -extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, - int = ORIENTATION_BOTLEFT, int = 0); + extern void TIFFPrintDirectory(TIFF *, FILE *, long = 0); + extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, + uint16_t sample = 0); + extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, + uint16_t sample = 0); + extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *, + int = 0); + extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *, + int = ORIENTATION_BOTLEFT, int = 0); #else -extern void TIFFPrintDirectory(TIFF*, FILE*, long); -extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample); -extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample); -extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int); -extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int); +extern void TIFFPrintDirectory(TIFF *, FILE *, long); +extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, + uint16_t sample); +extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, + uint16_t sample); +extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *, int); +extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *, + int, int); #endif -extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * ); -extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * ); -extern int TIFFReadRGBAStripExt(TIFF*, uint32, uint32 *, int stop_on_error ); -extern int TIFFReadRGBATileExt(TIFF*, uint32, uint32, uint32 *, int stop_on_error ); -extern int TIFFRGBAImageOK(TIFF*, char [1024]); -extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); -extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32); -extern void TIFFRGBAImageEnd(TIFFRGBAImage*); -extern TIFF* TIFFOpen(const char*, const char*); -# ifdef __WIN32__ -extern TIFF* TIFFOpenW(const wchar_t*, const char*); -# endif /* __WIN32__ */ -extern TIFF* TIFFFdOpen(int, const char*, const char*); -extern TIFF* TIFFClientOpen(const char*, const char*, - thandle_t, - TIFFReadWriteProc, TIFFReadWriteProc, - TIFFSeekProc, TIFFCloseProc, - TIFFSizeProc, - TIFFMapFileProc, TIFFUnmapFileProc); -extern const char* TIFFFileName(TIFF*); -extern const char* TIFFSetFileName(TIFF*, const char *); -extern void TIFFError(const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,2,3))); -extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4))); -extern void TIFFWarning(const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,2,3))); -extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4))); -extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); -extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt); -extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); -extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt); -extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); -extern uint32 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s); -extern int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s); -extern uint32 TIFFNumberOfTiles(TIFF*); -extern tmsize_t TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s); -extern tmsize_t TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s); -extern uint32 TIFFComputeStrip(TIFF*, uint32, uint16); -extern uint32 TIFFNumberOfStrips(TIFF*); -extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size); -extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size); -extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size); -extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size); -extern int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile, - void* inbuf, tmsize_t insize, - void* outbuf, tmsize_t outsize); -extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc); -extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc); -extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc); -extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc); -extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */ -extern void TIFFSetWriteOffset(TIFF* tif, toff_t off); -extern void TIFFSwabShort(uint16*); -extern void TIFFSwabLong(uint32*); -extern void TIFFSwabLong8(uint64*); -extern void TIFFSwabFloat(float*); -extern void TIFFSwabDouble(double*); -extern void TIFFSwabArrayOfShort(uint16* wp, tmsize_t n); -extern void TIFFSwabArrayOfTriples(uint8* tp, tmsize_t n); -extern void TIFFSwabArrayOfLong(uint32* lp, tmsize_t n); -extern void TIFFSwabArrayOfLong8(uint64* lp, tmsize_t n); -extern void TIFFSwabArrayOfFloat(float* fp, tmsize_t n); -extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n); -extern void TIFFReverseBits(uint8* cp, tmsize_t n); -extern const unsigned char* TIFFGetBitRevTable(int); + extern int TIFFReadRGBAStrip(TIFF *, uint32_t, uint32_t *); + extern int TIFFReadRGBATile(TIFF *, uint32_t, uint32_t, uint32_t *); + extern int TIFFReadRGBAStripExt(TIFF *, uint32_t, uint32_t *, + int stop_on_error); + extern int TIFFReadRGBATileExt(TIFF *, uint32_t, uint32_t, uint32_t *, + int stop_on_error); + extern int TIFFRGBAImageOK(TIFF *, char[1024]); + extern int TIFFRGBAImageBegin(TIFFRGBAImage *, TIFF *, int, char[1024]); + extern int TIFFRGBAImageGet(TIFFRGBAImage *, uint32_t *, uint32_t, + uint32_t); + extern void TIFFRGBAImageEnd(TIFFRGBAImage *); -extern uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile); -extern uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile); -extern uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr); -extern uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr); + extern const char *TIFFFileName(TIFF *); + extern const char *TIFFSetFileName(TIFF *, const char *); + extern void TIFFError(const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 2, 3))); + extern void TIFFErrorExt(thandle_t, const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); + extern void TIFFWarning(const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 2, 3))); + extern void TIFFWarningExt(thandle_t, const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); + extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); + extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt); + extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); + extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt); + + extern void TIFFWarningExtR(TIFF *, const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); + extern void TIFFErrorExtR(TIFF *, const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); + + typedef struct TIFFOpenOptions TIFFOpenOptions; + extern TIFFOpenOptions *TIFFOpenOptionsAlloc(void); + extern void TIFFOpenOptionsFree(TIFFOpenOptions *); + extern void + TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts, + tmsize_t max_single_mem_alloc); + extern void + TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts, + TIFFErrorHandlerExtR handler, + void *errorhandler_user_data); + extern void + TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts, + TIFFErrorHandlerExtR handler, + void *warnhandler_user_data); + + extern TIFF *TIFFOpen(const char *, const char *); + extern TIFF *TIFFOpenExt(const char *, const char *, TIFFOpenOptions *opts); +#ifdef __WIN32__ + extern TIFF *TIFFOpenW(const wchar_t *, const char *); + extern TIFF *TIFFOpenWExt(const wchar_t *, const char *, + TIFFOpenOptions *opts); +#endif /* __WIN32__ */ + extern TIFF *TIFFFdOpen(int, const char *, const char *); + extern TIFF *TIFFFdOpenExt(int, const char *, const char *, + TIFFOpenOptions *opts); + extern TIFF *TIFFClientOpen(const char *, const char *, thandle_t, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc); + extern TIFF *TIFFClientOpenExt(const char *, const char *, thandle_t, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc, + TIFFOpenOptions *opts); + extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); + extern uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, + uint32_t z, uint16_t s); + extern int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, + uint16_t s); + extern uint32_t TIFFNumberOfTiles(TIFF *); + extern tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, + uint32_t z, uint16_t s); + extern tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, + uint32_t z, uint16_t s); + extern uint32_t TIFFComputeStrip(TIFF *, uint32_t, uint16_t); + extern uint32_t TIFFNumberOfStrips(TIFF *); + extern tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size); + extern tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size); + extern tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, + tmsize_t size); + extern tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, + tmsize_t size); + extern int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, + tmsize_t insize, void *outbuf, + tmsize_t outsize); + extern tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data, + tmsize_t cc); + extern tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, + tmsize_t cc); + extern tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, + tmsize_t cc); + extern tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, + tmsize_t cc); + extern int TIFFDataWidth( + TIFFDataType); /* table of tag datatype widths within TIFF file. */ + extern void TIFFSetWriteOffset(TIFF *tif, toff_t off); + extern void TIFFSwabShort(uint16_t *); + extern void TIFFSwabLong(uint32_t *); + extern void TIFFSwabLong8(uint64_t *); + extern void TIFFSwabFloat(float *); + extern void TIFFSwabDouble(double *); + extern void TIFFSwabArrayOfShort(uint16_t *wp, tmsize_t n); + extern void TIFFSwabArrayOfTriples(uint8_t *tp, tmsize_t n); + extern void TIFFSwabArrayOfLong(uint32_t *lp, tmsize_t n); + extern void TIFFSwabArrayOfLong8(uint64_t *lp, tmsize_t n); + extern void TIFFSwabArrayOfFloat(float *fp, tmsize_t n); + extern void TIFFSwabArrayOfDouble(double *dp, tmsize_t n); + extern void TIFFReverseBits(uint8_t *cp, tmsize_t n); + extern const unsigned char *TIFFGetBitRevTable(int); + + extern uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile); + extern uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile); + extern uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, + int *pbErr); + extern uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, + int *pbErr); #ifdef LOGLUV_PUBLIC -#define U_NEU 0.210526316 -#define V_NEU 0.473684211 -#define UVSCALE 410. -extern double LogL16toY(int); -extern double LogL10toY(int); -extern void XYZtoRGB24(float*, uint8*); -extern int uv_decode(double*, double*, int); -extern void LogLuv24toXYZ(uint32, float*); -extern void LogLuv32toXYZ(uint32, float*); +#define U_NEU 0.210526316 +#define V_NEU 0.473684211 +#define UVSCALE 410. + extern double LogL16toY(int); + extern double LogL10toY(int); + extern void XYZtoRGB24(float *, uint8_t *); + extern int uv_decode(double *, double *, int); + extern void LogLuv24toXYZ(uint32_t, float *); + extern void LogLuv32toXYZ(uint32_t, float *); #if defined(c_plusplus) || defined(__cplusplus) -extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER); -extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER); -extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER); -extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER); -extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER); + extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER); + extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER); + extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER); + extern uint32_t LogLuv24fromXYZ(float *, int = SGILOGENCODE_NODITHER); + extern uint32_t LogLuv32fromXYZ(float *, int = SGILOGENCODE_NODITHER); #else -extern int LogL16fromY(double, int); -extern int LogL10fromY(double, int); -extern int uv_encode(double, double, int); -extern uint32 LogLuv24fromXYZ(float*, int); -extern uint32 LogLuv32fromXYZ(float*, int); + extern int LogL16fromY(double, int); + extern int LogL10fromY(double, int); + extern int uv_encode(double, double, int); + extern uint32_t LogLuv24fromXYZ(float *, int); + extern uint32_t LogLuv32fromXYZ(float *, int); #endif #endif /* LOGLUV_PUBLIC */ -extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*); -extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32, - float *, float *, float *); -extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, - uint32 *, uint32 *, uint32 *); + extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB *, const TIFFDisplay *, + float *); + extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32_t, int32_t, int32_t, + float *, float *, float *); + extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, uint32_t *, + uint32_t *, uint32_t *); -extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*); -extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32, - uint32 *, uint32 *, uint32 *); + extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *, float *, float *); + extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32_t, int32_t, int32_t, + uint32_t *, uint32_t *, uint32_t *); -/**************************************************************************** - * O B S O L E T E D I N T E R F A C E S - * - * Don't use this stuff in your applications, it may be removed in the future - * libtiff versions. - ****************************************************************************/ -typedef struct { - ttag_t field_tag; /* field's tag */ - short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ - short field_writecount; /* write count/TIFF_VARIABLE */ - TIFFDataType field_type; /* type of associated data */ - unsigned short field_bit; /* bit in fieldsset bit vector */ - unsigned char field_oktochange; /* if true, can change while writing */ - unsigned char field_passcount; /* if true, pass dir count on set */ - char *field_name; /* ASCII name */ -} TIFFFieldInfo; + /**************************************************************************** + * O B S O L E T E D I N T E R F A C E S + * + * Don't use this stuff in your applications, it may be removed in the + *future libtiff versions. + ****************************************************************************/ + typedef struct + { + ttag_t field_tag; /* field's tag */ + short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ + short field_writecount; /* write count/TIFF_VARIABLE */ + TIFFDataType field_type; /* type of associated data */ + unsigned short field_bit; /* bit in fieldsset bit vector */ + unsigned char field_oktochange; /* if true, can change while writing */ + unsigned char field_passcount; /* if true, pass dir count on set */ + char *field_name; /* ASCII name */ + } TIFFFieldInfo; + + extern int TIFFMergeFieldInfo(TIFF *, const TIFFFieldInfo[], uint32_t); -extern int TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], uint32); - #if defined(c_plusplus) || defined(__cplusplus) } #endif #endif /* _TIFFIO_ */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tiffio.hxx b/3rdparty/libtiff/tiffio.hxx index df2cbbceb7..6182449b13 100644 --- a/3rdparty/libtiff/tiffio.hxx +++ b/3rdparty/libtiff/tiffio.hxx @@ -2,47 +2,38 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _TIFFIO_HXX_ -#define _TIFFIO_HXX_ +#define _TIFFIO_HXX_ /* * TIFF I/O library definitions which provide C++ streams API. */ -#include #include "tiff.h" #include "tiffio.h" +#include -extern TIFF* TIFFStreamOpen(const char*, std::ostream *); -extern TIFF* TIFFStreamOpen(const char*, std::istream *); +extern TIFF *TIFFStreamOpen(const char *, std::ostream *); +extern TIFF *TIFFStreamOpen(const char *, std::istream *); #endif /* _TIFFIO_HXX_ */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c++ - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tiffiop.h b/3rdparty/libtiff/tiffiop.h index 39b54c8966..fbf7b0700b 100644 --- a/3rdparty/libtiff/tiffiop.h +++ b/3rdparty/libtiff/tiffiop.h @@ -2,28 +2,28 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _TIFFIOP_ -#define _TIFFIOP_ +#define _TIFFIOP_ /* * ``Library-private'' definitions. */ @@ -31,66 +31,48 @@ #include "tif_config.h" #ifdef HAVE_FCNTL_H -# include +#include #endif #ifdef HAVE_SYS_TYPES_H -# include +#include #endif -#ifdef HAVE_STRING_H -# include -#endif +#include #ifdef HAVE_ASSERT_H -# include +#include #else -# define assert(x) -#endif - -#ifdef HAVE_SEARCH_H -# include -#else -extern void *lfind(const void *, const void *, size_t *, size_t, - int (*)(const void *, const void *)); -#endif - -#if !defined(HAVE_SNPRINTF) && !defined(HAVE__SNPRINTF) -#undef snprintf -#define snprintf _TIFF_snprintf_f -extern int snprintf(char* str, size_t size, const char* format, ...); +#define assert(x) #endif +#include "tif_hash_set.h" #include "tiffio.h" #include "tif_dir.h" +#include + #ifndef STRIP_SIZE_DEFAULT -# define STRIP_SIZE_DEFAULT 8192 +#define STRIP_SIZE_DEFAULT 8192 #endif -#define streq(a,b) (strcmp(a,b) == 0) -#define strneq(a,b,n) (strncmp(a,b,n) == 0) +#ifndef TIFF_MAX_DIR_COUNT +#define TIFF_MAX_DIR_COUNT 1048576 +#endif + +#define TIFF_NON_EXISTENT_DIR_NUMBER UINT_MAX + +#define streq(a, b) (strcmp(a, b) == 0) +#define strneq(a, b, n) (strncmp(a, b, n) == 0) #ifndef TRUE -#define TRUE 1 -#define FALSE 0 +#define TRUE 1 +#define FALSE 0 #endif -#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) -#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) - -/* - * Largest 32-bit unsigned integer value. - */ -#define TIFF_UINT32_MAX 0xFFFFFFFFU - -/* - * Largest 64-bit unsigned integer value. - */ -#define TIFF_UINT64_MAX (((uint64)(TIFF_UINT32_MAX)) << 32 | TIFF_UINT32_MAX) - -typedef struct client_info { +typedef struct client_info +{ struct client_info *next; void *data; char *name; @@ -100,187 +82,231 @@ typedef struct client_info { * Typedefs for ``method pointers'' used internally. * these are deprecated and provided only for backwards compatibility. */ -typedef unsigned char tidataval_t; /* internal image data value type */ -typedef tidataval_t* tidata_t; /* reference to internal image data */ +typedef unsigned char tidataval_t; /* internal image data value type */ +typedef tidataval_t *tidata_t; /* reference to internal image data */ -typedef void (*TIFFVoidMethod)(TIFF*); -typedef int (*TIFFBoolMethod)(TIFF*); -typedef int (*TIFFPreMethod)(TIFF*, uint16); -typedef int (*TIFFCodeMethod)(TIFF* tif, uint8* buf, tmsize_t size, uint16 sample); -typedef int (*TIFFSeekMethod)(TIFF*, uint32); -typedef void (*TIFFPostMethod)(TIFF* tif, uint8* buf, tmsize_t size); -typedef uint32 (*TIFFStripMethod)(TIFF*, uint32); -typedef void (*TIFFTileMethod)(TIFF*, uint32*, uint32*); +typedef void (*TIFFVoidMethod)(TIFF *); +typedef int (*TIFFBoolMethod)(TIFF *); +typedef int (*TIFFPreMethod)(TIFF *, uint16_t); +typedef int (*TIFFCodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size, + uint16_t sample); +typedef int (*TIFFSeekMethod)(TIFF *, uint32_t); +typedef void (*TIFFPostMethod)(TIFF *tif, uint8_t *buf, tmsize_t size); +typedef uint32_t (*TIFFStripMethod)(TIFF *, uint32_t); +typedef void (*TIFFTileMethod)(TIFF *, uint32_t *, uint32_t *); -struct tiff { - char* tif_name; /* name of open file */ - int tif_fd; /* open file descriptor */ - int tif_mode; /* open mode (O_*) */ - uint32 tif_flags; - #define TIFF_FILLORDER 0x00003U /* natural bit fill order for machine */ - #define TIFF_DIRTYHEADER 0x00004U /* header must be written on close */ - #define TIFF_DIRTYDIRECT 0x00008U /* current directory must be written */ - #define TIFF_BUFFERSETUP 0x00010U /* data buffers setup */ - #define TIFF_CODERSETUP 0x00020U /* encoder/decoder setup done */ - #define TIFF_BEENWRITING 0x00040U /* written 1+ scanlines to file */ - #define TIFF_SWAB 0x00080U /* byte swap file information */ - #define TIFF_NOBITREV 0x00100U /* inhibit bit reversal logic */ - #define TIFF_MYBUFFER 0x00200U /* my raw data buffer; free on close */ - #define TIFF_ISTILED 0x00400U /* file is tile, not strip- based */ - #define TIFF_MAPPED 0x00800U /* file is mapped into memory */ - #define TIFF_POSTENCODE 0x01000U /* need call to postencode routine */ - #define TIFF_INSUBIFD 0x02000U /* currently writing a subifd */ - #define TIFF_UPSAMPLED 0x04000U /* library is doing data up-sampling */ - #define TIFF_STRIPCHOP 0x08000U /* enable strip chopping support */ - #define TIFF_HEADERONLY 0x10000U /* read header only, do not process the first directory */ - #define TIFF_NOREADRAW 0x20000U /* skip reading of raw uncompressed image data */ - #define TIFF_INCUSTOMIFD 0x40000U /* currently writing a custom IFD */ - #define TIFF_BIGTIFF 0x80000U /* read/write bigtiff */ - #define TIFF_BUF4WRITE 0x100000U /* rawcc bytes are for writing */ - #define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/ - #define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */ - #define TIFF_BUFFERMMAP 0x800000U /* read buffer (tif_rawdata) points into mmap() memory */ - #define TIFF_DEFERSTRILELOAD 0x1000000U /* defer strip/tile offset/bytecount array loading. */ - #define TIFF_LAZYSTRILELOAD 0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. Only used if TIFF_DEFERSTRILELOAD is set and in read-only mode */ - #define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip array */ - uint64 tif_diroff; /* file offset of current directory */ - uint64 tif_nextdiroff; /* file offset of following directory */ - uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */ - uint16 tif_dirlistsize; /* number of entries in offset list */ - uint16 tif_dirnumber; /* number of already seen directories */ - TIFFDirectory tif_dir; /* internal rep of current directory */ - TIFFDirectory tif_customdir; /* custom IFDs are separated from the main ones */ - union { - TIFFHeaderCommon common; - TIFFHeaderClassic classic; - TIFFHeaderBig big; - } tif_header; - uint16 tif_header_size; /* file's header block and its length */ - uint32 tif_row; /* current scanline */ - uint16 tif_curdir; /* current directory (index) */ - uint32 tif_curstrip; /* current strip for read/write */ - uint64 tif_curoff; /* current offset for read/write */ - uint64 tif_dataoff; /* current offset for writing dir */ - /* SubIFD support */ - uint16 tif_nsubifd; /* remaining subifds to write */ - uint64 tif_subifdoff; /* offset for patching SubIFD link */ - /* tiling support */ - uint32 tif_col; /* current column (offset by row too) */ - uint32 tif_curtile; /* current tile for read/write */ - tmsize_t tif_tilesize; /* # of bytes in a tile */ - /* compression scheme hooks */ - int tif_decodestatus; - TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */ - TIFFBoolMethod tif_setupdecode; /* called once before predecode */ - TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ - TIFFBoolMethod tif_setupencode; /* called once before preencode */ - int tif_encodestatus; - TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ - TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ - TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ - TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ - TIFFCodeMethod tif_decodestrip; /* strip decoding routine */ - TIFFCodeMethod tif_encodestrip; /* strip encoding routine */ - TIFFCodeMethod tif_decodetile; /* tile decoding routine */ - TIFFCodeMethod tif_encodetile; /* tile encoding routine */ - TIFFVoidMethod tif_close; /* cleanup-on-close routine */ - TIFFSeekMethod tif_seek; /* position within a strip routine */ - TIFFVoidMethod tif_cleanup; /* cleanup state routine */ - TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */ - TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */ - uint8* tif_data; /* compression scheme private data */ - /* input/output buffering */ - tmsize_t tif_scanlinesize; /* # of bytes in a scanline */ - tmsize_t tif_scanlineskew; /* scanline skew for reading strips */ - uint8* tif_rawdata; /* raw data buffer */ - tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */ - tmsize_t tif_rawdataoff; /* rawdata offset within strip */ - tmsize_t tif_rawdataloaded;/* amount of data in rawdata */ - uint8* tif_rawcp; /* current spot in raw buffer */ - tmsize_t tif_rawcc; /* bytes unread from raw buffer */ - /* memory-mapped file support */ - uint8* tif_base; /* base of mapped file */ - tmsize_t tif_size; /* size of mapped file region (bytes, thus tmsize_t) */ - TIFFMapFileProc tif_mapproc; /* map file method */ - TIFFUnmapFileProc tif_unmapproc; /* unmap file method */ - /* input/output callback methods */ - thandle_t tif_clientdata; /* callback parameter */ - TIFFReadWriteProc tif_readproc; /* read method */ - TIFFReadWriteProc tif_writeproc; /* write method */ - TIFFSeekProc tif_seekproc; /* lseek method */ - TIFFCloseProc tif_closeproc; /* close method */ - TIFFSizeProc tif_sizeproc; /* filesize method */ - /* post-decoding support */ - TIFFPostMethod tif_postdecode; /* post decoding routine */ - /* tag support */ - TIFFField** tif_fields; /* sorted table of registered tags */ - size_t tif_nfields; /* # entries in registered tag table */ - const TIFFField* tif_foundfield; /* cached pointer to already found tag */ - TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */ - TIFFClientInfoLink* tif_clientinfo; /* extra client information. */ - /* Backward compatibility stuff. We need these two fields for - * setting up an old tag extension scheme. */ - TIFFFieldArray* tif_fieldscompat; - size_t tif_nfieldscompat; +struct TIFFOffsetAndDirNumber +{ + uint64_t offset; + tdir_t dirNumber; +}; +typedef struct TIFFOffsetAndDirNumber TIFFOffsetAndDirNumber; + +struct tiff +{ + char *tif_name; /* name of open file */ + int tif_fd; /* open file descriptor */ + int tif_mode; /* open mode (O_*) */ + uint32_t tif_flags; +#define TIFF_FILLORDER 0x00003U /* natural bit fill order for machine */ +#define TIFF_DIRTYHEADER 0x00004U /* header must be written on close */ +#define TIFF_DIRTYDIRECT 0x00008U /* current directory must be written */ +#define TIFF_BUFFERSETUP 0x00010U /* data buffers setup */ +#define TIFF_CODERSETUP 0x00020U /* encoder/decoder setup done */ +#define TIFF_BEENWRITING 0x00040U /* written 1+ scanlines to file */ +#define TIFF_SWAB 0x00080U /* byte swap file information */ +#define TIFF_NOBITREV 0x00100U /* inhibit bit reversal logic */ +#define TIFF_MYBUFFER 0x00200U /* my raw data buffer; free on close */ +#define TIFF_ISTILED 0x00400U /* file is tile, not strip- based */ +#define TIFF_MAPPED 0x00800U /* file is mapped into memory */ +#define TIFF_POSTENCODE 0x01000U /* need call to postencode routine */ +#define TIFF_INSUBIFD 0x02000U /* currently writing a subifd */ +#define TIFF_UPSAMPLED 0x04000U /* library is doing data up-sampling */ +#define TIFF_STRIPCHOP 0x08000U /* enable strip chopping support */ +#define TIFF_HEADERONLY \ + 0x10000U /* read header only, do not process the first directory */ +#define TIFF_NOREADRAW \ + 0x20000U /* skip reading of raw uncompressed image data */ +#define TIFF_INCUSTOMIFD 0x40000U /* currently writing a custom IFD */ +#define TIFF_BIGTIFF 0x80000U /* read/write bigtiff */ +#define TIFF_BUF4WRITE 0x100000U /* rawcc bytes are for writing */ +#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/ +#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */ +#define TIFF_BUFFERMMAP \ + 0x800000U /* read buffer (tif_rawdata) points into mmap() memory */ +#define TIFF_DEFERSTRILELOAD \ + 0x1000000U /* defer strip/tile offset/bytecount array loading. */ +#define TIFF_LAZYSTRILELOAD \ + 0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. \ + Only used if TIFF_DEFERSTRILELOAD is set and in read-only \ + mode */ +#define TIFF_CHOPPEDUPARRAYS \ + 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip \ + array */ + uint64_t tif_diroff; /* file offset of current directory */ + uint64_t tif_nextdiroff; /* file offset of following directory */ + uint64_t tif_lastdiroff; /* file offset of last directory written so far */ + TIFFHashSet *tif_map_dir_offset_to_number; + TIFFHashSet *tif_map_dir_number_to_offset; + int tif_setdirectory_force_absolute; /* switch between relative and absolute + stepping in TIFFSetDirectory() */ + TIFFDirectory tif_dir; /* internal rep of current directory */ + TIFFDirectory + tif_customdir; /* custom IFDs are separated from the main ones */ + union + { + TIFFHeaderCommon common; + TIFFHeaderClassic classic; + TIFFHeaderBig big; + } tif_header; + uint16_t tif_header_size; /* file's header block and its length */ + uint32_t tif_row; /* current scanline */ + tdir_t tif_curdir; /* current directory (index) */ + uint32_t tif_curstrip; /* current strip for read/write */ + uint64_t tif_curoff; /* current offset for read/write */ + uint64_t tif_lastvalidoff; /* last valid offset allowed for rewrite in + place. Used only by TIFFAppendToStrip() */ + uint64_t tif_dataoff; /* current offset for writing dir */ + /* SubIFD support */ + uint16_t tif_nsubifd; /* remaining subifds to write */ + uint64_t tif_subifdoff; /* offset for patching SubIFD link */ + /* tiling support */ + uint32_t tif_col; /* current column (offset by row too) */ + uint32_t tif_curtile; /* current tile for read/write */ + tmsize_t tif_tilesize; /* # of bytes in a tile */ + /* compression scheme hooks */ + int tif_decodestatus; + TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */ + TIFFBoolMethod tif_setupdecode; /* called once before predecode */ + TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ + TIFFBoolMethod tif_setupencode; /* called once before preencode */ + int tif_encodestatus; + TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ + TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ + TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ + TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ + TIFFCodeMethod tif_decodestrip; /* strip decoding routine */ + TIFFCodeMethod tif_encodestrip; /* strip encoding routine */ + TIFFCodeMethod tif_decodetile; /* tile decoding routine */ + TIFFCodeMethod tif_encodetile; /* tile encoding routine */ + TIFFVoidMethod tif_close; /* cleanup-on-close routine */ + TIFFSeekMethod tif_seek; /* position within a strip routine */ + TIFFVoidMethod tif_cleanup; /* cleanup state routine */ + TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */ + TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */ + uint8_t *tif_data; /* compression scheme private data */ + /* input/output buffering */ + tmsize_t tif_scanlinesize; /* # of bytes in a scanline */ + tmsize_t tif_scanlineskew; /* scanline skew for reading strips */ + uint8_t *tif_rawdata; /* raw data buffer */ + tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */ + tmsize_t tif_rawdataoff; /* rawdata offset within strip */ + tmsize_t tif_rawdataloaded; /* amount of data in rawdata */ + uint8_t *tif_rawcp; /* current spot in raw buffer */ + tmsize_t tif_rawcc; /* bytes unread from raw buffer */ + /* memory-mapped file support */ + uint8_t *tif_base; /* base of mapped file */ + tmsize_t tif_size; /* size of mapped file region (bytes, thus tmsize_t) */ + TIFFMapFileProc tif_mapproc; /* map file method */ + TIFFUnmapFileProc tif_unmapproc; /* unmap file method */ + /* input/output callback methods */ + thandle_t tif_clientdata; /* callback parameter */ + TIFFReadWriteProc tif_readproc; /* read method */ + TIFFReadWriteProc tif_writeproc; /* write method */ + TIFFSeekProc tif_seekproc; /* lseek method */ + TIFFCloseProc tif_closeproc; /* close method */ + TIFFSizeProc tif_sizeproc; /* filesize method */ + /* post-decoding support */ + TIFFPostMethod tif_postdecode; /* post decoding routine */ + /* tag support */ + TIFFField **tif_fields; /* sorted table of registered tags */ + size_t tif_nfields; /* # entries in registered tag table */ + const TIFFField *tif_foundfield; /* cached pointer to already found tag */ + TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */ + TIFFClientInfoLink *tif_clientinfo; /* extra client information. */ + /* Backward compatibility stuff. We need these two fields for + * setting up an old tag extension scheme. */ + TIFFFieldArray *tif_fieldscompat; + size_t tif_nfieldscompat; + /* Error handler support */ + TIFFErrorHandlerExtR tif_errorhandler; + void *tif_errorhandler_user_data; + TIFFErrorHandlerExtR tif_warnhandler; + void *tif_warnhandler_user_data; + tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */ }; -#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ +struct TIFFOpenOptions +{ + TIFFErrorHandlerExtR errorhandler; /* may be NULL */ + void *errorhandler_user_data; /* may be NULL */ + TIFFErrorHandlerExtR warnhandler; /* may be NULL */ + void *warnhandler_user_data; /* may be NULL */ + tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */ +}; + +#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ #define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0) #define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0) #define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0) #define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0) -#define TIFFReadFile(tif, buf, size) \ - ((*(tif)->tif_readproc)((tif)->tif_clientdata,(buf),(size))) -#define TIFFWriteFile(tif, buf, size) \ - ((*(tif)->tif_writeproc)((tif)->tif_clientdata,(buf),(size))) -#define TIFFSeekFile(tif, off, whence) \ - ((*(tif)->tif_seekproc)((tif)->tif_clientdata,(off),(whence))) -#define TIFFCloseFile(tif) \ - ((*(tif)->tif_closeproc)((tif)->tif_clientdata)) -#define TIFFGetFileSize(tif) \ - ((*(tif)->tif_sizeproc)((tif)->tif_clientdata)) -#define TIFFMapFileContents(tif, paddr, psize) \ - ((*(tif)->tif_mapproc)((tif)->tif_clientdata,(paddr),(psize))) -#define TIFFUnmapFileContents(tif, addr, size) \ - ((*(tif)->tif_unmapproc)((tif)->tif_clientdata,(addr),(size))) +#define TIFFReadFile(tif, buf, size) \ + ((*(tif)->tif_readproc)((tif)->tif_clientdata, (buf), (size))) +#define TIFFWriteFile(tif, buf, size) \ + ((*(tif)->tif_writeproc)((tif)->tif_clientdata, (buf), (size))) +#define TIFFSeekFile(tif, off, whence) \ + ((*(tif)->tif_seekproc)((tif)->tif_clientdata, (off), (whence))) +#define TIFFCloseFile(tif) ((*(tif)->tif_closeproc)((tif)->tif_clientdata)) +#define TIFFGetFileSize(tif) ((*(tif)->tif_sizeproc)((tif)->tif_clientdata)) +#define TIFFMapFileContents(tif, paddr, psize) \ + ((*(tif)->tif_mapproc)((tif)->tif_clientdata, (paddr), (psize))) +#define TIFFUnmapFileContents(tif, addr, size) \ + ((*(tif)->tif_unmapproc)((tif)->tif_clientdata, (addr), (size))) /* * Default Read/Seek/Write definitions. */ #ifndef ReadOK -#define ReadOK(tif, buf, size) \ - (TIFFReadFile((tif),(buf),(size))==(size)) +#define ReadOK(tif, buf, size) (TIFFReadFile((tif), (buf), (size)) == (size)) #endif #ifndef SeekOK #define SeekOK(tif, off) _TIFFSeekOK(tif, off) #endif #ifndef WriteOK -#define WriteOK(tif, buf, size) \ - (TIFFWriteFile((tif),(buf),(size))==(size)) +#define WriteOK(tif, buf, size) (TIFFWriteFile((tif), (buf), (size)) == (size)) #endif -/* NB: the uint32 casts are to silence certain ANSI-C compilers */ -#define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \ - ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \ - 0U) +/* NB: the uint32_t casts are to silence certain ANSI-C compilers */ +#define TIFFhowmany_32(x, y) \ + (((uint32_t)x < (0xffffffff - (uint32_t)(y - 1))) \ + ? ((((uint32_t)(x)) + (((uint32_t)(y)) - 1)) / ((uint32_t)(y))) \ + : 0U) /* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */ /* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */ -#define TIFFhowmany_32_maxuint_compat(x, y) \ - (((uint32)(x) / (uint32)(y)) + ((((uint32)(x) % (uint32)(y)) != 0) ? 1 : 0)) -#define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3) -#define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y)) -#define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y))) -#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3) -#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y)) +#define TIFFhowmany_32_maxuint_compat(x, y) \ + (((uint32_t)(x) / (uint32_t)(y)) + \ + ((((uint32_t)(x) % (uint32_t)(y)) != 0) ? 1 : 0)) +#define TIFFhowmany8_32(x) \ + (((x)&0x07) ? ((uint32_t)(x) >> 3) + 1 : (uint32_t)(x) >> 3) +#define TIFFroundup_32(x, y) (TIFFhowmany_32(x, y) * (y)) +#define TIFFhowmany_64(x, y) \ + ((((uint64_t)(x)) + (((uint64_t)(y)) - 1)) / ((uint64_t)(y))) +#define TIFFhowmany8_64(x) \ + (((x)&0x07) ? ((uint64_t)(x) >> 3) + 1 : (uint64_t)(x) >> 3) +#define TIFFroundup_64(x, y) (TIFFhowmany_64(x, y) * (y)) -/* Safe multiply which returns zero if there is an *unsigned* integer overflow. This macro is not safe for *signed* integer types */ -#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0) +/* Safe multiply which returns zero if there is an *unsigned* integer overflow. + * This macro is not safe for *signed* integer types */ +#define TIFFSafeMultiply(t, v, m) \ + ((((t)(m) != (t)0) && (((t)(((v) * (m)) / (m))) == (t)(v))) \ + ? (t)((v) * (m)) \ + : (t)0) -#define TIFFmax(A,B) ((A)>(B)?(A):(B)) -#define TIFFmin(A,B) ((A)<(B)?(A):(B)) +#define TIFFmax(A, B) ((A) > (B) ? (A) : (B)) +#define TIFFmin(A, B) ((A) < (B) ? (A) : (B)) -#define TIFFArrayCount(a) (sizeof (a) / sizeof ((a)[0])) +#define TIFFArrayCount(a) (sizeof(a) / sizeof((a)[0])) /* Support for large files. @@ -301,28 +327,31 @@ struct tiff { must be available on the target computer in order for the program to run. */ #if defined(HAVE_FSEEKO) -# define fseek(stream,offset,whence) fseeko(stream,offset,whence) -# define ftell(stream,offset,whence) ftello(stream,offset,whence) +#define fseek(stream, offset, whence) fseeko(stream, offset, whence) +#define ftell(stream, offset, whence) ftello(stream, offset, whence) #endif #endif -#if defined(__WIN32__) && \ - !(defined(_MSC_VER) && _MSC_VER < 1400) && \ - !(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800) +#if defined(__WIN32__) && !(defined(_MSC_VER) && _MSC_VER < 1400) && \ + !(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800) typedef unsigned int TIFFIOSize_t; -#define _TIFF_lseek_f(fildes,offset,whence) _lseeki64(fildes,/* __int64 */ offset,whence) +#define _TIFF_lseek_f(fildes, offset, whence) \ + _lseeki64(fildes, /* __int64 */ offset, whence) /* #define _TIFF_tell_f(fildes) /\* __int64 *\/ _telli64(fildes) */ -#define _TIFF_fseek_f(stream,offset,whence) _fseeki64(stream,/* __int64 */ offset,whence) -#define _TIFF_fstat_f(fildes,stat_buff) _fstati64(fildes,/* struct _stati64 */ stat_buff) +#define _TIFF_fseek_f(stream, offset, whence) \ + _fseeki64(stream, /* __int64 */ offset, whence) +#define _TIFF_fstat_f(fildes, stat_buff) \ + _fstati64(fildes, /* struct _stati64 */ stat_buff) /* #define _TIFF_ftell_f(stream) /\* __int64 *\/ _ftelli64(stream) */ -/* #define _TIFF_stat_f(path,stat_buff) _stati64(path,/\* struct _stati64 *\/ stat_buff) */ +/* #define _TIFF_stat_f(path,stat_buff) _stati64(path,/\* struct _stati64 *\/ + * stat_buff) */ #define _TIFF_stat_s struct _stati64 #define _TIFF_off_t __int64 #else typedef size_t TIFFIOSize_t; -#define _TIFF_lseek_f(fildes,offset,whence) lseek(fildes,offset,whence) +#define _TIFF_lseek_f(fildes, offset, whence) lseek(fildes, offset, whence) /* #define _TIFF_tell_f(fildes) (_TIFF_lseek_f(fildes,0,SEEK_CUR)) */ -#define _TIFF_fseek_f(stream,offset,whence) fseek(stream,offset,whence) -#define _TIFF_fstat_f(fildes,stat_buff) fstat(fildes,stat_buff) +#define _TIFF_fseek_f(stream, offset, whence) fseek(stream, offset, whence) +#define _TIFF_fstat_f(fildes, stat_buff) fstat(fildes, stat_buff) /* #define _TIFF_ftell_f(stream) ftell(stream) */ /* #define _TIFF_stat_f(path,stat_buff) stat(path,stat_buff) */ #define _TIFF_stat_s struct stat @@ -331,7 +360,8 @@ typedef size_t TIFFIOSize_t; #if defined(__has_attribute) && defined(__clang__) #if __has_attribute(no_sanitize) -#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow"))) +#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW \ + __attribute__((no_sanitize("unsigned-integer-overflow"))) #else #define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW #endif @@ -339,139 +369,155 @@ typedef size_t TIFFIOSize_t; #define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW #endif - #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -extern int _TIFFgetMode(const char* mode, const char* module); -extern int _TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); -extern int _TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); -extern int _TIFFNoTileEncode(TIFF*, uint8* pp, tmsize_t cc, uint16 s); -extern int _TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); -extern int _TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); -extern int _TIFFNoTileDecode(TIFF*, uint8* pp, tmsize_t cc, uint16 s); -extern void _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc); -extern int _TIFFNoPreCode(TIFF* tif, uint16 s); -extern int _TIFFNoSeek(TIFF* tif, uint32 off); -extern void _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc); -extern void _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc); -extern void _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc); -extern void _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc); -extern int TIFFFlushData1(TIFF* tif); -extern int TIFFDefaultDirectory(TIFF* tif); -extern void _TIFFSetDefaultCompressionState(TIFF* tif); -extern int _TIFFRewriteField(TIFF *, uint16, TIFFDataType, tmsize_t, void *); -extern int TIFFSetCompressionScheme(TIFF* tif, int scheme); -extern int TIFFSetDefaultCompressionState(TIFF* tif); -extern uint32 _TIFFDefaultStripSize(TIFF* tif, uint32 s); -extern void _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th); -extern int _TIFFDataSize(TIFFDataType type); + extern int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, + const char *mode, const char *module); + extern int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, + uint16_t s); + extern int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, + uint16_t s); + extern int _TIFFNoTileEncode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s); + extern int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, + uint16_t s); + extern int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, + uint16_t s); + extern int _TIFFNoTileDecode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s); + extern void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern int _TIFFNoPreCode(TIFF *tif, uint16_t s); + extern int _TIFFNoSeek(TIFF *tif, uint32_t off); + extern void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern int TIFFFlushData1(TIFF *tif); + extern int TIFFDefaultDirectory(TIFF *tif); + extern void _TIFFSetDefaultCompressionState(TIFF *tif); + extern int _TIFFRewriteField(TIFF *, uint16_t, TIFFDataType, tmsize_t, + void *); + extern int TIFFSetCompressionScheme(TIFF *tif, int scheme); + extern int TIFFSetDefaultCompressionState(TIFF *tif); + extern uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s); + extern void _TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th); -/*--: Rational2Double: Return size of TIFFSetGetFieldType in bytes. */ -extern int _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype); + extern void _TIFFsetByteArray(void **, const void *, uint32_t); + extern void _TIFFsetByteArrayExt(TIFF *, void **, const void *, uint32_t); + extern void _TIFFsetShortArray(uint16_t **, const uint16_t *, uint32_t); + extern void _TIFFsetShortArrayExt(TIFF *, uint16_t **, const uint16_t *, + uint32_t); + extern void _TIFFsetLongArray(uint32_t **, const uint32_t *, uint32_t); + extern void _TIFFsetLongArrayExt(TIFF *, uint32_t **, const uint32_t *, + uint32_t); + extern void _TIFFsetFloatArray(float **, const float *, uint32_t); + extern void _TIFFsetFloatArrayExt(TIFF *, float **, const float *, + uint32_t); + extern void _TIFFsetDoubleArray(double **, const double *, uint32_t); + extern void _TIFFsetDoubleArrayExt(TIFF *, double **, const double *, + uint32_t); -extern void _TIFFsetByteArray(void**, void*, uint32); -extern void _TIFFsetString(char**, char*); -extern void _TIFFsetShortArray(uint16**, uint16*, uint32); -extern void _TIFFsetLongArray(uint32**, uint32*, uint32); -extern void _TIFFsetFloatArray(float**, float*, uint32); -extern void _TIFFsetDoubleArray(double**, double*, uint32); + extern void _TIFFprintAscii(FILE *, const char *); + extern void _TIFFprintAsciiTag(FILE *, const char *, const char *); -extern void _TIFFprintAscii(FILE*, const char*); -extern void _TIFFprintAsciiTag(FILE*, const char*, const char*); + extern TIFFErrorHandler _TIFFwarningHandler; + extern TIFFErrorHandler _TIFFerrorHandler; + extern TIFFErrorHandlerExt _TIFFwarningHandlerExt; + extern TIFFErrorHandlerExt _TIFFerrorHandlerExt; + void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata, + const char *module, const char *fmt, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 4, 5))); -extern TIFFErrorHandler _TIFFwarningHandler; -extern TIFFErrorHandler _TIFFerrorHandler; -extern TIFFErrorHandlerExt _TIFFwarningHandlerExt; -extern TIFFErrorHandlerExt _TIFFerrorHandlerExt; + extern uint32_t _TIFFMultiply32(TIFF *, uint32_t, uint32_t, const char *); + extern uint64_t _TIFFMultiply64(TIFF *, uint64_t, uint64_t, const char *); + extern tmsize_t _TIFFMultiplySSize(TIFF *, tmsize_t, tmsize_t, + const char *); + extern tmsize_t _TIFFCastUInt64ToSSize(TIFF *, uint64_t, const char *); + extern void *_TIFFCheckMalloc(TIFF *, tmsize_t, tmsize_t, const char *); + extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t, + const char *); -extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*); -extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*); -extern tmsize_t _TIFFMultiplySSize(TIFF*, tmsize_t, tmsize_t, const char*); -extern tmsize_t _TIFFCastUInt64ToSSize(TIFF*, uint64, const char*); -extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*); -extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*); + extern double _TIFFUInt64ToDouble(uint64_t); + extern float _TIFFUInt64ToFloat(uint64_t); -extern double _TIFFUInt64ToDouble(uint64); -extern float _TIFFUInt64ToFloat(uint64); + extern float _TIFFClampDoubleToFloat(double); + extern uint32_t _TIFFClampDoubleToUInt32(double); -extern float _TIFFClampDoubleToFloat(double); + extern void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif); -extern tmsize_t -_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip, - void **buf, tmsize_t bufsizetoalloc, - tmsize_t size_to_read); -extern tmsize_t -_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile, - void **buf, tmsize_t bufsizetoalloc, - tmsize_t size_to_read); -extern tmsize_t -_TIFFReadTileAndAllocBuffer(TIFF* tif, - void **buf, tmsize_t bufsizetoalloc, - uint32 x, uint32 y, uint32 z, uint16 s); -extern int _TIFFSeekOK(TIFF* tif, toff_t off); + extern tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, + uint32_t strip, + void **buf, + tmsize_t bufsizetoalloc, + tmsize_t size_to_read); + extern tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile, + void **buf, + tmsize_t bufsizetoalloc, + tmsize_t size_to_read); + extern tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf, + tmsize_t bufsizetoalloc, + uint32_t x, uint32_t y, + uint32_t z, uint16_t s); + extern int _TIFFSeekOK(TIFF *tif, toff_t off); -extern int TIFFInitDumpMode(TIFF*, int); + extern int TIFFInitDumpMode(TIFF *, int); #ifdef PACKBITS_SUPPORT -extern int TIFFInitPackBits(TIFF*, int); + extern int TIFFInitPackBits(TIFF *, int); #endif #ifdef CCITT_SUPPORT -extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int); -extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int); + extern int TIFFInitCCITTRLE(TIFF *, int), TIFFInitCCITTRLEW(TIFF *, int); + extern int TIFFInitCCITTFax3(TIFF *, int), TIFFInitCCITTFax4(TIFF *, int); #endif #ifdef THUNDER_SUPPORT -extern int TIFFInitThunderScan(TIFF*, int); + extern int TIFFInitThunderScan(TIFF *, int); #endif #ifdef NEXT_SUPPORT -extern int TIFFInitNeXT(TIFF*, int); + extern int TIFFInitNeXT(TIFF *, int); #endif #ifdef LZW_SUPPORT -extern int TIFFInitLZW(TIFF*, int); + extern int TIFFInitLZW(TIFF *, int); #endif #ifdef OJPEG_SUPPORT -extern int TIFFInitOJPEG(TIFF*, int); + extern int TIFFInitOJPEG(TIFF *, int); #endif #ifdef JPEG_SUPPORT -extern int TIFFInitJPEG(TIFF*, int); -extern int TIFFJPEGIsFullStripRequired(TIFF*); + extern int TIFFInitJPEG(TIFF *, int); + extern int TIFFJPEGIsFullStripRequired(TIFF *); #endif #ifdef JBIG_SUPPORT -extern int TIFFInitJBIG(TIFF*, int); + extern int TIFFInitJBIG(TIFF *, int); #endif #ifdef ZIP_SUPPORT -extern int TIFFInitZIP(TIFF*, int); + extern int TIFFInitZIP(TIFF *, int); #endif #ifdef PIXARLOG_SUPPORT -extern int TIFFInitPixarLog(TIFF*, int); + extern int TIFFInitPixarLog(TIFF *, int); #endif #ifdef LOGLUV_SUPPORT -extern int TIFFInitSGILog(TIFF*, int); + extern int TIFFInitSGILog(TIFF *, int); +#endif +#ifdef LERC_SUPPORT + extern int TIFFInitLERC(TIFF *tif, int); #endif #ifdef LZMA_SUPPORT -extern int TIFFInitLZMA(TIFF*, int); + extern int TIFFInitLZMA(TIFF *, int); #endif #ifdef ZSTD_SUPPORT -extern int TIFFInitZSTD(TIFF*, int); + extern int TIFFInitZSTD(TIFF *, int); #endif #ifdef WEBP_SUPPORT -extern int TIFFInitWebP(TIFF*, int); -#endif -#ifdef VMS -extern const TIFFCodec _TIFFBuiltinCODECS[]; -#else -extern TIFFCodec _TIFFBuiltinCODECS[]; + extern int TIFFInitWebP(TIFF *, int); #endif + extern const TIFFCodec _TIFFBuiltinCODECS[]; + extern void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *, uint32_t l, int32_t a, + int32_t b, float *, float *, float *); + + extern void *_TIFFmallocExt(TIFF *tif, tmsize_t s); + extern void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz); + extern void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s); + extern void _TIFFfreeExt(TIFF *tif, void *p); #if defined(__cplusplus) } #endif #endif /* _TIFFIOP_ */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/3rdparty/libtiff/tiffvers.h b/3rdparty/libtiff/tiffvers.h deleted file mode 100644 index 0cce798b83..0000000000 --- a/3rdparty/libtiff/tiffvers.h +++ /dev/null @@ -1,9 +0,0 @@ -#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.2.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." -/* - * This define can be used in code that requires - * compilation-related definitions specific to a - * version or versions of the library. Runtime - * version checking should be done based on the - * string returned by TIFFGetVersion. - */ -#define TIFFLIB_VERSION 20201219 diff --git a/3rdparty/libtiff/tiffvers.h.cmake.in b/3rdparty/libtiff/tiffvers.h.cmake.in new file mode 100644 index 0000000000..2898499807 --- /dev/null +++ b/3rdparty/libtiff/tiffvers.h.cmake.in @@ -0,0 +1,36 @@ +/* tiffvers.h version information is updated according to version information + * in configure.ac */ + +/* clang-format off */ + +/* clang-format disabled because FindTIFF.cmake is very sensitive to the + * formatting of below line being a single line. + * Furthermore, configure_file variables of type "@VAR@" are + * modified by clang-format and won't be substituted by CMake. + */ +#define TIFFLIB_VERSION_STR "LIBTIFF, Version @LIBTIFF_VERSION@\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +/* + * This define can be used in code that requires + * compilation-related definitions specific to a + * version or versions of the library. Runtime + * version checking should be done based on the + * string returned by TIFFGetVersion. + */ +#define TIFFLIB_VERSION @LIBTIFF_RELEASE_DATE@ + +/* The following defines have been added in 4.5.0 */ +#define TIFFLIB_MAJOR_VERSION @LIBTIFF_MAJOR_VERSION@ +#define TIFFLIB_MINOR_VERSION @LIBTIFF_MINOR_VERSION@ +#define TIFFLIB_MICRO_VERSION @LIBTIFF_MICRO_VERSION@ +#define TIFFLIB_VERSION_STR_MAJ_MIN_MIC "@LIBTIFF_VERSION@" + +/* Macro added in 4.5.0. Returns TRUE if the current libtiff version is + * greater or equal to major.minor.micro + */ +#define TIFFLIB_AT_LEAST(major, minor, micro) \ + (TIFFLIB_MAJOR_VERSION > (major) || \ + (TIFFLIB_MAJOR_VERSION == (major) && TIFFLIB_MINOR_VERSION > (minor)) || \ + (TIFFLIB_MAJOR_VERSION == (major) && TIFFLIB_MINOR_VERSION == (minor) && \ + TIFFLIB_MICRO_VERSION >= (micro))) + +/* clang-format on */ diff --git a/3rdparty/libtiff/uvcode.h b/3rdparty/libtiff/uvcode.h index 6286cfbb0c..fc87729244 100644 --- a/3rdparty/libtiff/uvcode.h +++ b/3rdparty/libtiff/uvcode.h @@ -1,180 +1,93 @@ /* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */ -#define UV_SQSIZ (float)0.003500 -#define UV_NDIVS 16289 -#define UV_VSTART (float)0.016940 -#define UV_NVS 163 -static const struct { - float ustart; - short nus, ncum; -} uv_row[UV_NVS] = { - { (float)0.247663, 4, 0 }, - { (float)0.243779, 6, 4 }, - { (float)0.241684, 7, 10 }, - { (float)0.237874, 9, 17 }, - { (float)0.235906, 10, 26 }, - { (float)0.232153, 12, 36 }, - { (float)0.228352, 14, 48 }, - { (float)0.226259, 15, 62 }, - { (float)0.222371, 17, 77 }, - { (float)0.220410, 18, 94 }, - { (float)0.214710, 21, 112 }, - { (float)0.212714, 22, 133 }, - { (float)0.210721, 23, 155 }, - { (float)0.204976, 26, 178 }, - { (float)0.202986, 27, 204 }, - { (float)0.199245, 29, 231 }, - { (float)0.195525, 31, 260 }, - { (float)0.193560, 32, 291 }, - { (float)0.189878, 34, 323 }, - { (float)0.186216, 36, 357 }, - { (float)0.186216, 36, 393 }, - { (float)0.182592, 38, 429 }, - { (float)0.179003, 40, 467 }, - { (float)0.175466, 42, 507 }, - { (float)0.172001, 44, 549 }, - { (float)0.172001, 44, 593 }, - { (float)0.168612, 46, 637 }, - { (float)0.168612, 46, 683 }, - { (float)0.163575, 49, 729 }, - { (float)0.158642, 52, 778 }, - { (float)0.158642, 52, 830 }, - { (float)0.158642, 52, 882 }, - { (float)0.153815, 55, 934 }, - { (float)0.153815, 55, 989 }, - { (float)0.149097, 58, 1044 }, - { (float)0.149097, 58, 1102 }, - { (float)0.142746, 62, 1160 }, - { (float)0.142746, 62, 1222 }, - { (float)0.142746, 62, 1284 }, - { (float)0.138270, 65, 1346 }, - { (float)0.138270, 65, 1411 }, - { (float)0.138270, 65, 1476 }, - { (float)0.132166, 69, 1541 }, - { (float)0.132166, 69, 1610 }, - { (float)0.126204, 73, 1679 }, - { (float)0.126204, 73, 1752 }, - { (float)0.126204, 73, 1825 }, - { (float)0.120381, 77, 1898 }, - { (float)0.120381, 77, 1975 }, - { (float)0.120381, 77, 2052 }, - { (float)0.120381, 77, 2129 }, - { (float)0.112962, 82, 2206 }, - { (float)0.112962, 82, 2288 }, - { (float)0.112962, 82, 2370 }, - { (float)0.107450, 86, 2452 }, - { (float)0.107450, 86, 2538 }, - { (float)0.107450, 86, 2624 }, - { (float)0.107450, 86, 2710 }, - { (float)0.100343, 91, 2796 }, - { (float)0.100343, 91, 2887 }, - { (float)0.100343, 91, 2978 }, - { (float)0.095126, 95, 3069 }, - { (float)0.095126, 95, 3164 }, - { (float)0.095126, 95, 3259 }, - { (float)0.095126, 95, 3354 }, - { (float)0.088276, 100, 3449 }, - { (float)0.088276, 100, 3549 }, - { (float)0.088276, 100, 3649 }, - { (float)0.088276, 100, 3749 }, - { (float)0.081523, 105, 3849 }, - { (float)0.081523, 105, 3954 }, - { (float)0.081523, 105, 4059 }, - { (float)0.081523, 105, 4164 }, - { (float)0.074861, 110, 4269 }, - { (float)0.074861, 110, 4379 }, - { (float)0.074861, 110, 4489 }, - { (float)0.074861, 110, 4599 }, - { (float)0.068290, 115, 4709 }, - { (float)0.068290, 115, 4824 }, - { (float)0.068290, 115, 4939 }, - { (float)0.068290, 115, 5054 }, - { (float)0.063573, 119, 5169 }, - { (float)0.063573, 119, 5288 }, - { (float)0.063573, 119, 5407 }, - { (float)0.063573, 119, 5526 }, - { (float)0.057219, 124, 5645 }, - { (float)0.057219, 124, 5769 }, - { (float)0.057219, 124, 5893 }, - { (float)0.057219, 124, 6017 }, - { (float)0.050985, 129, 6141 }, - { (float)0.050985, 129, 6270 }, - { (float)0.050985, 129, 6399 }, - { (float)0.050985, 129, 6528 }, - { (float)0.050985, 129, 6657 }, - { (float)0.044859, 134, 6786 }, - { (float)0.044859, 134, 6920 }, - { (float)0.044859, 134, 7054 }, - { (float)0.044859, 134, 7188 }, - { (float)0.040571, 138, 7322 }, - { (float)0.040571, 138, 7460 }, - { (float)0.040571, 138, 7598 }, - { (float)0.040571, 138, 7736 }, - { (float)0.036339, 142, 7874 }, - { (float)0.036339, 142, 8016 }, - { (float)0.036339, 142, 8158 }, - { (float)0.036339, 142, 8300 }, - { (float)0.032139, 146, 8442 }, - { (float)0.032139, 146, 8588 }, - { (float)0.032139, 146, 8734 }, - { (float)0.032139, 146, 8880 }, - { (float)0.027947, 150, 9026 }, - { (float)0.027947, 150, 9176 }, - { (float)0.027947, 150, 9326 }, - { (float)0.023739, 154, 9476 }, - { (float)0.023739, 154, 9630 }, - { (float)0.023739, 154, 9784 }, - { (float)0.023739, 154, 9938 }, - { (float)0.019504, 158, 10092 }, - { (float)0.019504, 158, 10250 }, - { (float)0.019504, 158, 10408 }, - { (float)0.016976, 161, 10566 }, - { (float)0.016976, 161, 10727 }, - { (float)0.016976, 161, 10888 }, - { (float)0.016976, 161, 11049 }, - { (float)0.012639, 165, 11210 }, - { (float)0.012639, 165, 11375 }, - { (float)0.012639, 165, 11540 }, - { (float)0.009991, 168, 11705 }, - { (float)0.009991, 168, 11873 }, - { (float)0.009991, 168, 12041 }, - { (float)0.009016, 170, 12209 }, - { (float)0.009016, 170, 12379 }, - { (float)0.009016, 170, 12549 }, - { (float)0.006217, 173, 12719 }, - { (float)0.006217, 173, 12892 }, - { (float)0.005097, 175, 13065 }, - { (float)0.005097, 175, 13240 }, - { (float)0.005097, 175, 13415 }, - { (float)0.003909, 177, 13590 }, - { (float)0.003909, 177, 13767 }, - { (float)0.002340, 177, 13944 }, - { (float)0.002389, 170, 14121 }, - { (float)0.001068, 164, 14291 }, - { (float)0.001653, 157, 14455 }, - { (float)0.000717, 150, 14612 }, - { (float)0.001614, 143, 14762 }, - { (float)0.000270, 136, 14905 }, - { (float)0.000484, 129, 15041 }, - { (float)0.001103, 123, 15170 }, - { (float)0.001242, 115, 15293 }, - { (float)0.001188, 109, 15408 }, - { (float)0.001011, 103, 15517 }, - { (float)0.000709, 97, 15620 }, - { (float)0.000301, 89, 15717 }, - { (float)0.002416, 82, 15806 }, - { (float)0.003251, 76, 15888 }, - { (float)0.003246, 69, 15964 }, - { (float)0.004141, 62, 16033 }, - { (float)0.005963, 55, 16095 }, - { (float)0.008839, 47, 16150 }, - { (float)0.010490, 40, 16197 }, - { (float)0.016994, 31, 16237 }, - { (float)0.023659, 21, 16268 }, +#define UV_SQSIZ (float)0.003500 +#define UV_NDIVS 16289 +#define UV_VSTART (float)0.016940 +#define UV_NVS 163 +static const struct +{ + float ustart; + short nus, ncum; +} uv_row[UV_NVS] = { + {(float)0.247663, 4, 0}, {(float)0.243779, 6, 4}, + {(float)0.241684, 7, 10}, {(float)0.237874, 9, 17}, + {(float)0.235906, 10, 26}, {(float)0.232153, 12, 36}, + {(float)0.228352, 14, 48}, {(float)0.226259, 15, 62}, + {(float)0.222371, 17, 77}, {(float)0.220410, 18, 94}, + {(float)0.214710, 21, 112}, {(float)0.212714, 22, 133}, + {(float)0.210721, 23, 155}, {(float)0.204976, 26, 178}, + {(float)0.202986, 27, 204}, {(float)0.199245, 29, 231}, + {(float)0.195525, 31, 260}, {(float)0.193560, 32, 291}, + {(float)0.189878, 34, 323}, {(float)0.186216, 36, 357}, + {(float)0.186216, 36, 393}, {(float)0.182592, 38, 429}, + {(float)0.179003, 40, 467}, {(float)0.175466, 42, 507}, + {(float)0.172001, 44, 549}, {(float)0.172001, 44, 593}, + {(float)0.168612, 46, 637}, {(float)0.168612, 46, 683}, + {(float)0.163575, 49, 729}, {(float)0.158642, 52, 778}, + {(float)0.158642, 52, 830}, {(float)0.158642, 52, 882}, + {(float)0.153815, 55, 934}, {(float)0.153815, 55, 989}, + {(float)0.149097, 58, 1044}, {(float)0.149097, 58, 1102}, + {(float)0.142746, 62, 1160}, {(float)0.142746, 62, 1222}, + {(float)0.142746, 62, 1284}, {(float)0.138270, 65, 1346}, + {(float)0.138270, 65, 1411}, {(float)0.138270, 65, 1476}, + {(float)0.132166, 69, 1541}, {(float)0.132166, 69, 1610}, + {(float)0.126204, 73, 1679}, {(float)0.126204, 73, 1752}, + {(float)0.126204, 73, 1825}, {(float)0.120381, 77, 1898}, + {(float)0.120381, 77, 1975}, {(float)0.120381, 77, 2052}, + {(float)0.120381, 77, 2129}, {(float)0.112962, 82, 2206}, + {(float)0.112962, 82, 2288}, {(float)0.112962, 82, 2370}, + {(float)0.107450, 86, 2452}, {(float)0.107450, 86, 2538}, + {(float)0.107450, 86, 2624}, {(float)0.107450, 86, 2710}, + {(float)0.100343, 91, 2796}, {(float)0.100343, 91, 2887}, + {(float)0.100343, 91, 2978}, {(float)0.095126, 95, 3069}, + {(float)0.095126, 95, 3164}, {(float)0.095126, 95, 3259}, + {(float)0.095126, 95, 3354}, {(float)0.088276, 100, 3449}, + {(float)0.088276, 100, 3549}, {(float)0.088276, 100, 3649}, + {(float)0.088276, 100, 3749}, {(float)0.081523, 105, 3849}, + {(float)0.081523, 105, 3954}, {(float)0.081523, 105, 4059}, + {(float)0.081523, 105, 4164}, {(float)0.074861, 110, 4269}, + {(float)0.074861, 110, 4379}, {(float)0.074861, 110, 4489}, + {(float)0.074861, 110, 4599}, {(float)0.068290, 115, 4709}, + {(float)0.068290, 115, 4824}, {(float)0.068290, 115, 4939}, + {(float)0.068290, 115, 5054}, {(float)0.063573, 119, 5169}, + {(float)0.063573, 119, 5288}, {(float)0.063573, 119, 5407}, + {(float)0.063573, 119, 5526}, {(float)0.057219, 124, 5645}, + {(float)0.057219, 124, 5769}, {(float)0.057219, 124, 5893}, + {(float)0.057219, 124, 6017}, {(float)0.050985, 129, 6141}, + {(float)0.050985, 129, 6270}, {(float)0.050985, 129, 6399}, + {(float)0.050985, 129, 6528}, {(float)0.050985, 129, 6657}, + {(float)0.044859, 134, 6786}, {(float)0.044859, 134, 6920}, + {(float)0.044859, 134, 7054}, {(float)0.044859, 134, 7188}, + {(float)0.040571, 138, 7322}, {(float)0.040571, 138, 7460}, + {(float)0.040571, 138, 7598}, {(float)0.040571, 138, 7736}, + {(float)0.036339, 142, 7874}, {(float)0.036339, 142, 8016}, + {(float)0.036339, 142, 8158}, {(float)0.036339, 142, 8300}, + {(float)0.032139, 146, 8442}, {(float)0.032139, 146, 8588}, + {(float)0.032139, 146, 8734}, {(float)0.032139, 146, 8880}, + {(float)0.027947, 150, 9026}, {(float)0.027947, 150, 9176}, + {(float)0.027947, 150, 9326}, {(float)0.023739, 154, 9476}, + {(float)0.023739, 154, 9630}, {(float)0.023739, 154, 9784}, + {(float)0.023739, 154, 9938}, {(float)0.019504, 158, 10092}, + {(float)0.019504, 158, 10250}, {(float)0.019504, 158, 10408}, + {(float)0.016976, 161, 10566}, {(float)0.016976, 161, 10727}, + {(float)0.016976, 161, 10888}, {(float)0.016976, 161, 11049}, + {(float)0.012639, 165, 11210}, {(float)0.012639, 165, 11375}, + {(float)0.012639, 165, 11540}, {(float)0.009991, 168, 11705}, + {(float)0.009991, 168, 11873}, {(float)0.009991, 168, 12041}, + {(float)0.009016, 170, 12209}, {(float)0.009016, 170, 12379}, + {(float)0.009016, 170, 12549}, {(float)0.006217, 173, 12719}, + {(float)0.006217, 173, 12892}, {(float)0.005097, 175, 13065}, + {(float)0.005097, 175, 13240}, {(float)0.005097, 175, 13415}, + {(float)0.003909, 177, 13590}, {(float)0.003909, 177, 13767}, + {(float)0.002340, 177, 13944}, {(float)0.002389, 170, 14121}, + {(float)0.001068, 164, 14291}, {(float)0.001653, 157, 14455}, + {(float)0.000717, 150, 14612}, {(float)0.001614, 143, 14762}, + {(float)0.000270, 136, 14905}, {(float)0.000484, 129, 15041}, + {(float)0.001103, 123, 15170}, {(float)0.001242, 115, 15293}, + {(float)0.001188, 109, 15408}, {(float)0.001011, 103, 15517}, + {(float)0.000709, 97, 15620}, {(float)0.000301, 89, 15717}, + {(float)0.002416, 82, 15806}, {(float)0.003251, 76, 15888}, + {(float)0.003246, 69, 15964}, {(float)0.004141, 62, 16033}, + {(float)0.005963, 55, 16095}, {(float)0.008839, 47, 16150}, + {(float)0.010490, 40, 16197}, {(float)0.016994, 31, 16237}, + {(float)0.023659, 21, 16268}, }; -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/modules/imgcodecs/src/grfmt_tiff.cpp b/modules/imgcodecs/src/grfmt_tiff.cpp index 7fbdfce1fd..e35113c449 100644 --- a/modules/imgcodecs/src/grfmt_tiff.cpp +++ b/modules/imgcodecs/src/grfmt_tiff.cpp @@ -60,6 +60,16 @@ namespace tiff_dummy_namespace { } using namespace tiff_dummy_namespace; +#ifndef _MSC_VER +namespace numeric_types = tiff_dummy_namespace; +#else +#include +namespace numeric_types { + using uint16 = std::uint16_t; + using uint32 = std::uint32_t; +} +#endif + namespace cv { @@ -264,8 +274,8 @@ bool TiffDecoder::readHeader() if (tif) { - uint32 wdth = 0, hght = 0; - uint16 photometric = 0; + numeric_types::uint32 wdth = 0, hght = 0; + numeric_types::uint16 photometric = 0; CV_TIFF_CHECK_CALL(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &wdth)); CV_TIFF_CHECK_CALL(TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &hght)); @@ -273,7 +283,7 @@ bool TiffDecoder::readHeader() { bool isGrayScale = photometric == PHOTOMETRIC_MINISWHITE || photometric == PHOTOMETRIC_MINISBLACK; - uint16 bpp = 8, ncn = isGrayScale ? 1 : 3; + numeric_types::uint16 bpp = 8, ncn = isGrayScale ? 1 : 3; if (0 == TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp)) { // TIFF bi-level images don't require TIFFTAG_BITSPERSAMPLE tag @@ -296,7 +306,7 @@ bool TiffDecoder::readHeader() (ncn != 1 && ncn != 3 && ncn != 4))) bpp = 8; - uint16 sample_format = SAMPLEFORMAT_UINT; + numeric_types::uint16 sample_format = SAMPLEFORMAT_UINT; TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sample_format); int wanted_channels = normalizeChannelsNumber(ncn); switch (bpp) @@ -378,7 +388,7 @@ bool TiffDecoder::nextPage() readHeader(); } -static void fixOrientationPartial(Mat &img, uint16 orientation) +static void fixOrientationPartial(Mat &img, numeric_types::uint16 orientation) { switch(orientation) { case ORIENTATION_RIGHTTOP: @@ -434,7 +444,7 @@ static void fixOrientationFull(Mat &img, int orientation) * For 8 bit some corrections are done by TIFFReadRGBAStrip/Tile already. * Not so for 16/32/64 bit. */ -static void fixOrientation(Mat &img, uint16 orientation, bool isOrientationFull) +static void fixOrientation(Mat &img, numeric_types::uint16 orientation, bool isOrientationFull) { if( isOrientationFull ) { @@ -595,7 +605,7 @@ bool TiffDecoder::readData( Mat& img ) CV_Assert(!m_tif.empty()); TIFF* tif = (TIFF*)m_tif.get(); - uint16 photometric = (uint16)-1; + numeric_types::uint16 photometric = (numeric_types::uint16)-1; CV_TIFF_CHECK_CALL(TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)); if (m_hdr && depth >= CV_32F) @@ -611,14 +621,14 @@ bool TiffDecoder::readData( Mat& img ) { int is_tiled = TIFFIsTiled(tif) != 0; bool isGrayScale = photometric == PHOTOMETRIC_MINISWHITE || photometric == PHOTOMETRIC_MINISBLACK; - uint16 bpp = 8, ncn = isGrayScale ? 1 : 3; + numeric_types::uint16 bpp = 8, ncn = isGrayScale ? 1 : 3; if (0 == TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp)) { // TIFF bi-level images don't require TIFFTAG_BITSPERSAMPLE tag bpp = 1; } CV_TIFF_CHECK_CALL_DEBUG(TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &ncn)); - uint16 img_orientation = ORIENTATION_TOPLEFT; + numeric_types::uint16 img_orientation = ORIENTATION_TOPLEFT; CV_TIFF_CHECK_CALL_DEBUG(TIFFGetField(tif, TIFFTAG_ORIENTATION, &img_orientation)); constexpr const int bitsPerByte = 8; int dst_bpp = (int)(img.elemSize1() * bitsPerByte); @@ -628,7 +638,7 @@ bool TiffDecoder::readData( Mat& img ) int wanted_channels = normalizeChannelsNumber(img.channels()); bool doReadScanline = false; - uint32 tile_width0 = m_width, tile_height0 = 0; + numeric_types::uint32 tile_width0 = m_width, tile_height0 = 0; if (is_tiled) { @@ -646,7 +656,7 @@ bool TiffDecoder::readData( Mat& img ) tile_width0 = m_width; if (tile_height0 == 0 || - (!is_tiled && tile_height0 == std::numeric_limits::max()) ) + (!is_tiled && tile_height0 == std::numeric_limits::max()) ) tile_height0 = m_height; const int TILE_MAX_WIDTH = (1 << 24); @@ -671,7 +681,7 @@ bool TiffDecoder::readData( Mat& img ) ( (uint64_t) MAX_TILE_SIZE * 95 / 100) ) { - uint16_t planerConfig = (uint16)-1; + uint16_t planerConfig = (numeric_types::uint16)-1; CV_TIFF_CHECK_CALL(TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planerConfig)); doReadScanline = (!is_tiled) // no tile @@ -727,7 +737,7 @@ bool TiffDecoder::readData( Mat& img ) MAX_TILE_SIZE * 95 / 100 ) { - uint16_t planerConfig = (uint16)-1; + uint16_t planerConfig = (numeric_types::uint16)-1; CV_TIFF_CHECK_CALL(TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planerConfig)); doReadScanline = (!is_tiled) // no tile @@ -811,7 +821,7 @@ bool TiffDecoder::readData( Mat& img ) uchar* bstart = src_buffer; if (doReadScanline) { - CV_TIFF_CHECK_CALL((int)TIFFReadScanline(tif, (uint32*)src_buffer, y) >= 0); + CV_TIFF_CHECK_CALL((int)TIFFReadScanline(tif, (numeric_types::uint32*)src_buffer, y) >= 0); if ( isNeedConvert16to8 ) { @@ -833,11 +843,11 @@ bool TiffDecoder::readData( Mat& img ) } else if (!is_tiled) { - CV_TIFF_CHECK_CALL(TIFFReadRGBAStrip(tif, y, (uint32*)src_buffer)); + CV_TIFF_CHECK_CALL(TIFFReadRGBAStrip(tif, y, (numeric_types::uint32*)src_buffer)); } else { - CV_TIFF_CHECK_CALL(TIFFReadRGBATile(tif, x, y, (uint32*)src_buffer)); + CV_TIFF_CHECK_CALL(TIFFReadRGBATile(tif, x, y, (numeric_types::uint32*)src_buffer)); // Tiles fill the buffer from the bottom up bstart += (tile_height0 - tile_height) * tile_width0 * 4; } @@ -931,15 +941,15 @@ bool TiffDecoder::readData( Mat& img ) { if (doReadScanline) { - CV_TIFF_CHECK_CALL((int)TIFFReadScanline(tif, (uint32*)src_buffer, y) >= 0); + CV_TIFF_CHECK_CALL((int)TIFFReadScanline(tif, (numeric_types::uint32*)src_buffer, y) >= 0); } else if (!is_tiled) { - CV_TIFF_CHECK_CALL((int)TIFFReadEncodedStrip(tif, tileidx, (uint32*)src_buffer, src_buffer_size) >= 0); + CV_TIFF_CHECK_CALL((int)TIFFReadEncodedStrip(tif, tileidx, (numeric_types::uint32*)src_buffer, src_buffer_size) >= 0); } else { - CV_TIFF_CHECK_CALL((int)TIFFReadEncodedTile(tif, tileidx, (uint32*)src_buffer, src_buffer_size) >= 0); + CV_TIFF_CHECK_CALL((int)TIFFReadEncodedTile(tif, tileidx, (numeric_types::uint32*)src_buffer, src_buffer_size) >= 0); } for (int i = 0; i < tile_height; i++) @@ -1256,7 +1266,7 @@ bool TiffEncoder::writeLibTiff( const std::vector& img_vec, const std::vect int page_compression = compression; int bitsPerChannel = -1; - uint16 sample_format = SAMPLEFORMAT_INT; + numeric_types::uint16 sample_format = SAMPLEFORMAT_INT; switch (depth) { case CV_8U: From bbfded21ac3876f1e297024621bbf4fc06714e70 Mon Sep 17 00:00:00 2001 From: Kumataro Date: Sat, 23 Mar 2024 10:16:30 +0900 Subject: [PATCH 29/56] imgcodecs: tiff: to avoid using TIFFTAG_* directly for imwrite() params. Normaly, we sets IMWRITE_* flags for imwrite() params. But imgcodecs expects to use some TIFFTAG_* directory. This patch introduce IMWRITE_TIFF_ROWSPERSTRIP and IMWRITE_TIFF_PREDICTOR instead of TIFFTAG_*. --- modules/imgcodecs/include/opencv2/imgcodecs.hpp | 2 ++ modules/imgcodecs/src/grfmt_tiff.cpp | 4 ++-- modules/imgcodecs/test/test_tiff.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index e815dc4e9b..85ddb838f5 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -104,6 +104,8 @@ enum ImwriteFlags { IMWRITE_TIFF_XDPI = 257,//!< For TIFF, use to specify the X direction DPI IMWRITE_TIFF_YDPI = 258,//!< For TIFF, use to specify the Y direction DPI IMWRITE_TIFF_COMPRESSION = 259,//!< For TIFF, use to specify the image compression scheme. See libtiff for integer constants corresponding to compression formats. Note, for images whose depth is CV_32F, only libtiff's SGILOG compression scheme is used. For other supported depths, the compression scheme can be specified by this flag; LZW compression is the default. + IMWRITE_TIFF_ROWSPERSTRIP = 278,//!< For TIFF, use to specify the number of rows per strip. + IMWRITE_TIFF_PREDICTOR = 317,//!< For TIFF, use to specify predictor. IMWRITE_JPEG2000_COMPRESSION_X1000 = 272,//!< For JPEG2000, use to specify the target compression rate (multiplied by 1000). The value can be from 0 to 1000. Default is 1000. IMWRITE_AVIF_QUALITY = 512,//!< For AVIF, it can be a quality between 0 and 100 (the higher the better). Default is 95. IMWRITE_AVIF_DEPTH = 513,//!< For AVIF, it can be 8, 10 or 12. If >8, it is stored/read as CV_32F. Default is 8. diff --git a/modules/imgcodecs/src/grfmt_tiff.cpp b/modules/imgcodecs/src/grfmt_tiff.cpp index e35113c449..3094bcc25c 100644 --- a/modules/imgcodecs/src/grfmt_tiff.cpp +++ b/modules/imgcodecs/src/grfmt_tiff.cpp @@ -1229,7 +1229,7 @@ bool TiffEncoder::writeLibTiff( const std::vector& img_vec, const std::vect int resUnit = -1, dpiX = -1, dpiY = -1; readParam(params, IMWRITE_TIFF_COMPRESSION, compression); - readParam(params, TIFFTAG_PREDICTOR, predictor); + readParam(params, IMWRITE_TIFF_PREDICTOR, predictor); readParam(params, IMWRITE_TIFF_RESUNIT, resUnit); readParam(params, IMWRITE_TIFF_XDPI, dpiX); readParam(params, IMWRITE_TIFF_YDPI, dpiY); @@ -1318,7 +1318,7 @@ bool TiffEncoder::writeLibTiff( const std::vector& img_vec, const std::vect CV_Assert(fileStep > 0); int rowsPerStrip = (int)((1 << 13) / fileStep); - readParam(params, TIFFTAG_ROWSPERSTRIP, rowsPerStrip); + readParam(params, IMWRITE_TIFF_ROWSPERSTRIP, rowsPerStrip); rowsPerStrip = std::max(1, std::min(height, rowsPerStrip)); int colorspace = channels > 1 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK; diff --git a/modules/imgcodecs/test/test_tiff.cpp b/modules/imgcodecs/test/test_tiff.cpp index 4b248fd5e1..bd815c02a0 100644 --- a/modules/imgcodecs/test/test_tiff.cpp +++ b/modules/imgcodecs/test/test_tiff.cpp @@ -28,7 +28,7 @@ TEST(Imgcodecs_Tiff, decode_tile16384x16384) string file4 = cv::tempfile(".tiff"); std::vector params; - params.push_back(TIFFTAG_ROWSPERSTRIP); + params.push_back(IMWRITE_TIFF_ROWSPERSTRIP); params.push_back(big.rows); EXPECT_NO_THROW(cv::imwrite(file4, big, params)); EXPECT_NO_THROW(cv::imwrite(file3, big.colRange(0, big.cols - 1), params)); @@ -767,7 +767,7 @@ TEST(Imgcodecs_Tiff, readWrite_32FC3_RAW) std::vector params; params.push_back(IMWRITE_TIFF_COMPRESSION); - params.push_back(1/*COMPRESSION_NONE*/); + params.push_back(COMPRESSION_NONE); ASSERT_TRUE(cv::imwrite(filenameOutput, img, params)); const Mat img2 = cv::imread(filenameOutput, IMREAD_UNCHANGED); @@ -824,9 +824,9 @@ TEST(Imgcodecs_Tiff, readWrite_predictor) string out = cv::tempfile(".tif"); std::vector params; - params.push_back(TIFFTAG_COMPRESSION); + params.push_back(IMWRITE_TIFF_COMPRESSION); params.push_back(methods[i]); - params.push_back(TIFFTAG_PREDICTOR); + params.push_back(IMWRITE_TIFF_PREDICTOR); params.push_back(PREDICTOR_HORIZONTAL); EXPECT_NO_THROW(cv::imwrite(out, mat, params)); From aae77b65a51ebd094eab1f8745855982af5817dc Mon Sep 17 00:00:00 2001 From: Kumataro Date: Mon, 25 Mar 2024 14:58:30 +0900 Subject: [PATCH 30/56] Merge pull request #25257 from Kumataro:fix25256 3rdparty: libtiff: fix for small version expression problems for built-in tiff460 #25257 Close #25256 1. fix to show build-int libtiff version 2. fix to set value of LIBTIFF_VERSION define. (RELEASE-DATE file coms from original libtiff 4.6.0) ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- 3rdparty/libtiff/CMakeLists.txt | 3 ++- 3rdparty/libtiff/RELEASE-DATE | 1 + cmake/OpenCVFindLibsGrfmt.cmake | 14 +++++++------- 3 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 3rdparty/libtiff/RELEASE-DATE diff --git a/3rdparty/libtiff/CMakeLists.txt b/3rdparty/libtiff/CMakeLists.txt index 30a052861f..9173e207f7 100644 --- a/3rdparty/libtiff/CMakeLists.txt +++ b/3rdparty/libtiff/CMakeLists.txt @@ -361,6 +361,7 @@ set(LIBTIFF_MAJOR_VERSION "4") set(LIBTIFF_MINOR_VERSION "6") set(LIBTIFF_MICRO_VERSION "0") set(LIBTIFF_VERSION "${LIBTIFF_MAJOR_VERSION}.${LIBTIFF_MINOR_VERSION}.${LIBTIFF_MICRO_VERSION}") +file(READ "RELEASE-DATE" LIBTIFF_RELEASE_DATE content) set(TIFF_MAX_DIR_COUNT "1048576") @@ -427,7 +428,7 @@ set(lib_srcs tiff.h tiffio.h tiffiop.h - tiffvers.h + "${CMAKE_CURRENT_BINARY_DIR}/tiffvers.h" uvcode.h tiffio.hxx "${CMAKE_CURRENT_BINARY_DIR}/tif_config.h" diff --git a/3rdparty/libtiff/RELEASE-DATE b/3rdparty/libtiff/RELEASE-DATE new file mode 100644 index 0000000000..68d943433e --- /dev/null +++ b/3rdparty/libtiff/RELEASE-DATE @@ -0,0 +1 @@ +20230908 diff --git a/cmake/OpenCVFindLibsGrfmt.cmake b/cmake/OpenCVFindLibsGrfmt.cmake index a76a9ed44a..f1478e96f4 100644 --- a/cmake/OpenCVFindLibsGrfmt.cmake +++ b/cmake/OpenCVFindLibsGrfmt.cmake @@ -124,13 +124,13 @@ if(WITH_TIFF) endif() if(NOT TIFF_VERSION_STRING AND TIFF_INCLUDE_DIR) - list(GET TIFF_INCLUDE_DIR 0 _TIFF_INCLUDE_DIR) - if(EXISTS "${_TIFF_INCLUDE_DIR}/tiffvers.h") - file(STRINGS "${_TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*") - string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*" "\\1" TIFF_VERSION_STRING "${tiff_version_str}") - unset(tiff_version_str) - endif() - unset(_TIFF_INCLUDE_DIR) + foreach(_TIFF_INCLUDE_DIR IN LISTS TIFF_INCLUDE_DIR) + if(EXISTS "${_TIFF_INCLUDE_DIR}/tiffvers.h") + file(STRINGS "${_TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*") + string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*" "\\1" TIFF_VERSION_STRING "${tiff_version_str}") + unset(tiff_version_str) + endif() + endforeach() endif() set(HAVE_TIFF YES) From 0b6c9a2123a8ff1fc0d9e340c8d0132dac3edb6b Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Mon, 25 Mar 2024 09:03:28 +0300 Subject: [PATCH 31/56] Merge pull request #25181 from dkurt:release_conv_weights Release convolution weightsMat after usage #25181 ### Pull Request Readiness Checklist related (but not resolved): https://github.com/opencv/opencv/issues/24134 Minor memory footprint improvement. Also, adds a test for VmHWM. RAM top memory usage (-230MB) | YOLOv3 (237MB file) | 4.x | PR | |---------------------|---------|---------| | no winograd | 808 MB | 581 MB | | winograd | 1985 MB | 1750 MB | See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- modules/dnn/src/layers/convolution_layer.cpp | 5 +++ modules/dnn/test/test_common.hpp | 2 ++ modules/dnn/test/test_common.impl.hpp | 32 ++++++++++++++++++++ modules/dnn/test/test_onnx_importer.cpp | 6 ++++ 4 files changed, 45 insertions(+) diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index a950ea18c2..d0791ecddd 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -1299,6 +1299,10 @@ public: fastConvImpl = initFastConv(weightsMat, &biasvec[0], ngroups, K, C, kernel_size, strides, dilations, pads_begin, pads_end, conv_dim, preferableTarget == DNN_TARGET_CPU_FP16, canUseWinograd); + // This is legal to release weightsMat here as this is not used anymore for + // OpenCV inference. If network needs to be reinitialized (new shape, new backend) + // a new version of weightsMat is created at .finalize() from original weights + weightsMat.release(); } runFastConv(inputs[0], outputs[0], fastConvImpl, nstripes, activ, reluslope, fusedAdd); @@ -1405,6 +1409,7 @@ public: params.set("input_zeropoint", inputZp); params.set("input_scale", inputScale); + Mat weightsMat = blobs[0].reshape(1, numOutput); Mat weightsQuantized(weightsMat.rows, weightsMat.cols, CV_8S); Mat biasQuantized(1, numOutput, CV_32S); Mat outputMultiplier(1, numOutput, CV_32F); diff --git a/modules/dnn/test/test_common.hpp b/modules/dnn/test/test_common.hpp index 6262a0f7a4..435f481566 100644 --- a/modules/dnn/test/test_common.hpp +++ b/modules/dnn/test/test_common.hpp @@ -232,6 +232,8 @@ public: expectNoFallbacks(net); } + size_t getTopMemoryUsageMB(); + protected: void checkBackend(Mat* inp = 0, Mat* ref = 0) { diff --git a/modules/dnn/test/test_common.impl.hpp b/modules/dnn/test/test_common.impl.hpp index 2a4ee34b02..e78dc6c1e4 100644 --- a/modules/dnn/test/test_common.impl.hpp +++ b/modules/dnn/test/test_common.impl.hpp @@ -15,6 +15,14 @@ #include #include +#ifdef _WIN32 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include +#endif // _WIN32 + namespace cv { namespace dnn { CV__DNN_INLINE_NS_BEGIN @@ -502,4 +510,28 @@ void initDNNTests() ); } +size_t DNNTestLayer::getTopMemoryUsageMB() +{ +#ifdef _WIN32 + PROCESS_MEMORY_COUNTERS proc; + GetProcessMemoryInfo(GetCurrentProcess(), &proc, sizeof(proc)); + return proc.PeakWorkingSetSize / pow(1024, 2); // bytes to megabytes +#else + std::ifstream status("/proc/self/status"); + std::string line, title; + while (std::getline(status, line)) + { + std::istringstream iss(line); + iss >> title; + if (title == "VmHWM:") + { + size_t mem; + iss >> mem; + return mem / 1024; + } + } + return 0l; +#endif +} + } // namespace diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index dc8d7dc0a0..859757d17a 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -2298,7 +2298,13 @@ TEST_P(Test_ONNX_nets, ResNet50v1) applyTestTag(CV_TEST_TAG_MEMORY_512MB); // output range: [-67; 75], after Softmax [0, 0.98] + size_t hwm0 = getTopMemoryUsageMB(); testONNXModels("resnet50v1", pb, default_l1, default_lInf, true, target != DNN_TARGET_MYRIAD); + size_t hwm1 = getTopMemoryUsageMB(); + if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_CPU) + { + EXPECT_LE(hwm1 - hwm0, 350) << "Top allocated memory"; + } } TEST_P(Test_ONNX_nets, ResNet50_Int8) From 025e7602b9e0213652bbf90012489425c3059fc9 Mon Sep 17 00:00:00 2001 From: Yuantao Feng Date: Mon, 25 Mar 2024 14:47:28 +0800 Subject: [PATCH 32/56] Merge pull request #25166 from fengyuentau:fix_cann_gemm dnn (CANN): Fix incorrect shape of 1d bias in Gemm #25166 Gemm layer was refactored some time ago. Users found that the mobilenet example in https://github.com/opencv/opencv/wiki/Huawei-CANN-Backend does not work because of incorrect shape set for 1d bias in Gemm. This PR resolves this issue. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- modules/dnn/src/layers/gemm_layer.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/dnn/src/layers/gemm_layer.cpp b/modules/dnn/src/layers/gemm_layer.cpp index fd10e9acdf..bbbb10d2df 100644 --- a/modules/dnn/src/layers/gemm_layer.cpp +++ b/modules/dnn/src/layers/gemm_layer.cpp @@ -269,7 +269,12 @@ public: } // set inputs : bias auto mat_C = have_bias && const_C ? blobs.back() : Mat::zeros(1, 1, CV_32F); - auto op_const_C = std::make_shared(mat_C.data, mat_C.type(), shape(mat_C), cv::format("%s_b", name.c_str())); + auto shape_C = shape(mat_C); + if (real_ndims_C == 1) { + int dim = static_cast(mat_C.total()); + shape_C = std::vector{dim}; + } + auto op_const_C = std::make_shared(mat_C.data, mat_C.type(), shape_C, cv::format("%s_b", name.c_str())); op->set_input_bias(*(op_const_C->getOp())); op->update_input_desc_bias(*(op_const_C->getTensorDesc())); From 4c86b287fd0aa1a98125e2056ba6956174808fb3 Mon Sep 17 00:00:00 2001 From: "Alessandro de Oliveira Faria (A.K.A.CABELO)" Date: Mon, 25 Mar 2024 04:02:17 -0300 Subject: [PATCH 33/56] Merge pull request #25176 from cabelo:4.x Added and tested yolov8s and yolov8n model #25176 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [X] I agree to contribute to the project under Apache 2 License. - [X] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [X] The PR is proposed to the proper branch - [X] There is a reference to the original bug report and related work - [X] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [X] The feature is well documented and sample code can be built with the project CMake Below is evidence of the test: ![yolos-n](https://github.com/opencv/opencv/assets/675645/f3bd19ae-85a4-4747-9fa9-f6e31257d2d5) --- samples/dnn/models.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/samples/dnn/models.yml b/samples/dnn/models.yml index f72a385942..d2d4fa661c 100644 --- a/samples/dnn/models.yml +++ b/samples/dnn/models.yml @@ -34,6 +34,36 @@ yolov8x: background_label_id: 0 sample: "yolo_detector" +yolov8s: + load_info: + url: "https://github.com/CVHub520/X-AnyLabeling/releases/download/v0.1.0/yolov8s.onnx" + sha1: "82cd83984396fe929909ecb58212b0e86d0904b1" + model: "yolov8s.onnx" + mean: 0.0 + scale: 0.00392 + width: 640 + height: 640 + rgb: true + classes: "object_detection_classes_yolo.txt" + background_label_id: 0 + sample: "yolo_detector" + +yolov8n: + load_info: + url: "https://github.com/CVHub520/X-AnyLabeling/releases/download/v0.1.0/yolov8n.onnx" + sha1: "68f864475d06e2ec4037181052739f268eeac38d" + model: "yolov8n.onnx" + mean: 0.0 + scale: 0.00392 + width: 640 + height: 640 + rgb: true + classes: "object_detection_classes_yolo.txt" + background_label_id: 0 + sample: "yolo_detector" + + + # YOLO4 object detection family from Darknet (https://github.com/AlexeyAB/darknet) # YOLO object detection family from Darknet (https://pjreddie.com/darknet/yolo/) # Might be used for all YOLOv2, TinyYolov2, YOLOv3, YOLOv4 and TinyYolov4 From 84a1248b0a0016f75caa9cf056caf098394e3b9e Mon Sep 17 00:00:00 2001 From: lpylpy0514 <1872918507@qq.com> Date: Mon, 25 Mar 2024 15:40:34 +0800 Subject: [PATCH 34/56] fix a bug about vittrack post-process --- modules/video/src/tracking/tracker_vit.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/video/src/tracking/tracker_vit.cpp b/modules/video/src/tracking/tracker_vit.cpp index b807948033..bef42dbb4d 100644 --- a/modules/video/src/tracking/tracker_vit.cpp +++ b/modules/video/src/tracking/tracker_vit.cpp @@ -163,7 +163,7 @@ void TrackerVitImpl::init(InputArray image_, const Rect &boundingBox_) preprocess(crop, blob, templateSize); net.setInput(blob, "template"); Size size(16, 16); - hanningWindow = hann2d(size, false); + hanningWindow = hann2d(size, true); rect_last = boundingBox_; } @@ -184,7 +184,7 @@ bool TrackerVitImpl::update(InputArray image_, Rect &boundingBoxRes) Mat size_map = outs[1].reshape(0, {2, 16, 16}); Mat offset_map = outs[2].reshape(0, {2, 16, 16}); - multiply(conf_map, (1.0 - hanningWindow), conf_map); + multiply(conf_map, hanningWindow, conf_map); double maxVal; Point maxLoc; From eaa88e7bc7200a2b9b89b16a52c86eb9df5ad898 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 25 Mar 2024 14:07:03 +0300 Subject: [PATCH 35/56] fix detect rotated grid, added test --- modules/calib3d/src/circlesgrid.cpp | 50 ++++++++++++++++------ modules/calib3d/src/circlesgrid.hpp | 1 + modules/calib3d/test/test_chesscorners.cpp | 37 ++++++++++++++++ 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/modules/calib3d/src/circlesgrid.cpp b/modules/calib3d/src/circlesgrid.cpp index df9534f755..d32913f9ef 100644 --- a/modules/calib3d/src/circlesgrid.cpp +++ b/modules/calib3d/src/circlesgrid.cpp @@ -701,22 +701,26 @@ bool CirclesGridFinder::isDetectionCorrect() { case CirclesGridFinderParameters::SYMMETRIC_GRID: { - if (holes.size() != patternSize.height) + rotatedGrid = holes.size() != patternSize.height && holes.size() == patternSize.width; + if (holes.size() != patternSize.height && holes.size() != patternSize.width) return false; - std::set vertices; + size_t num_vertices = 0ull; for (size_t i = 0; i < holes.size(); i++) { - if (holes[i].size() != patternSize.width) - return false; - - for (size_t j = 0; j < holes[i].size(); j++) + if (holes[i].size() != patternSize.width && rotatedGrid == false) { - vertices.insert(holes[i][j]); + return false; + } + else if (holes[i].size() != patternSize.height && rotatedGrid == true) + { + rotatedGrid = false; + return false; } - } - return vertices.size() == patternSize.area(); + num_vertices += holes[i].size(); + } + return num_vertices == patternSize.area(); } case CirclesGridFinderParameters::ASYMMETRIC_GRID: @@ -1431,12 +1435,32 @@ Size CirclesGridFinder::getDetectedGridSize() const void CirclesGridFinder::getHoles(std::vector &outHoles) const { outHoles.clear(); - - for (size_t i = 0; i < holes.size(); i++) + if (rotatedGrid == false) { - for (size_t j = 0; j < holes[i].size(); j++) + for (size_t i = 0ull; i < holes.size(); i++) { - outHoles.push_back(keypoints[holes[i][j]]); + for (size_t j = 0ull; j < holes[i].size(); j++) + { + outHoles.push_back(keypoints[holes[i][j]]); + } + } + } + else + { + bool visit_all = false; + size_t j = 0ull; + while (visit_all != true) + { + visit_all = true; + for (size_t i = 0ull; i < holes.size(); i++) + { + if (j < holes[i].size()) + { + outHoles.push_back(keypoints[holes[i][j]]); + visit_all = false; + } + } + j++; } } } diff --git a/modules/calib3d/src/circlesgrid.hpp b/modules/calib3d/src/circlesgrid.hpp index f058af7a43..8fba89fd11 100644 --- a/modules/calib3d/src/circlesgrid.hpp +++ b/modules/calib3d/src/circlesgrid.hpp @@ -186,6 +186,7 @@ private: const cv::Size_ patternSize; cv::CirclesGridFinderParameters parameters; + bool rotatedGrid = false; CirclesGridFinder& operator=(const CirclesGridFinder&); CirclesGridFinder(const CirclesGridFinder&); diff --git a/modules/calib3d/test/test_chesscorners.cpp b/modules/calib3d/test/test_chesscorners.cpp index 56cb81e4ab..a63d5b3e83 100644 --- a/modules/calib3d/test/test_chesscorners.cpp +++ b/modules/calib3d/test/test_chesscorners.cpp @@ -792,5 +792,42 @@ TEST(Calib3d_AsymmetricCirclesPatternDetector, regression_19498) EXPECT_FALSE(res); } +TEST(Calib3d_RotatedCirclesPatternDetector, issue_24964) +{ + string path = cvtest::findDataFile("cv/cameracalibration/circles/circles_24964.png"); + Mat image = cv::imread(path); + ASSERT_FALSE(image.empty()) << "Can't read image: " << path; + + vector centers; + Size parrernSize(7, 6); + Mat goldCenters(parrernSize.height, parrernSize.width, CV_32FC2); + Point2f firstGoldCenter(380.f, 430.f); + for (int i = 0; i < parrernSize.height; i++) + { + for (int j = 0; j < parrernSize.width; j++) + { + goldCenters.at(i, j) = Point2f(firstGoldCenter.x + j * 100.f, firstGoldCenter.y + i * 100.f); + } + } + + bool found = false; + found = findCirclesGrid(image, parrernSize, centers, CALIB_CB_SYMMETRIC_GRID); + + EXPECT_TRUE(found); + ASSERT_EQ(centers.size(), (size_t)parrernSize.area()); + double error = calcError(centers, goldCenters); + EXPECT_LE(error, precise_success_error_level); + + // "rotate" the circle grid by 90 degrees + swap(parrernSize.height, parrernSize.width); + + found = findCirclesGrid(image, parrernSize, centers, CALIB_CB_SYMMETRIC_GRID); + error = calcError(centers, goldCenters.t()); + + EXPECT_TRUE(found); + ASSERT_EQ(centers.size(), (size_t)parrernSize.area()); + EXPECT_LE(error, precise_success_error_level); +} + }} // namespace /* End of file. */ From 8f4dbdad0e7cc5fcdf30b01418de631c23f783bd Mon Sep 17 00:00:00 2001 From: RoboSchmied Date: Tue, 26 Mar 2024 02:23:06 +0100 Subject: [PATCH 36/56] Fix: 6 typos Signed-off-by: Michael Seibt --- modules/imgcodecs/src/exif.cpp | 2 +- modules/imgcodecs/src/exif.hpp | 6 +++--- modules/imgcodecs/src/grfmt_pfm.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/imgcodecs/src/exif.cpp b/modules/imgcodecs/src/exif.cpp index 5ca3cc315d..8ed9760556 100644 --- a/modules/imgcodecs/src/exif.cpp +++ b/modules/imgcodecs/src/exif.cpp @@ -165,7 +165,7 @@ void ExifReader::parseExif() * * @return INTEL, MOTO or NONE */ -Endianess_t ExifReader::getFormat() const +Endianness_t ExifReader::getFormat() const { if (m_data.size() < 1) return NONE; diff --git a/modules/imgcodecs/src/exif.hpp b/modules/imgcodecs/src/exif.hpp index 6cc95afb1a..a8914bec03 100644 --- a/modules/imgcodecs/src/exif.hpp +++ b/modules/imgcodecs/src/exif.hpp @@ -79,7 +79,7 @@ enum ExifTagName INVALID_TAG = 0xFFFF ///< Shows that the tag was not recognized }; -enum Endianess_t +enum Endianness_t { INTEL = 0x49, MOTO = 0x4D, @@ -179,7 +179,7 @@ public: private: std::vector m_data; std::map m_exif; - Endianess_t m_format; + Endianness_t m_format; void parseExif(); bool checkTagMark() const; @@ -193,7 +193,7 @@ private: uint16_t getResolutionUnit( const size_t offset ) const; uint16_t getYCbCrPos( const size_t offset ) const; - Endianess_t getFormat() const; + Endianness_t getFormat() const; ExifEntry_t parseExifEntry( const size_t offset ); diff --git a/modules/imgcodecs/src/grfmt_pfm.cpp b/modules/imgcodecs/src/grfmt_pfm.cpp index 97cf07b27e..addae34b4f 100644 --- a/modules/imgcodecs/src/grfmt_pfm.cpp +++ b/modules/imgcodecs/src/grfmt_pfm.cpp @@ -27,7 +27,7 @@ bool is_byte_order_swapped(double scale) #endif } -void swap_endianess(uint32_t& ui) +void swap_endianness(uint32_t& ui) { static const uint32_t A(0x000000ffU); static const uint32_t B(0x0000ff00U); @@ -137,7 +137,7 @@ bool PFMDecoder::readData(Mat& mat) for (int i = 0; i < m_width * buffer.channels(); ++i) { static_assert( sizeof(uint32_t) == sizeof(float), "uint32_t and float must have same size." ); - swap_endianess(buffer.ptr(y)[i]); + swap_endianness(buffer.ptr(y)[i]); } } } From 6e9dcb87c106d04424845424e56145852eb03c22 Mon Sep 17 00:00:00 2001 From: Yusuke Kameda Date: Tue, 26 Mar 2024 20:20:17 +0900 Subject: [PATCH 37/56] Merge pull request #25237 from YusukeKameda:4.x doc: add note on handling of spaces in CommandLineParser #25237 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake Added note that this class will not work properly if tabs and other whitespace characters are included in the key. The support of whitespace characters by istringstream, etc. is on hold because the future of this class is not clear compared to implementations in Python and other languages. --- modules/core/include/opencv2/core/utility.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/core/include/opencv2/core/utility.hpp b/modules/core/include/opencv2/core/utility.hpp index db8c42976f..e491352bcf 100644 --- a/modules/core/include/opencv2/core/utility.hpp +++ b/modules/core/include/opencv2/core/utility.hpp @@ -773,7 +773,7 @@ The sample below demonstrates how to use CommandLineParser: The keys parameter is a string containing several blocks, each one is enclosed in curly braces and describes one argument. Each argument contains three parts separated by the `|` symbol: --# argument names is a space-separated list of option synonyms (to mark argument as positional, prefix it with the `@` symbol) +-# argument names is a list of option synonyms separated by standard space characters ' ' (to mark argument as positional, prefix it with the `@` symbol) -# default value will be used if the argument was not provided (can be empty) -# help message (can be empty) @@ -796,6 +796,8 @@ For example: Note that there are no default values for `help` and `timestamp` so we can check their presence using the `has()` method. Arguments with default values are considered to be always present. Use the `get()` method in these cases to check their actual value instead. +Note that whitespace characters other than standard spaces are considered part of the string. +Additionally, leading and trailing standard spaces around the help messages are ignored. String keys like `get("@image1")` return the empty string `""` by default - even with an empty default value. Use the special `` default value to enforce that the returned string must not be empty. (like in `get("@image2")`) From accf200408c38bde6be9cd94ad9d30ebfffb3d9e Mon Sep 17 00:00:00 2001 From: Yuantao Feng Date: Tue, 26 Mar 2024 20:09:51 +0800 Subject: [PATCH 38/56] Merge pull request #25238 from fengyuentau:optimized_const dnn: avoid const layer forwarding in layer norm layer and attention layer #25238 While profiling ViTs with dnn, I found `ConstLayer` can take a proportion of the inference time, which is weird. This comes from the data copy during the inference of `ConstLayer`. There is a chance that we can improve the efficiency of data copying but the easiest and most convenient way is to avoid `ConstLayer`. This PR change the way how we handle constants in layer normalization layer and attention layer, which is storing in the layer blobs instead of making constant layers for them. Checklists: - [x] Backend compatibility in layer normalization layer. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- .../src/cuda4dnn/primitives/layer_norm.hpp | 38 ++++- modules/dnn/src/layers/attention_layer.cpp | 24 ++- modules/dnn/src/layers/layer_norm.cpp | 138 ++++++++++++------ modules/dnn/src/onnx/onnx_importer.cpp | 27 +--- 4 files changed, 150 insertions(+), 77 deletions(-) diff --git a/modules/dnn/src/cuda4dnn/primitives/layer_norm.hpp b/modules/dnn/src/cuda4dnn/primitives/layer_norm.hpp index 7f4658a50a..baf7691c46 100644 --- a/modules/dnn/src/cuda4dnn/primitives/layer_norm.hpp +++ b/modules/dnn/src/cuda4dnn/primitives/layer_norm.hpp @@ -28,11 +28,20 @@ namespace cv { namespace dnn { namespace cuda4dnn { public: using wrapper_type = GetCUDABackendWrapperType; - LayerNormOp(csl::Stream stream_, int normalized_axis, float epsilon_, size_t loops) + LayerNormOp(csl::Stream stream_, const Mat &scale, const Mat &bias, int normalized_axis, float epsilon_, size_t loops) : stream(std::move(stream_)), epsilon(epsilon_) { CV_CheckGE(normalized_axis, 0, "LayerNorm/CUDA: axis needs to be normalized"); axis = static_cast(normalized_axis); + if (!scale.empty()) { + input_scale_tensor = csl::makeTensorHeader(scale); + csl::copyMatToTensor(scale, input_scale_tensor, stream); + } + if (!bias.empty()) { + input_bias_tensor = csl::makeTensorHeader(bias); + csl::copyMatToTensor(bias, input_bias_tensor, stream); + } + csl::WorkspaceBuilder builder; builder.require(loops); builder.require(loops); @@ -43,10 +52,25 @@ namespace cv { namespace dnn { namespace cuda4dnn { const std::vector>& outputs, csl::Workspace& workspace) override { auto input_wrapper = inputs[0].dynamicCast(); - auto scale_wrapper = inputs[1].dynamicCast(); - auto input = input_wrapper->getView(); - auto scale = scale_wrapper->getView(); + + csl::TensorView scale; + if (input_scale_tensor.empty()) { + auto scale_wrapper = inputs[1].dynamicCast(); + scale = scale_wrapper->getView(); + } else { + scale = csl::TensorView(input_scale_tensor); + } + + csl::TensorView bias; + if (input_bias_tensor.empty()) { + if (inputs.size() >= 3) { + auto bias_wrapper = inputs[2].dynamicCast(); + bias = bias_wrapper->getView(); + } + } else { + bias = csl::TensorView(input_bias_tensor); + } auto output_wrapper = outputs[0].dynamicCast(); auto output = output_wrapper->getSpan(); @@ -67,9 +91,7 @@ namespace cv { namespace dnn { namespace cuda4dnn { kernels::reduce_mean_sqr_sum(stream, mean, inv_stddev, input, norm_size); kernels::compute_normalization_scale(stream, inv_stddev, mean, inv_stddev, norm_size, epsilon); - if (inputs.size() == 3) { - auto bias_wrapper = inputs[2].dynamicCast(); - auto bias = bias_wrapper->getView(); + if (!bias.empty()) { kernels::normalize_mean_variance_layernorm(stream, output, input, scale, bias, mean, inv_stddev, norm_size); } else { kernels::normalize_mean_variance_layernorm(stream, output, input, scale, mean, inv_stddev, norm_size); @@ -81,6 +103,8 @@ namespace cv { namespace dnn { namespace cuda4dnn { private: csl::Stream stream; + csl::Tensor input_scale_tensor; + csl::Tensor input_bias_tensor; float epsilon; size_t axis; diff --git a/modules/dnn/src/layers/attention_layer.cpp b/modules/dnn/src/layers/attention_layer.cpp index 559480d599..2bda1f3b18 100644 --- a/modules/dnn/src/layers/attention_layer.cpp +++ b/modules/dnn/src/layers/attention_layer.cpp @@ -63,10 +63,11 @@ class AttentionLayerImpl CV_FINAL : public AttentionLayer { const int requiredOutputs, std::vector &outputs, std::vector &internals) const CV_OVERRIDE { - CV_CheckEQ(inputs.size(), static_cast(3), "DNN/Attention: three inputs are required"); + int num_inputs = inputs.size() + blobs.size(); + CV_CheckEQ(num_inputs, 3, "DNN/Attention: three inputs are required"); const auto &input_shape = inputs[0]; - const auto &weight_shape = inputs[1]; - const auto &bias_shape = inputs[2]; + const auto &weight_shape = blobs.empty() ? inputs[1] : shape(blobs.front()); + const auto &bias_shape = blobs.empty() ? inputs[2] : shape(blobs.back()); CV_CheckEQ(input_shape.size(), static_cast(3), "DNN/Attention: invalid input dimension"); CV_CheckEQ(weight_shape.size(), static_cast(2), "DNN/Attention: invalid weight dimension"); @@ -109,10 +110,20 @@ class AttentionLayerImpl CV_FINAL : public AttentionLayer { seq_len = static_cast(input_shape[1]); input_hidden_size = static_cast(input_shape[2]); - const auto weight_shape = shape(inputs[1]); + const auto &weight = blobs.empty() ? inputs[1] : blobs.front(); + const auto weight_shape = shape(weight); hidden_size = weight_shape[1]; qkv_hidden_sizes[2] = hidden_size - qkv_hidden_sizes[0] - qkv_hidden_sizes[1]; qkv_head_sizes[2] = static_cast(qkv_hidden_sizes[2] / num_heads); + + if (!blobs.empty()) { + const auto *weight_data = weight.ptr(); + packWeight(num_heads, qkv_head_sizes[0], input_hidden_size, weight_data, hidden_size, packed_weight_q, opt); + packWeight(num_heads, qkv_head_sizes[1], input_hidden_size, weight_data + qkv_hidden_sizes[0], hidden_size, packed_weight_k, opt); + packWeight(num_heads, qkv_head_sizes[2], input_hidden_size, weight_data + qkv_hidden_sizes[0] + qkv_hidden_sizes[1], hidden_size, packed_weight_v, opt); + + is_prepacked = true; + } } void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE { @@ -132,8 +143,7 @@ class AttentionLayerImpl CV_FINAL : public AttentionLayer { // prepack weights if (!is_prepacked) { - // prepack - const auto &weight = inputs[1]; + const auto &weight = blobs.empty() ? inputs[1] : blobs.front(); const auto *weight_data = weight.ptr(); packWeight(num_heads, qkv_head_sizes[0], input_hidden_size, weight_data, hidden_size, packed_weight_q, opt); packWeight(num_heads, qkv_head_sizes[1], input_hidden_size, weight_data + qkv_hidden_sizes[0], hidden_size, packed_weight_k, opt); @@ -153,7 +163,7 @@ class AttentionLayerImpl CV_FINAL : public AttentionLayer { float *QKV[3] = {Q, K, V}; // Q, K, V: [B, N, S, H] { const auto &input = inputs[0]; - const auto &bias = inputs[2]; + const auto &bias = blobs.empty() ? inputs[2] : blobs.back(); const auto *input_data = input.ptr(); const auto *bias_data = bias.ptr(); diff --git a/modules/dnn/src/layers/layer_norm.cpp b/modules/dnn/src/layers/layer_norm.cpp index 5ebebbd32d..487383efdc 100644 --- a/modules/dnn/src/layers/layer_norm.cpp +++ b/modules/dnn/src/layers/layer_norm.cpp @@ -31,6 +31,10 @@ namespace cv { namespace dnn { // https://github.com/onnx/onnx/blob/main/docs/Operators.md#LayerNormalization class LayerNormLayerImpl CV_FINAL : public LayerNormLayer { +#ifdef HAVE_OPENCL + UMat weight_umat, bias_umat; +#endif + public: LayerNormLayerImpl(const LayerParams& params) { @@ -58,22 +62,24 @@ public: std::vector &internals) const CV_OVERRIDE { // check shapes of weight and bias if existed - // inputs >= 2 (X and Weight are requested, bias is optional) - CV_Check(inputs.size(), inputs.size() >= 2 && inputs.size() <= 3, "LayerNorm: require two (x, weight) or three (x, weight, bias) inputs"); + // inputs >= 2 (X and Weight are required, bias is optional) + int num_inputs = inputs.size() + blobs.size(); + CV_Check(num_inputs, num_inputs >= 2 && num_inputs <= 3, "LayerNorm: require two (x, weight) or three (x, weight, bias) inputs"); auto x_shape = inputs[0]; int x_ndims = static_cast(x_shape.size()); - auto w_shape = inputs[1]; + // Weight and bias are either constants or variable + auto w_shape = blobs.empty() ? inputs[1] : shape(blobs.front()); // if axis == last_dim, scale and b are both 1d tensor (represented as 2d mat nx1) int w_ndims = static_cast(w_shape.size()); w_ndims = (axis == x_ndims - 1 && w_ndims == 2) ? w_ndims - 1 : w_ndims; CV_CheckEQ(x_ndims - axis, w_ndims, "LayerNorm: shape of weight does not match with given axis and shape of input"); for (int i = 0; i < w_ndims; ++i) CV_CheckEQ(x_shape[axis+i], w_shape[i], "LayerNorm: weight dimensions does not match with input dimensions"); - if (inputs.size() == static_cast(3)) + if (num_inputs >= 3) { - auto b_shape = inputs[2]; + auto b_shape = blobs.empty() ? inputs[2] : shape(blobs.back()); CV_CheckEQ(w_shape.size(), b_shape.size(), "LayerNorm: shape of weight does not match with shape of bias"); for (size_t i = 0; i < w_shape.size(); ++i) CV_CheckEQ(w_shape[i], b_shape[i], "LayerNorm: bias dimensions does not match with weight dimensions"); @@ -89,6 +95,11 @@ public: const auto input_shape = shape(inputs[0]); axis = normalize_axis(axis, static_cast(input_shape.size())); + +#ifdef HAVE_OPENCL + weight_umat.release(); + bias_umat.release(); +#endif } void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE @@ -110,11 +121,11 @@ public: outputs_arr.getMatVector(outputs); const auto &input = inputs[0]; - const auto &scale = inputs[1]; + const auto &scale = blobs.empty() ? inputs[1] : blobs.front(); auto &output = outputs[0]; - if (inputs.size() == 3) { - const auto &bias = inputs[2]; + if ((inputs.size() + blobs.size()) >= 3) { + const auto &bias = blobs.empty() ? inputs[2] : blobs.back(); fastNorm(input, scale, bias, output, epsilon, static_cast(axis)); } else { fastNorm(input, scale, output, epsilon, static_cast(axis)); @@ -129,7 +140,13 @@ public: inputs_.getUMatVector(inputs); outputs_.getUMatVector(outputs); - const auto &input = inputs[0], &scale = inputs[1]; // &bias = inputs[2]; // bias is optional + const auto &input = inputs[0]; + + // no fp16 support + if (input.depth() == CV_16F) { + return false; + } + auto &output = outputs[0]; const auto input_shape = shape(input); @@ -137,11 +154,23 @@ public: norm_size = static_cast(total(input_shape, axis)); float inv_norm_size = 1.f / norm_size; - const auto &bias = inputs.size() == 3 ? inputs[2] : UMat::zeros(norm_size, 1, CV_32F); - - // no fp16 support - if (input.depth() == CV_16F) { - return false; + if (weight_umat.empty()) { + if (blobs.empty()) { + weight_umat = inputs[1]; + } else { + blobs.front().copyTo(weight_umat); + } + } + if (bias_umat.empty()) { + if ((inputs.size() + blobs.size()) == 3) { + if (blobs.empty()) { + bias_umat = inputs[2]; + } else { + blobs.back().copyTo(bias_umat); + } + } else { + bias_umat = UMat::zeros(norm_size, 1, CV_32F); + } } String base_opts = format(" -DT=float -DT4=float4 -Dconvert_T=convert_float4"); @@ -179,7 +208,7 @@ public: if (!ret) { return false; } - // Calculate instance norm: output = scale * (x - mean) / sqrt(var + eps) + bias + // Calculate instance norm: output = weight * (x - mean) / sqrt(var + eps) + bias String mvn_kernel_name = format("mvn%d", num_vector); build_opt += " -DNORM_VARIANCE -DLAYER_NORM -DKERNEL_MVN"; ocl::Kernel mvn_kernel(mvn_kernel_name.c_str(), ocl::dnn::mvn_oclsrc, build_opt); @@ -192,8 +221,8 @@ public: mvn_kernel.set(3, (float)epsilon); mvn_kernel.set(4, ocl::KernelArg::PtrReadOnly(mean)); mvn_kernel.set(5, ocl::KernelArg::PtrReadOnly(mean_square)); - mvn_kernel.set(6, ocl::KernelArg::PtrReadOnly(scale)); - mvn_kernel.set(7, ocl::KernelArg::PtrReadOnly(bias)); + mvn_kernel.set(6, ocl::KernelArg::PtrReadOnly(weight_umat)); + mvn_kernel.set(7, ocl::KernelArg::PtrReadOnly(bias_umat)); mvn_kernel.set(8, (int)1); mvn_kernel.set(9, (float)0.f); mvn_kernel.set(10, ocl::KernelArg::PtrWriteOnly(output)); @@ -218,15 +247,7 @@ public: CV_CheckNE(axis, static_cast(input_tensor_desc->GetShape().GetDimNum() - 1), "LayerNorm: CANN does not support axis set as last axis due to 1D mat compatibility issue"); - auto scale_tensor_wrapper = inputs[1].dynamicCast(); - auto scale_tensor_desc = scale_tensor_wrapper->getTensorDesc(); - - auto bias_tensor_wrapper = inputs[2].dynamicCast(); - auto bias_tensor_desc = bias_tensor_wrapper->getTensorDesc(); - auto last_node = nodes[0].dynamicCast()->getOp(); - auto scale_node = nodes[1].dynamicCast()->getOp(); - auto bias_node = nodes[2].dynamicCast()->getOp(); auto op = std::make_shared(name); @@ -239,12 +260,34 @@ public: // set inputs : x op->set_input_x_by_name(*last_node, input_tensor_wrapper->name.c_str()); op->update_input_desc_x(*input_tensor_desc); - // set inputs : gamma - op->set_input_gamma_by_name(*scale_node, scale_tensor_wrapper->name.c_str()); - op->update_input_desc_gamma(*scale_tensor_desc); - // set inputs : beta - op->set_input_beta_by_name(*bias_node, bias_tensor_wrapper->name.c_str()); - op->update_input_desc_beta(*bias_tensor_desc); + // set inputs : gamma & beta + if (blobs.empty()) { + auto scale_tensor_wrapper = inputs[1].dynamicCast(); + auto scale_tensor_desc = scale_tensor_wrapper->getTensorDesc(); + auto scale_node = nodes[1].dynamicCast()->getOp(); + op->set_input_gamma_by_name(*scale_node, scale_tensor_wrapper->name.c_str()); + op->update_input_desc_gamma(*scale_tensor_desc); + + if (inputs.size() == 3) { + auto bias_tensor_wrapper = inputs[2].dynamicCast(); + auto bias_tensor_desc = bias_tensor_wrapper->getTensorDesc(); + auto bias_node = nodes[2].dynamicCast()->getOp(); + op->set_input_beta_by_name(*bias_node, bias_tensor_wrapper->name.c_str()); + op->update_input_desc_beta(*bias_tensor_desc); + } + } else { + const auto &scale_mat = blobs.front(); + const auto op_const_scale = std::make_shared(scale_mat.data, scale_mat.type(), shape(scale_mat), cv::format("%s_w", name.c_str())); + op->set_input_gamma(*(op_const_scale->getOp())); + op->update_input_desc_gamma(*(op_const_scale->getTensorDesc())); + + if ((inputs.size() + blobs.size()) >= 3) { + const auto &bias_mat = blobs.back(); + const auto op_const_bias = std::make_shared(bias_mat.data, bias_mat.type(), shape(bias_mat), cv::format("%s_b", name.c_str())); + op->set_input_beta(*(op_const_bias->getOp())); + op->update_input_desc_beta(*(op_const_bias->getTensorDesc())); + } + } // set outputs auto output_desc_y = std::make_shared(ge::Shape(), ge::FORMAT_NCHW, ge::DT_FLOAT); @@ -264,6 +307,7 @@ public: auto ieInpNode = nodes[0].dynamicCast()->node; const auto &input_shape = ieInpNode.get_shape(); std::shared_ptr mvn, result; + ov::Output scale, bias; // mvn // https://docs.openvino.ai/2023.1/openvino_docs_ops_normalization_MVN_6.html @@ -274,23 +318,33 @@ public: mvn = std::make_shared(ieInpNode, axes, normalize_variance, epsilon, ov::op::MVNEpsMode::INSIDE_SQRT); // layer norm = scale * mvn + bias - auto scale = nodes[1].dynamicCast()->node; - ov::Output bias; - if (nodes.size() == 3) { - bias = nodes[2].dynamicCast()->node; + if (blobs.empty()) { + scale = nodes[1].dynamicCast()->node; + if (nodes.size() == 3) { + bias = nodes[2].dynamicCast()->node; + } + } else { + auto scale_mat = blobs.front(); + const auto scale_shape = shape(scale_mat); + scale = std::make_shared(ov::element::f32, std::vector(scale_shape.begin(), scale_shape.end()), scale_mat.data); + if ((nodes.size() + blobs.size()) == 3) { + auto bias_mat = blobs.back(); + const auto bias_shape = shape(bias_mat); + bias = std::make_shared(ov::element::f32, std::vector(bias_shape.begin(), bias_shape.end()), bias_mat.data); + } } if (axis == -1 || axis == input_shape.size() - 1) { // special case for 1D tensor (2D mat) std::vector shared_shape_v(input_shape.size(), 1); shared_shape_v.back() = -1; auto shared_shape = std::make_shared(ov::element::i64, ov::Shape{shared_shape_v.size()}, shared_shape_v.data()); - scale = std::make_shared(scale, shared_shape, true); - if (nodes.size() == 3) { - bias = std::make_shared(bias, shared_shape, true); + scale = std::make_shared(scale, shared_shape, true); + if ((nodes.size() + blobs.size()) == 3) { + bias = std::make_shared(bias, shared_shape, true); } } result = std::make_shared(mvn, scale); - if (nodes.size() == 3) { + if ((nodes.size() + blobs.size()) == 3) { result = std::make_shared(result, bias); } @@ -308,10 +362,12 @@ public: auto input_shape = input_wrapper->getShape(); size_t loops = static_cast(total(input_shape, 0, axis)); - return make_cuda_node(preferableTarget, std::move(context->stream), axis, epsilon, loops); + const auto scale = blobs.empty() ? Mat() : blobs.front(), + bias = blobs.empty() ? Mat() : blobs.back(); + + return make_cuda_node(preferableTarget, std::move(context->stream), scale, bias, axis, epsilon, loops); } #endif // HAVE_CUDA - }; Ptr LayerNormLayer::create(const LayerParams& params) diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp index 5583fd0453..997914c4cf 100644 --- a/modules/dnn/src/onnx/onnx_importer.cpp +++ b/modules/dnn/src/onnx/onnx_importer.cpp @@ -3160,18 +3160,9 @@ void ONNXImporter::parseLayerNorm(LayerParams& layerParams, const opencv_onnx::N // constants as constant inputs for (size_t i = 1; i < node_proto.input_size(); i++) { - if (layer_id.find(node_proto.input(i)) == layer_id.end()) - { + if (constBlobs.find(node_proto.input(i)) != constBlobs.end()) { Mat blob = getBlob(node_proto, i); - - LayerParams constParams; - constParams.name = node_proto.input(i); - constParams.type = "Const"; - constParams.blobs.push_back(blob); - - opencv_onnx::NodeProto proto; - proto.add_output(constParams.name); - addLayer(constParams, proto); + layerParams.blobs.push_back(blob); } } @@ -3935,17 +3926,9 @@ void ONNXImporter::parseAttention(LayerParams& params, const opencv_onnx::NodePr CV_CheckEQ(param_qkv_hidden_sizes.size(), 3, "ONNXImporter/parseAttention: qkv_hidden_sizes is must and only have three elements"); for (size_t i = 1; i < node_proto.input_size(); i++) { - if (layer_id.find(node_proto.input(i)) == layer_id.end()) { - Mat tensor = getBlob(node_proto, i); - - LayerParams const_params; - const_params.name = node_proto.input(i); - const_params.type = "Const"; - const_params.blobs.push_back(tensor); - - opencv_onnx::NodeProto proto; - proto.add_output(const_params.name); - addLayer(const_params, proto); + if (constBlobs.find(node_proto.input(i)) != constBlobs.end()) { + Mat blob = getBlob(node_proto, i); + params.blobs.push_back(blob); } } From 1a537ab98f351d7721a4e9137696e43cc6777e1c Mon Sep 17 00:00:00 2001 From: Pierre Chatelier Date: Tue, 26 Mar 2024 13:38:17 +0100 Subject: [PATCH 39/56] Merge pull request #24893 from chacha21:cart_polar_inplace Added in-place support for cartToPolar and polarToCart #24893 - a fused hal::cartToPolar[32|64]f() is used instead of sequential hal::magnitude[32|64]f/hal::fastAtan[32|64]f - ipp_polarToCart is skipped for in-place processing (it seems not to support it correctly) relates to #24891 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [X] I agree to contribute to the project under Apache 2 License. - [X] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [X] The PR is proposed to the proper branch - [X] There is a reference to the original bug report and related work - [X] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/core/include/opencv2/core/hal/hal.hpp | 4 + modules/core/src/hal_replacement.hpp | 36 ++++ modules/core/src/mathfuncs.cpp | 91 ++++++--- modules/core/src/mathfuncs_core.dispatch.cpp | 20 +- modules/core/src/mathfuncs_core.simd.hpp | 78 +++++++- modules/core/src/opencl/arithm.cl | 32 +++ modules/core/test/test_arithm.cpp | 183 ++++++++++++++++-- 7 files changed, 402 insertions(+), 42 deletions(-) diff --git a/modules/core/include/opencv2/core/hal/hal.hpp b/modules/core/include/opencv2/core/hal/hal.hpp index 24a6077101..deca4e9539 100644 --- a/modules/core/include/opencv2/core/hal/hal.hpp +++ b/modules/core/include/opencv2/core/hal/hal.hpp @@ -91,10 +91,14 @@ CV_EXPORTS void exp64f(const double* src, double* dst, int n); CV_EXPORTS void log32f(const float* src, float* dst, int n); CV_EXPORTS void log64f(const double* src, double* dst, int n); +CV_EXPORTS void cartToPolar32f(const float* x, const float* y, float* mag, float* angle, int n, bool angleInDegrees); +CV_EXPORTS void cartToPolar64f(const double* x, const double* y, double* mag, double* angle, int n, bool angleInDegrees); CV_EXPORTS void fastAtan32f(const float* y, const float* x, float* dst, int n, bool angleInDegrees); CV_EXPORTS void fastAtan64f(const double* y, const double* x, double* dst, int n, bool angleInDegrees); CV_EXPORTS void magnitude32f(const float* x, const float* y, float* dst, int n); CV_EXPORTS void magnitude64f(const double* x, const double* y, double* dst, int n); +CV_EXPORTS void polarToCart32f(const float* mag, const float* angle, float* x, float* y, int n, bool angleInDegrees); +CV_EXPORTS void polarToCart64f(const double* mag, const double* angle, double* x, double* y, int n, bool angleInDegrees); CV_EXPORTS void sqrt32f(const float* src, float* dst, int len); CV_EXPORTS void sqrt64f(const double* src, double* dst, int len); CV_EXPORTS void invSqrt32f(const float* src, float* dst, int len); diff --git a/modules/core/src/hal_replacement.hpp b/modules/core/src/hal_replacement.hpp index 1f2b259920..f0fd12ca35 100644 --- a/modules/core/src/hal_replacement.hpp +++ b/modules/core/src/hal_replacement.hpp @@ -413,6 +413,24 @@ inline int hal_ni_merge64s(const int64 **src_data, int64 *dst_data, int len, int #define cv_hal_merge64s hal_ni_merge64s //! @endcond +/** +@param x source X arrays +@param y source Y arrays +@param mag destination magnitude array +@param angle destination angle array +@param len length of arrays +@param angleInDegrees if set to true return angles in degrees, otherwise in radians +*/ +//! @addtogroup core_hal_interface_fastAtan Atan calculation +//! @{ +inline int hal_ni_cartToPolar32f(const float* x, const float* y, float* mag, float* angle, int len, bool angleInDegrees) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_cartToPolar64f(const double* x, const double* y, double* mag, double* angle, int len, bool angleInDegrees) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +//! @} + +//! @cond IGNORED +#define cv_hal_cartToPolar32f hal_ni_cartToPolar32f +#define cv_hal_cartToPolar64f hal_ni_cartToPolar64f +//! @endcond /** @param y source Y arrays @@ -450,6 +468,24 @@ inline int hal_ni_magnitude64f(const double *x, const double *y, double *dst, i #define cv_hal_magnitude64f hal_ni_magnitude64f //! @endcond +/** +@param mag source magnitude arrays +@param mag source angle arrays +@param x destination X array +@param y destination Y array +@param len length of arrays +@param angleInDegrees if set to true interpret angles from degrees, otherwise from radians +*/ +//! @addtogroup core_hal_interface_fastAtan Atan calculation +//! @{ +inline int hal_ni_polarToCart32f(const float* mag, const float* angle, float* x, float* y, int len, bool angleInDegrees) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_polarToCart64f(const double* mag, const double* angle, double* x, double* y, int len, bool angleInDegrees) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +//! @} + +//! @cond IGNORED +#define cv_hal_polarToCart32f hal_ni_polarToCart32f +#define cv_hal_polarToCart64f hal_ni_polarToCart64f +//! @endcond /** @param src source array diff --git a/modules/core/src/mathfuncs.cpp b/modules/core/src/mathfuncs.cpp index 04604e84c0..1aa16aaceb 100644 --- a/modules/core/src/mathfuncs.cpp +++ b/modules/core/src/mathfuncs.cpp @@ -233,16 +233,26 @@ static bool ocl_cartToPolar( InputArray _src1, InputArray _src2, rowsPerWI = d.isIntel() ? 4 : 1; bool doubleSupport = d.doubleFPConfig() > 0; + const bool _src1IsDstMag = (_src1.getObj() == _dst1.getObj()); + const bool _src1IsDstAngle = (_src1.getObj() == _dst2.getObj()); + const bool _src2IsDstMag = (_src2.getObj() == _dst1.getObj()); + const bool _src2IsDstAngle = (_src2.getObj() == _dst2.getObj()); + if ( !(_src1.dims() <= 2 && _src2.dims() <= 2 && (depth == CV_32F || depth == CV_64F) && type == _src2.type()) || (depth == CV_64F && !doubleSupport) ) return false; ocl::Kernel k("KF", ocl::core::arithm_oclsrc, - format("-D BINARY_OP -D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D OP_CTP_%s%s", + format("-D BINARY_OP -D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D OP_CTP_%s%s%s%s%s%s", ocl::typeToStr(CV_MAKE_TYPE(depth, 1)), depth, rowsPerWI, angleInDegrees ? "AD" : "AR", - doubleSupport ? " -D DOUBLE_SUPPORT" : "")); + doubleSupport ? " -D DOUBLE_SUPPORT" : "", + _src1IsDstMag ? " -D SRC1_IS_DST_MAG" : "", + _src1IsDstAngle ? " -D SRC1_IS_DST_ANGLE" : "", + _src2IsDstMag ? " -D SRC2_IS_DST_MAG" : "", + _src2IsDstAngle ? " -D SRC2_IS_DST_ANGLE" : "" + )); if (k.empty()) return false; @@ -254,8 +264,8 @@ static bool ocl_cartToPolar( InputArray _src1, InputArray _src2, _dst2.create(size, type); UMat dst1 = _dst1.getUMat(), dst2 = _dst2.getUMat(); - k.args(ocl::KernelArg::ReadOnlyNoSize(src1), - ocl::KernelArg::ReadOnlyNoSize(src2), + k.args(_src1IsDstMag || _src1IsDstAngle ? ocl::KernelArg::ReadWriteNoSize(src1) : ocl::KernelArg::ReadOnlyNoSize(src1), + _src2IsDstMag || _src2IsDstAngle ? ocl::KernelArg::ReadWriteNoSize(src2) : ocl::KernelArg::ReadOnlyNoSize(src2), ocl::KernelArg::WriteOnly(dst1, cn), ocl::KernelArg::WriteOnlyNoSize(dst2)); @@ -270,8 +280,7 @@ void cartToPolar( InputArray src1, InputArray src2, { CV_INSTRUMENT_REGION(); - CV_Assert(src1.getObj() != dst1.getObj() && src1.getObj() != dst2.getObj() && - src2.getObj() != dst1.getObj() && src2.getObj() != dst2.getObj()); + CV_Assert(dst1.getObj() != dst2.getObj()); CV_OCL_RUN(dst1.isUMat() && dst2.isUMat(), ocl_cartToPolar(src1, src2, dst1, dst2, angleInDegrees)) @@ -298,15 +307,13 @@ void cartToPolar( InputArray src1, InputArray src2, { const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1]; float *mag = (float*)ptrs[2], *angle = (float*)ptrs[3]; - hal::magnitude32f( x, y, mag, len ); - hal::fastAtan32f( y, x, angle, len, angleInDegrees ); + hal::cartToPolar32f( x, y, mag, angle, len, angleInDegrees ); } else { const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1]; - double *angle = (double*)ptrs[3]; - hal::magnitude64f(x, y, (double*)ptrs[2], len); - hal::fastAtan64f(y, x, angle, len, angleInDegrees); + double *mag = (double*)ptrs[2], *angle = (double*)ptrs[3]; + hal::cartToPolar64f(x, y, mag, angle, len, angleInDegrees); } ptrs[0] += len*esz1; ptrs[1] += len*esz1; @@ -474,15 +481,24 @@ static bool ocl_polarToCart( InputArray _mag, InputArray _angle, rowsPerWI = d.isIntel() ? 4 : 1; bool doubleSupport = d.doubleFPConfig() > 0; + const bool _src1IsDstX = (_mag.getObj() == _dst1.getObj()); + const bool _src1IsDstY = (_mag.getObj() == _dst2.getObj()); + const bool _src2IsDstX = (_angle.getObj() == _dst1.getObj()); + const bool _src2IsDstY = (_angle.getObj() == _dst2.getObj()); + if ( !doubleSupport && depth == CV_64F ) return false; ocl::Kernel k("KF", ocl::core::arithm_oclsrc, - format("-D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D BINARY_OP -D OP_PTC_%s%s", + format("-D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D BINARY_OP -D OP_PTC_%s%s%s%s%s%s", ocl::typeToStr(CV_MAKE_TYPE(depth, 1)), depth, rowsPerWI, angleInDegrees ? "AD" : "AR", - doubleSupport ? " -D DOUBLE_SUPPORT" : "")); + doubleSupport ? " -D DOUBLE_SUPPORT" : "", + _src1IsDstX ? " -D SRC1_IS_DST_X" : "", + _src1IsDstY ? " -D SRC1_IS_DST_Y" : "", + _src2IsDstX ? " -D SRC2_IS_DST_X" : "", + _src2IsDstY ? " -D SRC2_IS_DST_Y" : "")); if (k.empty()) return false; @@ -494,8 +510,10 @@ static bool ocl_polarToCart( InputArray _mag, InputArray _angle, _dst2.create(size, type); UMat dst1 = _dst1.getUMat(), dst2 = _dst2.getUMat(); - k.args(ocl::KernelArg::ReadOnlyNoSize(mag), ocl::KernelArg::ReadOnlyNoSize(angle), - ocl::KernelArg::WriteOnly(dst1, cn), ocl::KernelArg::WriteOnlyNoSize(dst2)); + k.args(_src1IsDstX || _src1IsDstY ? ocl::KernelArg::ReadWriteNoSize(mag) : ocl::KernelArg::ReadOnlyNoSize(mag), + _src2IsDstX || _src2IsDstY ? ocl::KernelArg::ReadWriteNoSize(angle) : ocl::KernelArg::ReadOnlyNoSize(angle), + ocl::KernelArg::WriteOnly(dst1, cn), + ocl::KernelArg::WriteOnlyNoSize(dst2)); size_t globalsize[2] = { (size_t)dst1.cols * cn, ((size_t)dst1.rows + rowsPerWI - 1) / rowsPerWI }; return k.run(2, globalsize, NULL, false); @@ -567,8 +585,13 @@ void polarToCart( InputArray src1, InputArray src2, { CV_INSTRUMENT_REGION(); - CV_Assert(src1.getObj() != dst1.getObj() && src1.getObj() != dst2.getObj() && - src2.getObj() != dst1.getObj() && src2.getObj() != dst2.getObj()); + CV_Assert(dst1.getObj() != dst2.getObj()); + + const bool isInPlace = + (src1.getObj() == dst1.getObj()) || + (src1.getObj() == dst2.getObj()) || + (src2.getObj() == dst1.getObj()) || + (src2.getObj() == dst2.getObj()); int type = src2.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); CV_Assert((depth == CV_32F || depth == CV_64F) && (src1.empty() || src1.type() == type)); @@ -582,7 +605,7 @@ void polarToCart( InputArray src1, InputArray src2, dst2.create( Angle.dims, Angle.size, type ); Mat X = dst1.getMat(), Y = dst2.getMat(); - CV_IPP_RUN(!angleInDegrees, ipp_polarToCart(Mag, Angle, X, Y)); + CV_IPP_RUN(!angleInDegrees && !isInPlace, ipp_polarToCart(Mag, Angle, X, Y)); const Mat* arrays[] = {&Mag, &Angle, &X, &Y, 0}; uchar* ptrs[4] = {}; @@ -592,7 +615,7 @@ void polarToCart( InputArray src1, InputArray src2, int j, k, total = (int)(it.size*cn), blockSize = std::min(total, ((BLOCK_SIZE+cn-1)/cn)*cn); size_t esz1 = Angle.elemSize1(); - if( depth == CV_64F ) + if (( depth == CV_64F ) || isInPlace) { _buf.allocate(blockSize*2); buf[0] = _buf.data(); @@ -604,7 +627,7 @@ void polarToCart( InputArray src1, InputArray src2, for( j = 0; j < total; j += blockSize ) { int len = std::min(total - j, blockSize); - if( depth == CV_32F ) + if (( depth == CV_32F ) && !isInPlace) { const float *mag = (const float*)ptrs[0], *angle = (const float*)ptrs[1]; float *x = (float*)ptrs[2], *y = (float*)ptrs[3]; @@ -632,6 +655,27 @@ void polarToCart( InputArray src1, InputArray src2, } } } + else if (( depth == CV_32F ) && isInPlace) + { + const float *mag = (const float*)ptrs[0], *angle = (const float*)ptrs[1]; + float *x = (float*)ptrs[2], *y = (float*)ptrs[3]; + + for( k = 0; k < len; k++ ) + buf[0][k] = (float)angle[k]; + + SinCos_32f( buf[0], buf[1], buf[0], len, angleInDegrees ); + if( mag ) + for( k = 0; k < len; k++ ) + { + float m = mag[k]; + x[k] = buf[0][k]*m; y[k] = buf[1][k]*m; + } + else + { + std::memcpy(x, buf[0], sizeof(float) * len); + std::memcpy(y, buf[1], sizeof(float) * len); + } + } else { const double *mag = (const double*)ptrs[0], *angle = (const double*)ptrs[1]; @@ -649,8 +693,11 @@ void polarToCart( InputArray src1, InputArray src2, } else { - std::memcpy(x, buf[0], sizeof(float) * len); - std::memcpy(y, buf[1], sizeof(float) * len); + for( k = 0; k < len; k++ ) + { + x[k] = buf[0][k]; + y[k] = buf[1][k]; + } } } diff --git a/modules/core/src/mathfuncs_core.dispatch.cpp b/modules/core/src/mathfuncs_core.dispatch.cpp index e48f84ebbe..485eac27b4 100644 --- a/modules/core/src/mathfuncs_core.dispatch.cpp +++ b/modules/core/src/mathfuncs_core.dispatch.cpp @@ -9,7 +9,25 @@ namespace cv { namespace hal { -///////////////////////////////////// ATAN2 //////////////////////////////////// +void cartToPolar32f(const float* x, const float* y, float* mag, float* angle, int len, bool angleInDegrees) +{ + CV_INSTRUMENT_REGION(); + + CALL_HAL(cartToPolar32f, cv_hal_cartToPolar32f, x, y, mag, angle, len, angleInDegrees); + + CV_CPU_DISPATCH(cartToPolar32f, (x, y, mag, angle, len, angleInDegrees), + CV_CPU_DISPATCH_MODES_ALL); +} + +void cartToPolar64f(const double* x, const double* y, double* mag, double* angle, int len, bool angleInDegrees) +{ + CV_INSTRUMENT_REGION(); + + CALL_HAL(cartToPolar64f, cv_hal_cartToPolar64f, x, y, mag, angle, len, angleInDegrees); + + CV_CPU_DISPATCH(cartToPolar64f, (x, y, mag, angle, len, angleInDegrees), + CV_CPU_DISPATCH_MODES_ALL); +} void fastAtan32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees ) { diff --git a/modules/core/src/mathfuncs_core.simd.hpp b/modules/core/src/mathfuncs_core.simd.hpp index 2aa107b9be..cb21064041 100644 --- a/modules/core/src/mathfuncs_core.simd.hpp +++ b/modules/core/src/mathfuncs_core.simd.hpp @@ -9,6 +9,8 @@ namespace cv { namespace hal { CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN // forward declarations +void cartToPolar32f(const float *X, const float *Y, float* mag, float *angle, int len, bool angleInDegrees); +void cartToPolar64f(const double *X, const double *Y, double* mag, double *angle, int len, bool angleInDegrees); void fastAtan32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees); void fastAtan64f(const double *Y, const double *X, double *angle, int len, bool angleInDegrees); void fastAtan2(const float *Y, const float *X, float *angle, int len, bool angleInDegrees); @@ -118,7 +120,81 @@ struct v_atan_f32 } // anonymous:: -///////////////////////////////////// ATAN2 //////////////////////////////////// +static void cartToPolar32f_(const float *X, const float *Y, float *mag, float *angle, int len, bool angleInDegrees ) +{ + float scale = angleInDegrees ? 1.f : (float)(CV_PI/180); + int i = 0; +#if CV_SIMD + const int VECSZ = VTraits::vlanes(); + v_atan_f32 v(scale); + + for( ; i < len; i += VECSZ*2 ) + { + if( i + VECSZ*2 > len ) + { + // if it's inplace operation, we cannot repeatedly process + // the tail for the second time, so we have to use the + // scalar code + if( i == 0 || angle == X || angle == Y ) + break; + i = len - VECSZ*2; + } + + v_float32 x0 = vx_load(X + i); + v_float32 y0 = vx_load(Y + i); + v_float32 x1 = vx_load(X + i + VECSZ); + v_float32 y1 = vx_load(Y + i + VECSZ); + + v_float32 m0 = v_sqrt(v_muladd(x0, x0, v_mul(y0, y0))); + v_float32 m1 = v_sqrt(v_muladd(x1, x1, v_mul(y1, y1))); + + v_float32 r0 = v.compute(y0, x0); + v_float32 r1 = v.compute(y1, x1); + + v_store(mag + i, m0); + v_store(mag + i + VECSZ, m1); + + v_store(angle + i, r0); + v_store(angle + i + VECSZ, r1); + } + vx_cleanup(); +#endif + + for( ; i < len; i++ ) + { + float x0 = X[i], y0 = Y[i]; + mag[i] = std::sqrt(x0*x0 + y0*y0); + angle[i] = atan_f32(y0, x0)*scale; + } +} + +void cartToPolar32f(const float *X, const float *Y, float *mag, float *angle, int len, bool angleInDegrees ) +{ + CV_INSTRUMENT_REGION(); + cartToPolar32f_(X, Y, mag, angle, len, angleInDegrees ); +} + +void cartToPolar64f(const double *X, const double *Y, double *mag, double *angle, int len, bool angleInDegrees) +{ + CV_INSTRUMENT_REGION(); + + const int BLKSZ = 128; + float ybuf[BLKSZ], xbuf[BLKSZ], mbuf[BLKSZ], abuf[BLKSZ]; + for( int i = 0; i < len; i += BLKSZ ) + { + int j, blksz = std::min(BLKSZ, len - i); + for( j = 0; j < blksz; j++ ) + { + xbuf[j] = (float)X[i + j]; + ybuf[j] = (float)Y[i + j]; + } + cartToPolar32f_(xbuf, ybuf, mbuf, abuf, blksz, angleInDegrees); + for( j = 0; j < blksz; j++ ) + mag[i + j] = mbuf[j]; + for( j = 0; j < blksz; j++ ) + angle[i + j] = abuf[j]; + } +} static void fastAtan32f_(const float *Y, const float *X, float *angle, int len, bool angleInDegrees ) { diff --git a/modules/core/src/opencl/arithm.cl b/modules/core/src/opencl/arithm.cl index d4165faae3..301cea9f98 100644 --- a/modules/core/src/opencl/arithm.cl +++ b/modules/core/src/opencl/arithm.cl @@ -381,6 +381,20 @@ #elif defined OP_CTP_AR #define TO_DEGREE #endif +#ifdef SRC1_IS_DST_MAG +#define ADAPT_SRC1 dstptr = srcptr1; +#elif SRC1_IS_DST_ANGLE +#define ADAPT_SRC1 dstptr2 = srcptr1; +#else +#define ADAPT_SRC1 +#endif +#ifdef SRC2_IS_DST_MAG +#define ADAPT_SRC2 dstptr = srcptr2; +#elif SRC2_IS_DST_ANGLE +#define ADAPT_SRC2 dstptr2 = srcptr2; +#else +#define ADAPT_SRC2 +#endif #define PROCESS_ELEM \ dstT x = srcelem1, y = srcelem2; \ dstT x2 = x * x, y2 = y * y; \ @@ -390,6 +404,8 @@ dstT tmp1 = y >= 0 ? CV_PI * 0.5f : CV_PI * 1.5f; \ dstT cartToPolar = y2 <= x2 ? x * y / mad((dstT)(0.28f), y2, x2 + CV_EPSILON) + tmp : (tmp1 - x * y / mad((dstT)(0.28f), x2, y2 + CV_EPSILON)); \ TO_DEGREE \ + ADAPT_SRC1 \ + ADAPT_SRC2 \ storedst(magnitude); \ storedst2(cartToPolar) @@ -399,9 +415,25 @@ #else #define FROM_DEGREE #endif +#ifdef SRC1_IS_DST_X +#define ADAPT_SRC1 dstptr = srcptr1; +#elif SRC1_IS_DST_Y +#define ADAPT_SRC1 dstptr2 = srcptr1; +#else +#define ADAPT_SRC1 +#endif +#ifdef SRC2_IS_DST_X +#define ADAPT_SRC2 dstptr = srcptr2; +#elif SRC2_IS_DST_Y +#define ADAPT_SRC2 dstptr2 = srcptr2; +#else +#define ADAPT_SRC2 +#endif #define PROCESS_ELEM \ dstT x = srcelem1, y = srcelem2, cosval; \ FROM_DEGREE; \ + ADAPT_SRC1; \ + ADAPT_SRC2; \ storedst2(sincos(y, &cosval) * x); \ storedst(cosval * x); diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index 499c766a84..73c755b0fa 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -2819,12 +2819,26 @@ TEST(Core_Magnitude, regression_19506) } } -TEST(Core_CartPolar, inplace) +PARAM_TEST_CASE(Core_CartPolar_reverse, int, bool) { - RNG& rng = TS::ptr()->get_rng(); - cv::Mat1d A[2] = {cv::Mat1d(10, 10), cv::Mat1d(10, 10)}; - cv::Mat1d B[2], C[2]; + int depth; + bool angleInDegrees; + + virtual void SetUp() + { + depth = GET_PARAM(0); + angleInDegrees = GET_PARAM(1); + } +}; + +TEST_P(Core_CartPolar_reverse, reverse) +{ + const int type = CV_MAKETYPE(depth, 1); + cv::Mat A[2] = {cv::Mat(10, 10, type), cv::Mat(10, 10, type)}; + cv::Mat B[2], C[2]; cv::UMat uA[2]; + cv::UMat uB[2]; + cv::UMat uC[2]; for(int i = 0; i < 2; ++i) { @@ -2833,22 +2847,155 @@ TEST(Core_CartPolar, inplace) } // Reverse - cv::cartToPolar(A[0], A[1], B[0], B[1], false); - cv::polarToCart(B[0], B[1], C[0], C[1], false); + cv::cartToPolar(A[0], A[1], B[0], B[1], angleInDegrees); + cv::polarToCart(B[0], B[1], C[0], C[1], angleInDegrees); EXPECT_MAT_NEAR(A[0], C[0], 2); EXPECT_MAT_NEAR(A[1], C[1], 2); - - // Inplace - EXPECT_THROW(cv::polarToCart(B[0], B[1], B[0], B[1], false), cv::Exception); - EXPECT_THROW(cv::polarToCart(B[0], B[1], B[1], B[0], false), cv::Exception); - EXPECT_THROW(cv::cartToPolar(A[0], A[1], A[0], A[1], false), cv::Exception); - EXPECT_THROW(cv::cartToPolar(A[0], A[1], A[1], A[0], false), cv::Exception); - // Inplace OCL - EXPECT_THROW(cv::polarToCart(uA[0], uA[1], uA[0], uA[1]), cv::Exception); - EXPECT_THROW(cv::polarToCart(uA[0], uA[1], uA[1], uA[0]), cv::Exception); - EXPECT_THROW(cv::cartToPolar(uA[0], uA[1], uA[0], uA[1]), cv::Exception); - EXPECT_THROW(cv::cartToPolar(uA[0], uA[1], uA[0], uA[1]), cv::Exception); - } +INSTANTIATE_TEST_CASE_P(Core_CartPolar, Core_CartPolar_reverse, + testing::Combine( + testing::Values(CV_32F, CV_64F), + testing::Values(false, true) + ) +); + +PARAM_TEST_CASE(Core_CartToPolar_inplace, int, bool) +{ + int depth; + bool angleInDegrees; + + virtual void SetUp() + { + depth = GET_PARAM(0); + angleInDegrees = GET_PARAM(1); + } +}; + +TEST_P(Core_CartToPolar_inplace, inplace) +{ + const int type = CV_MAKETYPE(depth, 1); + cv::Mat A[2] = {cv::Mat(10, 10, type), cv::Mat(10, 10, type)}; + cv::Mat B[2], C[2]; + cv::UMat uA[2]; + cv::UMat uB[2]; + cv::UMat uC[2]; + + for(int i = 0; i < 2; ++i) + { + cvtest::randUni(rng, A[i], Scalar::all(-1000), Scalar::all(1000)); + A[i].copyTo(uA[i]); + } + + // Inplace x<->mag y<->angle + for(int i = 0; i < 2; ++i) + A[i].copyTo(B[i]); + cv::cartToPolar(A[0], A[1], C[0], C[1], angleInDegrees); + cv::cartToPolar(B[0], B[1], B[0], B[1], angleInDegrees); + EXPECT_MAT_NEAR(C[0], B[0], 2); + EXPECT_MAT_NEAR(C[1], B[1], 2); + + // Inplace x<->angle y<->mag + for(int i = 0; i < 2; ++i) + A[i].copyTo(B[i]); + cv::cartToPolar(A[0], A[1], C[0], C[1], angleInDegrees); + cv::cartToPolar(B[0], B[1], B[1], B[0], angleInDegrees); + EXPECT_MAT_NEAR(C[0], B[1], 2); + EXPECT_MAT_NEAR(C[1], B[0], 2); + + // Inplace OCL x<->mag y<->angle + for(int i = 0; i < 2; ++i) + uA[i].copyTo(uB[i]); + cv::cartToPolar(uA[0], uA[1], uC[0], uC[1], angleInDegrees); + cv::cartToPolar(uB[0], uB[1], uB[0], uB[1], angleInDegrees); + EXPECT_MAT_NEAR(uC[0], uB[0], 2); + EXPECT_MAT_NEAR(uC[1], uB[1], 2); + + // Inplace OCL x<->angle y<->mag + for(int i = 0; i < 2; ++i) + uA[i].copyTo(uB[i]); + cv::cartToPolar(uA[0], uA[1], uC[0], uC[1], angleInDegrees); + cv::cartToPolar(uB[0], uB[1], uB[1], uB[0], angleInDegrees); + EXPECT_MAT_NEAR(uC[0], uB[1], 2); + EXPECT_MAT_NEAR(uC[1], uB[0], 2); +} + +INSTANTIATE_TEST_CASE_P(Core_CartPolar, Core_CartToPolar_inplace, + testing::Combine( + testing::Values(CV_32F, CV_64F), + testing::Values(false, true) + ) +); + +PARAM_TEST_CASE(Core_PolarToCart_inplace, int, bool, bool) +{ + int depth; + bool angleInDegrees; + bool implicitMagnitude; + + virtual void SetUp() + { + depth = GET_PARAM(0); + angleInDegrees = GET_PARAM(1); + implicitMagnitude = GET_PARAM(2); + } +}; + +TEST_P(Core_PolarToCart_inplace, inplace) +{ + const int type = CV_MAKETYPE(depth, 1); + cv::Mat A[2] = {cv::Mat(10, 10, type), cv::Mat(10, 10, type)}; + cv::Mat B[2], C[2]; + cv::UMat uA[2]; + cv::UMat uB[2]; + cv::UMat uC[2]; + + for(int i = 0; i < 2; ++i) + { + cvtest::randUni(rng, A[i], Scalar::all(-1000), Scalar::all(1000)); + A[i].copyTo(uA[i]); + } + + // Inplace OCL x<->mag y<->angle + for(int i = 0; i < 2; ++i) + A[i].copyTo(B[i]); + cv::polarToCart(implicitMagnitude ? cv::noArray() : A[0], A[1], C[0], C[1], angleInDegrees); + cv::polarToCart(implicitMagnitude ? cv::noArray() : B[0], B[1], B[0], B[1], angleInDegrees); + EXPECT_MAT_NEAR(C[0], B[0], 2); + EXPECT_MAT_NEAR(C[1], B[1], 2); + + // Inplace OCL x<->angle y<->mag + for(int i = 0; i < 2; ++i) + A[i].copyTo(B[i]); + cv::polarToCart(implicitMagnitude ? cv::noArray() : A[0], A[1], C[0], C[1], angleInDegrees); + cv::polarToCart(implicitMagnitude ? cv::noArray() : B[0], B[1], B[1], B[0], angleInDegrees); + EXPECT_MAT_NEAR(C[0], B[1], 2); + EXPECT_MAT_NEAR(C[1], B[0], 2); + + // Inplace OCL x<->mag y<->angle + for(int i = 0; i < 2; ++i) + uA[i].copyTo(uB[i]); + cv::polarToCart(implicitMagnitude ? cv::noArray() : uA[0], uA[1], uC[0], uC[1], angleInDegrees); + cv::polarToCart(implicitMagnitude ? cv::noArray() : uB[0], uB[1], uB[0], uB[1], angleInDegrees); + EXPECT_MAT_NEAR(uC[0], uB[0], 2); + EXPECT_MAT_NEAR(uC[1], uB[1], 2); + + // Inplace OCL x<->angle y<->mag + for(int i = 0; i < 2; ++i) + uA[i].copyTo(uB[i]); + cv::polarToCart(implicitMagnitude ? cv::noArray() : uA[0], uA[1], uC[0], uC[1], angleInDegrees); + cv::polarToCart(implicitMagnitude ? cv::noArray() : uB[0], uB[1], uB[1], uB[0], angleInDegrees); + EXPECT_MAT_NEAR(uC[0], uB[1], 2); + EXPECT_MAT_NEAR(uC[1], uB[0], 2); +} + +INSTANTIATE_TEST_CASE_P(Core_CartPolar, Core_PolarToCart_inplace, + testing::Combine( + testing::Values(CV_32F, CV_64F), + testing::Values(false, true), + testing::Values(true, false) + ) +); + + }} // namespace From e3ff6ce0cc1726a6df92536eda775423598f8047 Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Wed, 27 Mar 2024 12:43:56 +0300 Subject: [PATCH 40/56] Merge pull request #25182 from MaximSmolskiy:increase-decomposeProjectionMatrix-precision-for-small-scales Increase decomposeProjectionMatrix precision for small scales #25182 ### Pull Request Readiness Checklist Fix #23733 It is checked before that `|s| > DBL_EPSILON` (if not, then `s` will be equal to `0`, but `c` will be equal to `1`, then `z` will be equal to `1` and there will be no any problems with small values), so `sqrt(c^2 + s^2) >= |s| > DBL_EPSILON` and thus small values are already taken into account before and there is no need to add `DBL_EPSILON` to `c^2 + s^2` (and I think adding `DBL_EPSILON^2` instead of `DBL_EPSILON` would be more correct). I ran `Python` script from issue. `NumPy` and `SciPy` results ``` *Numpy* P (case 1): [[1. 0. 0. 0.] [0. 1. 0. 0.] [0. 0. 1. 0.]] Numpy, R.T @ R - I: [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] Numpy scaled 1e-6, R.T @ R - I: [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] P (case 2): [[52. -7. 4. 12.] [-6. 49. 12. 8.] [ 4. 17. 1. 0.]] Numpy, R.T @ R - I: [[-8.88178420e-16 -3.86302608e-16 -2.52050796e-17] [-3.86302608e-16 -5.55111512e-16 7.11675423e-18] [-2.52050796e-17 7.11675423e-18 -5.55111512e-16]] Numpy scaled 1e-6, R.T @ R - I: [[ 2.22044605e-16 -2.00683644e-16 -1.90063998e-17] [-2.00683644e-16 0.00000000e+00 1.16926308e-17] [-1.90063998e-17 1.16926308e-17 2.22044605e-16]] *Scipy* P (case 1): [[1. 0. 0. 0.] [0. 1. 0. 0.] [0. 0. 1. 0.]] Scipy, R.T @ R - I: [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] Scipy scaled 1e-6, R.T @ R - I: [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] P (case 2): [[52. -7. 4. 12.] [-6. 49. 12. 8.] [ 4. 17. 1. 0.]] Scipy, R.T @ R - I: [[-1.11022302e-16 -8.74062812e-18 -1.26178867e-17] [-8.74062812e-18 -1.11022302e-16 2.07820373e-17] [-1.26178867e-17 2.07820373e-17 -1.11022302e-16]] Scipy scaled 1e-6, R.T @ R - I: [[0.00000000e+00 4.04691435e-17 1.12452918e-16] [4.04691435e-17 4.44089210e-16 3.74164141e-16] [1.12452918e-16 3.74164141e-16 4.44089210e-16]] *Numpy* Numpy, P' - P: [[ 1.35525272e-20 -9.31736242e-21 8.47032947e-22 3.38813179e-21] [-3.38813179e-21 6.77626358e-21 1.69406589e-21 0.00000000e+00] [-1.69406589e-21 0.00000000e+00 0.00000000e+00 4.85524279e-22]] *Scipy* Scipy, P' - P: [[0.00000000e+00 8.47032947e-22 3.38813179e-21 3.38813179e-21] [3.38813179e-21 1.35525272e-20 1.52465931e-20 1.52465931e-20] [8.47032947e-22 3.38813179e-21 2.54109884e-21 3.39866995e-21]] ``` `OpenCV` results before ``` *OpenCV* P (case 1): [[1. 0. 0. 0.] [0. 1. 0. 0.] [0. 0. 1. 0.]] OpenCV, R.T @ R - I: [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] OpenCV scaled 1e-6, R.T @ R - I: [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] P (case 2): [[52. -7. 4. 12.] [-6. 49. 12. 8.] [ 4. 17. 1. 0.]] OpenCV, R.T @ R - I: [[ 2.22044605e-16 -9.12253504e-17 -2.20527203e-19] [-9.12253504e-17 0.00000000e+00 -9.12405093e-18] [-2.20527203e-19 -9.12405093e-18 2.22044605e-16]] OpenCV scaled 1e-6, R.T @ R - I: [[-1.28197013e-06 1.30450769e-07 7.67357467e-09] [ 1.30450769e-07 -1.52141637e-06 -9.92455574e-09] [ 7.67357467e-09 -9.92455574e-09 -1.35328272e-06]] *OpenCV* OpenCV, P' - P: [[-6.75449076e-11 1.73936564e-11 -4.94463312e-12 -1.61106020e-11] [ 1.41759913e-11 -7.54512016e-11 -1.67717374e-11 -9.74644390e-12] [-2.90254385e-12 -2.53521998e-11 -1.49130587e-12 4.00724440e-13]] ``` `OpenCV` results after ``` *OpenCV* P (case 1): [[1. 0. 0. 0.] [0. 1. 0. 0.] [0. 0. 1. 0.]] OpenCV, R.T @ R - I: [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] OpenCV scaled 1e-6, R.T @ R - I: [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] P (case 2): [[52. -7. 4. 12.] [-6. 49. 12. 8.] [ 4. 17. 1. 0.]] OpenCV, R.T @ R - I: [[ 2.22044605e-16 -9.12253504e-17 -2.20527203e-19] [-9.12253504e-17 0.00000000e+00 -9.12405093e-18] [-2.20527203e-19 -9.12405093e-18 2.22044605e-16]] OpenCV scaled 1e-6, R.T @ R - I: [[ 0.00000000e+00 4.36198333e-17 -2.66855078e-17] [ 4.36198333e-17 2.22044605e-16 3.17216400e-17] [-2.66855078e-17 3.17216400e-17 -2.22044605e-16]] *OpenCV* OpenCV, P' - P: [[ 6.77626358e-21 0.00000000e+00 -8.47032947e-22 1.69406589e-21] [-1.69406589e-21 6.77626358e-21 0.00000000e+00 3.38813179e-21] [ 8.47032947e-22 3.38813179e-21 2.11758237e-22 1.45657284e-21]] ``` See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/calib3d/src/calibration.cpp | 6 +++--- .../test/test_decompose_projection.cpp | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/modules/calib3d/src/calibration.cpp b/modules/calib3d/src/calibration.cpp index 24d2875fdd..50940a80ff 100644 --- a/modules/calib3d/src/calibration.cpp +++ b/modules/calib3d/src/calibration.cpp @@ -3190,7 +3190,7 @@ cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, */ s = std::abs(matM[2][1]) > DBL_EPSILON ? matM[2][1] : 0; c = std::abs(matM[2][1]) > DBL_EPSILON ? matM[2][2] : 1; - z = 1./std::sqrt(c * c + s * s + DBL_EPSILON); + z = 1./std::sqrt(c * c + s * s); c *= z; s *= z; @@ -3209,7 +3209,7 @@ cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, */ s = std::abs(matR[2][0]) > DBL_EPSILON ? -matR[2][0] : 0; c = std::abs(matR[2][0]) > DBL_EPSILON ? matR[2][2] : 1; - z = 1./std::sqrt(c * c + s * s + DBL_EPSILON); + z = 1./std::sqrt(c * c + s * s); c *= z; s *= z; @@ -3229,7 +3229,7 @@ cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, s = std::abs(matM[1][0]) > DBL_EPSILON ? matM[1][0] : 0; c = std::abs(matM[1][0]) > DBL_EPSILON ? matM[1][1] : 1; - z = 1./std::sqrt(c * c + s * s + DBL_EPSILON); + z = 1./std::sqrt(c * c + s * s); c *= z; s *= z; diff --git a/modules/calib3d/test/test_decompose_projection.cpp b/modules/calib3d/test/test_decompose_projection.cpp index 0e3a420d69..a25081b452 100644 --- a/modules/calib3d/test/test_decompose_projection.cpp +++ b/modules/calib3d/test/test_decompose_projection.cpp @@ -160,4 +160,24 @@ TEST(Calib3d_DecomposeProjectionMatrix, degenerate_cases) } } +TEST(Calib3d_DecomposeProjectionMatrix, bug_23733) +{ + cv::Matx34d P(52, -7, 4, 12, + -6, 49, 12, 8, + 4, 17, 1, 0); + P *= 1e-6; + + cv::Matx33d K, R; + cv::Vec4d t; + decomposeProjectionMatrix(P, K, R, t); + + EXPECT_LT(cv::norm(R.t() * R - cv::Matx33d::eye(), cv::NORM_INF), 1e-10); + + cv::Matx34d M; + cv::hconcat(R, -R * cv::Vec3d(t[0] / t[3], t[1] / t[3], t[2] / t[3]), M); + + cv::Matx34d P_recompose = K * M; + EXPECT_LT(cv::norm(P_recompose - P, cv::NORM_INF), 1e-16); +} + }} // namespace From 43666e13083f3a999aecc45d6fa8864958fb9310 Mon Sep 17 00:00:00 2001 From: Michael Klatis Date: Wed, 27 Mar 2024 05:10:40 -0700 Subject: [PATCH 41/56] Merge pull request #25190 from klatism:android-config-flags-enhancement Add component disable flag to android build #25190 Adding --disable flag to android sdk build script. The flag allows to exclude components from build by concatting -DWITH_XXX cmake flag to the build command. Example : --disable OPENEXR (uppercase). - [X] I agree to contribute to the project under Apache 2 License. - [X] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [X] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- platforms/android/build_sdk.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platforms/android/build_sdk.py b/platforms/android/build_sdk.py index ba739a9495..6e03698a5e 100755 --- a/platforms/android/build_sdk.py +++ b/platforms/android/build_sdk.py @@ -161,6 +161,7 @@ class Builder: self.opencl = True if config.opencl else False self.no_kotlin = True if config.no_kotlin else False self.shared = True if config.shared else False + self.disable = args.disable def get_cmake(self): if not self.config.use_android_buildtools and check_executable(['cmake', '--version']): @@ -265,6 +266,10 @@ class Builder: cmake_vars['WITH_ANDROID_MEDIANDK'] = "OFF" cmake_vars.update(abi.cmake_vars) + + if len(self.disable) > 0: + cmake_vars.update({'WITH_%s' % f : "OFF" for f in self.disable}) + cmd += [ "-D%s='%s'" % (k, v) for (k, v) in cmake_vars.items() if v is not None] cmd.append(self.opencvdir) execute(cmd) @@ -375,6 +380,7 @@ if __name__ == "__main__": parser.add_argument('--no_kotlin', action="store_true", help="Disable Kotlin extensions") parser.add_argument('--shared', action="store_true", help="Build shared libraries") parser.add_argument('--no_media_ndk', action="store_true", help="Do not link Media NDK (required for video I/O support)") + parser.add_argument('--disable', metavar='FEATURE', default=[], action='append', help='OpenCV features to disable (add WITH_*=OFF). To disable multiple, specify this flag again, e.g. "--disable TBB --disable OPENMP"') args = parser.parse_args() log.basicConfig(format='%(message)s', level=log.DEBUG) From ff9aeaceb0a8abede5fc5189f2551712037db9ef Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Wed, 27 Mar 2024 15:34:54 +0300 Subject: [PATCH 42/56] Merge pull request #25177 from MaximSmolskiy:speed-up-adaptive-image-binary-threshold-in-findChessboardCorners Speed up adaptive threshold in findChessboardCorners #25177 ### Pull Request Readiness Checklist If `block_size` hasn't been changed between iterations for same `k`, then all `adaptiveThreshold` arguments will be same and we can reuse result from previous iteration. I tested this PR with benchmark ``` python3 objdetect_benchmark.py --configuration=generate_run --board_x=7 --path=res_chessboard --synthetic_object=chessboard ``` PR speed up chessboards detection by `7.5/17%` without any changes in detected chessboards number: ``` cell_img_size = 100 (default) before category detected chessboard total detected chessboard total chessboard average detected error chessboard all 0.904167 13020 14400 0.600512 Total detected time: 107.27875600000003 sec after category detected chessboard total detected chessboard total chessboard average detected error chessboard all 0.904167 13020 14400 0.600512 Total detected time: 99.0223499999999 sec ---------------------------------------------------------------------------------------------------------------------------------------------- cell_img_size = 10 before category detected chessboard total detected chessboard total chessboard average detected error chessboard all 0.539792 7773 14400 4.209964 Total detected time: 2.989205999999999 sec after category detected chessboard total detected chessboard total chessboard average detected error chessboard all 0.539792 7773 14400 4.209964 Total detected time: 2.4802350000000013 sec ``` See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/calib3d/src/calibinit.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/modules/calib3d/src/calibinit.cpp b/modules/calib3d/src/calibinit.cpp index 7e9b87ba5d..37c982a4f9 100644 --- a/modules/calib3d/src/calibinit.cpp +++ b/modules/calib3d/src/calibinit.cpp @@ -583,8 +583,10 @@ bool findChessboardCorners(InputArray image_, Size pattern_size, } //if flag CALIB_CB_ADAPTIVE_THRESH is not set it doesn't make sense to iterate over k int max_k = useAdaptive ? 6 : 1; + Mat prev_thresh_img; for (int k = 0; k < max_k && !found; k++) { + int prev_block_size = -1; for (int dilations = min_dilations; dilations <= max_dilations; dilations++) { // convert the input grayscale image to binary (black-n-white) @@ -595,9 +597,18 @@ bool findChessboardCorners(InputArray image_, Size pattern_size, : prev_sqr_size * 2); block_size = block_size | 1; // convert to binary - adaptiveThreshold( img, thresh_img, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, block_size, (k/2)*5 ); - dilate( thresh_img, thresh_img, Mat(), Point(-1, -1), dilations ); - + if (block_size != prev_block_size) + { + adaptiveThreshold( img, thresh_img, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, block_size, (k/2)*5 ); + dilate( thresh_img, thresh_img, Mat(), Point(-1, -1), dilations ); + thresh_img.copyTo(prev_thresh_img); + } + else if (dilations > 0) + { + dilate( prev_thresh_img, prev_thresh_img, Mat(), Point(-1, -1), 1 ); + prev_thresh_img.copyTo(thresh_img); + } + prev_block_size = block_size; } else { From fd576d9e8efbea8bae7e3a81108cb3cdef54d5b6 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Thu, 28 Mar 2024 12:02:58 +0300 Subject: [PATCH 43/56] Added PNG instance of image for fisheye::undistort test as JPG is decoded differently with different libjpeg versions. --- modules/calib3d/test/test_fisheye.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/calib3d/test/test_fisheye.cpp b/modules/calib3d/test/test_fisheye.cpp index 2479dac8a8..36b7d0d653 100644 --- a/modules/calib3d/test/test_fisheye.cpp +++ b/modules/calib3d/test/test_fisheye.cpp @@ -185,7 +185,7 @@ TEST_F(fisheyeTest, undistortImage) cv::Matx33d theK = this->K; cv::Mat theD = cv::Mat(this->D); - std::string file = combine(datasets_repository_path, "/calib-3_stereo_from_JY/left/stereo_pair_014.jpg"); + std::string file = combine(datasets_repository_path, "stereo_pair_014.png"); cv::Matx33d newK = theK; cv::Mat distorted = cv::imread(file), undistorted; { From 7f1140b48b45060f4bc6e63458f2b025782d7036 Mon Sep 17 00:00:00 2001 From: John Slade Date: Thu, 28 Mar 2024 11:35:52 +0000 Subject: [PATCH 44/56] core: Add cgroupsv2 support to parallel.cpp The parallel code works out how many CPUs are on the system by checking the quota it has been assigned in the Linux cgroup. The existing code works under cgroups v1 but the file structure changed in cgroups v2. From [1]: "cpu.cfs_quota_us" and "cpu.cfs_period_us" are replaced by "cpu.max" which contains both quota and period. This commit add support to parallel so it will read from the cgroups v2 location. v1 support is still retained. Resolves #25284 [1] https://github.com/torvalds/linux/commit/0d5936344f30aba0f6ddb92b030cb6a05168efe6 --- modules/core/src/parallel.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/modules/core/src/parallel.cpp b/modules/core/src/parallel.cpp index 84e94da877..d81577cfed 100644 --- a/modules/core/src/parallel.cpp +++ b/modules/core/src/parallel.cpp @@ -870,7 +870,22 @@ int getNumberOfCPUsImpl(const char *filename) #if defined CV_HAVE_CGROUPS static inline -unsigned getNumberOfCPUsCFS() +unsigned getNumberOfCPUsCFSv2() +{ + int cfs_quota = 0; + int cfs_period = 0; + + std::ifstream ss_cpu_max("/sys/fs/cgroup/cpu.max", std::ios::in | std::ios::binary); + ss_cpu_max >> cfs_quota >> cfs_period; + + if (ss_cpu_max.fail() || cfs_quota < 1 || cfs_period < 1) /* values must not be 0 or negative */ + return 0; + + return (unsigned)max(1, cfs_quota/cfs_period); +} + +static inline +unsigned getNumberOfCPUsCFSv1() { int cfs_quota = 0; { @@ -966,8 +981,11 @@ int getNumberOfCPUs_() static unsigned ncpus_impl_cpuset = (unsigned)getNumberOfCPUsImpl("/sys/fs/cgroup/cpuset/cpuset.cpus"); ncpus = minNonZero(ncpus, ncpus_impl_cpuset); - static unsigned ncpus_impl_cfs = getNumberOfCPUsCFS(); - ncpus = minNonZero(ncpus, ncpus_impl_cfs); + static unsigned ncpus_impl_cfs_v1 = getNumberOfCPUsCFSv1(); + ncpus = minNonZero(ncpus, ncpus_impl_cfs_v1); + + static unsigned ncpus_impl_cfs_v2 = getNumberOfCPUsCFSv2(); + ncpus = minNonZero(ncpus, ncpus_impl_cfs_v2); #endif static unsigned ncpus_impl_devices = (unsigned)getNumberOfCPUsImpl("/sys/devices/system/cpu/online"); From f87e1efd2acc1d36791e0530a006e77dbd5c3a9e Mon Sep 17 00:00:00 2001 From: Michael Klatis Date: Thu, 28 Mar 2024 07:03:05 -0700 Subject: [PATCH 45/56] Merge pull request #25092 from klatism:libjpeg-upgrade libjpeg upgrade to version 9f #25092 Upgrade libjpeg dependency from version 9d to 9f. - [X] I agree to contribute to the project under Apache 2 License. - [X] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [X] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- 3rdparty/libjpeg/jcarith.c | 12 +- 3rdparty/libjpeg/jccoefct.c | 146 ++++++------- 3rdparty/libjpeg/jccolor.c | 35 ++-- 3rdparty/libjpeg/jcdctmgr.c | 29 +-- 3rdparty/libjpeg/jchuff.c | 296 ++++++++++++++------------- 3rdparty/libjpeg/jcmaster.c | 28 ++- 3rdparty/libjpeg/jconfig.h | 20 +- 3rdparty/libjpeg/jcparam.c | 21 +- 3rdparty/libjpeg/jcprepct.c | 22 +- 3rdparty/libjpeg/jcsample.c | 10 +- 3rdparty/libjpeg/jctrans.c | 56 +++-- 3rdparty/libjpeg/jdapimin.c | 35 +++- 3rdparty/libjpeg/jdarith.c | 12 +- 3rdparty/libjpeg/jdatadst.c | 16 +- 3rdparty/libjpeg/jdatasrc.c | 23 +-- 3rdparty/libjpeg/jdcoefct.c | 111 +++++----- 3rdparty/libjpeg/jdcolor.c | 180 ++++++++++------ 3rdparty/libjpeg/jdct.h | 4 +- 3rdparty/libjpeg/jdhuff.c | 14 +- 3rdparty/libjpeg/jdinput.c | 39 ++-- 3rdparty/libjpeg/jdmainct.c | 48 +++-- 3rdparty/libjpeg/jdmaster.c | 29 +-- 3rdparty/libjpeg/jdmerge.c | 33 ++- 3rdparty/libjpeg/jdsample.c | 75 +++---- 3rdparty/libjpeg/jinclude.h | 66 +++++- 3rdparty/libjpeg/jmorecfg.h | 31 ++- 3rdparty/libjpeg/jpegint.h | 13 +- 3rdparty/libjpeg/jpeglib.h | 4 +- 3rdparty/libjpeg/jquant1.c | 32 ++- 3rdparty/libjpeg/jquant2.c | 18 +- 3rdparty/libjpeg/jutils.c | 99 +++++---- 3rdparty/libjpeg/jversion.h | 6 +- modules/video/test/test_trackers.cpp | 4 +- 33 files changed, 839 insertions(+), 728 deletions(-) diff --git a/3rdparty/libjpeg/jcarith.c b/3rdparty/libjpeg/jcarith.c index 46ce6c6a39..1b45089a3a 100644 --- a/3rdparty/libjpeg/jcarith.c +++ b/3rdparty/libjpeg/jcarith.c @@ -1,7 +1,7 @@ /* * jcarith.c * - * Developed 1997-2019 by Guido Vollbeding. + * Developed 1997-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -361,7 +361,7 @@ emit_restart (j_compress_ptr cinfo, int restart_num) */ METHODDEF(boolean) -encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; unsigned char *st; @@ -450,7 +450,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; const int * natural_order; @@ -557,7 +557,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; unsigned char *st; @@ -592,7 +592,7 @@ encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; const int * natural_order; @@ -691,7 +691,7 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -encode_mcu (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; const int * natural_order; diff --git a/3rdparty/libjpeg/jccoefct.c b/3rdparty/libjpeg/jccoefct.c index 924a703dda..494aa22988 100644 --- a/3rdparty/libjpeg/jccoefct.c +++ b/3rdparty/libjpeg/jccoefct.c @@ -2,7 +2,7 @@ * jccoefct.c * * Copyright (C) 1994-1997, Thomas G. Lane. - * Modified 2003-2011 by Guido Vollbeding. + * Modified 2003-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -36,16 +36,14 @@ typedef struct { struct jpeg_c_coef_controller pub; /* public fields */ JDIMENSION iMCU_row_num; /* iMCU row # within image */ - JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ int MCU_vert_offset; /* counts MCU rows within iMCU row */ int MCU_rows_per_iMCU_row; /* number of such rows needed */ /* For single-pass compression, it's sufficient to buffer just one MCU - * (although this may prove a bit slow in practice). We allocate a - * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each - * MCU constructed and sent. (On 80x86, the workspace is FAR even though - * it's not really very big; this is to keep the module interfaces unchanged - * when a large coefficient buffer is necessary.) + * (although this may prove a bit slow in practice). + * We append a workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, + * and reuse it for each MCU constructed and sent. * In multi-pass modes, this array points to the current MCU's blocks * within the virtual arrays. */ @@ -53,6 +51,9 @@ typedef struct { /* In multi-pass modes, we need a virtual block array for each component. */ jvirt_barray_ptr whole_image[MAX_COMPONENTS]; + + /* Workspace for single-pass compression (omitted otherwise). */ + JBLOCK blk_buffer[C_MAX_BLOCKS_IN_MCU]; } my_coef_controller; typedef my_coef_controller * my_coef_ptr; @@ -88,7 +89,7 @@ start_iMCU_row (j_compress_ptr cinfo) coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; } - coef->mcu_ctr = 0; + coef->MCU_ctr = 0; coef->MCU_vert_offset = 0; } @@ -125,7 +126,6 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) #endif default: ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - break; } } @@ -147,59 +147,56 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - int blkn, bi, ci, yindex, yoffset, blockcnt; - JDIMENSION ypos, xpos; + int ci, xindex, yindex, yoffset, blockcnt; + JBLOCKROW blkp; + JSAMPARRAY input_ptr; + JDIMENSION xpos; jpeg_component_info *compptr; forward_DCT_ptr forward_DCT; /* Loop to write as much as one whole iMCU row */ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; yoffset++) { - for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col; + for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; MCU_col_num++) { /* Determine where data comes from in input_buf and do the DCT thing. - * Each call on forward_DCT processes a horizontal row of DCT blocks - * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks - * sequentially. Dummy blocks at the right or bottom edge are filled in + * Each call on forward_DCT processes a horizontal row of DCT blocks as + * wide as an MCU. Dummy blocks at the right or bottom edge are filled in * specially. The data in them does not matter for image reconstruction, * so we fill them with values that will encode to the smallest amount of * data, viz: all zeroes in the AC entries, DC entries equal to previous * block's DC value. (Thanks to Thomas Kinsman for this idea.) */ - blkn = 0; + blkp = coef->blk_buffer; /* pointer to current DCT block within MCU */ for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; forward_DCT = cinfo->fdct->forward_DCT[compptr->component_index]; + input_ptr = input_buf[compptr->component_index] + + yoffset * compptr->DCT_v_scaled_size; + /* ypos == (yoffset + yindex) * compptr->DCT_v_scaled_size */ blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width : compptr->last_col_width; xpos = MCU_col_num * compptr->MCU_sample_width; - ypos = yoffset * compptr->DCT_v_scaled_size; - /* ypos == (yoffset+yindex) * DCTSIZE */ for (yindex = 0; yindex < compptr->MCU_height; yindex++) { if (coef->iMCU_row_num < last_iMCU_row || - yoffset+yindex < compptr->last_row_height) { - (*forward_DCT) (cinfo, compptr, - input_buf[compptr->component_index], - coef->MCU_buffer[blkn], - ypos, xpos, (JDIMENSION) blockcnt); - if (blockcnt < compptr->MCU_width) { - /* Create some dummy blocks at the right edge of the image. */ - FMEMZERO((void FAR *) coef->MCU_buffer[blkn + blockcnt], - (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK)); - for (bi = blockcnt; bi < compptr->MCU_width; bi++) { - coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0]; - } - } + yoffset + yindex < compptr->last_row_height) { + (*forward_DCT) (cinfo, compptr, input_ptr, blkp, + xpos, (JDIMENSION) blockcnt); + input_ptr += compptr->DCT_v_scaled_size; + blkp += blockcnt; + /* Dummy blocks at right edge */ + if ((xindex = compptr->MCU_width - blockcnt) == 0) + continue; } else { - /* Create a row of dummy blocks at the bottom of the image. */ - FMEMZERO((void FAR *) coef->MCU_buffer[blkn], - compptr->MCU_width * SIZEOF(JBLOCK)); - for (bi = 0; bi < compptr->MCU_width; bi++) { - coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0]; - } + /* At bottom of image, need a whole row of dummy blocks */ + xindex = compptr->MCU_width; } - blkn += compptr->MCU_width; - ypos += compptr->DCT_v_scaled_size; + /* Fill in any dummy blocks needed in this row */ + MEMZERO(blkp, xindex * SIZEOF(JBLOCK)); + do { + blkp[0][0] = blkp[-1][0]; + blkp++; + } while (--xindex); } } /* Try to write the MCU. In event of a suspension failure, we will @@ -208,12 +205,12 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; - coef->mcu_ctr = MCU_col_num; + coef->MCU_ctr = MCU_col_num; return FALSE; } } /* Completed an MCU row, but perhaps not an iMCU row */ - coef->mcu_ctr = 0; + coef->MCU_ctr = 0; } /* Completed the iMCU row, advance counters for next one */ coef->iMCU_row_num++; @@ -256,6 +253,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) jpeg_component_info *compptr; JBLOCKARRAY buffer; JBLOCKROW thisblockrow, lastblockrow; + JSAMPARRAY input_ptr; forward_DCT_ptr forward_DCT; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; @@ -280,14 +278,15 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) if (ndummy > 0) ndummy = h_samp_factor - ndummy; forward_DCT = cinfo->fdct->forward_DCT[ci]; + input_ptr = input_buf[ci]; /* Perform DCT for all non-dummy blocks in this iMCU row. Each call * on forward_DCT processes a complete horizontal row of DCT blocks. */ for (block_row = 0; block_row < block_rows; block_row++) { thisblockrow = buffer[block_row]; - (*forward_DCT) (cinfo, compptr, input_buf[ci], thisblockrow, - (JDIMENSION) (block_row * compptr->DCT_v_scaled_size), + (*forward_DCT) (cinfo, compptr, input_ptr, thisblockrow, (JDIMENSION) 0, blocks_across); + input_ptr += compptr->DCT_v_scaled_size; if (ndummy > 0) { /* Create dummy blocks at the right edge of the image. */ thisblockrow += blocks_across; /* => first dummy block */ @@ -303,15 +302,14 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) * of the dummy blocks to match the last real block's DC value. * This squeezes a few more bytes out of the resulting file... */ - if (coef->iMCU_row_num == last_iMCU_row) { + if (block_row < compptr->v_samp_factor) { blocks_across += ndummy; /* include lower right corner */ MCUs_across = blocks_across / h_samp_factor; - for (block_row = block_rows; block_row < compptr->v_samp_factor; - block_row++) { + do { thisblockrow = buffer[block_row]; lastblockrow = buffer[block_row-1]; FMEMZERO((void FAR *) thisblockrow, - (size_t) (blocks_across * SIZEOF(JBLOCK))); + (size_t) blocks_across * SIZEOF(JBLOCK)); for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) { lastDC = lastblockrow[h_samp_factor-1][0]; for (bi = 0; bi < h_samp_factor; bi++) { @@ -320,7 +318,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) thisblockrow += h_samp_factor; /* advance to next MCU in row */ lastblockrow += h_samp_factor; } - } + } while (++block_row < compptr->v_samp_factor); } } /* NB: compress_output will increment iMCU_row_num if successful. @@ -347,8 +345,9 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; JDIMENSION MCU_col_num; /* index of current MCU within row */ - int blkn, ci, xindex, yindex, yoffset; + int ci, xindex, yindex, yoffset; JDIMENSION start_col; + JBLOCKARRAY blkp; JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; JBLOCKROW buffer_ptr; jpeg_component_info *compptr; @@ -368,30 +367,31 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) /* Loop to process one whole iMCU row */ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; yoffset++) { - for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row; MCU_col_num++) { /* Construct list of pointers to DCT blocks belonging to this MCU */ - blkn = 0; /* index of current DCT block within MCU */ + blkp = coef->MCU_buffer; /* pointer to current DCT block within MCU */ for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; start_col = MCU_col_num * compptr->MCU_width; for (yindex = 0; yindex < compptr->MCU_height; yindex++) { - buffer_ptr = buffer[ci][yindex+yoffset] + start_col; - for (xindex = 0; xindex < compptr->MCU_width; xindex++) { - coef->MCU_buffer[blkn++] = buffer_ptr++; - } + buffer_ptr = buffer[ci][yoffset + yindex] + start_col; + xindex = compptr->MCU_width; + do { + *blkp++ = buffer_ptr++; + } while (--xindex); } } /* Try to write the MCU. */ if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; - coef->mcu_ctr = MCU_col_num; + coef->MCU_ctr = MCU_col_num; return FALSE; } } /* Completed an MCU row, but perhaps not an iMCU row */ - coef->mcu_ctr = 0; + coef->MCU_ctr = 0; } /* Completed the iMCU row, advance counters for next one */ coef->iMCU_row_num++; @@ -411,13 +411,6 @@ jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) { my_coef_ptr coef; - coef = (my_coef_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); - cinfo->coef = (struct jpeg_c_coef_controller *) coef; - coef->pub.start_pass = start_pass_coef; - - /* Create the coefficient buffer. */ if (need_full_buffer) { #ifdef FULL_COEF_BUFFER_SUPPORTED /* Allocate a full-image virtual array for each component, */ @@ -425,6 +418,9 @@ jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) int ci; jpeg_component_info *compptr; + coef = (my_coef_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller) - SIZEOF(coef->blk_buffer)); for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) @@ -440,15 +436,21 @@ jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) #endif } else { /* We only need a single-MCU buffer. */ - JBLOCKROW buffer; - int i; + JBLOCKARRAY blkp; + JBLOCKROW buffer_ptr; + int bi; - buffer = (JBLOCKROW) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { - coef->MCU_buffer[i] = buffer + i; - } + coef = (my_coef_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_coef_controller)); + blkp = coef->MCU_buffer; + buffer_ptr = coef->blk_buffer; + bi = C_MAX_BLOCKS_IN_MCU; + do { + *blkp++ = buffer_ptr++; + } while (--bi); coef->whole_image[0] = NULL; /* flag for no virtual arrays */ } + + coef->pub.start_pass = start_pass_coef; + cinfo->coef = &coef->pub; } diff --git a/3rdparty/libjpeg/jccolor.c b/3rdparty/libjpeg/jccolor.c index db2ca429e8..c028dd9db3 100644 --- a/3rdparty/libjpeg/jccolor.c +++ b/3rdparty/libjpeg/jccolor.c @@ -2,7 +2,7 @@ * jccolor.c * * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2011-2019 by Guido Vollbeding. + * Modified 2011-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -40,10 +40,10 @@ typedef my_color_converter * my_cconvert_ptr; * Note that the derived conversion coefficients given in some of these * documents are imprecise. The general conversion equations are * Y = Kr * R + (1 - Kr - Kb) * G + Kb * B - * Cb = 0.5 * (B - Y) / (1 - Kb) - * Cr = 0.5 * (R - Y) / (1 - Kr) + * Cb = (B - Y) / (1 - Kb) / K + * Cr = (R - Y) / (1 - Kr) / K * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993 - * from the 1953 FCC NTSC primaries and CIE Illuminant C), + * from the 1953 FCC NTSC primaries and CIE Illuminant C), K = 2 for sYCC, * the conversion equations to be implemented are therefore * Y = 0.299 * R + 0.587 * G + 0.114 * B * Cb = -0.168735892 * R - 0.331264108 * G + 0.5 * B + CENTERJSAMPLE @@ -62,8 +62,8 @@ typedef my_color_converter * my_cconvert_ptr; * by precalculating the constants times R,G,B for all possible values. * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); * for 9-bit to 12-bit samples it is still acceptable. It's not very - * reasonable for 16-bit samples, but if you want lossless storage you - * shouldn't be changing colorspace anyway. + * reasonable for 16-bit samples, but if you want lossless storage + * you shouldn't be changing colorspace anyway. * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included * in the tables to save adding them separately in the inner loop. */ @@ -110,16 +110,16 @@ rgb_ycc_start (j_compress_ptr cinfo) for (i = 0; i <= MAXJSAMPLE; i++) { rgb_ycc_tab[i+R_Y_OFF] = FIX(0.299) * i; rgb_ycc_tab[i+G_Y_OFF] = FIX(0.587) * i; - rgb_ycc_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; + rgb_ycc_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; rgb_ycc_tab[i+R_CB_OFF] = (- FIX(0.168735892)) * i; rgb_ycc_tab[i+G_CB_OFF] = (- FIX(0.331264108)) * i; /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. * This ensures that the maximum output will round to MAXJSAMPLE * not MAXJSAMPLE+1, and thus that we don't have to range-limit. */ - rgb_ycc_tab[i+B_CB_OFF] = FIX(0.5) * i + CBCR_OFFSET + ONE_HALF-1; + rgb_ycc_tab[i+B_CB_OFF] = (i << (SCALEBITS-1)) + CBCR_OFFSET + ONE_HALF-1; /* B=>Cb and R=>Cr tables are the same - rgb_ycc_tab[i+R_CR_OFF] = FIX(0.5) * i + CBCR_OFFSET + ONE_HALF-1; + rgb_ycc_tab[i+R_CR_OFF] = (i << (SCALEBITS-1)) + CBCR_OFFSET + ONE_HALF-1; */ rgb_ycc_tab[i+G_CR_OFF] = (- FIX(0.418687589)) * i; rgb_ycc_tab[i+B_CR_OFF] = (- FIX(0.081312411)) * i; @@ -190,8 +190,8 @@ rgb_ycc_convert (j_compress_ptr cinfo, /* * Convert some rows of samples to the JPEG colorspace. - * This version handles RGB->grayscale conversion, which is the same - * as the RGB->Y portion of RGB->YCbCr. + * This version handles RGB->grayscale conversion, + * which is the same as the RGB->Y portion of RGB->YCbCr. * We assume rgb_ycc_start has been called (we only use the Y tables). */ @@ -201,7 +201,7 @@ rgb_gray_convert (j_compress_ptr cinfo, JDIMENSION output_row, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; + register INT32 y; register INT32 * ctab = cconvert->rgb_ycc_tab; register JSAMPROW inptr; register JSAMPROW outptr; @@ -212,14 +212,11 @@ rgb_gray_convert (j_compress_ptr cinfo, inptr = *input_buf++; outptr = output_buf[0][output_row++]; for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr[RGB_RED]); - g = GETJSAMPLE(inptr[RGB_GREEN]); - b = GETJSAMPLE(inptr[RGB_BLUE]); + y = ctab[R_Y_OFF + GETJSAMPLE(inptr[RGB_RED])]; + y += ctab[G_Y_OFF + GETJSAMPLE(inptr[RGB_GREEN])]; + y += ctab[B_Y_OFF + GETJSAMPLE(inptr[RGB_BLUE])]; inptr += RGB_PIXELSIZE; - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + outptr[col] = (JSAMPLE) (y >> SCALEBITS); } } } diff --git a/3rdparty/libjpeg/jcdctmgr.c b/3rdparty/libjpeg/jcdctmgr.c index fafab91c69..a48ccd8147 100644 --- a/3rdparty/libjpeg/jcdctmgr.c +++ b/3rdparty/libjpeg/jcdctmgr.c @@ -2,7 +2,7 @@ * jcdctmgr.c * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2003-2013 by Guido Vollbeding. + * Modified 2003-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -66,15 +66,14 @@ typedef union { * Perform forward DCT on one or more blocks of a component. * * The input samples are taken from the sample_data[] array starting at - * position start_row/start_col, and moving to the right for any additional - * blocks. The quantized coefficients are returned in coef_blocks[]. + * position start_col, and moving to the right for any additional blocks. + * The quantized coefficients are returned in coef_blocks[]. */ METHODDEF(void) forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks) + JDIMENSION start_col, JDIMENSION num_blocks) /* This version is used for integer DCT implementations. */ { /* This routine is heavily used, so it's worth coding it tightly. */ @@ -84,8 +83,6 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ JDIMENSION bi; - sample_data += start_row; /* fold in the vertical offset once */ - for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) { /* Perform the DCT */ (*do_dct) (workspace, sample_data, start_col); @@ -136,8 +133,7 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, METHODDEF(void) forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks) + JDIMENSION start_col, JDIMENSION num_blocks) /* This version is used for floating-point DCT implementations. */ { /* This routine is heavily used, so it's worth coding it tightly. */ @@ -147,8 +143,6 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */ JDIMENSION bi; - sample_data += start_row; /* fold in the vertical offset once */ - for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) { /* Perform the DCT */ (*do_dct) (workspace, sample_data, start_col); @@ -347,13 +341,11 @@ start_pass_fdctmgr (j_compress_ptr cinfo) #endif default: ERREXIT(cinfo, JERR_NOT_COMPILED); - break; } break; default: ERREXIT2(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_h_scaled_size, compptr->DCT_v_scaled_size); - break; } qtblno = compptr->quant_tbl_no; /* Make sure specified quantization table is present */ @@ -444,7 +436,6 @@ start_pass_fdctmgr (j_compress_ptr cinfo) #endif default: ERREXIT(cinfo, JERR_NOT_COMPILED); - break; } } } @@ -461,17 +452,15 @@ jinit_forward_dct (j_compress_ptr cinfo) int ci; jpeg_component_info *compptr; - fdct = (my_fdct_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_fdct_controller)); + fdct = (my_fdct_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_fdct_controller)); cinfo->fdct = &fdct->pub; fdct->pub.start_pass = start_pass_fdctmgr; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { /* Allocate a divisor table for each component */ - compptr->dct_table = - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(divisor_table)); + compptr->dct_table = (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(divisor_table)); } } diff --git a/3rdparty/libjpeg/jchuff.c b/3rdparty/libjpeg/jchuff.c index 02fc275b7a..1f527b2182 100644 --- a/3rdparty/libjpeg/jchuff.c +++ b/3rdparty/libjpeg/jchuff.c @@ -2,7 +2,7 @@ * jchuff.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2006-2019 by Guido Vollbeding. + * Modified 2006-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -26,17 +26,11 @@ /* The legal range of a DCT coefficient is - * -1024 .. +1023 for 8-bit data; - * -16384 .. +16383 for 12-bit data. - * Hence the magnitude should always fit in 10 or 14 bits respectively. + * -1024 .. +1023 for 8-bit sample data precision; + * -16384 .. +16383 for 12-bit sample data precision. + * Hence the magnitude should always fit in sample data precision + 2 bits. */ -#if BITS_IN_JSAMPLE == 8 -#define MAX_COEF_BITS 10 -#else -#define MAX_COEF_BITS 14 -#endif - /* Derived data constructed for each Huffman table */ typedef struct { @@ -542,11 +536,12 @@ emit_restart_e (huff_entropy_ptr entropy, int restart_num) */ METHODDEF(boolean) -encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; register int temp, temp2; register int nbits; + int max_coef_bits; int blkn, ci, tbl; ISHIFT_TEMPS @@ -558,6 +553,9 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) if (entropy->restarts_to_go == 0) emit_restart_e(entropy, entropy->next_restart_num); + /* Since we're encoding a difference, the range limit is twice as much. */ + max_coef_bits = cinfo->data_precision + 3; + /* Encode the MCU data blocks */ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { ci = cinfo->MCU_membership[blkn]; @@ -569,12 +567,17 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) temp = IRIGHT_SHIFT((int) (MCU_data[blkn][0][0]), cinfo->Al); /* DC differences are figured on the point-transformed values. */ - temp2 = temp - entropy->saved.last_dc_val[ci]; + if ((temp2 = temp - entropy->saved.last_dc_val[ci]) == 0) { + /* Count/emit the Huffman-coded symbol for the number of bits */ + emit_dc_symbol(entropy, tbl, 0); + + continue; + } + entropy->saved.last_dc_val[ci] = temp; /* Encode the DC coefficient difference per section G.1.2.1 */ - temp = temp2; - if (temp < 0) { + if ((temp = temp2) < 0) { temp = -temp; /* temp is abs value of input */ /* For a negative input, want temp2 = bitwise complement of abs(input) */ /* This code assumes we are on a two's complement machine */ @@ -583,14 +586,10 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) /* Find the number of bits needed for the magnitude of the coefficient */ nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values */ + if (nbits > max_coef_bits) ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count/emit the Huffman-coded symbol for the number of bits */ @@ -598,8 +597,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ - emit_bits_e(entropy, (unsigned int) temp2, nbits); + emit_bits_e(entropy, (unsigned int) temp2, nbits); } cinfo->dest->next_output_byte = entropy->next_output_byte; @@ -625,7 +623,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; const int * natural_order; @@ -633,7 +631,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) register int temp, temp2; register int nbits; register int r, k; - int Se, Al; + int Se, Al, max_coef_bits; entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; @@ -646,6 +644,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) Se = cinfo->Se; Al = cinfo->Al; natural_order = cinfo->natural_order; + max_coef_bits = cinfo->data_precision + 2; /* Encode the MCU data block */ block = MCU_data[0]; @@ -666,18 +665,23 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) */ if (temp < 0) { temp = -temp; /* temp is abs value of input */ - temp >>= Al; /* apply the point transform */ + /* Apply the point transform, and watch out for case */ + /* that nonzero coef is zero after point transform. */ + if ((temp >>= Al) == 0) { + r++; + continue; + } /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ temp2 = ~temp; } else { - temp >>= Al; /* apply the point transform */ + /* Apply the point transform, and watch out for case */ + /* that nonzero coef is zero after point transform. */ + if ((temp >>= Al) == 0) { + r++; + continue; + } temp2 = temp; } - /* Watch out for case that nonzero coef is zero after point transform */ - if (temp == 0) { - r++; - continue; - } /* Emit any pending EOBRUN */ if (entropy->EOBRUN > 0) @@ -689,11 +693,11 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) } /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) + if (nbits > max_coef_bits) ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count/emit Huffman symbol for run length / number of bits */ @@ -736,7 +740,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; int Al, blkn; @@ -779,7 +783,7 @@ encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; const int * natural_order; @@ -916,83 +920,89 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, register int nbits; register int r, k; int Se = state->cinfo->lim_Se; + int max_coef_bits = state->cinfo->data_precision + 3; const int * natural_order = state->cinfo->natural_order; /* Encode the DC coefficient difference per section F.1.2.1 */ - temp = temp2 = block[0] - last_dc_val; + if ((temp = block[0] - last_dc_val) == 0) { + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits_s(state, dctbl->ehufco[0], dctbl->ehufsi[0])) + return FALSE; + } else { + if ((temp2 = temp) < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* For a negative input, want temp2 = bitwise complement of abs(input) */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > max_coef_bits) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) - ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits_s(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) + return FALSE; - /* Emit the Huffman-coded symbol for the number of bits */ - if (! emit_bits_s(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ if (! emit_bits_s(state, (unsigned int) temp2, nbits)) return FALSE; + } /* Encode the AC coefficients per section F.1.2.2 */ r = 0; /* r = run length of zeros */ for (k = 1; k <= Se; k++) { - if ((temp2 = block[natural_order[k]]) == 0) { + if ((temp = block[natural_order[k]]) == 0) { r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - if (! emit_bits_s(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) - return FALSE; - r -= 16; - } - - temp = temp2; - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) - ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); - - /* Emit Huffman symbol for run length / number of bits */ - temp = (r << 4) + nbits; - if (! emit_bits_s(state, actbl->ehufco[temp], actbl->ehufsi[temp])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (! emit_bits_s(state, (unsigned int) temp2, nbits)) - return FALSE; - - r = 0; + continue; } + + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + if (! emit_bits_s(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) + return FALSE; + r -= 16; + } + + if ((temp2 = temp) < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Use ">=" instead of ">" so can use the + * same one larger limit from DC check here. + */ + if (nbits >= max_coef_bits) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit Huffman symbol for run length / number of bits */ + temp = (r << 4) + nbits; + if (! emit_bits_s(state, actbl->ehufco[temp], actbl->ehufsi[temp])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (! emit_bits_s(state, (unsigned int) temp2, nbits)) + return FALSE; + + r = 0; /* reset zero run length */ } /* If the last coef(s) were zero, emit an end-of-block code */ @@ -1009,7 +1019,7 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, */ METHODDEF(boolean) -encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_huff (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; working_state state; @@ -1122,28 +1132,31 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, register int nbits; register int r, k; int Se = cinfo->lim_Se; + int max_coef_bits = cinfo->data_precision + 3; const int * natural_order = cinfo->natural_order; /* Encode the DC coefficient difference per section F.1.2.1 */ - temp = block[0] - last_dc_val; - if (temp < 0) - temp = -temp; + if ((temp = block[0] - last_dc_val) == 0) { + /* Count the Huffman symbol for the number of bits */ + dc_counts[0]++; + } else { + if (temp < 0) + temp = -temp; /* temp is abs value of input */ - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > max_coef_bits) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count the Huffman symbol for the number of bits */ + dc_counts[nbits]++; } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) - ERREXIT(cinfo, JERR_BAD_DCT_COEF); - - /* Count the Huffman symbol for the number of bits */ - dc_counts[nbits]++; /* Encode the AC coefficients per section F.1.2.2 */ @@ -1152,30 +1165,33 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, for (k = 1; k <= Se; k++) { if ((temp = block[natural_order[k]]) == 0) { r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - ac_counts[0xF0]++; - r -= 16; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - if (temp < 0) - temp = -temp; - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) - ERREXIT(cinfo, JERR_BAD_DCT_COEF); - - /* Count Huffman symbol for run length / number of bits */ - ac_counts[(r << 4) + nbits]++; - - r = 0; + continue; } + + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + ac_counts[0xF0]++; + r -= 16; + } + + if (temp < 0) + temp = -temp; /* temp is abs value of input */ + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Use ">=" instead of ">" so can use the + * same one larger limit from DC check here. + */ + if (nbits >= max_coef_bits) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count Huffman symbol for run length / number of bits */ + ac_counts[(r << 4) + nbits]++; + + r = 0; /* reset zero run length */ } /* If the last coef(s) were zero, emit an end-of-block code */ @@ -1190,7 +1206,7 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, */ METHODDEF(boolean) -encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +encode_mcu_gather (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; int blkn, ci; diff --git a/3rdparty/libjpeg/jcmaster.c b/3rdparty/libjpeg/jcmaster.c index 89dcf78c2a..a70af0c020 100644 --- a/3rdparty/libjpeg/jcmaster.c +++ b/3rdparty/libjpeg/jcmaster.c @@ -2,7 +2,7 @@ * jcmaster.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2003-2019 by Guido Vollbeding. + * Modified 2003-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -391,16 +391,16 @@ per_scan_setup (j_compress_ptr cinfo) { int ci, mcublks, tmp; jpeg_component_info *compptr; - + if (cinfo->comps_in_scan == 1) { - + /* Noninterleaved (single-component) scan */ compptr = cinfo->cur_comp_info[0]; - + /* Overall image size in MCUs */ cinfo->MCUs_per_row = compptr->width_in_blocks; cinfo->MCU_rows_in_scan = compptr->height_in_blocks; - + /* For noninterleaved scan, always one block per MCU */ compptr->MCU_width = 1; compptr->MCU_height = 1; @@ -413,28 +413,26 @@ per_scan_setup (j_compress_ptr cinfo) tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); if (tmp == 0) tmp = compptr->v_samp_factor; compptr->last_row_height = tmp; - + /* Prepare array describing MCU composition */ cinfo->blocks_in_MCU = 1; cinfo->MCU_membership[0] = 0; - + } else { - + /* Interleaved (multi-component) scan */ if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, MAX_COMPS_IN_SCAN); - + /* Overall image size in MCUs */ cinfo->MCUs_per_row = (JDIMENSION) jdiv_round_up((long) cinfo->jpeg_width, (long) (cinfo->max_h_samp_factor * cinfo->block_size)); - cinfo->MCU_rows_in_scan = (JDIMENSION) - jdiv_round_up((long) cinfo->jpeg_height, - (long) (cinfo->max_v_samp_factor * cinfo->block_size)); - + cinfo->MCU_rows_in_scan = cinfo->total_iMCU_rows; + cinfo->blocks_in_MCU = 0; - + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; /* Sampling factors give # of blocks of component in each MCU */ @@ -457,7 +455,7 @@ per_scan_setup (j_compress_ptr cinfo) cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; } } - + } /* Convert restart specified in rows to actual MCU count. */ diff --git a/3rdparty/libjpeg/jconfig.h b/3rdparty/libjpeg/jconfig.h index e9d33e5870..8d6c8f5b3a 100644 --- a/3rdparty/libjpeg/jconfig.h +++ b/3rdparty/libjpeg/jconfig.h @@ -1,6 +1,8 @@ -/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 9x or NT. */ -/* This file also works for Borland C++ 32-bit (bcc32) on Windows 9x or NT. */ -/* see jconfig.txt for explanations */ +/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 9x or NT. + * This file also works for Borland/Embarcadero C++ for Win32 or Win64 + * (CLI: bcc32, bcc32c, bcc32x, bcc64; GUI IDE: C++Builder/RAD Studio). + * See jconfig.txt for explanations. + */ #define HAVE_PROTOTYPES #define HAVE_UNSIGNED_CHAR @@ -28,6 +30,16 @@ typedef unsigned char boolean; #endif #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +/* Define custom RGB color order, prevent jmorecfg.h from redefinition */ +#undef JPEG_HAVE_RGB_CUSTOM +/* Use Windows custom BGR color order defined in jmorecfg.h */ +#undef JPEG_USE_RGB_CUSTOM + +/* Define custom file I/O functions, prevent jinclude.h from redefinition */ +#undef JPEG_HAVE_FILE_IO_CUSTOM +/* Use Delphi custom file I/O functions defined in jinclude.h */ +#undef JPEG_USE_FILE_IO_CUSTOM + #ifdef JPEG_INTERNALS @@ -44,7 +56,7 @@ typedef unsigned char boolean; #define TARGA_SUPPORTED /* Targa image file format */ #define TWO_FILE_COMMANDLINE /* optional */ -#define USE_SETMODE /* Microsoft has setmode() */ +#define USE_SETMODE /* Microsoft/Borland/Embarcadero have setmode() */ #undef NEED_SIGNAL_CATCHER #undef DONT_USE_B_MODE #undef PROGRESS_REPORT /* optional */ diff --git a/3rdparty/libjpeg/jcparam.c b/3rdparty/libjpeg/jcparam.c index 3b7014ff2c..261ae86ca0 100644 --- a/3rdparty/libjpeg/jcparam.c +++ b/3rdparty/libjpeg/jcparam.c @@ -2,7 +2,7 @@ * jcparam.c * * Copyright (C) 1991-1998, Thomas G. Lane. - * Modified 2003-2019 by Guido Vollbeding. + * Modified 2003-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -62,8 +62,9 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, /* These are the sample quantization tables given in JPEG spec section K.1. - * The spec says that the values given produce "good" quality, and - * when divided by 2, "very good" quality. + * NOTE: chrominance DC value is changed from 17 to 16 for lossless support. + * The spec says that the values given produce "good" quality, + * and when divided by 2, "very good" quality. */ static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { 16, 11, 10, 16, 24, 40, 51, 61, @@ -76,7 +77,7 @@ static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { 72, 92, 95, 98, 112, 100, 103, 99 }; static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { - 17, 18, 24, 47, 99, 99, 99, 99, + 16, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, @@ -379,11 +380,13 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) case JCS_RGB: cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */ cinfo->num_components = 3; - SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, + SET_COMP(0, 0x52 /* 'R' */, 1,1, + cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0, cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0, cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0); SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0); - SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, + SET_COMP(2, 0x42 /* 'B' */, 1,1, + cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0, cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0, cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0); break; @@ -417,11 +420,13 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) cinfo->JFIF_major_version = 2; /* Set JFIF major version = 2 */ cinfo->num_components = 3; /* Add offset 0x20 to the normal R/G/B component IDs */ - SET_COMP(0, 0x72 /* 'r' */, 1,1, 0, + SET_COMP(0, 0x72 /* 'r' */, 1,1, + cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0, cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0, cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0); SET_COMP(1, 0x67 /* 'g' */, 1,1, 0, 0,0); - SET_COMP(2, 0x62 /* 'b' */, 1,1, 0, + SET_COMP(2, 0x62 /* 'b' */, 1,1, + cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0, cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0, cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0); break; diff --git a/3rdparty/libjpeg/jcprepct.c b/3rdparty/libjpeg/jcprepct.c index be44cc4b45..586964bd44 100644 --- a/3rdparty/libjpeg/jcprepct.c +++ b/3rdparty/libjpeg/jcprepct.c @@ -2,6 +2,7 @@ * jcprepct.c * * Copyright (C) 1994-1996, Thomas G. Lane. + * Modified 2003-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -109,7 +110,8 @@ expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, register int row; for (row = input_rows; row < output_rows; row++) { - jcopy_sample_rows(image_data, input_rows-1, image_data, row, + jcopy_sample_rows(image_data + input_rows - 1, + image_data + row, 1, num_cols); } } @@ -220,8 +222,8 @@ pre_process_context (j_compress_ptr cinfo, for (ci = 0; ci < cinfo->num_components; ci++) { int row; for (row = 1; row <= cinfo->max_v_samp_factor; row++) { - jcopy_sample_rows(prep->color_buf[ci], 0, - prep->color_buf[ci], -row, + jcopy_sample_rows(prep->color_buf[ci], + prep->color_buf[ci] - row, 1, cinfo->image_width); } } @@ -277,10 +279,9 @@ create_context_buffer (j_compress_ptr cinfo) /* Grab enough space for fake row pointers for all the components; * we need five row groups' worth of pointers for each component. */ - fake_buffer = (JSAMPARRAY) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (cinfo->num_components * 5 * rgroup_height) * - SIZEOF(JSAMPROW)); + fake_buffer = (JSAMPARRAY) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (cinfo->num_components * 5 * rgroup_height) * SIZEOF(JSAMPROW)); for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { @@ -324,10 +325,9 @@ jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) if (need_full_buffer) /* safety check */ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - prep = (my_prep_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_prep_controller)); - cinfo->prep = (struct jpeg_c_prep_controller *) prep; + prep = (my_prep_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_prep_controller)); + cinfo->prep = &prep->pub; prep->pub.start_pass = start_pass_prep; /* Allocate the color conversion buffer. diff --git a/3rdparty/libjpeg/jcsample.c b/3rdparty/libjpeg/jcsample.c index 4d36f85f35..2372c4173f 100644 --- a/3rdparty/libjpeg/jcsample.c +++ b/3rdparty/libjpeg/jcsample.c @@ -2,6 +2,7 @@ * jcsample.c * * Copyright (C) 1991-1996, Thomas G. Lane. + * Modified 2003-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -200,7 +201,7 @@ fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY output_data) { /* Copy the data */ - jcopy_sample_rows(input_data, 0, output_data, 0, + jcopy_sample_rows(input_data, output_data, cinfo->max_v_samp_factor, cinfo->image_width); /* Edge-expand */ expand_right_edge(output_data, cinfo->max_v_samp_factor, cinfo->image_width, @@ -483,10 +484,9 @@ jinit_downsampler (j_compress_ptr cinfo) boolean smoothok = TRUE; int h_in_group, v_in_group, h_out_group, v_out_group; - downsample = (my_downsample_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_downsampler)); - cinfo->downsample = (struct jpeg_downsampler *) downsample; + downsample = (my_downsample_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_downsampler)); + cinfo->downsample = &downsample->pub; downsample->pub.start_pass = start_pass_downsample; downsample->pub.downsample = sep_downsample; downsample->pub.need_context_rows = FALSE; diff --git a/3rdparty/libjpeg/jctrans.c b/3rdparty/libjpeg/jctrans.c index 5780de42e2..261dd2996e 100644 --- a/3rdparty/libjpeg/jctrans.c +++ b/3rdparty/libjpeg/jctrans.c @@ -2,7 +2,7 @@ * jctrans.c * * Copyright (C) 1995-1998, Thomas G. Lane. - * Modified 2000-2017 by Guido Vollbeding. + * Modified 2000-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -224,7 +224,7 @@ typedef struct { struct jpeg_c_coef_controller pub; /* public fields */ JDIMENSION iMCU_row_num; /* iMCU row # within image */ - JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ int MCU_vert_offset; /* counts MCU rows within iMCU row */ int MCU_rows_per_iMCU_row; /* number of such rows needed */ @@ -232,7 +232,7 @@ typedef struct { jvirt_barray_ptr * whole_image; /* Workspace for constructing dummy blocks at right/bottom edges. */ - JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU]; + JBLOCK dummy_buffer[C_MAX_BLOCKS_IN_MCU]; } my_coef_controller; typedef my_coef_controller * my_coef_ptr; @@ -257,7 +257,7 @@ start_iMCU_row (j_compress_ptr cinfo) coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; } - coef->mcu_ctr = 0; + coef->MCU_ctr = 0; coef->MCU_vert_offset = 0; } @@ -315,25 +315,30 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) /* Loop to process one whole iMCU row */ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; yoffset++) { - for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; MCU_col_num++) { /* Construct list of pointers to DCT blocks belonging to this MCU */ blkn = 0; /* index of current DCT block within MCU */ for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; - start_col = MCU_col_num * compptr->MCU_width; blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width : compptr->last_col_width; + start_col = MCU_col_num * compptr->MCU_width; for (yindex = 0; yindex < compptr->MCU_height; yindex++) { if (coef->iMCU_row_num < last_iMCU_row || - yindex+yoffset < compptr->last_row_height) { + yoffset + yindex < compptr->last_row_height) { /* Fill in pointers to real blocks in this row */ - buffer_ptr = buffer[ci][yindex+yoffset] + start_col; - for (xindex = 0; xindex < blockcnt; xindex++) + buffer_ptr = buffer[ci][yoffset + yindex] + start_col; + xindex = blockcnt; + do { MCU_buffer[blkn++] = buffer_ptr++; + } while (--xindex); + /* Dummy blocks at right edge */ + if ((xindex = compptr->MCU_width - blockcnt) == 0) + continue; } else { /* At bottom of image, need a whole row of dummy blocks */ - xindex = 0; + xindex = compptr->MCU_width; } /* Fill in any dummy blocks needed in this row. * Dummy blocks are filled in the same way as in jccoefct.c: @@ -341,23 +346,23 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) * block's DC value. The init routine has already zeroed the * AC entries, so we need only set the DC entries correctly. */ - for (; xindex < compptr->MCU_width; xindex++) { - MCU_buffer[blkn] = coef->dummy_buffer[blkn]; - MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0]; - blkn++; - } + buffer_ptr = coef->dummy_buffer + blkn; + do { + buffer_ptr[0][0] = MCU_buffer[blkn-1][0][0]; + MCU_buffer[blkn++] = buffer_ptr++; + } while (--xindex); } } /* Try to write the MCU. */ if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; - coef->mcu_ctr = MCU_col_num; + coef->MCU_ctr = MCU_col_num; return FALSE; } } /* Completed an MCU row, but perhaps not an iMCU row */ - coef->mcu_ctr = 0; + coef->MCU_ctr = 0; } /* Completed the iMCU row, advance counters for next one */ coef->iMCU_row_num++; @@ -379,12 +384,9 @@ transencode_coef_controller (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) { my_coef_ptr coef; - JBLOCKROW buffer; - int i; - coef = (my_coef_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); + coef = (my_coef_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_coef_controller)); cinfo->coef = &coef->pub; coef->pub.start_pass = start_pass_coef; coef->pub.compress_data = compress_output; @@ -392,12 +394,6 @@ transencode_coef_controller (j_compress_ptr cinfo, /* Save pointer to virtual arrays */ coef->whole_image = coef_arrays; - /* Allocate and pre-zero space for dummy DCT blocks. */ - buffer = (JBLOCKROW) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - FMEMZERO((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { - coef->dummy_buffer[i] = buffer + i; - } + /* Pre-zero space for dummy DCT blocks */ + MEMZERO(coef->dummy_buffer, SIZEOF(coef->dummy_buffer)); } diff --git a/3rdparty/libjpeg/jdapimin.c b/3rdparty/libjpeg/jdapimin.c index a6e0dd9fb8..785e527226 100644 --- a/3rdparty/libjpeg/jdapimin.c +++ b/3rdparty/libjpeg/jdapimin.c @@ -2,7 +2,7 @@ * jdapimin.c * * Copyright (C) 1994-1998, Thomas G. Lane. - * Modified 2009-2013 by Guido Vollbeding. + * Modified 2009-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -114,7 +114,7 @@ jpeg_abort_decompress (j_decompress_ptr cinfo) LOCAL(void) default_decompress_parms (j_decompress_ptr cinfo) { - int cid0, cid1, cid2; + int cid0, cid1, cid2, cid3; /* Guess the input colorspace, and set output colorspace accordingly. */ /* Note application may override our guesses. */ @@ -123,13 +123,16 @@ default_decompress_parms (j_decompress_ptr cinfo) cinfo->jpeg_color_space = JCS_GRAYSCALE; cinfo->out_color_space = JCS_GRAYSCALE; break; - + case 3: cid0 = cinfo->comp_info[0].component_id; cid1 = cinfo->comp_info[1].component_id; cid2 = cinfo->comp_info[2].component_id; - /* First try to guess from the component IDs */ + /* For robust detection of standard colorspaces + * regardless of the presence of special markers, + * check component IDs from SOF marker first. + */ if (cid0 == 0x01 && cid1 == 0x02 && cid2 == 0x03) cinfo->jpeg_color_space = JCS_YCbCr; else if (cid0 == 0x01 && cid1 == 0x22 && cid2 == 0x23) @@ -151,7 +154,6 @@ default_decompress_parms (j_decompress_ptr cinfo) default: WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ - break; } } else { TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); @@ -160,9 +162,22 @@ default_decompress_parms (j_decompress_ptr cinfo) /* Always guess RGB is proper output colorspace. */ cinfo->out_color_space = JCS_RGB; break; - + case 4: - if (cinfo->saw_Adobe_marker) { + cid0 = cinfo->comp_info[0].component_id; + cid1 = cinfo->comp_info[1].component_id; + cid2 = cinfo->comp_info[2].component_id; + cid3 = cinfo->comp_info[3].component_id; + + /* For robust detection of standard colorspaces + * regardless of the presence of special markers, + * check component IDs from SOF marker first. + */ + if (cid0 == 0x01 && cid1 == 0x02 && cid2 == 0x03 && cid3 == 0x04) + cinfo->jpeg_color_space = JCS_YCCK; + else if (cid0 == 0x43 && cid1 == 0x4D && cid2 == 0x59 && cid3 == 0x4B) + cinfo->jpeg_color_space = JCS_CMYK; /* ASCII 'C', 'M', 'Y', 'K' */ + else if (cinfo->saw_Adobe_marker) { switch (cinfo->Adobe_transform) { case 0: cinfo->jpeg_color_space = JCS_CMYK; @@ -173,19 +188,17 @@ default_decompress_parms (j_decompress_ptr cinfo) default: WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ - break; } } else { - /* No special markers, assume straight CMYK. */ + /* Unknown IDs and no special markers, assume straight CMYK. */ cinfo->jpeg_color_space = JCS_CMYK; } cinfo->out_color_space = JCS_CMYK; break; - + default: cinfo->jpeg_color_space = JCS_UNKNOWN; cinfo->out_color_space = JCS_UNKNOWN; - break; } /* Set defaults for other decompression parameters. */ diff --git a/3rdparty/libjpeg/jdarith.c b/3rdparty/libjpeg/jdarith.c index 9e4dfdf76d..2c9abe23f2 100644 --- a/3rdparty/libjpeg/jdarith.c +++ b/3rdparty/libjpeg/jdarith.c @@ -1,7 +1,7 @@ /* * jdarith.c * - * Developed 1997-2019 by Guido Vollbeding. + * Developed 1997-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -239,7 +239,7 @@ process_restart (j_decompress_ptr cinfo) */ METHODDEF(boolean) -decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; JBLOCKROW block; @@ -318,7 +318,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; JBLOCKROW block; @@ -400,7 +400,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; unsigned char *st; @@ -434,7 +434,7 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; JBLOCKROW block; @@ -509,7 +509,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; jpeg_component_info * compptr; diff --git a/3rdparty/libjpeg/jdatadst.c b/3rdparty/libjpeg/jdatadst.c index 75ebd7c22d..b3b4798ea4 100644 --- a/3rdparty/libjpeg/jdatadst.c +++ b/3rdparty/libjpeg/jdatadst.c @@ -2,7 +2,7 @@ * jdatadst.c * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2009-2019 by Guido Vollbeding. + * Modified 2009-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -28,17 +28,17 @@ extern void free JPP((void *ptr)); /* Expanded data destination object for stdio output */ +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ + typedef struct { struct jpeg_destination_mgr pub; /* public fields */ FILE * outfile; /* target stream */ - JOCTET * buffer; /* start of buffer */ + JOCTET buffer[OUTPUT_BUF_SIZE]; /* output buffer */ } my_destination_mgr; typedef my_destination_mgr * my_dest_ptr; -#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ - /* Expanded data destination object for memory output */ @@ -65,10 +65,6 @@ init_destination (j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - /* Allocate the output buffer --- it will be released when done with image */ - dest->buffer = (JOCTET *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); - dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; } @@ -187,8 +183,8 @@ term_mem_destination (j_compress_ptr cinfo) /* * Prepare for output to a stdio stream. - * The caller must have already opened the stream, and is responsible - * for closing it after finishing compression. + * The caller must have already opened the stream, + * and is responsible for closing it after finishing compression. */ GLOBAL(void) diff --git a/3rdparty/libjpeg/jdatasrc.c b/3rdparty/libjpeg/jdatasrc.c index 606ae11b4c..fd7a1a594b 100644 --- a/3rdparty/libjpeg/jdatasrc.c +++ b/3rdparty/libjpeg/jdatasrc.c @@ -2,7 +2,7 @@ * jdatasrc.c * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2009-2019 by Guido Vollbeding. + * Modified 2009-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -23,18 +23,18 @@ /* Expanded data source object for stdio input */ +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ + typedef struct { struct jpeg_source_mgr pub; /* public fields */ FILE * infile; /* source stream */ - JOCTET * buffer; /* start of buffer */ + JOCTET buffer[INPUT_BUF_SIZE]; /* input buffer */ boolean start_of_file; /* have we gotten any data yet? */ } my_source_mgr; typedef my_source_mgr * my_src_ptr; -#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ - /* * Initialize source --- called by jpeg_read_header @@ -204,8 +204,8 @@ term_source (j_decompress_ptr cinfo) /* * Prepare for input from a stdio stream. - * The caller must have already opened the stream, and is responsible - * for closing it after finishing decompression. + * The caller must have already opened the stream, + * and is responsible for closing it after finishing decompression. */ GLOBAL(void) @@ -213,19 +213,16 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) { my_src_ptr src; - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling jpeg_stdio_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) + /* The source object including the input buffer is made permanent so that + * a series of JPEG images can be read from the same file by calling + * jpeg_stdio_src only before the first one. (If we discarded the buffer + * at the end of one image, we'd likely lose the start of the next one.) * This makes it unsafe to use this manager and a different source * manager serially with the same JPEG object. Caveat programmer. */ if (cinfo->src == NULL) { /* first time for this JPEG object? */ cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_source_mgr)); - src = (my_src_ptr) cinfo->src; - src->buffer = (JOCTET *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * SIZEOF(JOCTET)); } src = (my_src_ptr) cinfo->src; diff --git a/3rdparty/libjpeg/jdcoefct.c b/3rdparty/libjpeg/jdcoefct.c index ed02fc378f..79ba420140 100644 --- a/3rdparty/libjpeg/jdcoefct.c +++ b/3rdparty/libjpeg/jdcoefct.c @@ -2,7 +2,7 @@ * jdcoefct.c * * Copyright (C) 1994-1997, Thomas G. Lane. - * Modified 2002-2011 by Guido Vollbeding. + * Modified 2002-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -19,11 +19,13 @@ #include "jinclude.h" #include "jpeglib.h" + /* Block smoothing is only applicable for progressive JPEG, so: */ #ifndef D_PROGRESSIVE_SUPPORTED #undef BLOCK_SMOOTHING_SUPPORTED #endif + /* Private buffer controller object */ typedef struct { @@ -38,11 +40,8 @@ typedef struct { /* The output side's location is represented by cinfo->output_iMCU_row. */ /* In single-pass modes, it's sufficient to buffer just one MCU. - * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, + * We append a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, * and let the entropy decoder write into that workspace each time. - * (On 80x86, the workspace is FAR even though it's not really very big; - * this is to keep the module interfaces unchanged when a large coefficient - * buffer is necessary.) * In multi-pass modes, this array points to the current MCU's blocks * within the virtual arrays; it is used only by the input side. */ @@ -58,10 +57,14 @@ typedef struct { int * coef_bits_latch; #define SAVED_COEFS 6 /* we save coef_bits[0..5] */ #endif + + /* Workspace for single-pass modes (omitted otherwise). */ + JBLOCK blk_buffer[D_MAX_BLOCKS_IN_MCU]; } my_coef_controller; typedef my_coef_controller * my_coef_ptr; + /* Forward declarations */ METHODDEF(int) decompress_onepass JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); @@ -151,7 +154,8 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - int blkn, ci, xindex, yindex, yoffset, useful_width; + int ci, xindex, yindex, yoffset, useful_width; + JBLOCKROW blkp; JSAMPARRAY output_ptr; JDIMENSION start_col, output_col; jpeg_component_info *compptr; @@ -162,10 +166,10 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) yoffset++) { for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; MCU_col_num++) { + blkp = coef->blk_buffer; /* pointer to current DCT block within MCU */ /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ if (cinfo->lim_Se) /* can bypass in DC only case */ - FMEMZERO((void FAR *) coef->MCU_buffer[0], - (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); + MEMZERO(blkp, cinfo->blocks_in_MCU * SIZEOF(JBLOCK)); if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; @@ -173,37 +177,34 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) return JPEG_SUSPENDED; } /* Determine where data should go in output_buf and do the IDCT thing. - * We skip dummy blocks at the right and bottom edges (but blkn gets - * incremented past them!). Note the inner loop relies on having - * allocated the MCU_buffer[] blocks sequentially. + * We skip dummy blocks at the right and bottom edges (but blkp gets + * incremented past them!). */ - blkn = 0; /* index of current DCT block within MCU */ for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; /* Don't bother to IDCT an uninteresting component. */ if (! compptr->component_needed) { - blkn += compptr->MCU_blocks; + blkp += compptr->MCU_blocks; continue; } inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; - useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width - : compptr->last_col_width; output_ptr = output_buf[compptr->component_index] + yoffset * compptr->DCT_v_scaled_size; + useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; start_col = MCU_col_num * compptr->MCU_sample_width; for (yindex = 0; yindex < compptr->MCU_height; yindex++) { if (cinfo->input_iMCU_row < last_iMCU_row || - yoffset+yindex < compptr->last_row_height) { + yoffset + yindex < compptr->last_row_height) { output_col = start_col; for (xindex = 0; xindex < useful_width; xindex++) { - (*inverse_DCT) (cinfo, compptr, - (JCOEFPTR) coef->MCU_buffer[blkn+xindex], + (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) (blkp + xindex), output_ptr, output_col); output_col += compptr->DCT_h_scaled_size; } + output_ptr += compptr->DCT_v_scaled_size; } - blkn += compptr->MCU_width; - output_ptr += compptr->DCT_v_scaled_size; + blkp += compptr->MCU_width; } } } @@ -212,7 +213,7 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) } /* Completed the iMCU row, advance counters for next one */ cinfo->output_iMCU_row++; - if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + if (++(cinfo->input_iMCU_row) <= last_iMCU_row) { start_iMCU_row(cinfo); return JPEG_ROW_COMPLETED; } @@ -247,8 +248,9 @@ consume_data (j_decompress_ptr cinfo) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; JDIMENSION MCU_col_num; /* index of current MCU within row */ - int blkn, ci, xindex, yindex, yoffset; + int ci, xindex, yindex, yoffset; JDIMENSION start_col; + JBLOCKARRAY blkp; JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; JBLOCKROW buffer_ptr; jpeg_component_info *compptr; @@ -272,15 +274,16 @@ consume_data (j_decompress_ptr cinfo) for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row; MCU_col_num++) { /* Construct list of pointers to DCT blocks belonging to this MCU */ - blkn = 0; /* index of current DCT block within MCU */ + blkp = coef->MCU_buffer; /* pointer to current DCT block within MCU */ for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; start_col = MCU_col_num * compptr->MCU_width; for (yindex = 0; yindex < compptr->MCU_height; yindex++) { - buffer_ptr = buffer[ci][yindex+yoffset] + start_col; - for (xindex = 0; xindex < compptr->MCU_width; xindex++) { - coef->MCU_buffer[blkn++] = buffer_ptr++; - } + buffer_ptr = buffer[ci][yoffset + yindex] + start_col; + xindex = compptr->MCU_width; + do { + *blkp++ = buffer_ptr++; + } while (--xindex); } } /* Try to fetch the MCU. */ @@ -370,7 +373,7 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) } } - if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + if (++(cinfo->output_iMCU_row) <= last_iMCU_row) return JPEG_ROW_COMPLETED; return JPEG_SCAN_COMPLETED; } @@ -419,10 +422,9 @@ smoothing_ok (j_decompress_ptr cinfo) /* Allocate latch area if not already done */ if (coef->coef_bits_latch == NULL) - coef->coef_bits_latch = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components * - (SAVED_COEFS * SIZEOF(int))); + coef->coef_bits_latch = (int *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * (SAVED_COEFS * SIZEOF(int))); coef_bits_latch = coef->coef_bits_latch; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; @@ -662,7 +664,7 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) } } - if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + if (++(cinfo->output_iMCU_row) <= last_iMCU_row) return JPEG_ROW_COMPLETED; return JPEG_SCAN_COMPLETED; } @@ -679,17 +681,6 @@ jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) { my_coef_ptr coef; - coef = (my_coef_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); - cinfo->coef = (struct jpeg_d_coef_controller *) coef; - coef->pub.start_input_pass = start_input_pass; - coef->pub.start_output_pass = start_output_pass; -#ifdef BLOCK_SMOOTHING_SUPPORTED - coef->coef_bits_latch = NULL; -#endif - - /* Create the coefficient buffer. */ if (need_full_buffer) { #ifdef D_MULTISCAN_FILES_SUPPORTED /* Allocate a full-image virtual array for each component, */ @@ -698,6 +689,9 @@ jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) int ci, access_rows; jpeg_component_info *compptr; + coef = (my_coef_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller) - SIZEOF(coef->blk_buffer)); for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { access_rows = compptr->v_samp_factor; @@ -722,20 +716,29 @@ jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) #endif } else { /* We only need a single-MCU buffer. */ - JBLOCKROW buffer; - int i; + JBLOCKARRAY blkp; + JBLOCKROW buffer_ptr; + int bi; - buffer = (JBLOCKROW) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { - coef->MCU_buffer[i] = buffer + i; - } + coef = (my_coef_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_coef_controller)); + buffer_ptr = coef->blk_buffer; if (cinfo->lim_Se == 0) /* DC only case: want to bypass later */ - FMEMZERO((void FAR *) buffer, - (size_t) (D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK))); + MEMZERO(buffer_ptr, SIZEOF(coef->blk_buffer)); + blkp = coef->MCU_buffer; + bi = D_MAX_BLOCKS_IN_MCU; + do { + *blkp++ = buffer_ptr++; + } while (--bi); coef->pub.consume_data = dummy_consume_data; coef->pub.decompress_data = decompress_onepass; coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ } + + coef->pub.start_input_pass = start_input_pass; + coef->pub.start_output_pass = start_output_pass; +#ifdef BLOCK_SMOOTHING_SUPPORTED + coef->coef_bits_latch = NULL; +#endif + cinfo->coef = &coef->pub; } diff --git a/3rdparty/libjpeg/jdcolor.c b/3rdparty/libjpeg/jdcolor.c index 3746c2e973..6b40fb5340 100644 --- a/3rdparty/libjpeg/jdcolor.c +++ b/3rdparty/libjpeg/jdcolor.c @@ -2,7 +2,7 @@ * jdcolor.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2011-2019 by Guido Vollbeding. + * Modified 2011-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -32,7 +32,9 @@ typedef struct { INT32 * Cb_g_tab; /* => table for Cb to G conversion */ /* Private state for RGB->Y conversion */ - INT32 * rgb_y_tab; /* => table for RGB to Y conversion */ + INT32 * R_y_tab; /* => table for R to Y conversion */ + INT32 * G_y_tab; /* => table for G to Y conversion */ + INT32 * B_y_tab; /* => table for B to Y conversion */ } my_color_deconverter; typedef my_color_deconverter * my_cconvert_ptr; @@ -87,29 +89,17 @@ typedef my_color_deconverter * my_cconvert_ptr; * by precalculating the constants times Cb and Cr for all possible values. * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); * for 9-bit to 12-bit samples it is still acceptable. It's not very - * reasonable for 16-bit samples, but if you want lossless storage you - * shouldn't be changing colorspace anyway. - * The Cr=>R and Cb=>B values can be rounded to integers in advance; the - * values for the G calculation are left scaled up, since we must add them - * together before rounding. + * reasonable for 16-bit samples, but if you want lossless storage + * you shouldn't be changing colorspace anyway. + * The Cr=>R and Cb=>B values can be rounded to integers in advance; + * the values for the G calculation are left scaled up, + * since we must add them together before rounding. */ #define SCALEBITS 16 /* speediest right-shift on some machines */ #define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) #define FIX(x) ((INT32) ((x) * (1L<Y conversion and divide it up into - * three parts, instead of doing three alloc_small requests. This lets us - * use a single table base address, which can be held in a register in the - * inner loops on many machines (more than can hold all three addresses, - * anyway). - */ - -#define R_Y_OFF 0 /* offset to R => Y section */ -#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ -#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ -#define TABLE_SIZE (3*(MAXJSAMPLE+1)) - /* * Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion. @@ -249,17 +239,19 @@ LOCAL(void) build_rgb_y_table (j_decompress_ptr cinfo) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - INT32 * rgb_y_tab; INT32 i; - /* Allocate and fill in the conversion tables. */ - cconvert->rgb_y_tab = rgb_y_tab = (INT32 *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, TABLE_SIZE * SIZEOF(INT32)); + cconvert->R_y_tab = (INT32 *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->G_y_tab = (INT32 *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->B_y_tab = (INT32 *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32)); for (i = 0; i <= MAXJSAMPLE; i++) { - rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i; - rgb_y_tab[i+G_Y_OFF] = FIX(0.587) * i; - rgb_y_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; + cconvert->R_y_tab[i] = FIX(0.299) * i; + cconvert->G_y_tab[i] = FIX(0.587) * i; + cconvert->B_y_tab[i] = FIX(0.114) * i + ONE_HALF; } } @@ -274,8 +266,10 @@ rgb_gray_convert (j_decompress_ptr cinfo, JSAMPARRAY output_buf, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_y_tab; + register INT32 y; + register INT32 * Rytab = cconvert->R_y_tab; + register INT32 * Gytab = cconvert->G_y_tab; + register INT32 * Bytab = cconvert->B_y_tab; register JSAMPROW outptr; register JSAMPROW inptr0, inptr1, inptr2; register JDIMENSION col; @@ -288,13 +282,10 @@ rgb_gray_convert (j_decompress_ptr cinfo, input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr0[col]); - g = GETJSAMPLE(inptr1[col]); - b = GETJSAMPLE(inptr2[col]); - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + y = Rytab[GETJSAMPLE(inptr0[col])]; + y += Gytab[GETJSAMPLE(inptr1[col])]; + y += Bytab[GETJSAMPLE(inptr2[col])]; + outptr[col] = (JSAMPLE) (y >> SCALEBITS); } } } @@ -354,7 +345,10 @@ rgb1_gray_convert (j_decompress_ptr cinfo, { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; register int r, g, b; - register INT32 * ctab = cconvert->rgb_y_tab; + register INT32 y; + register INT32 * Rytab = cconvert->R_y_tab; + register INT32 * Gytab = cconvert->G_y_tab; + register INT32 * Bytab = cconvert->B_y_tab; register JSAMPROW outptr; register JSAMPROW inptr0, inptr1, inptr2; register JDIMENSION col; @@ -373,12 +367,10 @@ rgb1_gray_convert (j_decompress_ptr cinfo, /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD * (modulo) operator is equivalent to the bitmask operator AND. */ - r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE; - b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE; - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + y = Rytab[(r + g - CENTERJSAMPLE) & MAXJSAMPLE]; + y += Gytab[g]; + y += Bytab[(b + g - CENTERJSAMPLE) & MAXJSAMPLE]; + outptr[col] = (JSAMPLE) (y >> SCALEBITS); } } } @@ -420,7 +412,7 @@ rgb_convert (j_decompress_ptr cinfo, /* * Color conversion for no colorspace change: just copy the data, * converting from separate-planes to interleaved representation. - * We assume out_color_components == num_components. + * Note: Omit uninteresting components in output buffer. */ METHODDEF(void) @@ -431,22 +423,27 @@ null_convert (j_decompress_ptr cinfo, register JSAMPROW outptr; register JSAMPROW inptr; register JDIMENSION count; - register int num_comps = cinfo->num_components; + register int out_comps = cinfo->out_color_components; JDIMENSION num_cols = cinfo->output_width; + JSAMPROW startptr; int ci; + jpeg_component_info *compptr; while (--num_rows >= 0) { /* It seems fastest to make a separate pass for each component. */ - for (ci = 0; ci < num_comps; ci++) { + startptr = *output_buf++; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (! compptr->component_needed) + continue; /* skip uninteresting component */ inptr = input_buf[ci][input_row]; - outptr = output_buf[0] + ci; + outptr = startptr++; for (count = num_cols; count > 0; count--) { *outptr = *inptr++; /* don't need GETJSAMPLE() here */ - outptr += num_comps; + outptr += out_comps; } } input_row++; - output_buf++; } } @@ -462,7 +459,7 @@ grayscale_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { - jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, + jcopy_sample_rows(input_buf[0] + input_row, output_buf, num_rows, cinfo->output_width); } @@ -549,6 +546,46 @@ ycck_cmyk_convert (j_decompress_ptr cinfo, } +/* + * Convert CMYK to YK part of YCCK for colorless output. + * We assume build_rgb_y_table has been called. + */ + +METHODDEF(void) +cmyk_yk_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register INT32 y; + register INT32 * Rytab = cconvert->R_y_tab; + register INT32 * Gytab = cconvert->G_y_tab; + register INT32 * Bytab = cconvert->B_y_tab; + register JSAMPROW outptr; + register JSAMPROW inptr0, inptr1, inptr2, inptr3; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + inptr3 = input_buf[3][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + y = Rytab[MAXJSAMPLE - GETJSAMPLE(inptr0[col])]; + y += Gytab[MAXJSAMPLE - GETJSAMPLE(inptr1[col])]; + y += Bytab[MAXJSAMPLE - GETJSAMPLE(inptr2[col])]; + outptr[0] = (JSAMPLE) (y >> SCALEBITS); + /* K passes through unchanged */ + outptr[1] = inptr3[col]; /* don't need GETJSAMPLE here */ + outptr += 2; + } + } +} + + /* * Empty method for start_pass. */ @@ -568,7 +605,7 @@ GLOBAL(void) jinit_color_deconverter (j_decompress_ptr cinfo) { my_cconvert_ptr cconvert; - int ci; + int ci, i; cconvert = (my_cconvert_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_color_deconverter)); @@ -608,7 +645,7 @@ jinit_color_deconverter (j_decompress_ptr cinfo) ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); /* Set out_color_components and conversion method based on requested space. - * Also clear the component_needed flags for any unused components, + * Also adjust the component_needed flags for any unused components, * so that earlier pipeline stages can avoid useless computation. */ @@ -674,9 +711,9 @@ jinit_color_deconverter (j_decompress_ptr cinfo) break; case JCS_BG_RGB: - cinfo->out_color_components = RGB_PIXELSIZE; if (cinfo->jpeg_color_space != JCS_BG_RGB) ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + cinfo->out_color_components = RGB_PIXELSIZE; switch (cinfo->color_transform) { case JCT_NONE: cconvert->pub.color_convert = rgb_convert; @@ -690,25 +727,38 @@ jinit_color_deconverter (j_decompress_ptr cinfo) break; case JCS_CMYK: + if (cinfo->jpeg_color_space != JCS_YCCK) + goto def_label; cinfo->out_color_components = 4; - switch (cinfo->jpeg_color_space) { - case JCS_YCCK: - cconvert->pub.color_convert = ycck_cmyk_convert; - build_ycc_rgb_table(cinfo); - break; - case JCS_CMYK: - cconvert->pub.color_convert = null_convert; - break; - default: - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - } + cconvert->pub.color_convert = ycck_cmyk_convert; + build_ycc_rgb_table(cinfo); break; - default: /* permit null conversion to same output space */ + case JCS_YCCK: + if (cinfo->jpeg_color_space != JCS_CMYK || + /* Support only YK part of YCCK for colorless output */ + ! cinfo->comp_info[0].component_needed || + cinfo->comp_info[1].component_needed || + cinfo->comp_info[2].component_needed || + ! cinfo->comp_info[3].component_needed) + goto def_label; + cinfo->out_color_components = 2; + /* Need all components on input side */ + cinfo->comp_info[1].component_needed = TRUE; + cinfo->comp_info[2].component_needed = TRUE; + cconvert->pub.color_convert = cmyk_yk_convert; + build_rgb_y_table(cinfo); + break; + + default: def_label: /* permit null conversion to same output space */ if (cinfo->out_color_space != cinfo->jpeg_color_space) /* unsupported non-null conversion */ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - cinfo->out_color_components = cinfo->num_components; + i = 0; + for (ci = 0; ci < cinfo->num_components; ci++) + if (cinfo->comp_info[ci].component_needed) + i++; /* count output color components */ + cinfo->out_color_components = i; cconvert->pub.color_convert = null_convert; } diff --git a/3rdparty/libjpeg/jdct.h b/3rdparty/libjpeg/jdct.h index c8ec6cd90e..0f251590c4 100644 --- a/3rdparty/libjpeg/jdct.h +++ b/3rdparty/libjpeg/jdct.h @@ -2,7 +2,7 @@ * jdct.h * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2002-2019 by Guido Vollbeding. + * Modified 2002-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -158,7 +158,7 @@ typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ #define jpeg_idct_6x12 jRD6x12 #define jpeg_idct_5x10 jRD5x10 #define jpeg_idct_4x8 jRD4x8 -#define jpeg_idct_3x6 jRD3x8 +#define jpeg_idct_3x6 jRD3x6 #define jpeg_idct_2x4 jRD2x4 #define jpeg_idct_1x2 jRD1x2 #endif /* NEED_SHORT_EXTERNAL_NAMES */ diff --git a/3rdparty/libjpeg/jdhuff.c b/3rdparty/libjpeg/jdhuff.c index aea06f6039..f175f0c323 100644 --- a/3rdparty/libjpeg/jdhuff.c +++ b/3rdparty/libjpeg/jdhuff.c @@ -2,7 +2,7 @@ * jdhuff.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2006-2019 by Guido Vollbeding. + * Modified 2006-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -704,7 +704,7 @@ process_restart (j_decompress_ptr cinfo) */ METHODDEF(boolean) -decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; int Al = cinfo->Al; @@ -776,7 +776,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; register int s, k, r; @@ -864,7 +864,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; JCOEF p1; @@ -913,7 +913,7 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; register int s, k, r; @@ -1072,7 +1072,7 @@ undoit: */ METHODDEF(boolean) -decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; const int * natural_order; @@ -1201,7 +1201,7 @@ decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) */ METHODDEF(boolean) -decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +decode_mcu (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; int blkn; diff --git a/3rdparty/libjpeg/jdinput.c b/3rdparty/libjpeg/jdinput.c index 0199553e89..29fbef90bf 100644 --- a/3rdparty/libjpeg/jdinput.c +++ b/3rdparty/libjpeg/jdinput.c @@ -2,7 +2,7 @@ * jdinput.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2002-2013 by Guido Vollbeding. + * Modified 2002-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -330,7 +330,6 @@ initial_setup (j_decompress_ptr cinfo) default: ERREXIT4(cinfo, JERR_BAD_PROGRESSION, cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); - break; } /* We initialize DCT_scaled_size and min_DCT_scaled_size to block_size. @@ -391,16 +390,16 @@ per_scan_setup (j_decompress_ptr cinfo) { int ci, mcublks, tmp; jpeg_component_info *compptr; - + if (cinfo->comps_in_scan == 1) { - + /* Noninterleaved (single-component) scan */ compptr = cinfo->cur_comp_info[0]; - + /* Overall image size in MCUs */ cinfo->MCUs_per_row = compptr->width_in_blocks; cinfo->MCU_rows_in_scan = compptr->height_in_blocks; - + /* For noninterleaved scan, always one block per MCU */ compptr->MCU_width = 1; compptr->MCU_height = 1; @@ -413,28 +412,26 @@ per_scan_setup (j_decompress_ptr cinfo) tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); if (tmp == 0) tmp = compptr->v_samp_factor; compptr->last_row_height = tmp; - + /* Prepare array describing MCU composition */ cinfo->blocks_in_MCU = 1; cinfo->MCU_membership[0] = 0; - + } else { - + /* Interleaved (multi-component) scan */ if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, MAX_COMPS_IN_SCAN); - + /* Overall image size in MCUs */ cinfo->MCUs_per_row = (JDIMENSION) jdiv_round_up((long) cinfo->image_width, (long) (cinfo->max_h_samp_factor * cinfo->block_size)); - cinfo->MCU_rows_in_scan = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor * cinfo->block_size)); - + cinfo->MCU_rows_in_scan = cinfo->total_iMCU_rows; + cinfo->blocks_in_MCU = 0; - + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; /* Sampling factors give # of blocks of component in each MCU */ @@ -457,7 +454,7 @@ per_scan_setup (j_decompress_ptr cinfo) cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; } } - + } } @@ -501,9 +498,8 @@ latch_quant_tables (j_decompress_ptr cinfo) cinfo->quant_tbl_ptrs[qtblno] == NULL) ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); /* OK, save away the quantization table */ - qtbl = (JQUANT_TBL *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(JQUANT_TBL)); + qtbl = (JQUANT_TBL *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(JQUANT_TBL)); MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); compptr->quant_table = qtbl; } @@ -644,9 +640,8 @@ jinit_input_controller (j_decompress_ptr cinfo) my_inputctl_ptr inputctl; /* Create subobject in permanent pool */ - inputctl = (my_inputctl_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_input_controller)); + inputctl = (my_inputctl_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_input_controller)); cinfo->inputctl = &inputctl->pub; /* Initialize method pointers */ inputctl->pub.consume_input = consume_markers; diff --git a/3rdparty/libjpeg/jdmainct.c b/3rdparty/libjpeg/jdmainct.c index 4d738fbaed..1cd66d853b 100644 --- a/3rdparty/libjpeg/jdmainct.c +++ b/3rdparty/libjpeg/jdmainct.c @@ -2,7 +2,7 @@ * jdmainct.c * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2002-2016 by Guido Vollbeding. + * Modified 2002-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -170,21 +170,22 @@ alloc_funny_pointers (j_decompress_ptr cinfo) /* Get top-level space for component array pointers. * We alloc both arrays with one call to save a few cycles. */ - mainp->xbuffer[0] = (JSAMPIMAGE) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); + mainp->xbuffer[0] = (JSAMPIMAGE) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); mainp->xbuffer[1] = mainp->xbuffer[0] + cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { + if (! compptr->component_needed) + continue; /* skip uninteresting component */ rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ /* Get space for pointer lists --- M+4 row groups in each list. * We alloc both pointer lists with one call to save a few cycles. */ - xbuf = (JSAMPARRAY) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); + xbuf = (JSAMPARRAY) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, + JPOOL_IMAGE, 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); xbuf += rgroup; /* want one row group at negative offsets */ mainp->xbuffer[0][ci] = xbuf; xbuf += rgroup * (M + 4); @@ -210,6 +211,8 @@ make_funny_pointers (j_decompress_ptr cinfo) for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { + if (! compptr->component_needed) + continue; /* skip uninteresting component */ rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ xbuf0 = mainp->xbuffer[0][ci]; @@ -250,6 +253,8 @@ set_wraparound_pointers (j_decompress_ptr cinfo) for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { + if (! compptr->component_needed) + continue; /* skip uninteresting component */ rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ xbuf0 = mainp->xbuffer[0][ci]; @@ -278,6 +283,8 @@ set_bottom_pointers (j_decompress_ptr cinfo) for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { + if (! compptr->component_needed) + continue; /* skip uninteresting component */ /* Count sample rows in one iMCU row and in one row group */ iMCUheight = compptr->v_samp_factor * compptr->DCT_v_scaled_size; rgroup = iMCUheight / cinfo->min_DCT_v_scaled_size; @@ -333,7 +340,6 @@ start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) #endif default: ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - break; } } @@ -344,9 +350,8 @@ start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) */ METHODDEF(void) -process_data_simple_main (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) +process_data_simple_main (j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) { my_main_ptr mainp = (my_main_ptr) cinfo->main; @@ -375,9 +380,8 @@ process_data_simple_main (j_decompress_ptr cinfo, */ METHODDEF(void) -process_data_context_main (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) +process_data_context_main (j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) { my_main_ptr mainp = (my_main_ptr) cinfo->main; @@ -449,13 +453,12 @@ process_data_context_main (j_decompress_ptr cinfo, #ifdef QUANT_2PASS_SUPPORTED METHODDEF(void) -process_data_crank_post (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) +process_data_crank_post (j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) { (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL, - (JDIMENSION *) NULL, (JDIMENSION) 0, - output_buf, out_row_ctr, out_rows_avail); + (JDIMENSION *) NULL, (JDIMENSION) 0, + output_buf, out_row_ctr, out_rows_avail); } #endif /* QUANT_2PASS_SUPPORTED */ @@ -472,9 +475,8 @@ jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) int ci, rgroup, ngroups; jpeg_component_info *compptr; - mainp = (my_main_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_main_controller)); + mainp = (my_main_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_main_controller)); cinfo->main = &mainp->pub; mainp->pub.start_pass = start_pass_main; @@ -497,6 +499,8 @@ jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { + if (! compptr->component_needed) + continue; /* skip uninteresting component */ rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ mainp->buffer[ci] = (*cinfo->mem->alloc_sarray) diff --git a/3rdparty/libjpeg/jdmaster.c b/3rdparty/libjpeg/jdmaster.c index c309f7629f..3070b7bb41 100644 --- a/3rdparty/libjpeg/jdmaster.c +++ b/3rdparty/libjpeg/jdmaster.c @@ -2,7 +2,7 @@ * jdmaster.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2002-2019 by Guido Vollbeding. + * Modified 2002-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -103,10 +103,8 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo) * This function is used for full decompression. */ { -#ifdef IDCT_SCALING_SUPPORTED - int ci, ssize; + int ci, i; jpeg_component_info *compptr; -#endif /* Prevent application from calling me at wrong times */ if (cinfo->global_state != DSTATE_READY) @@ -124,7 +122,7 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo) */ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - ssize = 1; + int ssize = 1; if (! cinfo->raw_data_out) while (cinfo->min_DCT_h_scaled_size * ssize <= (cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) && @@ -166,27 +164,22 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo) #endif /* IDCT_SCALING_SUPPORTED */ /* Report number of components in selected colorspace. */ - /* Probably this should be in the color conversion module... */ + /* This should correspond to the actual code in the color conversion module. */ switch (cinfo->out_color_space) { case JCS_GRAYSCALE: cinfo->out_color_components = 1; break; case JCS_RGB: case JCS_BG_RGB: -#if RGB_PIXELSIZE != 3 cinfo->out_color_components = RGB_PIXELSIZE; break; -#endif /* else share code with YCbCr */ - case JCS_YCbCr: - case JCS_BG_YCC: - cinfo->out_color_components = 3; - break; - case JCS_CMYK: - case JCS_YCCK: - cinfo->out_color_components = 4; - break; - default: /* else must be same colorspace as in file */ - cinfo->out_color_components = cinfo->num_components; + default: /* YCCK <=> CMYK conversion or same colorspace as in file */ + i = 0; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) + if (compptr->component_needed) + i++; /* count output color components */ + cinfo->out_color_components = i; } cinfo->output_components = (cinfo->quantize_colors ? 1 : cinfo->out_color_components); diff --git a/3rdparty/libjpeg/jdmerge.c b/3rdparty/libjpeg/jdmerge.c index 8b5c899cce..0d16821bed 100644 --- a/3rdparty/libjpeg/jdmerge.c +++ b/3rdparty/libjpeg/jdmerge.c @@ -2,7 +2,7 @@ * jdmerge.c * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2013-2019 by Guido Vollbeding. + * Modified 2013-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -20,17 +20,17 @@ * B = Y + K4 * Cb * only the Y term varies among the group of pixels corresponding to a pair * of chroma samples, so the rest of the terms can be calculated just once. - * At typical sampling ratios, this eliminates half or three-quarters of the - * multiplications needed for color conversion. + * At typical sampling ratios, this eliminates half or three-quarters + * of the multiplications needed for color conversion. * * This file currently provides implementations for the following cases: * YCC => RGB color conversion only (YCbCr or BG_YCC). * Sampling ratios of 2h1v or 2h2v. * No scaling needed at upsample time. * Corner-aligned (non-CCIR601) sampling alignment. - * Other special cases could be added, but in most applications these are - * the only common cases. (For uncommon cases we fall back on the more - * general code in jdsample.c and jdcolor.c.) + * Other special cases could be added, but in most applications these + * are the only common cases. (For uncommon cases we fall back on + * the more general code in jdsample.c and jdcolor.c.) */ #define JPEG_INTERNALS @@ -190,7 +190,7 @@ merged_2v_upsample (j_decompress_ptr cinfo, if (upsample->spare_full) { /* If we have a spare row saved from a previous cycle, just return it. */ - jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0, + jcopy_sample_rows(& upsample->spare_row, output_buf + *out_row_ctr, 1, upsample->out_row_width); num_rows = 1; upsample->spare_full = FALSE; @@ -286,9 +286,9 @@ h2v1_merged_upsample (j_decompress_ptr cinfo, /* Do the chroma part of the calculation */ cb = GETJSAMPLE(*inptr1++); cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; + cred = Crrtab[cr]; /* Fetch 2 Y values and emit 2 pixels */ y = GETJSAMPLE(*inptr0++); outptr[RGB_RED] = range_limit[y + cred]; @@ -303,15 +303,14 @@ h2v1_merged_upsample (j_decompress_ptr cinfo, } /* If image width is odd, do the last output column separately */ if (cinfo->output_width & 1) { + y = GETJSAMPLE(*inptr0); cb = GETJSAMPLE(*inptr1); cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr0); - outptr[RGB_RED] = range_limit[y + cred]; - outptr[RGB_GREEN] = range_limit[y + cgreen]; - outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; + outptr[RGB_GREEN] = range_limit[y + + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS))]; + outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; } } @@ -350,9 +349,9 @@ h2v2_merged_upsample (j_decompress_ptr cinfo, /* Do the chroma part of the calculation */ cb = GETJSAMPLE(*inptr1++); cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; + cred = Crrtab[cr]; /* Fetch 4 Y values and emit 4 pixels */ y = GETJSAMPLE(*inptr00++); outptr0[RGB_RED] = range_limit[y + cred]; @@ -379,9 +378,9 @@ h2v2_merged_upsample (j_decompress_ptr cinfo, if (cinfo->output_width & 1) { cb = GETJSAMPLE(*inptr1); cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; + cred = Crrtab[cr]; y = GETJSAMPLE(*inptr00); outptr0[RGB_RED] = range_limit[y + cred]; outptr0[RGB_GREEN] = range_limit[y + cgreen]; diff --git a/3rdparty/libjpeg/jdsample.c b/3rdparty/libjpeg/jdsample.c index fd9907e20c..15afeafe3d 100644 --- a/3rdparty/libjpeg/jdsample.c +++ b/3rdparty/libjpeg/jdsample.c @@ -2,7 +2,7 @@ * jdsample.c * * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2002-2015 by Guido Vollbeding. + * Modified 2002-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -27,7 +27,7 @@ /* Pointer to routine to upsample a single component */ typedef JMETHOD(void, upsample1_ptr, (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); + JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr)); /* Private subobject */ @@ -102,6 +102,9 @@ sep_upsample (j_decompress_ptr cinfo, if (upsample->next_row_out >= cinfo->max_v_samp_factor) { for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { + /* Don't bother to upsample an uninteresting component. */ + if (! compptr->component_needed) + continue; /* Invoke per-component upsample method. Notice we pass a POINTER * to color_buf[ci], so that fullsize_upsample can change it. */ @@ -156,25 +159,12 @@ sep_upsample (j_decompress_ptr cinfo, METHODDEF(void) fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) + JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr) { *output_data_ptr = input_data; } -/* - * This is a no-op version used for "uninteresting" components. - * These components will not be referenced by color conversion. - */ - -METHODDEF(void) -noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - *output_data_ptr = NULL; /* safety check */ -} - - /* * This version handles any integral sampling ratios. * This is not used for typical JPEG files, so it need not be fast. @@ -188,25 +178,25 @@ noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, METHODDEF(void) int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) + JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr) { my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - JSAMPARRAY output_data = *output_data_ptr; + JSAMPARRAY output_data, output_end; register JSAMPROW inptr, outptr; register JSAMPLE invalue; register int h; JSAMPROW outend; int h_expand, v_expand; - int inrow, outrow; h_expand = upsample->h_expand[compptr->component_index]; v_expand = upsample->v_expand[compptr->component_index]; - inrow = outrow = 0; - while (outrow < cinfo->max_v_samp_factor) { + output_data = *output_data_ptr; + output_end = output_data + cinfo->max_v_samp_factor; + for (; output_data < output_end; output_data += v_expand) { /* Generate one output row with proper horizontal expansion */ - inptr = input_data[inrow]; - outptr = output_data[outrow]; + inptr = *input_data++; + outptr = *output_data; outend = outptr + cinfo->output_width; while (outptr < outend) { invalue = *inptr++; /* don't need GETJSAMPLE() here */ @@ -216,11 +206,9 @@ int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, } /* Generate any additional output rows by duplicating the first one */ if (v_expand > 1) { - jcopy_sample_rows(output_data, outrow, output_data, outrow+1, - v_expand-1, cinfo->output_width); + jcopy_sample_rows(output_data, output_data + 1, + v_expand - 1, cinfo->output_width); } - inrow++; - outrow += v_expand; } } @@ -232,7 +220,7 @@ int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, METHODDEF(void) h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) + JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr) { JSAMPARRAY output_data = *output_data_ptr; register JSAMPROW inptr, outptr; @@ -260,28 +248,26 @@ h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, METHODDEF(void) h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) + JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr) { - JSAMPARRAY output_data = *output_data_ptr; + JSAMPARRAY output_data, output_end; register JSAMPROW inptr, outptr; register JSAMPLE invalue; JSAMPROW outend; - int inrow, outrow; - inrow = outrow = 0; - while (outrow < cinfo->max_v_samp_factor) { - inptr = input_data[inrow]; - outptr = output_data[outrow]; + output_data = *output_data_ptr; + output_end = output_data + cinfo->max_v_samp_factor; + for (; output_data < output_end; output_data += 2) { + inptr = *input_data++; + outptr = *output_data; outend = outptr + cinfo->output_width; while (outptr < outend) { invalue = *inptr++; /* don't need GETJSAMPLE() here */ *outptr++ = invalue; *outptr++ = invalue; } - jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + jcopy_sample_rows(output_data, output_data + 1, 1, cinfo->output_width); - inrow++; - outrow += 2; } } @@ -298,9 +284,8 @@ jinit_upsampler (j_decompress_ptr cinfo) jpeg_component_info * compptr; int h_in_group, v_in_group, h_out_group, v_out_group; - upsample = (my_upsample_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_upsampler)); + upsample = (my_upsample_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_upsampler)); cinfo->upsample = &upsample->pub; upsample->pub.start_pass = start_pass_upsample; upsample->pub.upsample = sep_upsample; @@ -314,6 +299,9 @@ jinit_upsampler (j_decompress_ptr cinfo) */ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { + /* Don't bother to upsample an uninteresting component. */ + if (! compptr->component_needed) + continue; /* Compute size of an "input group" after IDCT scaling. This many samples * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. */ @@ -324,11 +312,6 @@ jinit_upsampler (j_decompress_ptr cinfo) h_out_group = cinfo->max_h_samp_factor; v_out_group = cinfo->max_v_samp_factor; upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ - if (! compptr->component_needed) { - /* Don't bother to upsample an uninteresting component. */ - upsample->methods[ci] = noop_upsample; - continue; /* don't need to allocate buffer */ - } if (h_in_group == h_out_group && v_in_group == v_out_group) { /* Fullsize components can be processed without any work. */ upsample->methods[ci] = fullsize_upsample; diff --git a/3rdparty/libjpeg/jinclude.h b/3rdparty/libjpeg/jinclude.h index 20ed4ef11f..12ea8cd2fd 100644 --- a/3rdparty/libjpeg/jinclude.h +++ b/3rdparty/libjpeg/jinclude.h @@ -2,7 +2,7 @@ * jinclude.h * * Copyright (C) 1991-1994, Thomas G. Lane. - * Modified 2017 by Guido Vollbeding. + * Modified 2017-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -11,8 +11,8 @@ * care of by the standard jconfig symbols, but on really weird systems * you may have to edit this file.) * - * NOTE: this file is NOT intended to be included by applications using the - * JPEG library. Most applications need only include jpeglib.h. + * NOTE: this file is NOT intended to be included by applications using + * the JPEG library. Most applications need only include jpeglib.h. */ @@ -87,11 +87,71 @@ * * Furthermore, macros are provided for fflush() and ferror() in order * to facilitate adaption by applications using an own FILE class. + * + * You can define your own custom file I/O functions in jconfig.h and + * #define JPEG_HAVE_FILE_IO_CUSTOM there to prevent redefinition here. + * + * You can #define JPEG_USE_FILE_IO_CUSTOM in jconfig.h to use custom file + * I/O functions implemented in Delphi VCL (Visual Component Library) + * in Vcl.Imaging.jpeg.pas for the TJPEGImage component utilizing + * the Delphi RTL (Run-Time Library) TMemoryStream component: + * + * procedure jpeg_stdio_src(var cinfo: jpeg_decompress_struct; + * input_file: TStream); external; + * + * procedure jpeg_stdio_dest(var cinfo: jpeg_compress_struct; + * output_file: TStream); external; + * + * function jfread(var buf; recsize, reccount: Integer; S: TStream): Integer; + * begin + * Result := S.Read(buf, recsize * reccount); + * end; + * + * function jfwrite(const buf; recsize, reccount: Integer; S: TStream): Integer; + * begin + * Result := S.Write(buf, recsize * reccount); + * end; + * + * function jfflush(S: TStream): Integer; + * begin + * Result := 0; + * end; + * + * function jferror(S: TStream): Integer; + * begin + * Result := 0; + * end; + * + * TMemoryStream of Delphi RTL has the distinctive feature to provide dynamic + * memory buffer management with a file/stream-based interface, particularly for + * the write (output) operation, which is easier to apply compared with direct + * implementations as given in jdatadst.c for memory destination. Those direct + * implementations of dynamic memory write tend to be more difficult to use, + * so providing an option like TMemoryStream may be a useful alternative. + * + * The CFile/CMemFile classes of the Microsoft Foundation Class (MFC) Library + * may be used in a similar fashion. */ +#ifndef JPEG_HAVE_FILE_IO_CUSTOM +#ifdef JPEG_USE_FILE_IO_CUSTOM +extern size_t jfread(void * __ptr, size_t __size, size_t __n, FILE * __stream); +extern size_t jfwrite(const void * __ptr, size_t __size, size_t __n, FILE * __stream); +extern int jfflush(FILE * __stream); +extern int jferror(FILE * __fp); + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) jfread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) jfwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFFLUSH(file) jfflush(file) +#define JFERROR(file) jferror(file) +#else #define JFREAD(file,buf,sizeofbuf) \ ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) #define JFWRITE(file,buf,sizeofbuf) \ ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) #define JFFLUSH(file) fflush(file) #define JFERROR(file) ferror(file) +#endif +#endif diff --git a/3rdparty/libjpeg/jmorecfg.h b/3rdparty/libjpeg/jmorecfg.h index 679d68bdc5..4638d6af2d 100644 --- a/3rdparty/libjpeg/jmorecfg.h +++ b/3rdparty/libjpeg/jmorecfg.h @@ -2,7 +2,7 @@ * jmorecfg.h * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 1997-2013 by Guido Vollbeding. + * Modified 1997-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -351,8 +351,8 @@ typedef enum { FALSE = 0, TRUE = 1 } boolean; #define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN) */ +#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW) */ #define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ /* Note: if you selected more than 8-bit data precision, it is dangerous to * turn off ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only @@ -369,8 +369,8 @@ typedef enum { FALSE = 0, TRUE = 1 } boolean; #define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW)*/ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW) */ #define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ #define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ #undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ @@ -384,20 +384,31 @@ typedef enum { FALSE = 0, TRUE = 1 } boolean; /* * Ordering of RGB data in scanlines passed to or from the application. * If your application wants to deal with data in the order B,G,R, just - * change these macros. You can also deal with formats such as R,G,B,X - * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing - * the offsets will also change the order in which colormap data is organized. + * #define JPEG_USE_RGB_CUSTOM in jconfig.h, or define your own custom + * order in jconfig.h and #define JPEG_HAVE_RGB_CUSTOM. + * You can also deal with formats such as R,G,B,X (one extra byte per pixel) + * by changing RGB_PIXELSIZE. + * Note that changing the offsets will also change + * the order in which colormap data is organized. * RESTRICTIONS: * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. * 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE - * is not 3 (they don't understand about dummy color components!). So you - * can't use color quantization if you change that value. + * is not 3 (they don't understand about dummy color components!). + * So you can't use color quantization if you change that value. */ +#ifndef JPEG_HAVE_RGB_CUSTOM +#ifdef JPEG_USE_RGB_CUSTOM +#define RGB_RED 2 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 0 /* Offset of Blue */ +#else #define RGB_RED 0 /* Offset of Red in an RGB scanline element */ #define RGB_GREEN 1 /* Offset of Green */ #define RGB_BLUE 2 /* Offset of Blue */ +#endif #define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ +#endif /* Definitions for speed-related optimizations. */ diff --git a/3rdparty/libjpeg/jpegint.h b/3rdparty/libjpeg/jpegint.h index 52c708d4e3..3528bff5b7 100644 --- a/3rdparty/libjpeg/jpegint.h +++ b/3rdparty/libjpeg/jpegint.h @@ -2,7 +2,7 @@ * jpegint.h * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 1997-2019 by Guido Vollbeding. + * Modified 1997-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -103,8 +103,7 @@ struct jpeg_downsampler { typedef JMETHOD(void, forward_DCT_ptr, (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks)); + JDIMENSION start_col, JDIMENSION num_blocks)); struct jpeg_forward_dct { JMETHOD(void, start_pass, (j_compress_ptr cinfo)); @@ -115,7 +114,7 @@ struct jpeg_forward_dct { /* Entropy encoding */ struct jpeg_entropy_encoder { JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); - JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); + JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKARRAY MCU_data)); JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); }; @@ -211,7 +210,7 @@ struct jpeg_marker_reader { /* Entropy decoding */ struct jpeg_entropy_decoder { JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)); + JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, JBLOCKARRAY MCU_data)); JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); }; @@ -416,8 +415,8 @@ EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo)); /* Utility routines in jutils.c */ EXTERN(long) jdiv_round_up JPP((long a, long b)); EXTERN(long) jround_up JPP((long a, long b)); -EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, +EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, + JSAMPARRAY output_array, int num_rows, JDIMENSION num_cols)); EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, JDIMENSION num_blocks)); diff --git a/3rdparty/libjpeg/jpeglib.h b/3rdparty/libjpeg/jpeglib.h index 591a2cb605..e7e15ab2cd 100644 --- a/3rdparty/libjpeg/jpeglib.h +++ b/3rdparty/libjpeg/jpeglib.h @@ -2,7 +2,7 @@ * jpeglib.h * * Copyright (C) 1991-1998, Thomas G. Lane. - * Modified 2002-2019 by Guido Vollbeding. + * Modified 2002-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -39,7 +39,7 @@ extern "C" { #define JPEG_LIB_VERSION 90 /* Compatibility version 9.0 */ #define JPEG_LIB_VERSION_MAJOR 9 -#define JPEG_LIB_VERSION_MINOR 4 +#define JPEG_LIB_VERSION_MINOR 6 /* Various constants determining the sizes of things. diff --git a/3rdparty/libjpeg/jquant1.c b/3rdparty/libjpeg/jquant1.c index 9d11f70669..60b1843e73 100644 --- a/3rdparty/libjpeg/jquant1.c +++ b/3rdparty/libjpeg/jquant1.c @@ -2,7 +2,7 @@ * jquant1.c * * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2011 by Guido Vollbeding. + * Modified 2011-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -293,8 +293,7 @@ create_colormap (j_decompress_ptr cinfo) /* The colors are ordered in the map in standard row-major order, */ /* i.e. rightmost (highest-indexed) color changes most rapidly. */ - colormap = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, + colormap = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); /* blksize is number of adjacent repeated entries for a component */ @@ -400,9 +399,8 @@ make_odither_array (j_decompress_ptr cinfo, int ncolors) int j,k; INT32 num,den; - odither = (ODITHER_MATRIX_PTR) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(ODITHER_MATRIX)); + odither = (ODITHER_MATRIX_PTR) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(ODITHER_MATRIX)); /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). * Hence the dither value for the matrix cell with fill order f * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). @@ -531,8 +529,7 @@ quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, for (row = 0; row < num_rows; row++) { /* Initialize output values to 0 so can process components separately */ - FMEMZERO((void FAR *) output_buf[row], - (size_t) (width * SIZEOF(JSAMPLE))); + FMEMZERO((void FAR *) output_buf[row], (size_t) width * SIZEOF(JSAMPLE)); row_index = cquantize->row_index; for (ci = 0; ci < nc; ci++) { input_ptr = input_buf[row] + ci; @@ -636,8 +633,7 @@ quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, for (row = 0; row < num_rows; row++) { /* Initialize output values to 0 so can process components separately */ - FMEMZERO((void FAR *) output_buf[row], - (size_t) (width * SIZEOF(JSAMPLE))); + FMEMZERO((void FAR *) output_buf[row], (size_t) width * SIZEOF(JSAMPLE)); for (ci = 0; ci < nc; ci++) { input_ptr = input_buf[row] + ci; output_ptr = output_buf[row]; @@ -726,10 +722,10 @@ alloc_fs_workspace (j_decompress_ptr cinfo) size_t arraysize; int i; - arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + arraysize = ((size_t) cinfo->output_width + (size_t) 2) * SIZEOF(FSERROR); for (i = 0; i < cinfo->out_color_components; i++) { - cquantize->fserrors[i] = (FSERRPTR) - (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); + cquantize->fserrors[i] = (FSERRPTR) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); } } @@ -780,13 +776,12 @@ start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) if (cquantize->fserrors[0] == NULL) alloc_fs_workspace(cinfo); /* Initialize the propagated errors to zero. */ - arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + arraysize = ((size_t) cinfo->output_width + (size_t) 2) * SIZEOF(FSERROR); for (i = 0; i < cinfo->out_color_components; i++) FMEMZERO((void FAR *) cquantize->fserrors[i], arraysize); break; default: ERREXIT(cinfo, JERR_NOT_COMPILED); - break; } } @@ -823,10 +818,9 @@ jinit_1pass_quantizer (j_decompress_ptr cinfo) { my_cquantize_ptr cquantize; - cquantize = (my_cquantize_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_cquantizer)); - cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize = (my_cquantize_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_cquantizer)); + cinfo->cquantize = &cquantize->pub; cquantize->pub.start_pass = start_pass_1_quant; cquantize->pub.finish_pass = finish_pass_1_quant; cquantize->pub.new_color_map = new_color_map_1_quant; diff --git a/3rdparty/libjpeg/jquant2.c b/3rdparty/libjpeg/jquant2.c index 38fc2af7a5..662b9bcef3 100644 --- a/3rdparty/libjpeg/jquant2.c +++ b/3rdparty/libjpeg/jquant2.c @@ -2,7 +2,7 @@ * jquant2.c * * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2011 by Guido Vollbeding. + * Modified 2011-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -1197,8 +1197,8 @@ start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); if (cinfo->dither_mode == JDITHER_FS) { - size_t arraysize = (size_t) ((cinfo->output_width + 2) * - (3 * SIZEOF(FSERROR))); + size_t arraysize = ((size_t) cinfo->output_width + (size_t) 2) + * (3 * SIZEOF(FSERROR)); /* Allocate Floyd-Steinberg workspace if we didn't already. */ if (cquantize->fserrors == NULL) cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) @@ -1247,10 +1247,9 @@ jinit_2pass_quantizer (j_decompress_ptr cinfo) my_cquantize_ptr cquantize; int i; - cquantize = (my_cquantize_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_cquantizer)); - cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize = (my_cquantize_ptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_cquantizer)); + cinfo->cquantize = &cquantize->pub; cquantize->pub.start_pass = start_pass_2_quant; cquantize->pub.new_color_map = new_color_map_2_quant; cquantize->fserrors = NULL; /* flag optional arrays not allocated */ @@ -1284,7 +1283,8 @@ jinit_2pass_quantizer (j_decompress_ptr cinfo) if (desired > MAXNUMCOLORS) ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3); + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) desired, (JDIMENSION) 3); cquantize->desired = desired; } else cquantize->sv_colormap = NULL; @@ -1302,7 +1302,7 @@ jinit_2pass_quantizer (j_decompress_ptr cinfo) if (cinfo->dither_mode == JDITHER_FS) { cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR)))); + ((size_t) cinfo->output_width + (size_t) 2) * (3 * SIZEOF(FSERROR))); /* Might as well create the error-limiting table too. */ init_error_limit(cinfo); } diff --git a/3rdparty/libjpeg/jutils.c b/3rdparty/libjpeg/jutils.c index 1e2dfb017b..31e16dfb53 100644 --- a/3rdparty/libjpeg/jutils.c +++ b/3rdparty/libjpeg/jutils.c @@ -2,7 +2,7 @@ * jutils.c * * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2009-2019 by Guido Vollbeding. + * Modified 2009-2020 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -52,67 +52,67 @@ const int jpeg_zigzag_order[DCTSIZE2] = { */ const int jpeg_natural_order[DCTSIZE2+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 }; const int jpeg_natural_order7[7*7+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 14, 21, 28, 35, - 42, 49, 50, 43, 36, 29, 22, 30, - 37, 44, 51, 52, 45, 38, 46, 53, - 54, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 14, 21, 28, 35, + 42, 49, 50, 43, 36, 29, 22, 30, + 37, 44, 51, 52, 45, 38, 46, 53, + 54, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 }; const int jpeg_natural_order6[6*6+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 41, 34, 27, - 20, 13, 21, 28, 35, 42, 43, 36, - 29, 37, 44, 45, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 41, 34, 27, + 20, 13, 21, 28, 35, 42, 43, 36, + 29, 37, 44, 45, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 }; const int jpeg_natural_order5[5*5+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 12, - 19, 26, 33, 34, 27, 20, 28, 35, - 36, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 12, + 19, 26, 33, 34, 27, 20, 28, 35, + 36, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 }; const int jpeg_natural_order4[4*4+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 25, 18, 11, 19, 26, 27, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 25, 18, 11, 19, 26, 27, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 }; const int jpeg_natural_order3[3*3+16] = { - 0, 1, 8, 16, 9, 2, 10, 17, - 18, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 + 0, 1, 8, 16, 9, 2, 10, 17, + 18, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 }; const int jpeg_natural_order2[2*2+16] = { - 0, 1, 8, 9, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 + 0, 1, 8, 9, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 }; @@ -174,12 +174,12 @@ jzero_far (void FAR * target, size_t bytestozero) GLOBAL(void) -jcopy_sample_rows (JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, +jcopy_sample_rows (JSAMPARRAY input_array, + JSAMPARRAY output_array, int num_rows, JDIMENSION num_cols) /* Copy some rows of samples from one place to another. - * num_rows rows are copied from input_array[source_row++] - * to output_array[dest_row++]; these areas may overlap for duplication. + * num_rows rows are copied from *input_array++ to *output_array++; + * these areas may overlap for duplication. * The source and destination arrays must be at least as wide as num_cols. */ { @@ -191,9 +191,6 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row, #endif register int row; - input_array += source_row; - output_array += dest_row; - for (row = num_rows; row > 0; row--) { inptr = *input_array++; outptr = *output_array++; diff --git a/3rdparty/libjpeg/jversion.h b/3rdparty/libjpeg/jversion.h index c9befacde2..df53ef5e55 100644 --- a/3rdparty/libjpeg/jversion.h +++ b/3rdparty/libjpeg/jversion.h @@ -1,7 +1,7 @@ /* * jversion.h * - * Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding. + * Copyright (C) 1991-2024, Thomas G. Lane, Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -9,6 +9,6 @@ */ -#define JVERSION "9d 12-Jan-2020" +#define JVERSION "9f 14-Jan-2024" -#define JCOPYRIGHT "Copyright (C) 2020, Thomas G. Lane, Guido Vollbeding" +#define JCOPYRIGHT "Copyright (C) 2024, Thomas G. Lane, Guido Vollbeding" diff --git a/modules/video/test/test_trackers.cpp b/modules/video/test/test_trackers.cpp index 7186d0fe6b..aae4492bd7 100644 --- a/modules/video/test/test_trackers.cpp +++ b/modules/video/test/test_trackers.cpp @@ -166,7 +166,9 @@ TEST(vittrack, accuracy_vittrack) cv::TrackerVit::Params params; params.net = model; cv::Ptr tracker = TrackerVit::create(params); - checkTrackingAccuracy(tracker, 0.67); + // NOTE: Test threshold was reduced from 0.67 (libjpeg-turbo) to 0.66 (libjpeg 9f), + // becase libjpeg and libjpeg-turbo produce slightly different images + checkTrackingAccuracy(tracker, 0.66); } }} // namespace opencv_test:: From afb91b552eaf57abb2c4a11266bf29812b274d53 Mon Sep 17 00:00:00 2001 From: thewoz Date: Fri, 29 Mar 2024 08:51:19 +0100 Subject: [PATCH 46/56] Merge pull request #24415 from thewoz:imread Add imread #24415 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [X] I agree to contribute to the project under Apache 2 License. - [X] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [X] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake Hello everyone, I created this new version of the imread function and I think it can be very useful in several cases. It is actually passed to it object on which you want to upload the image. The advantages can be different like in case one needs to open several large images all the same in sequence. one can use the same pointer and the system would not allocate memory each time. --- .../imgcodecs/include/opencv2/imgcodecs.hpp | 11 ++++++++ modules/imgcodecs/src/loadsave.cpp | 21 ++++++++++++++- modules/imgcodecs/test/test_png.cpp | 13 +++++++++ modules/python/test/test_imread.py | 27 +++++++++++++++++++ modules/python/test/test_pathlike.py | 2 +- 5 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 modules/python/test/test_imread.py diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index 85ddb838f5..df02eaf021 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -228,6 +228,17 @@ Currently, the following file formats are supported: */ CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR ); +/** @brief Loads an image from a file. + +This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts and the return value. +@param filename Name of file to be loaded. +@param dst object in which the image will be loaded. +@param flags Flag that can take values of cv::ImreadModes +@note +The image passing through the img parameter can be pre-allocated. The memory is reused if the shape and the type match with the load image. + */ +CV_EXPORTS_W void imread( const String& filename, OutputArray dst, int flags = IMREAD_COLOR ); + /** @brief Loads a multi-page image from a file. The function imreadmulti loads a multi-page image from the specified file into a vector of Mat objects. diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp index bc28efe49b..2586fc1fa4 100644 --- a/modules/imgcodecs/src/loadsave.cpp +++ b/modules/imgcodecs/src/loadsave.cpp @@ -457,7 +457,16 @@ imread_( const String& filename, int flags, Mat& mat ) type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1); } - mat.create( size.height, size.width, type ); + if (mat.empty()) + { + mat.create( size.height, size.width, type ); + } + else + { + CV_CheckEQ(size, mat.size(), ""); + CV_CheckTypeEQ(type, mat.type(), ""); + CV_Assert(mat.isContinuous()); + } // read the image data bool success = false; @@ -632,6 +641,16 @@ Mat imread( const String& filename, int flags ) return img; } +void imread( const String& filename, OutputArray dst, int flags ) +{ + CV_TRACE_FUNCTION(); + + Mat img = dst.getMat(); + + /// load the data + imread_(filename, flags, img); +} + /** * Read a multi-page image * diff --git a/modules/imgcodecs/test/test_png.cpp b/modules/imgcodecs/test/test_png.cpp index cdc7da39b2..655c59430d 100644 --- a/modules/imgcodecs/test/test_png.cpp +++ b/modules/imgcodecs/test/test_png.cpp @@ -7,6 +7,19 @@ namespace opencv_test { namespace { #if defined(HAVE_PNG) || defined(HAVE_SPNG) +TEST(Imgcodecs_Png, imread_passing_mat) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + const string imgName = root + "../cv/shared/lena.png"; + + Mat ref = imread(imgName); + Mat img(ref.size(), ref.type()); + void* ptr = img.data; + imread(imgName, img); + EXPECT_EQ(cv::norm(ref, img, NORM_INF), 0); + EXPECT_EQ(img.data, ptr); +} + TEST(Imgcodecs_Png, write_big) { const string root = cvtest::TS::ptr()->get_data_path(); diff --git a/modules/python/test/test_imread.py b/modules/python/test/test_imread.py new file mode 100644 index 0000000000..b5f286d426 --- /dev/null +++ b/modules/python/test/test_imread.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +''' +Test for imread +''' + +# Python 2/3 compatibility +from __future__ import print_function + +import cv2 as cv +import numpy as np +import sys + +from tests_common import NewOpenCVTests + +class imread_test(NewOpenCVTests): + def test_imread_to_buffer(self): + path = self.extraTestDataPath + '/cv/shared/lena.png' + ref = cv.imread(path) + + img = np.zeros_like(ref) + cv.imread(path, img) + self.assertEqual(cv.norm(ref, img, cv.NORM_INF), 0.0) + + +if __name__ == '__main__': + NewOpenCVTests.bootstrap() diff --git a/modules/python/test/test_pathlike.py b/modules/python/test/test_pathlike.py index d654ce24ad..9122a757ce 100644 --- a/modules/python/test/test_pathlike.py +++ b/modules/python/test/test_pathlike.py @@ -28,7 +28,7 @@ class CanPassPathLike(NewOpenCVTests): def test_type_mismatch(self): import_path() # checks python version - with self.assertRaises(TypeError) as context: + with self.assertRaises(cv.error) as context: cv.imread(123) self.assertTrue('str or path-like' in str(context.exception)) From 7945f2cf40bb56e208a7c5ace1cf13ea9a9c712e Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 29 Mar 2024 10:55:42 +0300 Subject: [PATCH 47/56] Fixed HAL invocation for DCT. --- modules/core/src/dxt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/dxt.cpp b/modules/core/src/dxt.cpp index d491be5cd1..85966a5a52 100644 --- a/modules/core/src/dxt.cpp +++ b/modules/core/src/dxt.cpp @@ -4363,7 +4363,7 @@ struct ReplacementDCT2D : public hal::DCT2D ReplacementDCT2D() : context(0), isInitialized(false) {} bool init(int width, int height, int depth, int flags) { - int res = hal_ni_dctInit2D(&context, width, height, depth, flags); + int res = cv_hal_dctInit2D(&context, width, height, depth, flags); isInitialized = (res == CV_HAL_ERROR_OK); return isInitialized; } From 01dc010436b938e06bd67bfaf3dbc5fab1b693f7 Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Fri, 29 Mar 2024 11:21:13 +0300 Subject: [PATCH 48/56] Merge pull request #25273 from dkurt:tflite_new_layers TFLite new layers #25273 ### Pull Request Readiness Checklist resolves https://github.com/opencv/opencv/issues/25272, https://github.com/opencv/opencv/issues/24965 **Merge with extra**: https://github.com/opencv/opencv_extra/pull/1160 See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- modules/dnn/src/tflite/tflite_importer.cpp | 42 +++++++++++++++++++++- modules/dnn/test/test_tflite_importer.cpp | 12 +++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/modules/dnn/src/tflite/tflite_importer.cpp b/modules/dnn/src/tflite/tflite_importer.cpp index f0e1546306..a23bff2545 100644 --- a/modules/dnn/src/tflite/tflite_importer.cpp +++ b/modules/dnn/src/tflite/tflite_importer.cpp @@ -66,6 +66,10 @@ private: void parseDequantize(const Operator& op, const std::string& opcode, LayerParams& layerParams); void parseDetectionPostProcess(const Operator& op, const std::string& opcode, LayerParams& layerParams); void parseActivation(const Operator& op, const std::string& opcode, LayerParams& layerParams); + void parseSplit(const Operator& op, const std::string& opcode, LayerParams& layerParams); + void parseFullyConnected(const Operator& op, const std::string& opcode, LayerParams& layerParams); + void parseSoftmax(const Operator& op, const std::string& opcode, LayerParams& layerParams); + void parseCast(const Operator& op, const std::string& opcode, LayerParams& layerParams); void parseFusedActivation(const Operator& op, ActivationFunctionType activ); void parseActivation(const Operator& op, const std::string& opcode, LayerParams& layerParams, bool isFused); @@ -109,7 +113,7 @@ Mat TFLiteImporter::parseTensor(const Tensor& tensor) default: CV_Error(Error::StsNotImplemented, format("Parse tensor with type %s", EnumNameTensorType(tensor.type()))); } - return Mat(shape, dtype, const_cast(data)); + return shape.empty() ? Mat() : Mat(shape, dtype, const_cast(data)); } TFLiteImporter::TFLiteImporter(Net& dstNet, const char* modelBuffer, size_t bufSize) @@ -275,6 +279,10 @@ TFLiteImporter::DispatchMap TFLiteImporter::buildDispatchMap() dispatch["Convolution2DTransposeBias"] = &TFLiteImporter::parseDeconvolution; dispatch["QUANTIZE"] = &TFLiteImporter::parseQuantize; dispatch["DEQUANTIZE"] = &TFLiteImporter::parseDequantize; + dispatch["SPLIT"] = &TFLiteImporter::parseSplit; + dispatch["FULLY_CONNECTED"] = &TFLiteImporter::parseFullyConnected; + dispatch["SOFTMAX"] = &TFLiteImporter::parseSoftmax; + dispatch["CAST"] = &TFLiteImporter::parseCast; dispatch["TFLite_Detection_PostProcess"] = &TFLiteImporter::parseDetectionPostProcess; return dispatch; } @@ -809,6 +817,38 @@ void TFLiteImporter::parseDequantize(const Operator& op, const std::string& opco addLayer(layerParams, op); } +void TFLiteImporter::parseSplit(const Operator& op, const std::string& opcode, LayerParams& layerParams) { + layerParams.type = "Slice"; + auto options = op.builtin_options_as_SplitOptions(); + CV_Assert(options); + layerParams.set("num_split", options->num_splits()); + addLayer(layerParams, op); +} + +void TFLiteImporter::parseFullyConnected(const Operator& op, const std::string& opcode, LayerParams& layerParams) { + layerParams.type = "Gemm"; + auto options = op.builtin_options_as_FullyConnectedOptions(); + CV_Assert(options); + + int idx = op.inputs()->Get(1); + Mat weights = allTensors[idx]; + layerParams.blobs.resize(1, weights); + layerParams.set("transB", true); + layerParams.set("constB", true); + addLayer(layerParams, op); + parseFusedActivation(op, options->fused_activation_function()); +} + +void TFLiteImporter::parseSoftmax(const Operator& op, const std::string& opcode, LayerParams& layerParams) { + layerParams.type = "Softmax"; + addLayer(layerParams, op); +} + +void TFLiteImporter::parseCast(const Operator& op, const std::string& opcode, LayerParams& layerParams) { + layerParams.type = "Identity"; + addLayer(layerParams, op); +} + void TFLiteImporter::parseDetectionPostProcess(const Operator& op, const std::string& opcode, LayerParams& layerParams) { // Parse parameters; std::vector keys(1, ""); diff --git a/modules/dnn/test/test_tflite_importer.cpp b/modules/dnn/test/test_tflite_importer.cpp index 29f8bae25e..26f2c373b8 100644 --- a/modules/dnn/test/test_tflite_importer.cpp +++ b/modules/dnn/test/test_tflite_importer.cpp @@ -235,6 +235,18 @@ TEST_P(Test_TFLite, replicate_by_pack) { testLayer("replicate_by_pack", l1, lInf); } +TEST_P(Test_TFLite, split) { + testLayer("split"); +} + +TEST_P(Test_TFLite, fully_connected) { + if (backend == DNN_BACKEND_CUDA) + applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA, CV_TEST_TAG_DNN_SKIP_CUDA_FP16); + if (backend == DNN_BACKEND_VKCOM) + applyTestTag(CV_TEST_TAG_DNN_SKIP_VULKAN); + testLayer("fully_connected"); +} + INSTANTIATE_TEST_CASE_P(/**/, Test_TFLite, dnnBackendsAndTargets()); }} // namespace From 2b9d1a2ff8566129607728284342ca4117ad9aba Mon Sep 17 00:00:00 2001 From: zzuliys <68427285+zzuliys@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:23:41 +0800 Subject: [PATCH 49/56] Merge pull request #24877 from zzuliys:feature/mac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Orbbec Camera supports MacOS,Gemini2 and Gemini2L support Y16 format #24877 note: 1.Gemini2 and Gemini2L must use the latest firmware -- https://github.com/orbbec/OrbbecFirmware; 2.Administrator privileges are necessary to run on MacOS. --- 3rdparty/orbbecsdk/orbbecsdk.cmake | 18 ++ CMakeLists.txt | 8 +- modules/videoio/CMakeLists.txt | 38 +++-- modules/videoio/cmake/detect_obsensor.cmake | 68 +++++--- modules/videoio/include/opencv2/videoio.hpp | 2 +- .../obsensor_uvc_stream_channel.cpp | 34 ++-- modules/videoio/src/cap_obsensor_capture.cpp | 16 +- modules/videoio/src/cap_obsensor_capture.hpp | 3 +- .../videoio/src/cap_obsensor_liborbbec.cpp | 154 ++++++++++++++++++ .../videoio/src/cap_obsensor_liborbbec.hpp | 74 +++++++++ samples/cpp/videocapture_obsensor.cpp | 2 +- 11 files changed, 357 insertions(+), 60 deletions(-) create mode 100644 3rdparty/orbbecsdk/orbbecsdk.cmake create mode 100644 modules/videoio/src/cap_obsensor_liborbbec.cpp create mode 100644 modules/videoio/src/cap_obsensor_liborbbec.hpp diff --git a/3rdparty/orbbecsdk/orbbecsdk.cmake b/3rdparty/orbbecsdk/orbbecsdk.cmake new file mode 100644 index 0000000000..7a553946b6 --- /dev/null +++ b/3rdparty/orbbecsdk/orbbecsdk.cmake @@ -0,0 +1,18 @@ +function(download_orbbec_sdk root_var) + set(ORBBECSDK_DOWNLOAD_DIR "${OpenCV_BINARY_DIR}/3rdparty/orbbecsdk") + set(ORBBECSDK_FILE_HASH_CMAKE "2624c84837d3416fd8b3e95750e6e725") + ocv_download(FILENAME "v1.9.4.tar.gz" + HASH ${ORBBECSDK_FILE_HASH_CMAKE} + URL "https://github.com/orbbec/OrbbecSDK/archive/refs/tags/v1.9.4/" + DESTINATION_DIR ${ORBBECSDK_DOWNLOAD_DIR} + ID OrbbecSDK + STATUS res + UNPACK RELATIVE_URL + ) + if(${res}) + message(STATUS "orbbec sdk downloaded to: ${ORBBECSDK_DOWNLOAD_DIR}") + set(${root_var} "${ORBBECSDK_DOWNLOAD_DIR}/OrbbecSDK-1.9.4" PARENT_SCOPE) + else() + message(FATAL_ERROR "Failed to download orbbec sdk") + endif() +endfunction() \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 933aed91d6..e20f68cca0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -478,9 +478,11 @@ OCV_OPTION(WITH_ONNX "Include Microsoft ONNX Runtime support" OFF OCV_OPTION(WITH_TIMVX "Include Tim-VX support" OFF VISIBLE_IF TRUE VERIFY HAVE_TIMVX) -# attention: Astra2, Gemini2, and Gemini2L cameras currently only support Windows and Linux kernel versions no higher than 4.15, and higher versions of Linux kernel may have exceptions. -OCV_OPTION(WITH_OBSENSOR "Include obsensor support (Orbbec RGB-D modules: Astra+/Femto)" ON - VISIBLE_IF (WIN32 AND NOT ARM AND NOT WINRT AND NOT MINGW) OR ( UNIX AND NOT APPLE AND NOT ANDROID) +# Attention when OBSENSOR_USE_ORBBEC_SDK set to off: +# Astra2 cameras currently only support Windows and Linux kernel versions no higher than 4.15, and higher versions of Linux kernel may have exceptions. +OCV_OPTION(OBSENSOR_USE_ORBBEC_SDK "Use Orbbec SDK as backend to support more camera models and platforms (force to ON on MacOS)" OFF) +OCV_OPTION(WITH_OBSENSOR "Include obsensor support (Orbbec 3D Cameras)" ON + VISIBLE_IF (WIN32 AND NOT ARM AND NOT WINRT AND NOT MINGW) OR ( UNIX AND NOT APPLE AND NOT ANDROID) OR (APPLE AND AARCH64 AND NOT IOS) VERIFY HAVE_OBSENSOR) OCV_OPTION(WITH_CANN "Include CANN support" OFF VISIBLE_IF TRUE diff --git a/modules/videoio/CMakeLists.txt b/modules/videoio/CMakeLists.txt index f800babdcd..776c1bb84d 100644 --- a/modules/videoio/CMakeLists.txt +++ b/modules/videoio/CMakeLists.txt @@ -236,25 +236,31 @@ if(TARGET ocv.3rdparty.android_native_camera) endif() if(TARGET ocv.3rdparty.obsensor) - list(APPEND videoio_srcs - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor_capture.cpp) - list(APPEND videoio_hdrs - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor_capture.hpp - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_interface.hpp) - if(HAVE_OBSENSOR_MSMF) +if(OBSENSOR_USE_ORBBEC_SDK) list(APPEND videoio_srcs - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_uvc_stream_channel.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_msmf.cpp) - list(APPEND videoio_hdrs - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_uvc_stream_channel.hpp - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_msmf.hpp) - elseif(HAVE_OBSENSOR_V4L2) + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor_liborbbec.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor_liborbbec.cpp) + else() list(APPEND videoio_srcs - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_uvc_stream_channel.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_v4l2.cpp) + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor_capture.cpp) list(APPEND videoio_hdrs - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_uvc_stream_channel.hpp - ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_v4l2.hpp) + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor_capture.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_interface.hpp) + if(HAVE_OBSENSOR_MSMF) + list(APPEND videoio_srcs + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_uvc_stream_channel.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_msmf.cpp) + list(APPEND videoio_hdrs + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_uvc_stream_channel.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_msmf.hpp) + elseif(HAVE_OBSENSOR_V4L2) + list(APPEND videoio_srcs + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_uvc_stream_channel.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_v4l2.cpp) + list(APPEND videoio_hdrs + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_uvc_stream_channel.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_obsensor/obsensor_stream_channel_v4l2.hpp) + endif() endif() list(APPEND tgts ocv.3rdparty.obsensor) endif() diff --git a/modules/videoio/cmake/detect_obsensor.cmake b/modules/videoio/cmake/detect_obsensor.cmake index fe3f893b48..cf5a9063a9 100644 --- a/modules/videoio/cmake/detect_obsensor.cmake +++ b/modules/videoio/cmake/detect_obsensor.cmake @@ -1,28 +1,54 @@ # --- obsensor --- if(NOT HAVE_OBSENSOR) - if(WIN32) - check_include_file(mfapi.h HAVE_MFAPI) - check_include_file(vidcap.h HAVE_VIDCAP) - if(HAVE_MFAPI AND HAVE_VIDCAP) - set(HAVE_OBSENSOR TRUE) - set(HAVE_OBSENSOR_MSMF TRUE) - ocv_add_external_target(obsensor "" "" "HAVE_OBSENSOR;HAVE_OBSENSOR_MSMF") - else() - set(HAVE_OBSENSOR OFF) - set(HAVE_OBSENSOR_MSMF OFF) - if(NOT HAVE_MFAPI) - MESSAGE(STATUS "Could not find mfapi.h. Turning HAVE_OBSENSOR OFF") - endif() - if(NOT HAVE_VIDCAP) - MESSAGE(STATUS "Could not find vidcap.h. Turning HAVE_OBSENSOR OFF") + if(APPLE) + # force to use orbbec sdk on mac + set(OBSENSOR_USE_ORBBEC_SDK ON) + endif() + + if(OBSENSOR_USE_ORBBEC_SDK) + include(${CMAKE_SOURCE_DIR}/3rdparty/orbbecsdk/orbbecsdk.cmake) + download_orbbec_sdk(ORBBEC_SDK_ROOT_DIR) + message(STATUS "ORBBEC_SDK_ROOT_DIR: ${ORBBEC_SDK_ROOT_DIR}") + if(ORBBEC_SDK_ROOT_DIR) + set(OrbbecSDK_DIR "${ORBBEC_SDK_ROOT_DIR}") + find_package(OrbbecSDK REQUIRED) + message(STATUS "OrbbecSDK_FOUND: ${OrbbecSDK_FOUND}") + message(STATUS "OrbbecSDK_INCLUDE_DIRS: ${OrbbecSDK_INCLUDE_DIRS}") + if(OrbbecSDK_FOUND) + set(HAVE_OBSENSOR TRUE) + set(HAVE_OBSENSOR_ORBBEC_SDK TRUE) + ocv_add_external_target(obsensor "${OrbbecSDK_INCLUDE_DIRS}" "${OrbbecSDK_LIBRARY}" "HAVE_OBSENSOR;HAVE_OBSENSOR_ORBBEC_SDK") + file(COPY ${OrbbecSDK_DLL_FILES} DESTINATION ${CMAKE_BINARY_DIR}/bin) + file(COPY ${OrbbecSDK_DLL_FILES} DESTINATION ${CMAKE_BINARY_DIR}/lib) + install(FILES ${OrbbecSDK_DLL_FILES} DESTINATION ${OPENCV_LIB_INSTALL_PATH}) + ocv_install_3rdparty_licenses(OrbbecSDK ${OrbbecSDK_DIR}/LICENSE.txt) endif() endif() - elseif(UNIX) - check_include_file(linux/videodev2.h HAVE_CAMV4L2_OBSENSOR) - if(HAVE_CAMV4L2_OBSENSOR) - set(HAVE_OBSENSOR TRUE) - set(HAVE_OBSENSOR_V4L2 TRUE) - ocv_add_external_target(obsensor "" "" "HAVE_OBSENSOR;HAVE_OBSENSOR_V4L2") + else() + if(WIN32) + check_include_file(mfapi.h HAVE_MFAPI) + check_include_file(vidcap.h HAVE_VIDCAP) + if(HAVE_MFAPI AND HAVE_VIDCAP) + set(HAVE_OBSENSOR TRUE) + set(HAVE_OBSENSOR_MSMF TRUE) + ocv_add_external_target(obsensor "" "" "HAVE_OBSENSOR;HAVE_OBSENSOR_MSMF") + else() + set(HAVE_OBSENSOR OFF) + set(HAVE_OBSENSOR_MSMF OFF) + if(NOT HAVE_MFAPI) + MESSAGE(STATUS "Could not find mfapi.h. Turning HAVE_OBSENSOR OFF") + endif() + if(NOT HAVE_VIDCAP) + MESSAGE(STATUS "Could not find vidcap.h. Turning HAVE_OBSENSOR OFF") + endif() + endif() + elseif(UNIX) + check_include_file(linux/videodev2.h HAVE_CAMV4L2_OBSENSOR) + if(HAVE_CAMV4L2_OBSENSOR) + set(HAVE_OBSENSOR TRUE) + set(HAVE_OBSENSOR_V4L2 TRUE) + ocv_add_external_target(obsensor "" "" "HAVE_OBSENSOR;HAVE_OBSENSOR_V4L2") + endif() endif() endif() endif() diff --git a/modules/videoio/include/opencv2/videoio.hpp b/modules/videoio/include/opencv2/videoio.hpp index ee23dbe82f..fb47036bbf 100644 --- a/modules/videoio/include/opencv2/videoio.hpp +++ b/modules/videoio/include/opencv2/videoio.hpp @@ -128,7 +128,7 @@ enum VideoCaptureAPIs { CAP_INTEL_MFX = 2300, //!< Intel MediaSDK CAP_XINE = 2400, //!< XINE engine (Linux) CAP_UEYE = 2500, //!< uEye Camera API - CAP_OBSENSOR = 2600, //!< For Orbbec 3D-Sensor device/module (Astra+, Femto, Astra2, Gemini2, Gemini2L, Gemini2XL, Femto Mega) attention: Astra2, Gemini2, and Gemini2L cameras currently only support Windows and Linux kernel versions no higher than 4.15, and higher versions of Linux kernel may have exceptions. + CAP_OBSENSOR = 2600, //!< For Orbbec 3D-Sensor device/module (Astra+, Femto, Astra2, Gemini2, Gemini2L, Gemini2XL, Femto Mega) attention: Astra2 cameras currently only support Windows and Linux kernel versions no higher than 4.15, and higher versions of Linux kernel may have exceptions. }; diff --git a/modules/videoio/src/cap_obsensor/obsensor_uvc_stream_channel.cpp b/modules/videoio/src/cap_obsensor/obsensor_uvc_stream_channel.cpp index 9145a010d2..eec7634eca 100644 --- a/modules/videoio/src/cap_obsensor/obsensor_uvc_stream_channel.cpp +++ b/modules/videoio/src/cap_obsensor/obsensor_uvc_stream_channel.cpp @@ -316,14 +316,14 @@ bool IUvcStreamChannel::getProperty(int propId, uint8_t* recvData, uint32_t* rec if(OBSENSOR_GEMINI2_PID == devInfo_.pid){ // return default param CameraParam param; - param.p0[0] = 516.652f; - param.p0[1] = 516.692f; - param.p0[2] = 322.988f; - param.p0[3] = 235.787f; - param.p1[0] = 516.652f; - param.p1[1] = 516.692f; - param.p1[2] = 322.988f; - param.p1[3] = 235.787f; + param.p0[0] = 519.342f; + param.p0[1] = 519.043f; + param.p0[2] = 319.41f; + param.p0[3] = 240.839f; + param.p1[0] = 519.342f; + param.p1[1] = 519.043f; + param.p1[2] = 319.41f; + param.p1[3] = 240.839f; param.p6[0] = 640; param.p6[1] = 480; param.p7[0] = 640; @@ -421,7 +421,7 @@ bool IUvcStreamChannel::getProperty(int propId, uint8_t* recvData, uint32_t* rec bool IUvcStreamChannel::initDepthFrameProcessor() { - if(OBSENSOR_GEMINI2_PID == devInfo_.pid || OBSENSOR_ASTRA2_PID == devInfo_.pid || OBSENSOR_GEMINI2L_PID == devInfo_.pid){ + if( OBSENSOR_ASTRA2_PID == devInfo_.pid){ uint8_t* rcvData; uint32_t rcvLen; @@ -433,7 +433,19 @@ bool IUvcStreamChannel::initDepthFrameProcessor() depthFrameProcessor_ = makePtr(); return true; - }else if(OBSENSOR_GEMINI2XL_PID == devInfo_.pid){ + } + else if(OBSENSOR_GEMINI2_PID == devInfo_.pid || OBSENSOR_GEMINI2L_PID == devInfo_.pid){ + uint8_t* rcvData; + uint32_t rcvLen; + + setXu(2, OB_EXT_CMD7, sizeof(OB_EXT_CMD7)); + getXu(2, &rcvData, &rcvLen); + + setXu(2, OB_EXT_CMD9, sizeof(OB_EXT_CMD9)); + getXu(2, &rcvData, &rcvLen); + return true; + } + else if(OBSENSOR_GEMINI2XL_PID == devInfo_.pid){ uint8_t* rcvData; uint32_t rcvLen; @@ -445,7 +457,7 @@ bool IUvcStreamChannel::initDepthFrameProcessor() return true; } - else if (streamType_ == OBSENSOR_STREAM_DEPTH && setXu(2, OB_EXT_CMD4, sizeof(OB_EXT_CMD4))) + else if(streamType_ == OBSENSOR_STREAM_DEPTH && setXu(2, OB_EXT_CMD4, sizeof(OB_EXT_CMD4))) { uint8_t* rcvData; uint32_t rcvLen; diff --git a/modules/videoio/src/cap_obsensor_capture.cpp b/modules/videoio/src/cap_obsensor_capture.cpp index 21db152fc3..4c64faee11 100644 --- a/modules/videoio/src/cap_obsensor_capture.cpp +++ b/modules/videoio/src/cap_obsensor_capture.cpp @@ -23,7 +23,8 @@ #include "cap_obsensor_capture.hpp" #include "cap_obsensor/obsensor_stream_channel_interface.hpp" -#ifdef HAVE_OBSENSOR + +#if defined(HAVE_OBSENSOR) && !defined(HAVE_OBSENSOR_ORBBEC_SDK) namespace cv { Ptr create_obsensor_capture(int index) { @@ -34,13 +35,13 @@ VideoCapture_obsensor::VideoCapture_obsensor(int index) : isOpened_(false) { static const obsensor::StreamProfile colorProfile = { 640, 480, 30, obsensor::FRAME_FORMAT_MJPG }; static const obsensor::StreamProfile depthProfile = {640, 480, 30, obsensor::FRAME_FORMAT_Y16}; - static const obsensor::StreamProfile gemini2DepthProfile = {1280, 800, 30, obsensor::FRAME_FORMAT_Y14}; + static const obsensor::StreamProfile gemini2DepthProfile = {1280, 800, 30, obsensor::FRAME_FORMAT_Y16}; static const obsensor::StreamProfile astra2ColorProfile = {800, 600, 30, obsensor::FRAME_FORMAT_MJPG}; static const obsensor::StreamProfile astra2DepthProfile = {800, 600, 30, obsensor::FRAME_FORMAT_Y14}; static const obsensor::StreamProfile megaColorProfile = {1280, 720, 30, obsensor::FRAME_FORMAT_MJPG}; static const obsensor::StreamProfile megaDepthProfile = {640, 576, 30, obsensor::FRAME_FORMAT_Y16}; static const obsensor::StreamProfile gemini2lColorProfile = { 1280, 720, 30, obsensor::FRAME_FORMAT_MJPG}; - static const obsensor::StreamProfile gemini2lDepthProfile = {1280, 800, 30, obsensor::FRAME_FORMAT_Y14}; + static const obsensor::StreamProfile gemini2lDepthProfile = {1280, 800, 30, obsensor::FRAME_FORMAT_Y16}; static const obsensor::StreamProfile gemini2XlColorProfile = { 1280, 800, 10, obsensor::FRAME_FORMAT_MJPG}; static const obsensor::StreamProfile gemini2XlDepthProfile = {1280, 800, 10, obsensor::FRAME_FORMAT_Y16}; @@ -143,19 +144,22 @@ bool VideoCapture_obsensor::retrieveFrame(int outputType, OutputArray frame) if (!grabbedDepthFrame_.empty()) { if(OBSENSOR_GEMINI2_PID == streamChannelGroup_.front()->getPid()){ - grabbedDepthFrame_ = grabbedDepthFrame_*0.8; + const double DepthValueScaleGemini2 = 0.2; + grabbedDepthFrame_ = grabbedDepthFrame_*DepthValueScaleGemini2; Rect rect(320, 160, 640, 480); grabbedDepthFrame_(rect).copyTo(frame); } else if(OBSENSOR_ASTRA2_PID == streamChannelGroup_.front()->getPid()){ - grabbedDepthFrame_ = grabbedDepthFrame_*0.8; + const double DepthValueScaleAstra2 = 0.8; + grabbedDepthFrame_ = grabbedDepthFrame_*DepthValueScaleAstra2; grabbedDepthFrame_.copyTo(frame); } else if(OBSENSOR_FEMTO_MEGA_PID == streamChannelGroup_.front()->getPid()){ Rect rect(0, 0, 640, 360); grabbedDepthFrame_(rect).copyTo(frame); }else if(OBSENSOR_GEMINI2L_PID == streamChannelGroup_.front()->getPid()){ - grabbedDepthFrame_ = grabbedDepthFrame_*0.8; + const double DepthValueScaleGemini2L = 0.2; + grabbedDepthFrame_ = grabbedDepthFrame_*DepthValueScaleGemini2L; Rect rect(0, 40, 1280, 720); grabbedDepthFrame_(rect).copyTo(frame); }else if(OBSENSOR_GEMINI2XL_PID == streamChannelGroup_.front()->getPid()){ diff --git a/modules/videoio/src/cap_obsensor_capture.hpp b/modules/videoio/src/cap_obsensor_capture.hpp index 821e6193a0..89ab403bb2 100644 --- a/modules/videoio/src/cap_obsensor_capture.hpp +++ b/modules/videoio/src/cap_obsensor_capture.hpp @@ -28,7 +28,8 @@ #include "cap_obsensor/obsensor_stream_channel_interface.hpp" -#ifdef HAVE_OBSENSOR +#if defined(HAVE_OBSENSOR) && !defined(HAVE_OBSENSOR_ORBBEC_SDK) + namespace cv { class VideoCapture_obsensor : public IVideoCapture { diff --git a/modules/videoio/src/cap_obsensor_liborbbec.cpp b/modules/videoio/src/cap_obsensor_liborbbec.cpp new file mode 100644 index 0000000000..ac581d81dc --- /dev/null +++ b/modules/videoio/src/cap_obsensor_liborbbec.cpp @@ -0,0 +1,154 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +/* +* Copyright(C) 2024 by ORBBEC Technology., Inc. +* Authors: +* Huang Zhenchang +* Yu Shuai +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "precomp.hpp" + +#if defined(HAVE_OBSENSOR) && defined(HAVE_OBSENSOR_ORBBEC_SDK) +#include "libobsensor/ObSensor.hpp" +#include "cap_obsensor_liborbbec.hpp" + +namespace cv +{ +Ptr create_obsensor_capture(int index) +{ + return makePtr(index); +} + +VideoCapture_obsensor::VideoCapture_obsensor(int) +{ + ob::Context::setLoggerToFile(OB_LOG_SEVERITY_OFF, ""); + config = std::make_shared(); + pipe = std::make_shared(); + auto colorProfiles = pipe->getStreamProfileList(OB_SENSOR_COLOR); + auto colorProfile = colorProfiles->getProfile(OB_PROFILE_DEFAULT); + config->enableStream(colorProfile->as()); + + auto depthProfiles = pipe->getStreamProfileList(OB_SENSOR_DEPTH); + auto depthProfile = depthProfiles->getProfile(OB_PROFILE_DEFAULT); + config->enableStream(depthProfile->as()); + + config->setAlignMode(ALIGN_D2C_SW_MODE); + + pipe->start(config, [&](std::shared_ptr frameset) { + std::unique_lock lk(videoFrameMutex); + colorFrame = frameset->colorFrame(); + depthFrame = frameset->depthFrame(); + }); + + auto param = pipe->getCameraParam(); + camParam.p1[0] = param.rgbIntrinsic.fx; + camParam.p1[1] = param.rgbIntrinsic.fy; + camParam.p1[2] = param.rgbIntrinsic.cx; + camParam.p1[3] = param.rgbIntrinsic.cy; +} + +VideoCapture_obsensor::~VideoCapture_obsensor(){ + pipe->stop(); +} + +double VideoCapture_obsensor::getProperty(int propIdx) const +{ + double rst = 0.0; + propIdx = propIdx & (~CAP_OBSENSOR_GENERATORS_MASK); + switch (propIdx) + { + case CAP_PROP_OBSENSOR_INTRINSIC_FX: + rst = camParam.p1[0]; + break; + case CAP_PROP_OBSENSOR_INTRINSIC_FY: + rst = camParam.p1[1]; + break; + case CAP_PROP_OBSENSOR_INTRINSIC_CX: + rst = camParam.p1[2]; + break; + case CAP_PROP_OBSENSOR_INTRINSIC_CY: + rst = camParam.p1[3]; + break; + } + return rst; +} + +bool VideoCapture_obsensor::setProperty(int, double) +{ + return false; +} + +bool VideoCapture_obsensor::grabFrame() +{ + std::unique_lock lk(videoFrameMutex); + grabbedColorFrame = colorFrame; + grabbedDepthFrame = depthFrame; + + return grabbedColorFrame || grabbedDepthFrame; +} + +bool VideoCapture_obsensor::retrieveFrame(int outputType, cv::OutputArray frame) +{ + switch (outputType) + { + case CAP_OBSENSOR_BGR_IMAGE: + if(grabbedColorFrame != nullptr){ + auto format = grabbedColorFrame->format(); + if(format != OB_FORMAT_MJPEG){ + CV_LOG_WARNING(NULL, "Unsupported color frame format"); + return false; + } + auto mjpgMat = Mat(1, grabbedColorFrame->dataSize() , CV_8UC1, grabbedColorFrame->data()).clone(); + auto bgrMat = imdecode(mjpgMat, IMREAD_COLOR); + if(bgrMat.empty()){ + CV_LOG_WARNING(NULL, "Failed to decode color frame"); + return false; + } + bgrMat.copyTo(frame); + return true; + } + break; + case CAP_OBSENSOR_DEPTH_MAP: + if(grabbedDepthFrame != nullptr){ + auto format = grabbedDepthFrame->format(); + if(format != OB_FORMAT_Y16){ + CV_LOG_WARNING(NULL, "Unsupported depth frame format"); + return false; + } + Mat(grabbedDepthFrame->height(), grabbedDepthFrame->width(), CV_16UC1, grabbedDepthFrame->data()).copyTo(frame); + return true; + } + break; + default: + return false; + } + + return false; +} + +int VideoCapture_obsensor::getCaptureDomain() +{ + return CAP_OBSENSOR; +} + +bool VideoCapture_obsensor::isOpened() const +{ + return true; +} + +} +#endif diff --git a/modules/videoio/src/cap_obsensor_liborbbec.hpp b/modules/videoio/src/cap_obsensor_liborbbec.hpp new file mode 100644 index 0000000000..13dbf413ca --- /dev/null +++ b/modules/videoio/src/cap_obsensor_liborbbec.hpp @@ -0,0 +1,74 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +/* +* Copyright(C) 2024 by ORBBEC Technology., Inc. +* Authors: +* Huang Zhenchang +* Yu Shuai +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _CAP_LIBORBBEC_HPP_ +#define _CAP_LIBORBBEC_HPP_ + +#if defined(HAVE_OBSENSOR) && defined(HAVE_OBSENSOR_ORBBEC_SDK) + +#include +#include + +namespace cv +{ + +struct CameraParam +{ + float p0[4]; + float p1[4]; + float p2[9]; + float p3[3]; + float p4[5]; + float p5[5]; + uint32_t p6[2]; + uint32_t p7[2]; +}; + +class VideoCapture_obsensor : public IVideoCapture +{ +public: + VideoCapture_obsensor(int index); + virtual ~VideoCapture_obsensor(); + + virtual double getProperty(int propIdx) const CV_OVERRIDE; + virtual bool setProperty(int propIdx, double propVal) CV_OVERRIDE; + + virtual bool grabFrame() CV_OVERRIDE; + virtual bool retrieveFrame(int outputType, OutputArray frame) CV_OVERRIDE; + virtual int getCaptureDomain() CV_OVERRIDE; + virtual bool isOpened() const CV_OVERRIDE; + +protected: + std::mutex videoFrameMutex; + std::shared_ptr colorFrame; + std::shared_ptr depthFrame; + std::shared_ptr grabbedColorFrame; + std::shared_ptr grabbedDepthFrame; + std::shared_ptr pipe; + std::shared_ptr config; + CameraParam camParam; +}; + +} + +#endif +#endif diff --git a/samples/cpp/videocapture_obsensor.cpp b/samples/cpp/videocapture_obsensor.cpp index 7dda3386ce..ce71a1808b 100644 --- a/samples/cpp/videocapture_obsensor.cpp +++ b/samples/cpp/videocapture_obsensor.cpp @@ -1,5 +1,5 @@ /** - * attention: Astra2, Gemini2, and Gemini2L cameras currently only support Windows and Linux kernel versions no higher than 4.15, and higher versions of Linux kernel may have exceptions. + * attention: Astra2 cameras currently only support Windows and Linux kernel versions no higher than 4.15, and higher versions of Linux kernel may have exceptions. */ #include From a7d6f105e7f0f65d04fb89be85447b02dbeaeafc Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 29 Mar 2024 11:33:12 +0300 Subject: [PATCH 50/56] Skip InferROI.TestStreamingInfer as unstable as it hangs on CI time-to-time. --- modules/gapi/test/infer/gapi_infer_ie_test.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/gapi/test/infer/gapi_infer_ie_test.cpp b/modules/gapi/test/infer/gapi_infer_ie_test.cpp index f6a6be0651..058896bc83 100644 --- a/modules/gapi/test/infer/gapi_infer_ie_test.cpp +++ b/modules/gapi/test/infer/gapi_infer_ie_test.cpp @@ -1649,6 +1649,9 @@ TEST(Infer, TestStreamingInfer) TEST(InferROI, TestStreamingInfer) { + if (cvtest::skipUnstableTests) + throw SkipTestException("Skip InferROI.TestStreamingInfer as it hangs sporadically"); + initDLDTDataPath(); std::string filepath = findDataFile("cv/video/768x576.avi"); From cfa42e43384fabc065e976692bd464d476c677dc Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Fri, 29 Mar 2024 09:40:03 +0300 Subject: [PATCH 51/56] Einsum OpenVINO backend --- modules/dnn/src/layers/einsum_layer.cpp | 23 +++++++++++++++++-- ...conformance_layer_filter__openvino.inl.hpp | 2 +- modules/dnn/test/test_onnx_importer.cpp | 4 ++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/modules/dnn/src/layers/einsum_layer.cpp b/modules/dnn/src/layers/einsum_layer.cpp index 7f8eb47112..4e3eca2378 100644 --- a/modules/dnn/src/layers/einsum_layer.cpp +++ b/modules/dnn/src/layers/einsum_layer.cpp @@ -5,6 +5,7 @@ #include #include #include "../precomp.hpp" +#include "../ie_ngraph.hpp" #include "layers_common.hpp" #include "cpu_kernels/fast_gemm.hpp" @@ -304,7 +305,7 @@ public: MatShape einsumOutDims; // vector to store output dimentions // These hold equation subring, left hand side and right it of - String lhs_eq, rhs_eq; + String lhs_eq, rhs_eq, equation; // Holds token from left hand side of the equation std::vector lhs_eq_tokens; @@ -378,7 +379,7 @@ public: LayerEinsumImpl(const LayerParams& params) { setParamsFrom(params); - String equation = params.get("equation"); + equation = params.get("equation"); int outputSize = params.get("outputSize"); numInputs = params.get("inputSize"); @@ -423,6 +424,11 @@ public: calculateOutputShape(); } + virtual bool supportBackend(int backendId) CV_OVERRIDE { + return backendId == DNN_BACKEND_OPENCV || + backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH; + } + // getMeoryShapes bool getMemoryShapes(const std::vector &inputs, const int requiredOutputs, @@ -553,6 +559,19 @@ public: result = result.reshape(1, einsumOutDims.size(), einsumOutDims.data()); result.copyTo(outputs[0]); } // forward + +#ifdef HAVE_DNN_NGRAPH + virtual Ptr initNgraph(const std::vector >&, + const std::vector >& nodes) CV_OVERRIDE { + ov::OutputVector inputs(nodes.size()); + for (size_t i = 0; i < nodes.size(); ++i) { + inputs[i] = nodes[i].dynamicCast()->node; + } + auto einsum = std::make_shared(inputs, equation); + return new InfEngineNgraphNode(einsum); + } +#endif // HAVE_DNN_NGRAPH + }; // EinsumClass Mat LayerEinsumImpl::reduceSum(Mat& src, MatShape& reduceAxis) diff --git a/modules/dnn/test/test_onnx_conformance_layer_filter__openvino.inl.hpp b/modules/dnn/test/test_onnx_conformance_layer_filter__openvino.inl.hpp index 291ea30e92..509cf6007d 100644 --- a/modules/dnn/test/test_onnx_conformance_layer_filter__openvino.inl.hpp +++ b/modules/dnn/test/test_onnx_conformance_layer_filter__openvino.inl.hpp @@ -597,7 +597,7 @@ CASE(test_dynamicquantizelinear_min_adjusted_expanded) CASE(test_edge_pad) // no filter CASE(test_einsum_batch_diagonal) - // no filter + SKIP; CASE(test_einsum_batch_matmul) // no filter CASE(test_einsum_inner_prod) diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index 859757d17a..4d475857e5 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -1471,6 +1471,8 @@ TEST_P(Test_ONNX_layers, Einsum_2D) TEST_P(Test_ONNX_layers, Einsum_2D_Ellipses) { + if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); testONNXModels("einsum_2d_ellipses", npy, 0, 0, false, false, 2); } @@ -1501,6 +1503,8 @@ TEST_P(Test_ONNX_layers, DISABLED_Einsum_HadamardProduct) TEST_P(Test_ONNX_layers, Einsum_Batch_Diagonal) { + if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); testONNXModels("einsum_batch_diagonal", npy, 0, 0, false, false, 1); } From b758897c2972e1b46601808e7b785e94a1def0bd Mon Sep 17 00:00:00 2001 From: Yuantao Feng Date: Fri, 29 Mar 2024 22:35:23 +0800 Subject: [PATCH 52/56] Merge pull request #25271 from fengyuentau:matmul_bias Merge with https://github.com/opencv/opencv_extra/pull/1158 Todo: - [x] Fix Attention pattern recognition. - [x] Handle other backends. Benchmark: "VIT_B_32 OCV/CPU", M1, results in milliseconds. | Model | 4.x | This PR | | - | - | - | | VIT_B_32 OCV/CPU | 87.66 | **83.83** | ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- .../cuda4dnn/primitives/matmul_broadcast.hpp | 26 ++- modules/dnn/src/layers/matmul_layer.cpp | 202 ++++++++++++++++-- .../dnn/src/onnx/onnx_graph_simplifier.cpp | 136 ++++++++++-- modules/dnn/src/onnx/onnx_importer.cpp | 13 +- modules/dnn/test/test_graph_simplifier.cpp | 7 + modules/dnn/test/test_onnx_importer.cpp | 6 + 6 files changed, 347 insertions(+), 43 deletions(-) diff --git a/modules/dnn/src/cuda4dnn/primitives/matmul_broadcast.hpp b/modules/dnn/src/cuda4dnn/primitives/matmul_broadcast.hpp index 824d917382..c99a1b5f3a 100644 --- a/modules/dnn/src/cuda4dnn/primitives/matmul_broadcast.hpp +++ b/modules/dnn/src/cuda4dnn/primitives/matmul_broadcast.hpp @@ -12,6 +12,8 @@ #include "../csl/tensor.hpp" #include "../csl/tensor_ops.hpp" +#include "../kernels/eltwise_ops.hpp" // for adding bias + #include #include @@ -23,7 +25,7 @@ namespace cv { namespace dnn { namespace cuda4dnn { public: using wrapper_type = GetCUDABackendWrapperType; - MatMulBroadcastOp(csl::Stream stream_, csl::cublas::Handle handle, const Mat &B, bool _transA, bool _transB, + MatMulBroadcastOp(csl::Stream stream_, csl::cublas::Handle handle, const Mat &B, const Mat &bias, bool _transA, bool _transB, const std::vector &A_offsets_, const std::vector &B_offsets_, std::vector &C_offsets_, size_t batch_) : stream(std::move(stream_)), cublasHandle(std::move(handle)), A_offsets(A_offsets_), B_offsets(B_offsets_), C_offsets(C_offsets_), batch(batch_) @@ -33,6 +35,11 @@ namespace cv { namespace dnn { namespace cuda4dnn { csl::copyMatToTensor(B, input_B_tensor, stream); } + if (!bias.empty()) { + bias_tensor = csl::makeTensorHeader(bias); + csl::copyMatToTensor(bias, bias_tensor, stream); + } + transA = _transA; transB = _transB; } @@ -42,9 +49,6 @@ namespace cv { namespace dnn { namespace cuda4dnn { const std::vector>& outputs, csl::Workspace& workspace) override { - CV_Assert(((inputs.size() == 2 && input_B_tensor.empty()) || - (inputs.size() == 1 && !input_B_tensor.empty())) && outputs.size() == 1); - auto input_A_wrapper = inputs[0].dynamicCast(); auto input_A = input_A_wrapper->getView(); @@ -60,12 +64,26 @@ namespace cv { namespace dnn { namespace cuda4dnn { auto output = output_wrapper->getSpan(); csl::tensor_ops::gemmBatched(cublasHandle, batch, 0.f, output, C_offsets, 1.f, transA, input_A, A_offsets, transB, input_B, B_offsets); + + // add bias if exists + if (!bias_tensor.empty() || inputs.size() >= 3) { + csl::TensorView bias; + if (bias_tensor.empty()) { + auto bias_wrapper = inputs[2].dynamicCast(); + bias = bias_wrapper->getView(); + } else { + bias = csl::TensorView(bias_tensor); + } + + kernels::eltwise_sum_2(stream, output, output, bias); + } } private: csl::Stream stream; csl::cublas::Handle cublasHandle; csl::Tensor input_B_tensor; + csl::Tensor bias_tensor; bool transA, transB; std::vector A_offsets; diff --git a/modules/dnn/src/layers/matmul_layer.cpp b/modules/dnn/src/layers/matmul_layer.cpp index a571592dfb..448af27c18 100644 --- a/modules/dnn/src/layers/matmul_layer.cpp +++ b/modules/dnn/src/layers/matmul_layer.cpp @@ -26,6 +26,10 @@ using namespace cv::dnn::cuda4dnn; namespace cv { namespace dnn { class MatMulLayerImpl CV_FINAL : public MatMulLayer { +#ifdef HAVE_OPENCL + UMat weight_umat, bias_umat; +#endif + public: MatMulLayerImpl(const LayerParams& params) { setParamsFrom(params); @@ -34,6 +38,8 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { trans_b = params.get("transB", false); alpha = params.get("alpha", 1.f); beta = params.get("beta", 1.f); + + real_ndims_C = params.get("real_ndims_C", -1); } virtual bool supportBackend(int backendId) CV_OVERRIDE { @@ -48,8 +54,9 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { const int requiredOutputs, std::vector &outputs, std::vector &internals) const CV_OVERRIDE { - CV_CheckGE(inputs.size(), static_cast(1), "DNN/MatMul: one varible input at least"); - CV_CheckLE(inputs.size(), static_cast(2), "DNN/MatMul: two variable inputs at most"); + int num_inputs = inputs.size() + blobs.size(); + CV_CheckGE(num_inputs, 2, "DNN/MatMul: two inputs at least"); + CV_CheckLE(num_inputs, 3, "DNN/MatMul: three inputs at most"); const auto shape_A = inputs[0], shape_B = blobs.empty() ? inputs[1] : shape(blobs[0]); CV_CheckGE(shape_A.size(), static_cast(2), "DNN/MatMul: invalid shape of input A"); @@ -64,7 +71,7 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { int K_B = trans_b ? nB : mB; CV_CheckEQ(K_A, K_B, "DNN/MatMul: invalid dimension K"); - // Check legal broadcast. It is legal for sure if A and B are 2d, or one of them is 2d. + // Check if inputs are broadcastable. MatShape common_shape; if (shape_A.size() != 2 || shape_B.size() != 2) { const auto &shape_more_dims = shape_A.size() > shape_B.size() ? shape_A : shape_B; @@ -89,6 +96,24 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { common_shape[1] = N; } + // Check if bias is broadcastable + if (num_inputs == 3) { + const auto shape_C = blobs.empty() ? inputs.back() : shape(blobs.back()); + if (real_ndims_C == 1) { // (1) or (N) + CV_Check(shape_C[0], shape_C[0] == 1 || shape_C[0] == N, "DNN/MatMul: invalid dimension of C"); + } else if (real_ndims_C >= 2) { + const auto &shape_large = common_shape.size() > shape_C.size() ? common_shape : shape_C; + const auto &shape_small = common_shape.size() > shape_C.size() ? shape_C : common_shape; + size_t diff_dims = shape_large.size() - shape_small.size(); + for (size_t i = 0; i < shape_small.size(); i++) { + const auto dl = shape_small[i], dm = shape_large[i + diff_dims]; + if (dl != 1 && dm != 1 && dl != dm) { + CV_Error(Error::StsBadSize, "DNN/MatMul: invalid shape of C"); + } + } + } + } + outputs.assign(1, common_shape); return false; } @@ -109,6 +134,44 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { fastGemmPackB(blobs[0], packed_input_B, trans_b, opt); helper.updatePackedBOffsets(packed_input_B.size()); } + + // broadcast bias if needed + if ((inputs.size() + blobs.size()) >= 3 && blobs.size() >= 2) { + const auto bias_mat = blobs.back(); + const auto bias_shape = shape(bias_mat); + bool is_broadcast_needed = real_ndims_C == 0 || real_ndims_C == 1 || (total(bias_shape) != total(C_shape) || bias_shape.size() != C_shape.size()); + + if (is_broadcast_needed) { + broadcast_bias = Mat(C_shape, CV_32F); + auto *broadcast_bias_ptr = broadcast_bias.ptr(); + + const auto *bias = bias_mat.ptr(); + if (bias_mat.total() == 1) { // [], [1], [1, ...] + float b = (*bias) * beta; + for (size_t i = 0; i < broadcast_bias.total(); i++) { + broadcast_bias_ptr[i] = b; + } + } else if (real_ndims_C == 1) { // [n] + size_t inner_size = C_shape.back(), + loops = total(C_shape) / inner_size; + for (size_t i = 0; i < loops; i++) { + size_t step = i * inner_size; + for (size_t j = 0; j < inner_size; j++) { + broadcast_bias_ptr[step + j] = beta * bias[j]; + } + } + } else { + broadcast(bias_mat, C_shape, broadcast_bias); + } + } else { + broadcast_bias = blobs.back(); + } + } + +#ifdef HAVE_OPENCL + weight_umat.release(); + bias_umat.release(); +#endif } // works like Y = numpy.matmul(A, B) @@ -134,7 +197,38 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { const auto *a = A.ptr(); auto *y = Y.ptr(); - std::memset(y, 0, Y.total() * sizeof(float)); + // add bias if existed + if ((inputs.size() + blobs.size()) >= 3) { + const auto &shape_Y = shape(Y); + if (blobs.empty()) { // bias from input + const auto &bias_mat = inputs.back(); + const auto *bias = bias_mat.ptr(); + if (bias_mat.total() == 1) { // [], [1], [1, ...] + float b = (*bias) * beta; + for (size_t i = 0; i < Y.total(); i++) { + y[i] = b; + } + } else if (real_ndims_C == 1) { // [n] + const size_t inner_size = shape_Y.back(), + batches = total(Y) / inner_size; + parallel_for_(Range(0, batches), [&] (const Range &r) { + for (int i = r.start; i < r.end; i++) { + const size_t output_offset = i * inner_size; + for (size_t j = 0; j < inner_size; j++) { + y[output_offset + j] = beta * bias[j]; + } + } + }, double(batches * inner_size * (1 / 1024.0))); + } else { + broadcast(bias_mat, shape_Y, Y); + } + } else { // bias from constant + const auto *bias = broadcast_bias.ptr(); + std::memcpy(y, bias, total(shape_Y) * sizeof(float)); + } + } else { + std::memset(y, 0, Y.total() * sizeof(float)); + } if (blobs.empty()) { const auto &B = inputs[1]; @@ -158,14 +252,36 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { inputs_arr.getUMatVector(inputs); outputs_arr.getUMatVector(outputs); - const auto &input_A = inputs[0]; - UMat input_B; - if (blobs.empty()) { - input_B = inputs[1]; - } else { - blobs[0].copyTo(input_B); + // does not support bias as input + if (inputs.size() >= 3) { + return false; } + + const auto &input_A = inputs[0]; auto &output = outputs[0]; + const auto output_shape = shape(output); + + if (blobs.empty()) { + weight_umat = inputs[1]; + if ((inputs.size() + blobs.size() >= 3)) { + bias_umat = UMat::zeros(output_shape.size(), output_shape.data(), CV_32F); + } + } else { + if (weight_umat.empty()) { + blobs.front().copyTo(weight_umat); + } + if ((inputs.size() + blobs.size() >= 3)) { + if (bias_umat.empty()) { + broadcast_bias.copyTo(bias_umat); + } + } else { + if (bias_umat.empty()) { + bias_umat = UMat::zeros(output_shape.size(), output_shape.data(), CV_32F); + } + } + } + + auto &input_B = weight_umat; int M = static_cast(helper.M), N = static_cast(helper.N), @@ -181,7 +297,7 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { UMat A, B, C, A_fp32, B_fp32, C_fp32; for (int i = 0; i < batch; i++) { A = input_A_2d.row(helper.A_rows[i]).reshape(1, trans_a ? K : M); - B = input_B_2d.row(helper.B_rows[i]).reshape(1, trans_b ? K : N); + B = input_B_2d.row(helper.B_rows[i]).reshape(1, trans_b ? N : K); C = output_2d.row(helper.C_rows[i]).reshape(1, M); if (trans_a) { @@ -200,7 +316,6 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { B_fp32 = B; C_fp32 = C; } - cv::gemm(A_fp32, B_fp32, 1.f, noArray(), 0.f, C_fp32); if (use_half) { A_fp32.convertTo(A, CV_16F); @@ -208,6 +323,12 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { C_fp32.convertTo(C, CV_16F); } } + + // add bias + if (!bias_umat.empty()) { + cv::add(output, bias_umat, output); + } + return true; } #endif // HAVE_OPENCL @@ -216,18 +337,28 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { virtual Ptr initNgraph(const std::vector >& inputs, const std::vector >& nodes) CV_OVERRIDE { auto& input_A_node = nodes[0].dynamicCast()->node; - std::shared_ptr matmul; + std::shared_ptr result; + ov::Output bias; - if (nodes.size() == 2) { + if (blobs.empty()) { auto &input_B_node = nodes[1].dynamicCast()->node; - matmul = std::make_shared(input_A_node, input_B_node, trans_a, trans_b); + result = std::make_shared(input_A_node, input_B_node, trans_a, trans_b); + if (nodes.size() >= 3) { + bias = nodes[2].dynamicCast()->node; + result = std::make_shared(result, bias); + } } else { auto input_B_shape = getShape(blobs[0]); auto input_B_node = std::make_shared(ov::element::f32, input_B_shape, blobs[0].data); - matmul = std::make_shared(input_A_node, input_B_node, trans_a, trans_b); + result = std::make_shared(input_A_node, input_B_node, trans_a, trans_b); + if ((nodes.size() + blobs.size()) >= 3) { + const auto bias_shape = shape(broadcast_bias); + bias = std::make_shared(ov::element::f32, std::vector(bias_shape.begin(), bias_shape.end()), broadcast_bias.data); + result = std::make_shared(result, bias); + } } - return Ptr(new InfEngineNgraphNode(matmul)); + return Ptr(new InfEngineNgraphNode(result)); } #endif // HAVE_DNN_NGRAPH @@ -239,7 +370,7 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { const auto input_A_shape = shape(*input_A_wrapper->getMat()); const auto output_shape = shape(*output_wrapper->getMat()); - if (output_shape.size() != 2) { + if ((inputs.size() + blobs.size()) >= 3 || output_shape.size() != 2) { return Ptr(); } @@ -259,11 +390,17 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { const std::vector>& inputs, const std::vector>& outputs) override { auto context = reinterpret_cast(context_); - auto input_B = blobs.empty() ? Mat() : blobs[0]; + auto input_B = Mat(), bias = Mat(); + if (!blobs.empty()) { + input_B = blobs.front(); + if (blobs.size() >= 2) { + bias = broadcast_bias; + } + } CV_CheckFalse(helper.empty(), "DNN/MatMul/CUDA: MatMulHelper is not initialized"); - return make_cuda_node(preferableTarget, std::move(context->stream), std::move(context->cublas_handle), input_B, trans_a, trans_b, helper.A_offsets, helper.B_offsets, helper.C_offsets, helper.batch); + return make_cuda_node(preferableTarget, std::move(context->stream), std::move(context->cublas_handle), input_B, bias, trans_a, trans_b, helper.A_offsets, helper.B_offsets, helper.C_offsets, helper.batch); } #endif // HAVE_CUDA @@ -275,7 +412,7 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { auto input_A_desc = input_A_wrapper->getTensorDesc(); auto input_A_node = nodes[0].dynamicCast()->getOp(); - auto op = std::make_shared(name); + auto op = std::make_shared(name); // set attributes op->set_attr_adj_x1(trans_a); @@ -292,11 +429,31 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { auto input_B_node = nodes[1].dynamicCast()->getOp(); op->set_input_x2_by_name(*input_B_node, "y"); op->update_input_desc_x2(*input_B_desc); + if (inputs.size() >= 3) { + auto input_bias_wrapper = inputs[2].dynamicCast(); + auto input_bias_desc = input_bias_wrapper->getTensorDesc(); + auto input_bias_node = nodes[2].dynamicCast()->getOp(); + op->set_input_bias_by_name(*input_bias_node, "y"); + op->update_input_desc_bias(*input_bias_desc); + } } else { // constant input B auto B = blobs[0]; auto const_B_node = std::make_shared(B.data, B.type(), shape(B), cv::format("%s_B", name.c_str())); op->set_input_x2_by_name(*(const_B_node->getOp()), "y"); op->update_input_desc_x2(*(const_B_node->getTensorDesc())); + if ((inputs.size() + blobs.size()) >= 3) { // does not support broadcast bias + auto bias_mat = blobs.back(); + auto bias_shape = shape(bias_mat); + + // reshape if 1d + if (real_ndims_C == 1 && bias_shape.front() != 1) { + bias_shape = std::vector{bias_shape.front()}; + } + + auto const_bias_node = std::make_shared(bias_mat.data, bias_mat.type(), bias_shape, cv::format("%s_bias", name.c_str())); + op->set_input_bias_by_name(*(const_bias_node->getOp()), "y"); + op->update_input_desc_bias(*(const_bias_node->getTensorDesc())); + } } // set outputs @@ -312,7 +469,10 @@ class MatMulLayerImpl CV_FINAL : public MatMulLayer { float alpha; float beta; + int real_ndims_C; + std::vector packed_input_B; + Mat broadcast_bias; FastGemmOpt opt; MatMulHelper helper; diff --git a/modules/dnn/src/onnx/onnx_graph_simplifier.cpp b/modules/dnn/src/onnx/onnx_graph_simplifier.cpp index 7b8dd483c7..a87910a4c4 100644 --- a/modules/dnn/src/onnx/onnx_graph_simplifier.cpp +++ b/modules/dnn/src/onnx/onnx_graph_simplifier.cpp @@ -242,6 +242,115 @@ class AdjustSliceAllOptionalInputsSubgraph : public Subgraph { size_t num_inputs_; }; +/* Fusion for biased MatMul. + + Graph before fusion: [Input] -> MatMul -> Add -> [Output] + + Graph after fusion: [Input] -> MatMul -> [Output] + \ + bias +*/ + +class BiasedMatmulSubgraph : public Subgraph { + public: + BiasedMatmulSubgraph() { + int input = addNodeToMatch(""); + matmul_id = addNodeToMatch("MatMul", input, addNodeToMatch("")); + add_id = addNodeToMatch("Add", addNodeToMatch(""), matmul_id); + + setFusedNode("MatMul", input); + } + + virtual bool match(const Ptr& net, int nodeId, + std::vector& matchedNodesIds) CV_OVERRIDE { + if (Subgraph::match(net, nodeId, matchedNodesIds)) { + auto onnx_net = net.dynamicCast(); + + // get input weight from MatMul + { + // make sure that input A is not Constant + if (onnx_net->getInputInitializerId(matchedNodesIds[matmul_id], 0) >= 0) { + return false; + } else { + const Ptr node = net->getNode(matchedNodesIds[matmul_id]); + + int constant_id = Subgraph::getInputNodeId(net, node, 0); + auto constant_node = net->getNode(constant_id); + if (constant_node->getType() == "Constant") { + return false; + } + } + + bool is_weight_const = false; + int initializer_id = onnx_net->getInputInitializerId(matchedNodesIds[matmul_id], 1); + if (initializer_id != -1) { // Initializer + weight_name = onnx_net->getNameOfInitializer(initializer_id); + is_weight_const = true; + } else { // Constant layer + const Ptr node = net->getNode(matchedNodesIds[matmul_id]); + + int constant_id = Subgraph::getInputNodeId(net, node, 1); + auto constant_node = net->getNode(constant_id); + if (constant_node->getType() == "Constant") { + weight_name = node->getInputName(1); + is_weight_const = true; + } + } + + if (!is_weight_const) { + return false; + } + } + + // get input bias from Add + { + bool is_bias_const = false; + int initializer_id = std::max(onnx_net->getInputInitializerId(matchedNodesIds[add_id], 0), + onnx_net->getInputInitializerId(matchedNodesIds[add_id], 1)); + if (initializer_id != -1) { + bias_name = onnx_net->getNameOfInitializer(initializer_id); + is_bias_const = true; + } else { // Constant layer + const Ptr node = net->getNode(matchedNodesIds[add_id]); + + int constant_id = Subgraph::getInputNodeId(net, node, 0); + auto constant_node = net->getNode(constant_id); + if (constant_node->getType() == "Constant") { + bias_name = node->getInputName(0); + is_bias_const = true; + } else { + constant_id = Subgraph::getInputNodeId(net, node, 1); + constant_node = net->getNode(constant_id); + if (constant_node->getType() == "Constant") { + bias_name = node->getInputName(1); + is_bias_const = true; + } + } + } + if (!is_bias_const) { + return false; + } + } + + return true; + } + return false; + } + + virtual void finalize(const Ptr& net, + const Ptr& fusedNode, + std::vector >&) CV_OVERRIDE { + opencv_onnx::NodeProto* node = fusedNode.dynamicCast()->node; + // add inputs + node->add_input(weight_name); + node->add_input(bias_name); + } + + private: + int matmul_id, add_id; + std::string weight_name, bias_name; +}; + /* The fusion for the multi-head attention from vision transformer. Abbreviations: @@ -322,22 +431,21 @@ class AttentionSubGraph : public Subgraph { AttentionSubGraph() { int input = addNodeToMatch(""); int transpose = addNodeToMatch("Transpose", input); // tranpose does not make any differences to the accuracy here in this subgraph - att_matmul = addNodeToMatch("MatMul", transpose, addNodeToMatch("")); - att_add = addNodeToMatch("Add", addNodeToMatch(""), att_matmul); + att_matmul = addNodeToMatch("MatMul", transpose, addNodeToMatch(""), addNodeToMatch("")); // add is fused into matmul via BiasedMatMulSubgraph // v_path - slice_v = addNodeToMatch("Slice", std::vector{att_add, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); + slice_v = addNodeToMatch("Slice", std::vector{att_matmul, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); int reshape_v = addNodeToMatch("Reshape", slice_v, addNodeToMatch("")); int transpose_v = addNodeToMatch("Transpose", reshape_v); // q_path - slice_q = addNodeToMatch("Slice", std::vector{att_add, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); + slice_q = addNodeToMatch("Slice", std::vector{att_matmul, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); reshape_q = addNodeToMatch("Reshape", slice_q, addNodeToMatch("")); int transpose_q = addNodeToMatch("Transpose", reshape_q); div_q = addNodeToMatch("Div", transpose_q, addNodeToMatch("")); // k_path - slice_k = addNodeToMatch("Slice", std::vector{att_add, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); + slice_k = addNodeToMatch("Slice", std::vector{att_matmul, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); int reshape_k = addNodeToMatch("Reshape", slice_k, addNodeToMatch("")); int transpose_k = addNodeToMatch("Transpose", reshape_k); @@ -380,7 +488,7 @@ class AttentionSubGraph : public Subgraph { // get names weight_name = getInputName(net, matchedNodesIds[att_matmul], 1); - bias_name = getInputName(net, matchedNodesIds[att_add], 0); + bias_name = getInputName(net, matchedNodesIds[att_matmul], 2); return true; } return false; @@ -414,7 +522,7 @@ class AttentionSubGraph : public Subgraph { } private: - int att_matmul, att_add; + int att_matmul; int slice_q, slice_k, slice_v; int reshape_q, div_q, last_reshape; @@ -436,20 +544,19 @@ class AttentionSingleHeadSubGraph : public Subgraph { AttentionSingleHeadSubGraph() { int input = addNodeToMatch(""); int transpose = addNodeToMatch("Transpose", input); // tranpose does not make any differences to the accuracy here in this subgraph - att_matmul = addNodeToMatch("MatMul", transpose, addNodeToMatch("")); - att_add = addNodeToMatch("Add", addNodeToMatch(""), att_matmul); + att_matmul = addNodeToMatch("MatMul", transpose, addNodeToMatch(""), addNodeToMatch("")); // add is fused into matmul via BiasedMatMulSubgraph // v_path - slice_v = addNodeToMatch("Slice", std::vector{att_add, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); + slice_v = addNodeToMatch("Slice", std::vector{att_matmul, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); int transpose_v = addNodeToMatch("Transpose", slice_v); // q_path - slice_q = addNodeToMatch("Slice", std::vector{att_add, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); + slice_q = addNodeToMatch("Slice", std::vector{att_matmul, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); int transpose_q = addNodeToMatch("Transpose", slice_q); div_q = addNodeToMatch("Div", transpose_q, addNodeToMatch("")); // k_path - slice_k = addNodeToMatch("Slice", std::vector{att_add, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); + slice_k = addNodeToMatch("Slice", std::vector{att_matmul, addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch(""), addNodeToMatch("")}); int transpose_k = addNodeToMatch("Transpose", slice_k); // qk @@ -491,7 +598,7 @@ class AttentionSingleHeadSubGraph : public Subgraph { // get names weight_name = getInputName(net, matchedNodesIds[att_matmul], 1); - bias_name = getInputName(net, matchedNodesIds[att_add], 0); + bias_name = getInputName(net, matchedNodesIds[att_matmul], 2); return true; } return false; @@ -525,7 +632,7 @@ class AttentionSingleHeadSubGraph : public Subgraph { } protected: - int att_matmul, att_add; + int att_matmul; int slice_q, slice_k, slice_v; int div_q, last_reshape; @@ -1558,6 +1665,7 @@ public: void simplifySubgraphs(opencv_onnx::GraphProto& net) { std::vector > subgraphs; + subgraphs.push_back(makePtr()); subgraphs.push_back(makePtr(3)); subgraphs.push_back(makePtr(4)); subgraphs.push_back(makePtr()); diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp index 997914c4cf..c8fb026d8d 100644 --- a/modules/dnn/src/onnx/onnx_importer.cpp +++ b/modules/dnn/src/onnx/onnx_importer.cpp @@ -1961,7 +1961,8 @@ void ONNXImporter::parseGemm(LayerParams& layerParams, const opencv_onnx::NodePr void ONNXImporter::parseMatMul(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto_) { auto node_proto = node_proto_; - CV_CheckEQ(node_proto.input_size(), 2, "ONNXImporter/MatMul: two inputs required"); + CV_CheckGE(node_proto.input_size(), 2, "ONNXImporter/MatMul: two inputs required at least"); + CV_CheckLE(node_proto.input_size(), 3, "ONNXImporter/MatMul: three inputs required at most"); for (int i = 0; i < node_proto.input_size(); i++) { if (constBlobs.find(node_proto.input(i)) == constBlobs.end()) { @@ -1970,9 +1971,7 @@ void ONNXImporter::parseMatMul(LayerParams& layerParams, const opencv_onnx::Node Mat blob = getBlob(node_proto, i); - if (i == 1) { - layerParams.blobs.push_back(blob); - } else { + if (i == 0) { LayerParams const_params; const_params.name = node_proto.input(i); const_params.type = "Const"; @@ -1983,6 +1982,12 @@ void ONNXImporter::parseMatMul(LayerParams& layerParams, const opencv_onnx::Node addLayer(const_params, const_node_proto); node_proto.set_input(i, const_params.name); + } else { + layerParams.blobs.push_back(blob); + } + + if (i == 2 && constBlobsExtraInfo.find(node_proto.input(2)) != constBlobsExtraInfo.end()) { + layerParams.set("real_ndims_C", getBlobExtraInfo(node_proto, 2).real_ndims); } } diff --git a/modules/dnn/test/test_graph_simplifier.cpp b/modules/dnn/test/test_graph_simplifier.cpp index 91b4e271f5..24da7e65b0 100644 --- a/modules/dnn/test/test_graph_simplifier.cpp +++ b/modules/dnn/test/test_graph_simplifier.cpp @@ -143,4 +143,11 @@ TEST_F(Test_Graph_Simplifier, AttentionSubgraph) { test("attention_single_head", "Attention"); } +TEST_F(Test_Graph_Simplifier, BiasedMatMulSubgraph) { + /* Test for 1 subgraphs + - BiasedMatMulSubgraph + */ + test("biased_matmul", "MatMul"); +} + }} diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index 4d475857e5..4b9229a11e 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -3090,6 +3090,12 @@ TEST_P(Test_ONNX_layers, LayerNormNoFusion) { testONNXModels("layer_norm_no_fusion"); } +TEST_P(Test_ONNX_layers, MatMulAddFusion) { + double l1 = (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL) ? 0.0018 : default_l1; + double lInf = (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL) ? 0.011 : default_lInf; + testONNXModels("biased_matmul", npy, l1, lInf); +} + INSTANTIATE_TEST_CASE_P(/**/, Test_ONNX_nets, dnnBackendsAndTargets()); }} // namespace From 912cf2a02809e1bff483932cee162524c6200894 Mon Sep 17 00:00:00 2001 From: Kumataro Date: Fri, 29 Mar 2024 23:38:06 +0900 Subject: [PATCH 53/56] Merge pull request #25280 from Kumataro:fix25274 imgcodecs: jpeg: re-support to read CMYK Jpeg #25280 Close #25274 OpenCV Extra: https://github.com/opencv/opencv_extra/pull/1163 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- modules/imgcodecs/src/grfmt_jpeg.cpp | 82 +++++++++++++++------------- modules/imgcodecs/test/test_jpeg.cpp | 38 +++++++++++++ 2 files changed, 81 insertions(+), 39 deletions(-) diff --git a/modules/imgcodecs/src/grfmt_jpeg.cpp b/modules/imgcodecs/src/grfmt_jpeg.cpp index 54dfea5a75..87187f131b 100644 --- a/modules/imgcodecs/src/grfmt_jpeg.cpp +++ b/modules/imgcodecs/src/grfmt_jpeg.cpp @@ -402,16 +402,12 @@ int my_jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht, bool JpegDecoder::readData( Mat& img ) { volatile bool result = false; - size_t step = img.step; - bool color = img.channels() > 1; + const bool color = img.channels() > 1; if( m_state && m_width && m_height ) { jpeg_decompress_struct* cinfo = &((JpegState*)m_state)->cinfo; JpegErrorMgr* jerr = &((JpegState*)m_state)->jerr; -#ifndef JCS_EXTENSIONS - JSAMPARRAY buffer = 0; -#endif if( setjmp( jerr->setjmp_buffer ) == 0 ) { @@ -431,29 +427,30 @@ bool JpegDecoder::readData( Mat& img ) } #endif -#ifdef JCS_EXTENSIONS - if( color ) - { - cinfo->out_color_space = JCS_EXT_BGR; - cinfo->out_color_components = 3; - } - else - { - cinfo->out_color_space = JCS_GRAYSCALE; - cinfo->out_color_components = 1; - } -#else + // See https://github.com/opencv/opencv/issues/25274 + // Conversion CMYK->BGR is not supported in libjpeg-turbo. + // So supporting both directly and indirectly is necessary. + bool doDirectRead = false; + if( color ) { if( cinfo->num_components != 4 ) { +#ifdef JCS_EXTENSIONS + cinfo->out_color_space = JCS_EXT_BGR; + cinfo->out_color_components = 3; + doDirectRead = true; // BGR -> BGR +#else cinfo->out_color_space = JCS_RGB; cinfo->out_color_components = 3; + doDirectRead = false; // RGB -> BGR +#endif } else { cinfo->out_color_space = JCS_CMYK; cinfo->out_color_components = 4; + doDirectRead = false; // CMYK -> BGR } } else @@ -462,14 +459,15 @@ bool JpegDecoder::readData( Mat& img ) { cinfo->out_color_space = JCS_GRAYSCALE; cinfo->out_color_components = 1; + doDirectRead = true; // GRAY -> GRAY } else { cinfo->out_color_space = JCS_CMYK; cinfo->out_color_components = 4; + doDirectRead = false; // CMYK -> GRAY } } -#endif // Check for Exif marker APP1 jpeg_saved_marker_ptr exif_marker = NULL; @@ -496,33 +494,39 @@ bool JpegDecoder::readData( Mat& img ) jpeg_start_decompress( cinfo ); -#ifndef JCS_EXTENSIONS - buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo, - JPOOL_IMAGE, m_width*4, 1 ); -#endif - - uchar* data = img.ptr(); - for( ; m_height--; data += step ) + if( doDirectRead) { -#ifdef JCS_EXTENSIONS - jpeg_read_scanlines( cinfo, &data, 1 ); -#else - jpeg_read_scanlines( cinfo, buffer, 1 ); - if( color ) + for( int iy = 0 ; iy < m_height; iy ++ ) { - if( cinfo->out_color_components == 3 ) - icvCvt_RGB2BGR_8u_C3R( buffer[0], 0, data, 0, Size(m_width,1) ); - else - icvCvt_CMYK2BGR_8u_C4C3R( buffer[0], 0, data, 0, Size(m_width,1) ); + uchar* data = img.ptr(iy); + jpeg_read_scanlines( cinfo, &data, 1 ); } - else + } + else + { + JSAMPARRAY buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo, + JPOOL_IMAGE, m_width*4, 1 ); + + for( int iy = 0 ; iy < m_height; iy ++ ) { - if( cinfo->out_color_components == 1 ) - memcpy( data, buffer[0], m_width ); + uchar* data = img.ptr(iy); + jpeg_read_scanlines( cinfo, buffer, 1 ); + + if( color ) + { + if( cinfo->out_color_components == 3 ) + icvCvt_RGB2BGR_8u_C3R( buffer[0], 0, data, 0, Size(m_width,1) ); + else + icvCvt_CMYK2BGR_8u_C4C3R( buffer[0], 0, data, 0, Size(m_width,1) ); + } else - icvCvt_CMYK2Gray_8u_C4C1R( buffer[0], 0, data, 0, Size(m_width,1) ); + { + if( cinfo->out_color_components == 1 ) + memcpy( data, buffer[0], m_width ); + else + icvCvt_CMYK2Gray_8u_C4C1R( buffer[0], 0, data, 0, Size(m_width,1) ); + } } -#endif } result = true; diff --git a/modules/imgcodecs/test/test_jpeg.cpp b/modules/imgcodecs/test/test_jpeg.cpp index b7932a0020..9d1db923d5 100644 --- a/modules/imgcodecs/test/test_jpeg.cpp +++ b/modules/imgcodecs/test/test_jpeg.cpp @@ -178,6 +178,44 @@ TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg) EXPECT_EQ(0, remove(output_normal.c_str())); } +// See https://github.com/opencv/opencv/issues/25274 +typedef testing::TestWithParam Imgcodecs_Jpeg_decode_cmyk; +TEST_P(Imgcodecs_Jpeg_decode_cmyk, regression25274) +{ + const int imread_flag = GetParam(); + + /* + * "test_1_c4.jpg" is CMYK-JPEG. + * $ convert test_1_c3.jpg -colorspace CMYK test_1_c4.jpg + * $ identify test_1_c4.jpg + * test_1_c4.jpg JPEG 480x640 480x640+0+0 8-bit CMYK 11240B 0.000u 0:00.000 + */ + + cvtest::TS& ts = *cvtest::TS::ptr(); + + string rgb_filename = string(ts.get_data_path()) + "readwrite/test_1_c3.jpg"; + cv::Mat rgb_img = cv::imread(rgb_filename, imread_flag); + ASSERT_FALSE(rgb_img.empty()); + + string cmyk_filename = string(ts.get_data_path()) + "readwrite/test_1_c4.jpg"; + cv::Mat cmyk_img = cv::imread(cmyk_filename, imread_flag); + ASSERT_FALSE(cmyk_img.empty()); + + EXPECT_EQ(rgb_img.size(), cmyk_img.size()); + EXPECT_EQ(rgb_img.type(), cmyk_img.type()); + + // Jpeg is lossy compression. + // There may be small differences in decoding results by environments. + // -> 255 * 1% = 2.55 . + EXPECT_EQ(3, cvtest::norm(rgb_img, cmyk_img, NORM_INF)); +} + +INSTANTIATE_TEST_CASE_P( /* nothing */, + Imgcodecs_Jpeg_decode_cmyk, + testing::Values(cv::IMREAD_COLOR, + cv::IMREAD_GRAYSCALE, + cv::IMREAD_ANYCOLOR)); + //================================================================================================== static const uint32_t default_sampling_factor = static_cast(0x221111); From 9c8606e0c05a818a38c888883fabe53f41f6490e Mon Sep 17 00:00:00 2001 From: Kumataro Date: Sat, 30 Mar 2024 13:49:08 +0900 Subject: [PATCH 54/56] imgcodecs: jpeg: fix condition to compare rgb and cmyk jpeg --- modules/imgcodecs/test/test_jpeg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/imgcodecs/test/test_jpeg.cpp b/modules/imgcodecs/test/test_jpeg.cpp index 9d1db923d5..12abc0a8e3 100644 --- a/modules/imgcodecs/test/test_jpeg.cpp +++ b/modules/imgcodecs/test/test_jpeg.cpp @@ -207,7 +207,7 @@ TEST_P(Imgcodecs_Jpeg_decode_cmyk, regression25274) // Jpeg is lossy compression. // There may be small differences in decoding results by environments. // -> 255 * 1% = 2.55 . - EXPECT_EQ(3, cvtest::norm(rgb_img, cmyk_img, NORM_INF)); + EXPECT_LE(cvtest::norm(rgb_img, cmyk_img, NORM_INF), 3); // norm() <= 3 } INSTANTIATE_TEST_CASE_P( /* nothing */, From eba158fb0c68b98d785746a4538a54253fcbddac Mon Sep 17 00:00:00 2001 From: HAN Liutong Date: Sun, 31 Mar 2024 21:47:06 +0800 Subject: [PATCH 55/56] Merge pull request #25230 from hanliutong/rvv-conv Optimize int8 layers in DNN modules by using RISC-V Vector intrinsic. #25230 This patch optimize 3 functions in the int8 layer by using RVV Native Intrinsic. This patch was tested on QEMU using VLEN=128 and VLEN=256 on `./bin/opencv_test_dnn --gtest_filter="*Int8*"`; On the real device (k230, VLEN=128), `EfficientDet_int8` in `opencv_perf_dnn` showed a performance improvement of 1.46x. | Name of Test | Original | optimized | Speed-up | | ------------------------------------------ | -------- | ---------- | -------- | | EfficientDet_int8::DNNTestNetwork::OCV/CPU | 2843.467 | 1947.013 | 1.46 | ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [ ] I agree to contribute to the project under Apache 2 License. - [ ] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/dnn/CMakeLists.txt | 2 +- .../dnn/src/int8layers/convolution_layer.cpp | 17 +- .../src/int8layers/fully_connected_layer.cpp | 9 +- .../dnn/src/int8layers/layers_common.simd.hpp | 435 ++++++++++++++++++ 4 files changed, 460 insertions(+), 3 deletions(-) diff --git a/modules/dnn/CMakeLists.txt b/modules/dnn/CMakeLists.txt index 562b14483c..3b66b460d9 100644 --- a/modules/dnn/CMakeLists.txt +++ b/modules/dnn/CMakeLists.txt @@ -5,7 +5,7 @@ endif() set(the_description "Deep neural network module. It allows to load models from different frameworks and to make forward pass") ocv_add_dispatched_file_force_all("layers/layers_common" AVX AVX2 AVX512_SKX RVV LASX) -ocv_add_dispatched_file_force_all("int8layers/layers_common" AVX2 AVX512_SKX LASX) +ocv_add_dispatched_file_force_all("int8layers/layers_common" AVX2 AVX512_SKX RVV LASX) ocv_add_dispatched_file_force_all("layers/cpu_kernels/conv_block" AVX AVX2 NEON NEON_FP16) ocv_add_dispatched_file_force_all("layers/cpu_kernels/conv_depthwise" AVX AVX2 RVV LASX) ocv_add_dispatched_file_force_all("layers/cpu_kernels/conv_winograd_f63" AVX AVX2 NEON_FP16) diff --git a/modules/dnn/src/int8layers/convolution_layer.cpp b/modules/dnn/src/int8layers/convolution_layer.cpp index 603100ae11..25132542cd 100644 --- a/modules/dnn/src/int8layers/convolution_layer.cpp +++ b/modules/dnn/src/int8layers/convolution_layer.cpp @@ -702,13 +702,14 @@ public: bool useAVX2; bool useAVX512; bool useLASX; + bool useRVV; int blk_size_cn; int inpZp, outZp; const std::vector* multiplier; ParallelConv() : input_(0), weights_(0), output_(0), ngroups_(0), nstripes_(0), - biasvec_(0), activLUT_(0), activ_(0), is1x1_(false), useAVX2(false), useAVX512(false), useLASX(false) + biasvec_(0), activLUT_(0), activ_(0), is1x1_(false), useAVX2(false), useAVX512(false), useLASX(false), useRVV(false) , blk_size_cn(0), inpZp(0), outZp(0), multiplier(0) {} @@ -765,6 +766,7 @@ public: p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX512_SKX && isConv2D; p.useLASX = checkHardwareSupport(CPU_LASX) && isConv2D; + p.useRVV = checkHardwareSupport(CPU_RVV) && isConv2D; int kernel_d = isConv3D? kernel_size[0] : 1; int kernel_h = isConv1D? 1 : kernel_size[kernel_size.size() - 2]; @@ -970,6 +972,13 @@ public: biasptr, multptr, inptr_, height, width, outptr_, out_d, outH, outW, inpZp, outZp); else #endif + #if CV_TRY_RVV && defined(__riscv_v_intrinsic) && __riscv_v_intrinsic>=11000 + if(useRVV) + opt_RVV::fastDepthwiseConv(wptr, kernel_h, kernel_w, + stride_h, stride_w, dilation_h, dilation_w, pad_t, pad_l, + biasptr, multptr, inptr_, height, width, outptr_, out_d, outH, outW, inpZp, outZp); + else + #endif #if CV_RVP052 if(isConv2D) opt_RVP052::fastDepthwiseConv(wptr, kernel_h, kernel_w, @@ -1356,6 +1365,12 @@ public: outShape, bsz, vsz, vsz_a, outZp, multptr, cn0 == 0, cn1 == inpCn); else #endif + #if CV_TRY_RVV && defined(__riscv_v_intrinsic) && __riscv_v_intrinsic>=11000 + if(useRVV) + opt_RVV::fastConv(wptr, wstep, biasptr, rowbuf0, data_out0 + ofs0, + outShape, bsz, vsz, vsz_a, outZp, multptr, cn0 == 0, cn1 == inpCn); + else + #endif #if CV_RVP052 if(isConv2D) opt_RVP052::fastConv(wptr, wstep, biasptr, rowbuf0, data_out0 + ofs0, diff --git a/modules/dnn/src/int8layers/fully_connected_layer.cpp b/modules/dnn/src/int8layers/fully_connected_layer.cpp index 6691128990..105b2dbaac 100644 --- a/modules/dnn/src/int8layers/fully_connected_layer.cpp +++ b/modules/dnn/src/int8layers/fully_connected_layer.cpp @@ -228,7 +228,7 @@ public: { public: FullyConnected() : srcMat(0), weights(0), biasMat(0), outputMultiplier(0), activationLUT(0), activ(0), - dstMat(0), nstripes(0), outZp(0), useAVX2(false), useAVX512(false), useLASX(false) {} + dstMat(0), nstripes(0), outZp(0), useAVX2(false), useAVX512(false), useLASX(false), useRVV(false) {} static void run(const Mat& srcMat, const Mat& weights, const Mat& biasMat, const Mat& outputMultiplier, const Mat& activationLUT, Mat& dstMat, const ActivationLayerInt8* activ, int nstripes, int outZp) @@ -253,6 +253,7 @@ public: p.useAVX2 = checkHardwareSupport(CPU_AVX2); p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX512_SKX; p.useLASX = checkHardwareSupport(CPU_LASX); + p.useRVV = checkHardwareSupport(CPU_RVV); parallel_for_(Range(0, nstripes), p, nstripes); } @@ -303,6 +304,11 @@ public: opt_LASX::fastGEMM1T( sptr, wptr, wstep, biasptr, multptr, dptr, nw, vecsize, outZp ); else #endif + #if CV_TRY_RVV && defined(__riscv_v_intrinsic) && __riscv_v_intrinsic>=11000 + if( useRVV) + opt_RVV::fastGEMM1T( sptr, wptr, wstep, biasptr, multptr, dptr, nw, vecsize, outZp ); + else + #endif #if CV_RVP052 if( 1 ) opt_RVP052::fastGEMM1T( sptr, wptr, wstep, biasptr, multptr, dptr, nw, vecsize, outZp ); @@ -363,6 +369,7 @@ public: bool useAVX2; bool useAVX512; bool useLASX; + bool useRVV; }; void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE diff --git a/modules/dnn/src/int8layers/layers_common.simd.hpp b/modules/dnn/src/int8layers/layers_common.simd.hpp index 1b3ac7a4b8..7f9dca505e 100644 --- a/modules/dnn/src/int8layers/layers_common.simd.hpp +++ b/modules/dnn/src/int8layers/layers_common.simd.hpp @@ -1257,5 +1257,440 @@ void fastGEMM1T( const int8_t* vec, const int8_t* weights, } #endif // CV_LASX +#if !defined(CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY) && CV_RVV && defined(__riscv_v_intrinsic) && __riscv_v_intrinsic>=11000 + +static const size_t __cv_rvv_e8m1_max = __riscv_vsetvlmax_e8m1(); +static const size_t __cv_rvv_e16m1_max = __riscv_vsetvlmax_e16m1(); +static const size_t __cv_rvv_e32m2_max = __riscv_vsetvlmax_e32m2(); + +inline vint32m2_t __riscv_vwmacc_vv_i32m2(vint32m2_t& dst, const vint8m1_t& a, const vint8m1_t& b, size_t vl) { + vint16m2_t tmp = __riscv_vwmul(a, b, vl); + dst = __riscv_vwadd_wv_i32m2_tu(dst, dst, __riscv_vget_i16m1(tmp, 0), vl); + dst = __riscv_vwadd_wv_i32m2_tu(dst, dst, __riscv_vget_i16m1(tmp, 1), vl > __cv_rvv_e16m1_max ? vl - __cv_rvv_e16m1_max : 0); + return dst; +} + +enum { FASCONV_BASE_VECSZ = 4 }; +void fastConv( const int8_t* weights, size_t wstep, const int* bias, + const int8_t* rowbuf, int* output, const int* outShape, + int blockSize, int vecsize, int vecsize_aligned, int outZp, + const float* multiplier, bool initOutput, bool finalOutput ) +{ + const size_t e8m1 = __cv_rvv_e8m1_max; + int outCn = outShape[1]; + size_t outPlaneSize = outShape[2]*outShape[3]; + // now compute dot product of the weights + // and im2row-transformed part of the tensor + for( int i = 0; i < outCn; i += 3 ) + { + int unroll_tail = FASCONV_BASE_VECSZ; + const int8_t* wptr0 = weights + i*wstep; + const int8_t* wptr1 = wptr0 + wstep; + const int8_t* wptr2 = wptr1 + wstep; + int* outptr0 = output + i*outPlaneSize; + int* outptr1 = outptr0 + outPlaneSize; + int* outptr2 = outptr1 + outPlaneSize; + int bias0 = bias[i], bias1 = bias[i+1], bias2 = bias[i+2]; + float mult0 = multiplier[i], mult1 = multiplier[i+1], mult2 = multiplier[i+2]; + + if( i+2 >= outCn ) + { + wptr2 = wptr1; + outptr2 = outptr1; + bias2 = bias1; + mult2 = mult1; + if( i+1 >= outCn ) + { + wptr2 = wptr1 = wptr0; + outptr2 = outptr1 = outptr0; + bias2 = bias1 = bias0; + mult2 = mult1 = mult0; + } + } + + int j = 0; + for( ; j < blockSize; j += FASCONV_BASE_VECSZ ) + { + const int8_t* rptr = rowbuf + j*vecsize_aligned; + const int8_t *rptr1 = rptr + vecsize_aligned*1, + *rptr2 = rptr + vecsize_aligned*2, + *rptr3 = rptr + vecsize_aligned*3; + + if (j + FASCONV_BASE_VECSZ > blockSize) + { + unroll_tail = blockSize - j; + rptr1 = rptr + vecsize_aligned*std::min(1, unroll_tail-1); + rptr2 = rptr + vecsize_aligned*std::min(2, unroll_tail-1); + rptr3 = rptr + vecsize_aligned*std::min(3, unroll_tail-1); + } + + int vl, avl = vecsize; + + vint32m2_t + vs00 = __riscv_vmv_v_x_i32m2(0, e8m1), vs10 = __riscv_vmv_v_x_i32m2(0, e8m1), vs20 = __riscv_vmv_v_x_i32m2(0, e8m1), + vs01 = __riscv_vmv_v_x_i32m2(0, e8m1), vs11 = __riscv_vmv_v_x_i32m2(0, e8m1), vs21 = __riscv_vmv_v_x_i32m2(0, e8m1), + vs02 = __riscv_vmv_v_x_i32m2(0, e8m1), vs12 = __riscv_vmv_v_x_i32m2(0, e8m1), vs22 = __riscv_vmv_v_x_i32m2(0, e8m1), + vs03 = __riscv_vmv_v_x_i32m2(0, e8m1), vs13 = __riscv_vmv_v_x_i32m2(0, e8m1), vs23 = __riscv_vmv_v_x_i32m2(0, e8m1); + for (int k = 0; k < vecsize; k += vl, avl -= vl) + { + vl = __riscv_vsetvl_e8m1(avl); + + vint8m1_t w0 = (__riscv_vle8_v_i8m1(wptr0 + k, vl)); + vint8m1_t w1 = (__riscv_vle8_v_i8m1(wptr1 + k, vl)); + vint8m1_t w2 = (__riscv_vle8_v_i8m1(wptr2 + k, vl)); + vint8m1_t r0 = (__riscv_vle8_v_i8m1(rptr, vl)); + + + vs00 = __riscv_vwmacc_vv_i32m2(vs00, w0, r0, vl); + vs10 = __riscv_vwmacc_vv_i32m2(vs10, w1, r0, vl); + vs20 = __riscv_vwmacc_vv_i32m2(vs20, w2, r0, vl); + + r0 = (__riscv_vle8_v_i8m1(rptr1, vl)); + vs01 = __riscv_vwmacc_vv_i32m2(vs01, w0, r0, vl); + vs11 = __riscv_vwmacc_vv_i32m2(vs11, w1, r0, vl); + vs21 = __riscv_vwmacc_vv_i32m2(vs21, w2, r0, vl); + + r0 = (__riscv_vle8_v_i8m1(rptr2, vl)); + vs02 = __riscv_vwmacc_vv_i32m2(vs02, w0, r0, vl); + vs12 = __riscv_vwmacc_vv_i32m2(vs12, w1, r0, vl); + vs22 = __riscv_vwmacc_vv_i32m2(vs22, w2, r0, vl); + + r0 = (__riscv_vle8_v_i8m1(rptr3, vl)); + vs03 = __riscv_vwmacc_vv_i32m2(vs03, w0, r0, vl); + vs13 = __riscv_vwmacc_vv_i32m2(vs13, w1, r0, vl); + vs23 = __riscv_vwmacc_vv_i32m2(vs23, w2, r0, vl); + + rptr += vl; rptr1 += vl; rptr2 += vl; rptr3 += vl; + } + + // compute sum of each vs + vint32m1_t zero = __riscv_vmv_v_x_i32m1(0, e8m1); + int sum0[FASCONV_BASE_VECSZ], sum1[FASCONV_BASE_VECSZ], sum2[FASCONV_BASE_VECSZ]; + + sum0[0] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs00, zero, e8m1)); + sum0[1] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs01, zero, e8m1)); + sum0[2] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs02, zero, e8m1)); + sum0[3] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs03, zero, e8m1)); + + sum1[0] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs10, zero, e8m1)); + sum1[1] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs11, zero, e8m1)); + sum1[2] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs12, zero, e8m1)); + sum1[3] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs13, zero, e8m1)); + + sum2[0] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs20, zero, e8m1)); + sum2[1] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs21, zero, e8m1)); + sum2[2] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs22, zero, e8m1)); + sum2[3] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs23, zero, e8m1)); + + vint32m1_t s0, s1, s2; + if( initOutput ) + { + s0 = __riscv_vmv_v_x_i32m1(bias0, unroll_tail); + s1 = __riscv_vmv_v_x_i32m1(bias1, unroll_tail); + s2 = __riscv_vmv_v_x_i32m1(bias2, unroll_tail); + } + else + { + s0 = __riscv_vle32_v_i32m1(outptr0 + j, unroll_tail); + s1 = __riscv_vle32_v_i32m1(outptr1 + j, unroll_tail); + s2 = __riscv_vle32_v_i32m1(outptr2 + j, unroll_tail); + } + s0 = __riscv_vadd(__riscv_vle32_v_i32m1(sum0, unroll_tail), s0, unroll_tail); + s1 = __riscv_vadd(__riscv_vle32_v_i32m1(sum1, unroll_tail), s1, unroll_tail); + s2 = __riscv_vadd(__riscv_vle32_v_i32m1(sum2, unroll_tail), s2, unroll_tail); + + if( finalOutput ) + { + s0 = __riscv_vadd(__riscv_vfcvt_x_f_v_i32m1(__riscv_vfmul(__riscv_vfcvt_f_x_v_f32m1(s0, unroll_tail), mult0, unroll_tail), unroll_tail), outZp, unroll_tail); + s1 = __riscv_vadd(__riscv_vfcvt_x_f_v_i32m1(__riscv_vfmul(__riscv_vfcvt_f_x_v_f32m1(s1, unroll_tail), mult1, unroll_tail), unroll_tail), outZp, unroll_tail); + s2 = __riscv_vadd(__riscv_vfcvt_x_f_v_i32m1(__riscv_vfmul(__riscv_vfcvt_f_x_v_f32m1(s2, unroll_tail), mult2, unroll_tail), unroll_tail), outZp, unroll_tail); + + s0 = __riscv_vmin(__riscv_vmax(s0, -128, unroll_tail), 127, unroll_tail); + s1 = __riscv_vmin(__riscv_vmax(s1, -128, unroll_tail), 127, unroll_tail); + s2 = __riscv_vmin(__riscv_vmax(s2, -128, unroll_tail), 127, unroll_tail); + } + + __riscv_vse32(outptr0 + j, s0, unroll_tail); + __riscv_vse32(outptr1 + j, s1, unroll_tail); + __riscv_vse32(outptr2 + j, s2, unroll_tail); + } + } +} + +void fastDepthwiseConv( const int8_t* wptr, + int kernel_h, int kernel_w, + int stride_h, int stride_w, + int dilation_h, int dilation_w, + int pad_t, int pad_l, + const int* biasptr, const float* multptr, + const int8_t* inptr_, + int height, int width, + int* outptr_, + int out_d, int outH, int outW, + int inpZp, int outZp) +{ + int vl; + const int8_t w00_ = wptr[0], w01_ = wptr[1], w02_ = wptr[2], + w10 = wptr[3], w11 = wptr[4], w12 = wptr[5], + w20_ = wptr[6], w21_ = wptr[7], w22_ = wptr[8]; + int outW1 = std::min(outW, (width - dilation_w*(kernel_w - 1) + pad_l)/stride_w); + float mult = multptr[out_d]; + int bias = biasptr[out_d]; + int biasCopy; + + for (int out_i = 0; out_i < outH; out_i++) + { + int in_i = out_i * stride_h - pad_t, out_j = 0; + const int8_t* imgptr0 = inptr_ + in_i*width; + const int8_t* imgptr1 = imgptr0 + dilation_h*width; + const int8_t* imgptr2 = imgptr0 + (dilation_h*2)*width; + int8_t w00 = w00_, w01 = w01_, w02 = w02_; + int8_t w20 = w20_, w21 = w21_, w22 = w22_; + int out, out1; + biasCopy = bias; + if (in_i < 0) + { + biasCopy += inpZp * (w00 + w01 + w02); + w00 = w01 = w02 = 0; + imgptr0 = imgptr1; + } + else if (in_i + dilation_h*(kernel_h-1) >= height) + { + biasCopy += inpZp * (w20 + w21 + w22); + w20 = w21 = w22 = 0; + imgptr2 = imgptr1; + } + int* outptr = outptr_ + out_i*outW; + if (pad_l > 0) + { + out = (int)imgptr0[0]*w01 + (int)imgptr0[dilation_w]*w02 + + (int)imgptr1[0]*w11 + (int)imgptr1[dilation_w]*w12 + + (int)imgptr2[0]*w21 + (int)imgptr2[dilation_w]*w22 + + biasCopy + inpZp*(w00 + w10 + w20); + out1 = outZp + (int)std::round(out*mult); + outptr[0] = std::min(std::max(out1, -128), 127); + out_j = 1; + } + if (stride_w == 1 || (stride_w == 2 && dilation_w == 1)) + { + int avl = outW1 - out_j; + if( stride_w == 1 ) + for( ; out_j < outW1; out_j += vl, avl -= vl) + { + vl = __riscv_vsetvl_e8m2(avl); + int in_j = out_j * stride_w - pad_l; + + vint32m8_t vout = __riscv_vmv_v_x_i32m8(biasCopy, vl); + vout = __riscv_vwmacc(vout, w00, __riscv_vwcvt_x_x_v_i16m4(__riscv_vle8_v_i8m2(imgptr0 + in_j , vl), vl), vl); + vout = __riscv_vwmacc(vout, w01, __riscv_vwcvt_x_x_v_i16m4(__riscv_vle8_v_i8m2(imgptr0 + in_j + dilation_w , vl), vl), vl); + vout = __riscv_vwmacc(vout, w02, __riscv_vwcvt_x_x_v_i16m4(__riscv_vle8_v_i8m2(imgptr0 + in_j + dilation_w*2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w10, __riscv_vwcvt_x_x_v_i16m4(__riscv_vle8_v_i8m2(imgptr1 + in_j , vl), vl), vl); + vout = __riscv_vwmacc(vout, w11, __riscv_vwcvt_x_x_v_i16m4(__riscv_vle8_v_i8m2(imgptr1 + in_j + dilation_w , vl), vl), vl); + vout = __riscv_vwmacc(vout, w12, __riscv_vwcvt_x_x_v_i16m4(__riscv_vle8_v_i8m2(imgptr1 + in_j + dilation_w*2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w20, __riscv_vwcvt_x_x_v_i16m4(__riscv_vle8_v_i8m2(imgptr2 + in_j , vl), vl), vl); + vout = __riscv_vwmacc(vout, w21, __riscv_vwcvt_x_x_v_i16m4(__riscv_vle8_v_i8m2(imgptr2 + in_j + dilation_w , vl), vl), vl); + vout = __riscv_vwmacc(vout, w22, __riscv_vwcvt_x_x_v_i16m4(__riscv_vle8_v_i8m2(imgptr2 + in_j + dilation_w*2, vl), vl), vl); + + vout = __riscv_vfcvt_x(__riscv_vfmul(__riscv_vfcvt_f_x_v_f32m8(vout, vl), mult, vl), vl); + vout = __riscv_vadd(vout, outZp, vl); + vout = __riscv_vmin(__riscv_vmax(vout, -128, vl), 127, vl); + + __riscv_vse32_v_i32m8(outptr + out_j, vout, vl); + + } + else //stride_w == 2 && dilation_w == 1; + { + for( ; out_j < outW1; out_j += vl, avl -= vl) + { + vl = __riscv_vsetvl_e8m2(avl); + int in_j = out_j * stride_w - pad_l; + + vint32m8_t vout = __riscv_vmv_v_x_i32m8(biasCopy, vl); + + vout = __riscv_vwmacc(vout, w00, __riscv_vwcvt_x_x_v_i16m4(__riscv_vlse8_v_i8m2(imgptr0+in_j , 2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w01, __riscv_vwcvt_x_x_v_i16m4(__riscv_vlse8_v_i8m2(imgptr0+in_j+1, 2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w02, __riscv_vwcvt_x_x_v_i16m4(__riscv_vlse8_v_i8m2(imgptr0+in_j+2, 2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w10, __riscv_vwcvt_x_x_v_i16m4(__riscv_vlse8_v_i8m2(imgptr1+in_j , 2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w11, __riscv_vwcvt_x_x_v_i16m4(__riscv_vlse8_v_i8m2(imgptr1+in_j+1, 2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w12, __riscv_vwcvt_x_x_v_i16m4(__riscv_vlse8_v_i8m2(imgptr1+in_j+2, 2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w20, __riscv_vwcvt_x_x_v_i16m4(__riscv_vlse8_v_i8m2(imgptr2+in_j , 2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w21, __riscv_vwcvt_x_x_v_i16m4(__riscv_vlse8_v_i8m2(imgptr2+in_j+1, 2, vl), vl), vl); + vout = __riscv_vwmacc(vout, w22, __riscv_vwcvt_x_x_v_i16m4(__riscv_vlse8_v_i8m2(imgptr2+in_j+2, 2, vl), vl), vl); + + vout = __riscv_vfcvt_x(__riscv_vfmul(__riscv_vfcvt_f_x_v_f32m8(vout, vl), mult, vl), vl); + vout = __riscv_vadd(vout, outZp, vl); + vout = __riscv_vmin(__riscv_vmax(vout, -128, vl), 127, vl); + + __riscv_vse32_v_i32m8(outptr + out_j, vout, vl); + } + } + } + + for (; out_j < outW1; out_j++) + { + int in_j = out_j * stride_w - pad_l; + out = (int)imgptr0[in_j]*w00 + (int)imgptr0[in_j + dilation_w]*w01 + (int)imgptr0[in_j + dilation_w*2]*w02 + + (int)imgptr1[in_j]*w10 + (int)imgptr1[in_j + dilation_w]*w11 + (int)imgptr1[in_j + dilation_w*2]*w12 + + (int)imgptr2[in_j]*w20 + (int)imgptr2[in_j + dilation_w]*w21 + (int)imgptr2[in_j + dilation_w*2]*w22 + biasCopy; + outptr[out_j] = std::min(std::max(outZp + (int)std::round(out*mult), -128), 127); + } + + for (; out_j < outW; out_j++ ) + { + int in_j0 = out_j * stride_w - pad_l, in_j1 = in_j0 + dilation_w, in_j2 = in_j0 + dilation_w*2; + int s0 = 1, s1 = 1, s2 = 1; + if (in_j0 >= width) + { + in_j0 = 0; + s0 = 0; + biasCopy += inpZp*(w00 + w10 + w20); + } + if (in_j1 >= width) + { + in_j1 = 0; + s1 = 0; + biasCopy += inpZp*(w01 + w11 + w21); + } + if (in_j2 >= width) + { + in_j2 = 0; + s2 = 0; + biasCopy += inpZp*(w02 + w12 + w22); + } + out = (int)imgptr0[in_j0]*w00*s0 + (int)imgptr0[in_j1]*w01*s1 + (int)imgptr0[in_j2]*w02*s2 + + (int)imgptr1[in_j0]*w10*s0 + (int)imgptr1[in_j1]*w11*s1 + (int)imgptr1[in_j2]*w12*s2 + + (int)imgptr2[in_j0]*w20*s0 + (int)imgptr2[in_j1]*w21*s1 + (int)imgptr2[in_j2]*w22*s2 + biasCopy; + outptr[out_j] = std::min(std::max(outZp + (int)std::round(out*mult), -128), 127); + } + } +} + +void fastGEMM1T( const int8_t* vec, const int8_t* weights, + size_t wstep, const int* bias, const float* multiplier, + int* dst, int nvecs, int vecsize, int outZp ) +{ + int i = 0; + for( ; i <= nvecs - 15; i += 15 ) + { + const int8_t* wptr = weights + i*wstep; + vint32m2_t + vs0 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs1 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs2 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs3 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs4 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs5 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs6 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs7 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs8 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs9 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs10 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs11 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs12 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs13 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs14 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max); + int avl = vecsize, vl; + for(int k = 0 ; k < vecsize; k += vl, wptr += vl, avl -= vl) + { + vl = __riscv_vsetvl_e8m1(avl); + vint8m1_t v = __riscv_vle8_v_i8m1(vec + k, vl); + + vs0 = __riscv_vwmacc_vv_i32m2(vs0, __riscv_vle8_v_i8m1(wptr, vl), v, vl); + vs1 = __riscv_vwmacc_vv_i32m2(vs1, __riscv_vle8_v_i8m1(wptr + wstep, vl), v, vl); + vs2 = __riscv_vwmacc_vv_i32m2(vs2, __riscv_vle8_v_i8m1(wptr + wstep*2, vl), v, vl); + vs3 = __riscv_vwmacc_vv_i32m2(vs3, __riscv_vle8_v_i8m1(wptr + wstep*3, vl), v, vl); + vs4 = __riscv_vwmacc_vv_i32m2(vs4, __riscv_vle8_v_i8m1(wptr + wstep*4, vl), v, vl); + vs5 = __riscv_vwmacc_vv_i32m2(vs5, __riscv_vle8_v_i8m1(wptr + wstep*5, vl), v, vl); + vs6 = __riscv_vwmacc_vv_i32m2(vs6, __riscv_vle8_v_i8m1(wptr + wstep*6, vl), v, vl); + vs7 = __riscv_vwmacc_vv_i32m2(vs7, __riscv_vle8_v_i8m1(wptr + wstep*7, vl), v, vl); + vs8 = __riscv_vwmacc_vv_i32m2(vs8, __riscv_vle8_v_i8m1(wptr + wstep*8, vl), v, vl); + vs9 = __riscv_vwmacc_vv_i32m2(vs9, __riscv_vle8_v_i8m1(wptr + wstep*9, vl), v, vl); + vs10 = __riscv_vwmacc_vv_i32m2(vs10, __riscv_vle8_v_i8m1(wptr + wstep*10, vl), v, vl); + vs11 = __riscv_vwmacc_vv_i32m2(vs11, __riscv_vle8_v_i8m1(wptr + wstep*11, vl), v, vl); + vs12 = __riscv_vwmacc_vv_i32m2(vs12, __riscv_vle8_v_i8m1(wptr + wstep*12, vl), v, vl); + vs13 = __riscv_vwmacc_vv_i32m2(vs13, __riscv_vle8_v_i8m1(wptr + wstep*13, vl), v, vl); + vs14 = __riscv_vwmacc_vv_i32m2(vs14, __riscv_vle8_v_i8m1(wptr + wstep*14, vl), v, vl); + } + + int sum[15]; + vint32m1_t zero = __riscv_vmv_v_x_i32m1(0, __cv_rvv_e32m2_max); + sum[0] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs0, zero, __cv_rvv_e32m2_max)); + sum[1] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs1, zero, __cv_rvv_e32m2_max)); + sum[2] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs2, zero, __cv_rvv_e32m2_max)); + sum[3] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs3, zero, __cv_rvv_e32m2_max)); + sum[4] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs4, zero, __cv_rvv_e32m2_max)); + sum[5] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs5, zero, __cv_rvv_e32m2_max)); + sum[6] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs6, zero, __cv_rvv_e32m2_max)); + sum[7] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs7, zero, __cv_rvv_e32m2_max)); + sum[8] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs8, zero, __cv_rvv_e32m2_max)); + sum[9] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs9, zero, __cv_rvv_e32m2_max)); + sum[10] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs10, zero, __cv_rvv_e32m2_max)); + sum[11] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs11, zero, __cv_rvv_e32m2_max)); + sum[12] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs12, zero, __cv_rvv_e32m2_max)); + sum[13] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs13, zero, __cv_rvv_e32m2_max)); + sum[14] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs14, zero, __cv_rvv_e32m2_max)); + + vint32m4_t s0 = __riscv_vadd(__riscv_vle32_v_i32m4(sum, 15), __riscv_vle32_v_i32m4(bias + i, 15), 15); + + s0 = __riscv_vfcvt_x(__riscv_vfmul(__riscv_vfcvt_f_x_v_f32m4(s0, 15), __riscv_vle32_v_f32m4(multiplier + i, 15), 15), 15); + s0 = __riscv_vadd(s0, outZp, 15); + s0 = __riscv_vmin(__riscv_vmax(s0, -128, 15), 127, 15); + __riscv_vse32_v_i32m4(dst + i, s0, 15); + } + int unroll_tail = nvecs - i; + if (unroll_tail > 0) + { + const int8_t* wptr = weights + i*wstep; + vint32m2_t + vs0 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs1 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs2 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs3 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs4 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs5 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs6 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs7 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs8 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs9 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs10 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs11 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), + vs12 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max), vs13 = __riscv_vmv_v_x_i32m2(0, __cv_rvv_e32m2_max); + int avl = vecsize, vl; + for(int k = 0 ; k < vecsize; k += vl, wptr += vl, avl -= vl) + { + vl = __riscv_vsetvl_e8m1(avl); + vint8m1_t v = __riscv_vle8_v_i8m1(vec + k, vl); + + vs0 = __riscv_vwmacc_vv_i32m2(vs0, __riscv_vle8_v_i8m1(wptr, vl), v, vl); + vs1 = __riscv_vwmacc_vv_i32m2(vs1, __riscv_vle8_v_i8m1(wptr + wstep*std::min(1, unroll_tail-1), vl), v, vl); + vs2 = __riscv_vwmacc_vv_i32m2(vs2, __riscv_vle8_v_i8m1(wptr + wstep*std::min(2, unroll_tail-1), vl), v, vl); + vs3 = __riscv_vwmacc_vv_i32m2(vs3, __riscv_vle8_v_i8m1(wptr + wstep*std::min(3, unroll_tail-1), vl), v, vl); + vs4 = __riscv_vwmacc_vv_i32m2(vs4, __riscv_vle8_v_i8m1(wptr + wstep*std::min(4, unroll_tail-1), vl), v, vl); + vs5 = __riscv_vwmacc_vv_i32m2(vs5, __riscv_vle8_v_i8m1(wptr + wstep*std::min(5, unroll_tail-1), vl), v, vl); + vs6 = __riscv_vwmacc_vv_i32m2(vs6, __riscv_vle8_v_i8m1(wptr + wstep*std::min(6, unroll_tail-1), vl), v, vl); + vs7 = __riscv_vwmacc_vv_i32m2(vs7, __riscv_vle8_v_i8m1(wptr + wstep*std::min(7, unroll_tail-1), vl), v, vl); + vs8 = __riscv_vwmacc_vv_i32m2(vs8, __riscv_vle8_v_i8m1(wptr + wstep*std::min(8, unroll_tail-1), vl), v, vl); + vs9 = __riscv_vwmacc_vv_i32m2(vs9, __riscv_vle8_v_i8m1(wptr + wstep*std::min(9, unroll_tail-1), vl), v, vl); + vs10 = __riscv_vwmacc_vv_i32m2(vs10, __riscv_vle8_v_i8m1(wptr + wstep*std::min(10, unroll_tail-1), vl), v, vl); + vs11 = __riscv_vwmacc_vv_i32m2(vs11, __riscv_vle8_v_i8m1(wptr + wstep*std::min(11, unroll_tail-1), vl), v, vl); + vs13 = __riscv_vwmacc_vv_i32m2(vs13, __riscv_vle8_v_i8m1(wptr + wstep*std::min(12, unroll_tail-1), vl), v, vl); + vs12 = __riscv_vwmacc_vv_i32m2(vs12, __riscv_vle8_v_i8m1(wptr + wstep*std::min(13, unroll_tail-1), vl), v, vl); + } + + int sum[14]; + vint32m1_t zero = __riscv_vmv_v_x_i32m1(0, __cv_rvv_e32m2_max); + sum[0] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs0, zero, __cv_rvv_e32m2_max)); + sum[1] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs1, zero, __cv_rvv_e32m2_max)); + sum[2] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs2, zero, __cv_rvv_e32m2_max)); + sum[3] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs3, zero, __cv_rvv_e32m2_max)); + sum[4] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs4, zero, __cv_rvv_e32m2_max)); + sum[5] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs5, zero, __cv_rvv_e32m2_max)); + sum[6] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs6, zero, __cv_rvv_e32m2_max)); + sum[7] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs7, zero, __cv_rvv_e32m2_max)); + sum[8] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs8, zero, __cv_rvv_e32m2_max)); + sum[9] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs9, zero, __cv_rvv_e32m2_max)); + sum[10] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs10, zero, __cv_rvv_e32m2_max)); + sum[11] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs11, zero, __cv_rvv_e32m2_max)); + sum[12] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs12, zero, __cv_rvv_e32m2_max)); + sum[13] = __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(vs13, zero, __cv_rvv_e32m2_max)); + + vint32m4_t s0 = __riscv_vadd(__riscv_vle32_v_i32m4(sum, unroll_tail), __riscv_vle32_v_i32m4(bias + i, unroll_tail), unroll_tail); + + s0 = __riscv_vfcvt_x(__riscv_vfmul(__riscv_vfcvt_f_x_v_f32m4(s0, unroll_tail), __riscv_vle32_v_f32m4(multiplier + i, unroll_tail), unroll_tail), unroll_tail); + s0 = __riscv_vadd(s0, outZp, unroll_tail); + s0 = __riscv_vmin(__riscv_vmax(s0, -128, unroll_tail), 127, unroll_tail); + __riscv_vse32_v_i32m4(dst + i, s0, unroll_tail); + } +} + +#endif // CV_RVV + CV_CPU_OPTIMIZATION_NAMESPACE_END }} // namespace From 93800a85b2468a7acf56374ee15b241b3703474f Mon Sep 17 00:00:00 2001 From: daiyin Date: Mon, 1 Apr 2024 10:32:37 +0800 Subject: [PATCH 56/56] fix download file hash value mismatch issue --- 3rdparty/orbbecsdk/orbbecsdk.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/orbbecsdk/orbbecsdk.cmake b/3rdparty/orbbecsdk/orbbecsdk.cmake index 7a553946b6..db51aee9c4 100644 --- a/3rdparty/orbbecsdk/orbbecsdk.cmake +++ b/3rdparty/orbbecsdk/orbbecsdk.cmake @@ -1,6 +1,6 @@ function(download_orbbec_sdk root_var) set(ORBBECSDK_DOWNLOAD_DIR "${OpenCV_BINARY_DIR}/3rdparty/orbbecsdk") - set(ORBBECSDK_FILE_HASH_CMAKE "2624c84837d3416fd8b3e95750e6e725") + set(ORBBECSDK_FILE_HASH_CMAKE "e7566fa915a1b0c02640df41891916fe") ocv_download(FILENAME "v1.9.4.tar.gz" HASH ${ORBBECSDK_FILE_HASH_CMAKE} URL "https://github.com/orbbec/OrbbecSDK/archive/refs/tags/v1.9.4/"