ITADN

Interleaved mode reading confusion with heif_image_get_bits_per_pixel_range > 8

#1761Closedbobfriesenhahn 创建于 2026-04-11
B
bobfriesenhahncommented
I am attempting to implement interleaved (heif_chroma_interleaved_R*) reading mode in GraphicsMagick. I am successful with heif_image_get_bits_per_pixel_range <= 8, but the implementation I provided for 9-16 bits is crashing half way through as if it is striding twice as fast as it should be (I did not see that in the debugger), or heif_image_get_plane_readonly2() returned a buffer half the size as was expected. I feel like I must be doing something dumb, but still have not figured it out. For the input file, the original preferred colorspace is heif_colorspace_RGB, and original preferred chroma is heif_chroma_444. For purpose of decode (heif_decode_image), colorspace is heif_colorspace_RGB and chroma_decode is heif_chroma_interleaved_RRGGBB_BE. This is the related implementation code. What might I be doing wrong for the "else if (bits_per_pixel_range <= 16)" case? The code intends to parse each sample value as a native 'uint16_t'. ``` { /* Decode RGB(A) interleaved pixels This requires set-up in advance to request the desired RGB(A) sub-format. heif_chroma_interleaved_RGB heif_chroma_interleaved_RGBA heif_chroma_interleaved_RRGGBB_BE heif_chroma_interleaved_RRGGBBAA_BE heif_chroma_interleaved_RRGGBB_LE heif_chroma_interleaved_RRGGBBAA_LE */ typedef union { const uint8_t *u8; const uint16_t *u16; } magick_pixels_t; magick_pixels_t pixels; size_t row_stride; unsigned long x, y; int bits_per_pixel, bits_per_pixel_range; enum heif_channel heif_channel; const MagickBool matte = image->matte; if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Chroma format: %s", heif_chroma_format_str); heif_channel = heif_channel_interleaved; heif_channel_str = HEIF_channel_to_string(heif_channel); bits_per_pixel = heif_image_get_bits_per_pixel(heif_image, heif_channel); bits_per_pixel_range = heif_image_get_bits_per_pixel_range(heif_image, heif_channel); pixels.u8 = heif_image_get_plane_readonly2(heif_image, heif_channel, &row_stride); if (pixels.u8 == (const uint8_t*) NULL) { if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "heif_image_get_plane_readonly2() returned NULL" " (channel %s)!",heif_channel_str); ThrowHEIFThrowReadImageFrameException(CorruptImageError, AnErrorHasOccurredReadingFromFile, image); } /* interleaved row stride 1536 (8 bits in 24 bit quantum) */ /* interleaved row stride 3072 (16 bit samples in 48 bit packet) */ if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), " %s row stride %zu (%d bit samples in %d bit packet)", heif_channel_str, row_stride, bits_per_pixel_range, bits_per_pixel); /* FIXME: TODO */ if (bits_per_pixel_range <= 8) { const uint8_t *p; for (y=0; y < image->rows; y++) { p=pixels.u8+y*row_stride; q=SetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) { HEIFReadImageFrameCleanup(); return MagickFail; } for (x=0; x < image->columns; x++) { SetRedSample(q,ScaleCharToQuantum(*p++)); SetGreenSample(q,ScaleCharToQuantum(*p++)); SetBlueSample(q,ScaleCharToQuantum(*p++)); if (matte) SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(*p++)); else SetOpacitySample(q,OpaqueOpacity); q++; } if (!SyncImagePixelsEx(image,exception)) { HEIFReadImageFrameCleanup(); return MagickFail; } } } else if (bits_per_pixel_range <= 16) { const uint16_t *p; for (y=0; y < image->rows; y++) { p=pixels.u16+y*row_stride; q=SetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) { HEIFReadImageFrameCleanup(); return MagickFail; } for (x=0; x < image->columns; x++) { SetRedSample(q,ScaleShortToQuantum(*p++)); SetGreenSample(q,ScaleShortToQuantum(*p++)); SetBlueSample(q,ScaleShortToQuantum(*p++)); if (matte) SetOpacitySample(q,MaxRGB-ScaleShortToQuantum(*p++)); else SetOpacitySample(q,OpaqueOpacity); q++; } if (!SyncImagePixelsEx(image,exception)) { HEIFReadImageFrameCleanup(); return MagickFail; } } } } ```
关闭于 2026-04-11 4 条评论