image_ops.cc (3180B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include "lib/jxl/image_ops.h" 7 8 #include <cstddef> 9 #include <cstring> 10 11 #include "lib/jxl/base/common.h" 12 #include "lib/jxl/base/compiler_specific.h" 13 #include "lib/jxl/base/status.h" 14 #include "lib/jxl/frame_dimensions.h" 15 #include "lib/jxl/image.h" 16 17 namespace jxl { 18 19 void PadImageToBlockMultipleInPlace(Image3F* JXL_RESTRICT in, 20 size_t block_dim) { 21 const size_t xsize_orig = in->xsize(); 22 const size_t ysize_orig = in->ysize(); 23 const size_t xsize = RoundUpTo(xsize_orig, block_dim); 24 const size_t ysize = RoundUpTo(ysize_orig, block_dim); 25 // Expands image size to the originally-allocated size. 26 in->ShrinkTo(xsize, ysize); 27 for (size_t c = 0; c < 3; c++) { 28 for (size_t y = 0; y < ysize_orig; y++) { 29 float* JXL_RESTRICT row = in->PlaneRow(c, y); 30 for (size_t x = xsize_orig; x < xsize; x++) { 31 row[x] = row[xsize_orig - 1]; 32 } 33 } 34 const float* JXL_RESTRICT row_src = in->ConstPlaneRow(c, ysize_orig - 1); 35 for (size_t y = ysize_orig; y < ysize; y++) { 36 memcpy(in->PlaneRow(c, y), row_src, xsize * sizeof(float)); 37 } 38 } 39 } 40 41 static void DoDownsampleImage(const ImageF& input, size_t factor, 42 ImageF* output) { 43 JXL_ASSERT(factor != 1); 44 output->ShrinkTo(DivCeil(input.xsize(), factor), 45 DivCeil(input.ysize(), factor)); 46 size_t in_stride = input.PixelsPerRow(); 47 for (size_t y = 0; y < output->ysize(); y++) { 48 float* row_out = output->Row(y); 49 const float* row_in = input.Row(factor * y); 50 for (size_t x = 0; x < output->xsize(); x++) { 51 size_t cnt = 0; 52 float sum = 0; 53 for (size_t iy = 0; iy < factor && iy + factor * y < input.ysize(); 54 iy++) { 55 for (size_t ix = 0; ix < factor && ix + factor * x < input.xsize(); 56 ix++) { 57 sum += row_in[iy * in_stride + x * factor + ix]; 58 cnt++; 59 } 60 } 61 row_out[x] = sum / cnt; 62 } 63 } 64 } 65 66 StatusOr<ImageF> DownsampleImage(const ImageF& image, size_t factor) { 67 ImageF downsampled; 68 // Allocate extra space to avoid a reallocation when padding. 69 JXL_ASSIGN_OR_RETURN( 70 downsampled, ImageF::Create(DivCeil(image.xsize(), factor) + kBlockDim, 71 DivCeil(image.ysize(), factor) + kBlockDim)); 72 DoDownsampleImage(image, factor, &downsampled); 73 return downsampled; 74 } 75 76 StatusOr<Image3F> DownsampleImage(const Image3F& opsin, size_t factor) { 77 JXL_ASSERT(factor != 1); 78 // Allocate extra space to avoid a reallocation when padding. 79 Image3F downsampled; 80 JXL_ASSIGN_OR_RETURN( 81 downsampled, Image3F::Create(DivCeil(opsin.xsize(), factor) + kBlockDim, 82 DivCeil(opsin.ysize(), factor) + kBlockDim)); 83 downsampled.ShrinkTo(downsampled.xsize() - kBlockDim, 84 downsampled.ysize() - kBlockDim); 85 for (size_t c = 0; c < 3; c++) { 86 DoDownsampleImage(opsin.Plane(c), factor, &downsampled.Plane(c)); 87 } 88 return downsampled; 89 } 90 91 } // namespace jxl