libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

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