common_internal.h (4553B)
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 #ifndef LIB_JPEGLI_COMMON_INTERNAL_H_ 7 #define LIB_JPEGLI_COMMON_INTERNAL_H_ 8 9 #include <cstddef> 10 #include <cstdint> 11 #include <cstring> 12 13 // Suppress any -Wdeprecated-declarations warning that might be emitted by 14 // GCC or Clang by std::stable_sort in C++17 or later mode 15 #ifdef __clang__ 16 #pragma clang diagnostic push 17 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 18 #elif defined(__GNUC__) 19 #pragma GCC push_options 20 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 21 #endif 22 23 #include <algorithm> 24 25 #ifdef __clang__ 26 #pragma clang diagnostic pop 27 #elif defined(__GNUC__) 28 #pragma GCC pop_options 29 #endif 30 31 #include <hwy/aligned_allocator.h> 32 33 #include "lib/jpegli/memory_manager.h" 34 #include "lib/jpegli/simd.h" 35 #include "lib/jxl/base/compiler_specific.h" // for ssize_t 36 37 namespace jpegli { 38 39 enum State { 40 kDecNull, 41 kDecStart, 42 kDecInHeader, 43 kDecHeaderDone, 44 kDecProcessMarkers, 45 kDecProcessScan, 46 kEncNull, 47 kEncStart, 48 kEncHeader, 49 kEncReadImage, 50 kEncWriteCoeffs, 51 }; 52 53 template <typename T1, typename T2> 54 constexpr inline T1 DivCeil(T1 a, T2 b) { 55 return (a + b - 1) / b; 56 } 57 58 template <typename T1, typename T2> 59 constexpr inline T1 RoundUpTo(T1 a, T2 b) { 60 return DivCeil(a, b) * b; 61 } 62 63 constexpr size_t kDCTBlockSize = 64; 64 // This is set to the same value as MAX_COMPS_IN_SCAN, because that is the 65 // maximum number of channels the libjpeg-turbo decoder can decode. 66 constexpr int kMaxComponents = 4; 67 constexpr int kMaxQuantTables = 4; 68 constexpr int kJpegPrecision = 8; 69 constexpr int kMaxHuffmanTables = 4; 70 constexpr size_t kJpegHuffmanMaxBitLength = 16; 71 constexpr int kJpegHuffmanAlphabetSize = 256; 72 constexpr int kJpegDCAlphabetSize = 12; 73 constexpr int kMaxDHTMarkers = 512; 74 constexpr int kMaxDimPixels = 65535; 75 constexpr uint8_t kApp1 = 0xE1; 76 constexpr uint8_t kApp2 = 0xE2; 77 const uint8_t kIccProfileTag[12] = "ICC_PROFILE"; 78 const uint8_t kExifTag[6] = "Exif\0"; 79 const uint8_t kXMPTag[29] = "http://ns.adobe.com/xap/1.0/"; 80 81 /* clang-format off */ 82 constexpr uint32_t kJPEGNaturalOrder[80] = { 83 0, 1, 8, 16, 9, 2, 3, 10, 84 17, 24, 32, 25, 18, 11, 4, 5, 85 12, 19, 26, 33, 40, 48, 41, 34, 86 27, 20, 13, 6, 7, 14, 21, 28, 87 35, 42, 49, 56, 57, 50, 43, 36, 88 29, 22, 15, 23, 30, 37, 44, 51, 89 58, 59, 52, 45, 38, 31, 39, 46, 90 53, 60, 61, 54, 47, 55, 62, 63, 91 // extra entries for safety in decoder 92 63, 63, 63, 63, 63, 63, 63, 63, 93 63, 63, 63, 63, 63, 63, 63, 63 94 }; 95 96 constexpr uint32_t kJPEGZigZagOrder[64] = { 97 0, 1, 5, 6, 14, 15, 27, 28, 98 2, 4, 7, 13, 16, 26, 29, 42, 99 3, 8, 12, 17, 25, 30, 41, 43, 100 9, 11, 18, 24, 31, 40, 44, 53, 101 10, 19, 23, 32, 39, 45, 52, 54, 102 20, 22, 33, 38, 46, 51, 55, 60, 103 21, 34, 37, 47, 50, 56, 59, 61, 104 35, 36, 48, 49, 57, 58, 62, 63 105 }; 106 /* clang-format on */ 107 108 template <typename T> 109 class RowBuffer { 110 public: 111 template <typename CInfoType> 112 void Allocate(CInfoType cinfo, size_t num_rows, size_t rowsize) { 113 static_assert(sizeof(T) == 4); 114 size_t vec_size = std::max(VectorSize(), sizeof(T)); 115 size_t alignment = std::max<size_t>(HWY_ALIGNMENT, vec_size); 116 size_t min_memstride = alignment + rowsize * sizeof(T) + vec_size; 117 size_t memstride = RoundUpTo(min_memstride, alignment); 118 xsize_ = rowsize; 119 ysize_ = num_rows; 120 stride_ = memstride / sizeof(T); 121 offset_ = alignment / sizeof(T); 122 data_ = ::jpegli::Allocate<T>(cinfo, ysize_ * stride_, JPOOL_IMAGE_ALIGNED); 123 } 124 125 T* Row(ssize_t y) const { 126 return &data_[((ysize_ + y) % ysize_) * stride_ + offset_]; 127 } 128 129 size_t xsize() const { return xsize_; }; 130 size_t ysize() const { return ysize_; }; 131 size_t stride() const { return stride_; } 132 133 void PadRow(size_t y, size_t from, int border) { 134 float* row = Row(y); 135 for (int offset = -border; offset < 0; ++offset) { 136 row[offset] = row[0]; 137 } 138 float last_val = row[from - 1]; 139 for (size_t x = from; x < xsize_ + border; ++x) { 140 row[x] = last_val; 141 } 142 } 143 144 void CopyRow(ssize_t dst_row, ssize_t src_row, int border) { 145 memcpy(Row(dst_row) - border, Row(src_row) - border, 146 (xsize_ + 2 * border) * sizeof(T)); 147 } 148 149 void FillRow(ssize_t y, T val, size_t len) { 150 T* row = Row(y); 151 for (size_t x = 0; x < len; ++x) { 152 row[x] = val; 153 } 154 } 155 156 private: 157 size_t xsize_; 158 size_t ysize_; 159 size_t stride_; 160 size_t offset_; 161 T* data_; 162 }; 163 164 } // namespace jpegli 165 166 #endif // LIB_JPEGLI_COMMON_INTERNAL_H_