tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

image_ops.cc (3554B)


      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 Status 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  JXL_RETURN_IF_ERROR(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  return true;
     40 }
     41 
     42 static Status DoDownsampleImage(const ImageF& input, size_t factor,
     43                                ImageF* output) {
     44  JXL_ENSURE(factor != 1);
     45  JXL_RETURN_IF_ERROR(output->ShrinkTo(DivCeil(input.xsize(), factor),
     46                                       DivCeil(input.ysize(), factor)));
     47  size_t in_stride = input.PixelsPerRow();
     48  for (size_t y = 0; y < output->ysize(); y++) {
     49    float* row_out = output->Row(y);
     50    const float* row_in = input.Row(factor * y);
     51    for (size_t x = 0; x < output->xsize(); x++) {
     52      size_t cnt = 0;
     53      float sum = 0;
     54      for (size_t iy = 0; iy < factor && iy + factor * y < input.ysize();
     55           iy++) {
     56        for (size_t ix = 0; ix < factor && ix + factor * x < input.xsize();
     57             ix++) {
     58          sum += row_in[iy * in_stride + x * factor + ix];
     59          cnt++;
     60        }
     61      }
     62      row_out[x] = sum / cnt;
     63    }
     64  }
     65  return true;
     66 }
     67 
     68 StatusOr<ImageF> DownsampleImage(const ImageF& image, size_t factor) {
     69  ImageF downsampled;
     70  // Allocate extra space to avoid a reallocation when padding.
     71  JxlMemoryManager* memory_manager = image.memory_manager();
     72  JXL_ASSIGN_OR_RETURN(
     73      downsampled,
     74      ImageF::Create(memory_manager, DivCeil(image.xsize(), factor) + kBlockDim,
     75                     DivCeil(image.ysize(), factor) + kBlockDim));
     76  JXL_RETURN_IF_ERROR(DoDownsampleImage(image, factor, &downsampled));
     77  return downsampled;
     78 }
     79 
     80 StatusOr<Image3F> DownsampleImage(const Image3F& opsin, size_t factor) {
     81  JXL_ENSURE(factor != 1);
     82  // Allocate extra space to avoid a reallocation when padding.
     83  Image3F downsampled;
     84  JxlMemoryManager* memory_manager = opsin.memory_manager();
     85  JXL_ASSIGN_OR_RETURN(
     86      downsampled, Image3F::Create(memory_manager,
     87                                   DivCeil(opsin.xsize(), factor) + kBlockDim,
     88                                   DivCeil(opsin.ysize(), factor) + kBlockDim));
     89  JXL_RETURN_IF_ERROR(downsampled.ShrinkTo(downsampled.xsize() - kBlockDim,
     90                                           downsampled.ysize() - kBlockDim));
     91  for (size_t c = 0; c < 3; c++) {
     92    JXL_RETURN_IF_ERROR(
     93        DoDownsampleImage(opsin.Plane(c), factor, &downsampled.Plane(c)));
     94  }
     95  return downsampled;
     96 }
     97 
     98 }  // namespace jxl