summaryrefslogtreecommitdiff
path: root/lib/jxl/test_image.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/jxl/test_image.h')
-rw-r--r--lib/jxl/test_image.h143
1 files changed, 67 insertions, 76 deletions
diff --git a/lib/jxl/test_image.h b/lib/jxl/test_image.h
index 0093443..137806b 100644
--- a/lib/jxl/test_image.h
+++ b/lib/jxl/test_image.h
@@ -6,11 +6,16 @@
#ifndef LIB_JXL_TEST_IMAGE_H_
#define LIB_JXL_TEST_IMAGE_H_
-#include <stdint.h>
+#include <jxl/codestream_header.h>
+#include <jxl/types.h>
+#include <stddef.h>
+#include <cstdint>
+#include <string>
#include <vector>
-#include "lib/jxl/base/random.h"
+#include "lib/extras/packed_image.h"
+#include "lib/jxl/base/span.h"
namespace jxl {
namespace test {
@@ -19,83 +24,69 @@ namespace test {
// channel, big endian order, 1 to 4 channels
// The seed parameter allows to create images with different pixel content.
std::vector<uint8_t> GetSomeTestImage(size_t xsize, size_t ysize,
- size_t num_channels, uint16_t seed) {
- // Cause more significant image difference for successive seeds.
- Rng generator(seed);
+ size_t num_channels, uint16_t seed);
- // Returns random integer in interval [0, max_value)
- auto rng = [&generator](size_t max_value) -> size_t {
- return generator.UniformU(0, max_value);
- };
+class TestImage {
+ public:
+ TestImage();
+
+ extras::PackedPixelFile& ppf() { return ppf_; }
+
+ TestImage& DecodeFromBytes(const std::vector<uint8_t>& bytes);
+
+ TestImage& ClearMetadata();
+
+ TestImage& SetDimensions(size_t xsize, size_t ysize);
+
+ TestImage& SetChannels(size_t num_channels);
+
+ // Sets the same bit depth on color, alpha and all extra channels.
+ TestImage& SetAllBitDepths(uint32_t bits_per_sample,
+ uint32_t exponent_bits_per_sample = 0);
+
+ TestImage& SetDataType(JxlDataType data_type);
+
+ TestImage& SetEndianness(JxlEndianness endianness);
+
+ TestImage& SetColorEncoding(const std::string& description);
+
+ TestImage& CoalesceGIFAnimationWithAlpha();
+
+ class Frame {
+ public:
+ Frame(TestImage* parent, bool is_preview, size_t index);
- // Dark background gradient color
- uint16_t r0 = rng(32768);
- uint16_t g0 = rng(32768);
- uint16_t b0 = rng(32768);
- uint16_t a0 = rng(32768);
- uint16_t r1 = rng(32768);
- uint16_t g1 = rng(32768);
- uint16_t b1 = rng(32768);
- uint16_t a1 = rng(32768);
-
- // Circle with different color
- size_t circle_x = rng(xsize);
- size_t circle_y = rng(ysize);
- size_t circle_r = rng(std::min(xsize, ysize));
-
- // Rectangle with random noise
- size_t rect_x0 = rng(xsize);
- size_t rect_y0 = rng(ysize);
- size_t rect_x1 = rng(xsize);
- size_t rect_y1 = rng(ysize);
- if (rect_x1 < rect_x0) std::swap(rect_x0, rect_y1);
- if (rect_y1 < rect_y0) std::swap(rect_y0, rect_y1);
-
- size_t num_pixels = xsize * ysize;
- // 16 bits per channel, big endian, 4 channels
- std::vector<uint8_t> pixels(num_pixels * num_channels * 2);
- // Create pixel content to test, actual content does not matter as long as it
- // can be compared after roundtrip.
- for (size_t y = 0; y < ysize; y++) {
- for (size_t x = 0; x < xsize; x++) {
- uint16_t r = r0 * (ysize - y - 1) / ysize + r1 * y / ysize;
- uint16_t g = g0 * (ysize - y - 1) / ysize + g1 * y / ysize;
- uint16_t b = b0 * (ysize - y - 1) / ysize + b1 * y / ysize;
- uint16_t a = a0 * (ysize - y - 1) / ysize + a1 * y / ysize;
- // put some shape in there for visual debugging
- if ((x - circle_x) * (x - circle_x) + (y - circle_y) * (y - circle_y) <
- circle_r * circle_r) {
- r = (65535 - x * y) ^ seed;
- g = (x << 8) + y + seed;
- b = (y << 8) + x * seed;
- a = 32768 + x * 256 - y;
- } else if (x > rect_x0 && x < rect_x1 && y > rect_y0 && y < rect_y1) {
- r = rng(65536);
- g = rng(65536);
- b = rng(65536);
- a = rng(65536);
- }
- size_t i = (y * xsize + x) * 2 * num_channels;
- pixels[i + 0] = (r >> 8);
- pixels[i + 1] = (r & 255);
- if (num_channels >= 2) {
- // This may store what is called 'g' in the alpha channel of a 2-channel
- // image, but that's ok since the content is arbitrary
- pixels[i + 2] = (g >> 8);
- pixels[i + 3] = (g & 255);
- }
- if (num_channels >= 3) {
- pixels[i + 4] = (b >> 8);
- pixels[i + 5] = (b & 255);
- }
- if (num_channels >= 4) {
- pixels[i + 6] = (a >> 8);
- pixels[i + 7] = (a & 255);
- }
+ void ZeroFill();
+ void RandomFill(uint16_t seed = 177);
+
+ void SetValue(size_t y, size_t x, size_t c, float val);
+
+ private:
+ extras::PackedPixelFile& ppf() const { return parent_->ppf(); }
+
+ extras::PackedFrame& frame() {
+ return is_preview_ ? *ppf().preview_frame : ppf().frames[index_];
}
- }
- return pixels;
-}
+
+ TestImage* parent_;
+ bool is_preview_;
+ size_t index_;
+ };
+
+ Frame AddFrame();
+
+ Frame AddPreview(size_t xsize, size_t ysize);
+
+ private:
+ extras::PackedPixelFile ppf_;
+ JxlPixelFormat format_ = {3, JXL_TYPE_UINT8, JXL_LITTLE_ENDIAN, 0};
+
+ static void CropLayerInfo(size_t xsize, size_t ysize, JxlLayerInfo* info);
+
+ static void CropImage(size_t xsize, size_t ysize, extras::PackedImage* image);
+
+ static JxlDataType DefaultDataType(const JxlBasicInfo& info);
+};
} // namespace test
} // namespace jxl