diff --git a/src/JPEGView/AVIFWrapper.cpp b/src/JPEGView/AVIFWrapper.cpp index eb19fa4a..9ea36ff1 100644 --- a/src/JPEGView/AVIFWrapper.cpp +++ b/src/JPEGView/AVIFWrapper.cpp @@ -2,6 +2,7 @@ #include "AVIFWrapper.h" #include "avif/avif.h" +#include "BasicProcessing.h" #include "MaxImageDef.h" #include "ICCProfileTransform.h" @@ -46,6 +47,7 @@ void* AvifReader::ReadImage(int& width, memcpy(cache.data, buffer, sizebytes); cache.decoder = avifDecoderCreate(); cache.decoder->maxThreads = nthreads; + cache.decoder->strictFlags = AVIF_STRICT_DISABLED; result = avifDecoderSetIOMemory(cache.decoder, cache.data, sizebytes); if (result != AVIF_RESULT_OK) { DeleteCache(); @@ -91,6 +93,46 @@ void* AvifReader::ReadImage(int& width, DeleteCache(); return NULL; } + + // Handle clap, irot and imir boxes + avifTransformFlags flags = cache.decoder->image->transformFlags; + if (flags & AVIF_TRANSFORM_CLAP) { + avifCleanApertureBox* clap = &cache.decoder->image->clap; + avifCropRect crop; + avifDiagnostics diag; + if (avifCropRectConvertCleanApertureBox(&crop, clap, width, height, cache.decoder->image->yuvFormat, &diag)) { + POINT point = { crop.x, crop.y }; + SIZE sz = { crop.width, crop.height }; + void* pixels = CBasicProcessing::Crop32bpp(width, height, cache.rgb.pixels, CRect(point, sz)); + if (pixels != NULL) { + delete[] cache.rgb.pixels; + cache.rgb.pixels = (uint8_t*)pixels; + width = crop.width; + height = crop.height; + } + } + } + if (flags & AVIF_TRANSFORM_IROT) { + int angle = 360 - cache.decoder->image->irot.angle * 90; + void* pixels = CBasicProcessing::Rotate32bpp(width, height, cache.rgb.pixels, angle); + if (pixels != NULL) { + delete[] cache.rgb.pixels; + cache.rgb.pixels = (uint8_t*)pixels; + if (angle != 180) { + int temp = width; + width = height; + height = temp; + } + } + } + if (flags & AVIF_TRANSFORM_IMIR) { + void* pixels = CBasicProcessing::Mirror32bpp(width, height, cache.rgb.pixels, cache.decoder->image->imir.axis); + if (pixels != NULL) { + delete[] cache.rgb.pixels; + cache.rgb.pixels = (uint8_t*)pixels; + } + } + avifRWData icc = cache.decoder->image->icc; if (cache.transform == NULL) cache.transform = ICCProfileTransform::CreateTransform(icc.data, icc.size, ICCProfileTransform::FORMAT_BGRA); diff --git a/src/JPEGView/BasicProcessing.cpp b/src/JPEGView/BasicProcessing.cpp index bab24427..e2903052 100644 --- a/src/JPEGView/BasicProcessing.cpp +++ b/src/JPEGView/BasicProcessing.cpp @@ -654,6 +654,11 @@ void* CBasicProcessing::Rotate32bpp(int nWidth, int nHeight, const void* pDIBPix return pTarget; } +void* CBasicProcessing::Mirror32bpp(int nWidth, int nHeight, const void* pDIBPixels, bool bHorizontally) { + return bHorizontally ? CBasicProcessing::MirrorH32bpp(nWidth, nHeight, pDIBPixels) : + CBasicProcessing::MirrorV32bpp(nWidth, nHeight, pDIBPixels); +} + void* CBasicProcessing::MirrorH32bpp(int nWidth, int nHeight, const void* pDIBPixels) { uint32* pTarget = new(std::nothrow) uint32[nWidth * nHeight]; if (pTarget == NULL) return NULL; diff --git a/src/JPEGView/BasicProcessing.h b/src/JPEGView/BasicProcessing.h index 83cba2c7..92078ea1 100644 --- a/src/JPEGView/BasicProcessing.h +++ b/src/JPEGView/BasicProcessing.h @@ -56,6 +56,9 @@ class CBasicProcessing // cases the return value is NULL static void* Rotate32bpp(int nWidth, int nHeight, const void* pDIBPixels, int nRotationAngleCW); + // Mirror 32 bit DIB + static void* Mirror32bpp(int nWidth, int nHeight, const void* pDIBPixels, bool bHorizontally); + // Mirror 32 bit DIB horizontally static void* MirrorH32bpp(int nWidth, int nHeight, const void* pDIBPixels); diff --git a/src/JPEGView/JPEGImage.cpp b/src/JPEGView/JPEGImage.cpp index 5c465f06..1ec23f41 100644 --- a/src/JPEGView/JPEGImage.cpp +++ b/src/JPEGView/JPEGImage.cpp @@ -715,8 +715,7 @@ bool CJPEGImage::Mirror(bool bHorizontally) { } InvalidateAllCachedPixelData(); - void* pNewOriginalPixels = bHorizontally ? CBasicProcessing::MirrorH32bpp(m_nOrigWidth, m_nOrigHeight, m_pOrigPixels) : - CBasicProcessing::MirrorV32bpp(m_nOrigWidth, m_nOrigHeight, m_pOrigPixels); + void* pNewOriginalPixels = CBasicProcessing::Mirror32bpp(m_nOrigWidth, m_nOrigHeight, m_pOrigPixels, bHorizontally); if (pNewOriginalPixels == NULL) return false; delete[] m_pOrigPixels; m_pOrigPixels = pNewOriginalPixels;