@@ -248,6 +248,57 @@ ImagingGetExtrema(Imaging im, void *extrema) {
248248 return 1 ; /* ok */
249249}
250250
251+ int
252+ ImagingGetExtremaMultiband (Imaging im , UINT8 extrema [const 8 ]) {
253+ // Per-band min/max for interleaved 8-bit images (up to 4 bands).
254+ // Writes 2 * im->bands bytes to extrema as [min0, max0, min1, max1, ...].
255+ // Returns the band count on success, 0 for an empty image, or -1 on error.
256+ int bands = im -> bands , xsize = im -> xsize , ysize = im -> ysize ;
257+ UINT8 vmin [4 ], vmax [4 ];
258+
259+ if (im -> type != IMAGING_TYPE_UINT8 || im -> image8 || bands < 2 || bands > 4 ) {
260+ // `_getextrema` should have checked these, but best be sure,
261+ // in case someone ends up calling this directly.
262+ (void )ImagingError_ModeError ();
263+ return -1 ;
264+ }
265+
266+ if (!xsize || !ysize ) {
267+ return 0 ; /* zero size */
268+ }
269+
270+ UINT8 * restrict in = (UINT8 * )im -> image [0 ];
271+ for (int b = 0 ; b < 4 ; b ++ ) {
272+ vmin [b ] = vmax [b ] = in [b ];
273+ }
274+
275+ for (int y = 0 ; y < ysize ; y ++ ) {
276+ UINT8 * restrict in = (UINT8 * )im -> image [y ];
277+ for (int x = 0 ; x < xsize ; x ++ , in += 4 ) {
278+ for (int b = 0 ; b < 4 ; b ++ ) {
279+ if (in [b ] < vmin [b ]) {
280+ vmin [b ] = in [b ];
281+ }
282+ if (in [b ] > vmax [b ]) {
283+ vmax [b ] = in [b ];
284+ }
285+ }
286+ }
287+ }
288+
289+ // The second band of a two-band image is stored in the fourth byte
290+ // (mirrors the special case in ImagingGetBand).
291+ if (bands == 2 ) {
292+ vmin [1 ] = vmin [3 ];
293+ vmax [1 ] = vmax [3 ];
294+ }
295+ for (int b = 0 ; b < bands ; b ++ ) {
296+ extrema [b * 2 + 0 ] = vmin [b ];
297+ extrema [b * 2 + 1 ] = vmax [b ];
298+ }
299+ return bands ;
300+ }
301+
251302/* static ImagingColorItem* getcolors8(Imaging im, int maxcolors, int* size);*/
252303static ImagingColorItem *
253304getcolors32 (Imaging im , int maxcolors , int * size );
0 commit comments