@@ -141,8 +141,8 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
141
141
vImage_Buffer origCb = {
142
142
.data = avif->yuvPlanes [AVIF_CHAN_U],
143
143
.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 ,
146
146
};
147
147
148
148
if (!origCb.data ) { // allocate dummy data to convert monochrome images.
@@ -159,8 +159,8 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
159
159
vImage_Buffer origCr = {
160
160
.data = avif->yuvPlanes [AVIF_CHAN_V],
161
161
.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 ,
164
164
};
165
165
if (!origCr.data ) { // allocate dummy data to convert monochrome images.
166
166
dummyCr = calloc (origCr.width , sizeof (uint8_t ));
@@ -282,23 +282,38 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
282
282
return ;
283
283
}
284
284
285
+ ((uint8_t *)origY.data )[origY.rowBytes * (origY.height-1 ) + origY.width ] = 255 ;
286
+ const vImagePixelCount alignedWidth = (origY.width +1 ) & (~1 );
285
287
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 ,
288
290
.height = origY.height ,
289
- .rowBytes = origY. width /2 * sizeof (uint8_t ),
291
+ .rowBytes = alignedWidth /2 * sizeof (uint8_t ),
290
292
};
291
293
if (!tmpY1.data ) {
292
294
free (argbPixels);
293
295
free (dummyCb);
294
296
free (dummyCr);
295
297
return ;
296
298
}
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
+ }
297
312
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 ,
300
315
.height = origY.height ,
301
- .rowBytes = origY. width /2 * sizeof (uint8_t ),
316
+ .rowBytes = alignedWidth /2 * sizeof (uint8_t ),
302
317
};
303
318
if (!tmpY2.data ) {
304
319
free (argbPixels);
@@ -307,13 +322,15 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
307
322
free (tmpY1.data );
308
323
return ;
309
324
}
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 */ ,
313
329
origY.width /2 , origY.height ,
314
330
origY.rowBytes , kvImageNoFlags);
331
+ tmpY2.width = alignedWidth/2 ;
315
332
if (err != kvImageNoError) {
316
- NSLog (@" Failed to separate Y channel: %ld " , err);
333
+ NSLog (@" Failed to separate second Y channel: %ld " , err);
317
334
free (argbPixels);
318
335
free (dummyCb);
319
336
free (dummyCr);
@@ -322,10 +339,10 @@ static void ConvertAvifImagePlanar8ToRGB8(avifImage * avif, uint8_t * outPixels)
322
339
return ;
323
340
}
324
341
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 ,
327
344
.height = avif->height ,
328
- .rowBytes = avif-> width / 2 * 4 * sizeof (uint8_t ),
345
+ .rowBytes = alignedWidth / 2 * 4 * sizeof (uint8_t ),
329
346
};
330
347
if (!tmpBuffer.data ) {
331
348
free (argbPixels);
@@ -437,8 +454,8 @@ static void ConvertAvifImagePlanar16ToRGB16U(avifImage * avif, uint8_t * outPixe
437
454
vImage_Buffer origCb = {
438
455
.data = avif->yuvPlanes [AVIF_CHAN_U],
439
456
.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 ,
442
459
};
443
460
444
461
if (!origCb.data ) { // allocate dummy data to convert monochrome images.
@@ -465,8 +482,8 @@ static void ConvertAvifImagePlanar16ToRGB16U(avifImage * avif, uint8_t * outPixe
465
482
vImage_Buffer origCr = {
466
483
.data = avif->yuvPlanes [AVIF_CHAN_V],
467
484
.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 ,
470
487
};
471
488
472
489
if (!origCr.data ) { // allocate dummy data to convert monochrome images.
0 commit comments