@@ -55,36 +55,7 @@ static CGImageRef CreateImageFromBuffer(avifImage * avif, vImage_Buffer* result)
5555 return imageRef;
5656}
5757
58- static avifBool avifPrepareReformatState (const avifImage * image, const avifRGBImage * rgb, avifReformatState * state)
59- {
60- if ((image->depth != 8 ) && (image->depth != 10 ) && (image->depth != 12 )) {
61- return AVIF_FALSE;
62- }
63- if ((rgb->depth != 8 ) && (rgb->depth != 10 ) && (rgb->depth != 12 ) && (rgb->depth != 16 )) {
64- return AVIF_FALSE;
65- }
66-
67- // These matrix coefficients values are currently unsupported. Revise this list as more support is added.
68- //
69- // YCgCo performs limited-full range adjustment on R,G,B but the current implementation performs range adjustment
70- // on Y,U,V. So YCgCo with limited range is unsupported.
71- if ((image->matrixCoefficients == 3 /* CICP reserved */ ) ||
72- ((image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO) && (image->yuvRange == AVIF_RANGE_LIMITED)) ||
73- (image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_BT2020_CL) ||
74- (image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_SMPTE2085) ||
75- (image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL) ||
76- (image->matrixCoefficients >= AVIF_MATRIX_COEFFICIENTS_ICTCP)) { // Note the >= catching "future" CICP values here too
77- return AVIF_FALSE;
78- }
79-
80- if ((image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY) && (image->yuvFormat != AVIF_PIXEL_FORMAT_YUV444)) {
81- return AVIF_FALSE;
82- }
83-
84- if (image->yuvFormat == AVIF_PIXEL_FORMAT_NONE) {
85- return AVIF_FALSE;
86- }
87-
58+ static void PrepareReformatState (const avifImage * image, avifReformatState * state) {
8859 avifGetPixelFormatInfo (image->yuvFormat , &state->formatInfo );
8960 avifCalcYUVCoefficients (image, &state->kr , &state->kg , &state->kb );
9061 state->mode = AVIF_REFORMAT_MODE_YUV_COEFFICIENTS;
@@ -100,113 +71,13 @@ static avifBool avifPrepareReformatState(const avifImage * image, const avifRGBI
10071 state->kg = 0 .0f ;
10172 state->kb = 0 .0f ;
10273 }
103-
104- state->yuvChannelBytes = (image->depth > 8 ) ? 2 : 1 ;
105- state->rgbChannelBytes = (rgb->depth > 8 ) ? 2 : 1 ;
106- state->rgbChannelCount = avifRGBFormatChannelCount (rgb->format );
107- state->rgbPixelBytes = state->rgbChannelBytes * state->rgbChannelCount ;
108-
109- switch (rgb->format ) {
110- case AVIF_RGB_FORMAT_RGB:
111- state->rgbOffsetBytesR = state->rgbChannelBytes * 0 ;
112- state->rgbOffsetBytesG = state->rgbChannelBytes * 1 ;
113- state->rgbOffsetBytesB = state->rgbChannelBytes * 2 ;
114- state->rgbOffsetBytesA = 0 ;
115- break ;
116- case AVIF_RGB_FORMAT_RGBA:
117- state->rgbOffsetBytesR = state->rgbChannelBytes * 0 ;
118- state->rgbOffsetBytesG = state->rgbChannelBytes * 1 ;
119- state->rgbOffsetBytesB = state->rgbChannelBytes * 2 ;
120- state->rgbOffsetBytesA = state->rgbChannelBytes * 3 ;
121- break ;
122- case AVIF_RGB_FORMAT_ARGB:
123- state->rgbOffsetBytesA = state->rgbChannelBytes * 0 ;
124- state->rgbOffsetBytesR = state->rgbChannelBytes * 1 ;
125- state->rgbOffsetBytesG = state->rgbChannelBytes * 2 ;
126- state->rgbOffsetBytesB = state->rgbChannelBytes * 3 ;
127- break ;
128- case AVIF_RGB_FORMAT_BGR:
129- state->rgbOffsetBytesB = state->rgbChannelBytes * 0 ;
130- state->rgbOffsetBytesG = state->rgbChannelBytes * 1 ;
131- state->rgbOffsetBytesR = state->rgbChannelBytes * 2 ;
132- state->rgbOffsetBytesA = 0 ;
133- break ;
134- case AVIF_RGB_FORMAT_BGRA:
135- state->rgbOffsetBytesB = state->rgbChannelBytes * 0 ;
136- state->rgbOffsetBytesG = state->rgbChannelBytes * 1 ;
137- state->rgbOffsetBytesR = state->rgbChannelBytes * 2 ;
138- state->rgbOffsetBytesA = state->rgbChannelBytes * 3 ;
139- break ;
140- case AVIF_RGB_FORMAT_ABGR:
141- state->rgbOffsetBytesA = state->rgbChannelBytes * 0 ;
142- state->rgbOffsetBytesB = state->rgbChannelBytes * 1 ;
143- state->rgbOffsetBytesG = state->rgbChannelBytes * 2 ;
144- state->rgbOffsetBytesR = state->rgbChannelBytes * 3 ;
145- break ;
146-
147- default :
148- return AVIF_FALSE;
149- }
150-
151- state->yuvDepth = image->depth ;
152- state->yuvRange = image->yuvRange ;
153- state->yuvMaxChannel = (1 << image->depth ) - 1 ;
154- state->rgbMaxChannel = (1 << rgb->depth ) - 1 ;
155- state->rgbMaxChannelF = (float )state->rgbMaxChannel ;
156- state->biasY = (state->yuvRange == AVIF_RANGE_LIMITED) ? (float )(16 << (state->yuvDepth - 8 )) : 0 .0f ;
157- state->biasUV = (float )(1 << (state->yuvDepth - 1 ));
158- state->rangeY = (float )((state->yuvRange == AVIF_RANGE_LIMITED) ? (219 << (state->yuvDepth - 8 )) : state->yuvMaxChannel );
159- state->rangeUV = (float )((state->yuvRange == AVIF_RANGE_LIMITED) ? (224 << (state->yuvDepth - 8 )) : state->yuvMaxChannel );
160-
161- uint32_t cpCount = 1 << image->depth ;
162- if (state->mode == AVIF_REFORMAT_MODE_IDENTITY) {
163- for (uint32_t cp = 0 ; cp < cpCount; ++cp) {
164- state->unormFloatTableY [cp] = ((float )cp - state->biasY ) / state->rangeY ;
165- state->unormFloatTableUV [cp] = ((float )cp - state->biasY ) / state->rangeY ;
166- }
167- } else {
168- for (uint32_t cp = 0 ; cp < cpCount; ++cp) {
169- // Review this when implementing YCgCo limited range support.
170- state->unormFloatTableY [cp] = ((float )cp - state->biasY ) / state->rangeY ;
171- state->unormFloatTableUV [cp] = ((float )cp - state->biasUV ) / state->rangeUV ;
172- }
173- }
174-
175- state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_NO_OP;
176- if (image->alphaPlane ) {
177- if (!avifRGBFormatHasAlpha (rgb->format ) || rgb->ignoreAlpha ) {
178- // if we are converting some image with alpha into a format without alpha, we should do 'premultiply alpha' before
179- // discarding alpha plane. This has the same effect of rendering this image on a black background, which makes sense.
180- if (!image->alphaPremultiplied ) {
181- state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_MULTIPLY;
182- }
183- } else {
184- if (!image->alphaPremultiplied && rgb->alphaPremultiplied ) {
185- state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_MULTIPLY;
186- } else if (image->alphaPremultiplied && !rgb->alphaPremultiplied ) {
187- state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_UNMULTIPLY;
188- }
189- }
190- }
191-
192- return AVIF_TRUE;
19374}
19475
195-
196- static void SetupConversionInfo (avifImage * avif,
76+ static void SetupConversionInfo (const avifImage * avif,
19777 avifReformatState* state,
19878 vImage_YpCbCrToARGBMatrix* matrix,
19979 vImage_YpCbCrPixelRange* pixelRange) {
200- avifRGBImage emptyRGBImage = {
201- .width = avif->width ,
202- .height = avif->height ,
203- .depth = avif->depth ,
204- .format = AVIF_RGB_FORMAT_ARGB,
205-
206- .pixels = NULL ,
207- .rowBytes = 0 ,
208- };
209- avifPrepareReformatState (avif, &emptyRGBImage, state);
80+ PrepareReformatState (avif, state);
21081
21182 // Setup Matrix
21283 matrix->Yp = 1 .0f ;
0 commit comments