@@ -141,8 +141,8 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
141141 vImage_Buffer origCb = {
142142 .data = avif->yuvPlanes [AVIF_CHAN_U],
143143 .rowBytes = avif->yuvRowBytes [AVIF_CHAN_U],
144- .width = avif->width >> state.formatInfo .chromaShiftX ,
145- .height = avif->height >> state.formatInfo .chromaShiftY ,
144+ .width = ( avif->width +state. formatInfo . chromaShiftX ) >> state.formatInfo .chromaShiftX ,
145+ .height = ( avif->height +state. formatInfo . chromaShiftY ) >> state.formatInfo .chromaShiftY ,
146146 };
147147
148148 if (!origCb.data ) { // allocate dummy data to convert monochrome images.
@@ -159,8 +159,8 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
159159 vImage_Buffer origCr = {
160160 .data = avif->yuvPlanes [AVIF_CHAN_V],
161161 .rowBytes = avif->yuvRowBytes [AVIF_CHAN_V],
162- .width = avif->width >> state.formatInfo .chromaShiftX ,
163- .height = avif->height >> state.formatInfo .chromaShiftY ,
162+ .width = ( avif->width +state. formatInfo . chromaShiftX ) >> state.formatInfo .chromaShiftX ,
163+ .height = ( avif->height +state. formatInfo . chromaShiftY ) >> state.formatInfo .chromaShiftY ,
164164 };
165165 if (!origCr.data ) { // allocate dummy data to convert monochrome images.
166166 dummyCr = calloc (origCr.width , sizeof (uint8_t ));
@@ -282,23 +282,38 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
282282 return ;
283283 }
284284
285+ ((uint8_t *)origY.data )[origY.rowBytes * (origY.height-1 ) + origY.width ] = 255 ;
286+ const vImagePixelCount alignedWidth = (origY.width +1 ) & (~1 );
285287 vImage_Buffer tmpY1 = {
286- .data = calloc (origY. width /2 * origY.height , sizeof (uint8_t )),
287- .width = origY. width /2 ,
288+ .data = calloc (alignedWidth /2 * origY.height , sizeof (uint8_t )),
289+ .width = alignedWidth /2 ,
288290 .height = origY.height ,
289- .rowBytes = origY. width /2 * sizeof (uint8_t ),
291+ .rowBytes = alignedWidth /2 * sizeof (uint8_t ),
290292 };
291293 if (!tmpY1.data ) {
292294 free (argbPixels);
293295 free (dummyCb);
294296 free (dummyCr);
295297 return ;
296298 }
299+ err = vImageConvert_ChunkyToPlanar8 ((const void *[]){origY.data },
300+ (const vImage_Buffer*[]){&tmpY1},
301+ 1 /* channelCount */ , 2 /* src srcStrideBytes */ ,
302+ alignedWidth/2 , origY.height ,
303+ origY.rowBytes , kvImageNoFlags);
304+ if (err != kvImageNoError) {
305+ NSLog (@" Failed to separate first Y channel: %ld " , err);
306+ free (argbPixels);
307+ free (dummyCb);
308+ free (dummyCr);
309+ free (tmpY1.data );
310+ return ;
311+ }
297312 vImage_Buffer tmpY2 = {
298- .data = calloc (origY. width /2 * origY.height , sizeof (uint8_t )),
299- .width = origY. width /2 ,
313+ .data = calloc (alignedWidth /2 * origY.height , sizeof (uint8_t )),
314+ .width = alignedWidth /2 ,
300315 .height = origY.height ,
301- .rowBytes = origY. width /2 * sizeof (uint8_t ),
316+ .rowBytes = alignedWidth /2 * sizeof (uint8_t ),
302317 };
303318 if (!tmpY2.data ) {
304319 free (argbPixels);
@@ -307,13 +322,15 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
307322 free (tmpY1.data );
308323 return ;
309324 }
310- err= vImageConvert_ChunkyToPlanar8 ((const void *[]){origY.data , origY.data +1 },
311- (const vImage_Buffer*[]){&tmpY1, &tmpY2},
312- 2 /* channelCount */ ,2 /* src srcStrideBytes */ ,
325+ tmpY2.width = origY.width /2 ;
326+ err = vImageConvert_ChunkyToPlanar8 ((const void *[]){origY.data + 1 },
327+ (const vImage_Buffer*[]){&tmpY2},
328+ 1 /* channelCount */ , 2 /* src srcStrideBytes */ ,
313329 origY.width /2 , origY.height ,
314330 origY.rowBytes , kvImageNoFlags);
331+ tmpY2.width = alignedWidth/2 ;
315332 if (err != kvImageNoError) {
316- NSLog (@" Failed to separate Y channel: %ld " , err);
333+ NSLog (@" Failed to separate second Y channel: %ld " , err);
317334 free (argbPixels);
318335 free (dummyCb);
319336 free (dummyCr);
@@ -322,10 +339,10 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
322339 return ;
323340 }
324341 vImage_Buffer tmpBuffer = {
325- .data = calloc (avif-> width * avif->height * 2 , sizeof (uint8_t )),
326- .width = avif-> width /2 ,
342+ .data = calloc (alignedWidth * avif->height * 2 , sizeof (uint8_t )),
343+ .width = alignedWidth /2 ,
327344 .height = avif->height ,
328- .rowBytes = avif-> width / 2 * 4 * sizeof (uint8_t ),
345+ .rowBytes = alignedWidth / 2 * 4 * sizeof (uint8_t ),
329346 };
330347 if (!tmpBuffer.data ) {
331348 free (argbPixels);
@@ -437,8 +454,8 @@ static void ConvertAvifImagePlanar16ToRGB16U(avifImage * avif, uint8_t * outPixe
437454 vImage_Buffer origCb = {
438455 .data = avif->yuvPlanes [AVIF_CHAN_U],
439456 .rowBytes = avif->yuvRowBytes [AVIF_CHAN_U],
440- .width = avif->width >> state.formatInfo .chromaShiftX ,
441- .height = avif->height >> state.formatInfo .chromaShiftY ,
457+ .width = ( avif->width +state. formatInfo . chromaShiftX ) >> state.formatInfo .chromaShiftX ,
458+ .height = ( avif->height +state. formatInfo . chromaShiftY ) >> state.formatInfo .chromaShiftY ,
442459 };
443460
444461 if (!origCb.data ) { // allocate dummy data to convert monochrome images.
@@ -465,8 +482,8 @@ static void ConvertAvifImagePlanar16ToRGB16U(avifImage * avif, uint8_t * outPixe
465482 vImage_Buffer origCr = {
466483 .data = avif->yuvPlanes [AVIF_CHAN_V],
467484 .rowBytes = avif->yuvRowBytes [AVIF_CHAN_V],
468- .width = avif->width >> state.formatInfo .chromaShiftX ,
469- .height = avif->height >> state.formatInfo .chromaShiftY ,
485+ .width = ( avif->width +state. formatInfo . chromaShiftX ) >> state.formatInfo .chromaShiftX ,
486+ .height = ( avif->height +state. formatInfo . chromaShiftY ) >> state.formatInfo .chromaShiftY ,
470487 };
471488
472489 if (!origCr.data ) { // allocate dummy data to convert monochrome images.
0 commit comments