@@ -1079,19 +1079,19 @@ class qoi{
1079
1079
constexpr std::uint32_t mask_tail_4 = 0b0000'1111u ;
1080
1080
const auto vr = (i >> 4 );
1081
1081
const auto vb = (i & mask_tail_4);
1082
- table[i] = vr*3 + vb*7 ;
1082
+ table[i] = ( vr*3 + vb*7 ) % index_size ;
1083
1083
}
1084
1084
for (std::size_t i = chunk_tag::diff; i < chunk_tag::luma; ++i){
1085
1085
constexpr std::uint32_t mask_tail_2 = 0b0000'0011u ;
1086
- const auto vr = ((i >> 4 ) & mask_tail_2) - 2 ;
1087
- const auto vg = ((i >> 2 ) & mask_tail_2) - 2 ;
1088
- const auto vb = ( i & mask_tail_2) - 2 ;
1089
- table[i+hash_table_offset] = vr*3 + vg*5 + vb*7 ;
1086
+ const auto vr = static_cast < int > ((i >> 4 ) & mask_tail_2) - 2 ;
1087
+ const auto vg = static_cast < int > ((i >> 2 ) & mask_tail_2) - 2 ;
1088
+ const auto vb = static_cast < int > ( i & mask_tail_2) - 2 ;
1089
+ table[i+hash_table_offset] = static_cast <std:: uint8_t >(( vr*3 + vg*5 + vb*7 ) % index_size) ;
1090
1090
}
1091
1091
for (std::size_t i = chunk_tag::luma; i < chunk_tag::run; ++i){
1092
1092
constexpr int vgv = chunk_tag::luma+40 ;
1093
1093
const int vg = i - vgv;
1094
- table[i+hash_table_offset] = vg*3 + (vg+8 )*5 + vg*7 ;
1094
+ table[i+hash_table_offset] = static_cast <std:: uint8_t >(( vg*3 + (vg+8 )*5 + vg*7 ) % index_size) ;
1095
1095
}
1096
1096
return table;
1097
1097
}
@@ -1130,8 +1130,12 @@ class qoi{
1130
1130
if constexpr (std::is_same<rgba_t , qoi::rgba_t >::value)
1131
1131
px.a = 255 ;
1132
1132
rgba_t index [index_size];
1133
- if constexpr (std::is_same<rgba_t , qoi::rgba_t >::value)
1133
+ if constexpr (std::is_same<rgba_t , qoi::rgba_t >::value){
1134
1134
index [(0 *3 +0 *5 +0 *7 +0 *11 )%index_size] = {};
1135
+ index [(0 *3 +0 *5 +0 *7 +255 *11 )%index_size] = px;
1136
+ }
1137
+ else
1138
+ index [(0 *3 +0 *5 +0 *7 +255 *11 )%index_size] = {};
1135
1139
1136
1140
#if QOIXX_DECODE_WITH_TABLES
1137
1141
#define QOIXX_HPP_WITH_TABLES (...) __VA_ARGS__
@@ -1147,10 +1151,7 @@ class qoi{
1147
1151
static constexpr auto hash_diff_table = luma_hash_diff_table.data () + hash_table_offset;
1148
1152
)
1149
1153
1150
- const auto f = [&pixels, &p, &px_len, &size, &px, &index QOIXX_HPP_WITH_TABLES (, &hash)](bool first){
1151
- static constexpr std::uint32_t mask_tail_6 = 0b0011'1111u ;
1152
- [[maybe_unused]] static constexpr std::uint32_t mask_tail_4 = 0b0000'1111u ;
1153
- [[maybe_unused]] static constexpr std::uint32_t mask_tail_2 = 0b0000'0011u ;
1154
+ const auto f = [&pixels, &p, &px_len, &size, &px, &index QOIXX_HPP_WITH_TABLES (, &hash)]{
1154
1155
const auto b1 = p.pull ();
1155
1156
--size;
1156
1157
@@ -1183,18 +1184,12 @@ class qoi{
1183
1184
if (b1 >= chunk_tag::run){
1184
1185
if (b1 < chunk_tag::rgb){
1185
1186
/* run*/
1187
+ static constexpr std::uint32_t mask_tail_6 = 0b0011'1111u ;
1186
1188
std::size_t run = b1 & mask_tail_6;
1187
1189
if (run >= px_len)[[unlikely]]
1188
1190
run = px_len;
1189
1191
px_len -= run;
1190
1192
QOIXX_HPP_DECODE_RUN (px, run)
1191
- if (first)[[unlikely]]{
1192
- QOIXX_HPP_WITH_TABLES (hash = (0 *3 +0 *5 +0 *7 +255 *11 ) % index_size;)
1193
- if constexpr (std::is_same<rgba_t , qoi::rgba_t >::value)
1194
- index [QOIXX_HPP_WITH_TABLES (hash) QOIXX_HPP_WITHOUT_TABLES ((0 *3 +0 *5 +0 *7 +255 *11 ) % index_size)] = px;
1195
- else
1196
- efficient_memcpy<Channels>(index + QOIXX_HPP_WITH_TABLES (hash) QOIXX_HPP_WITHOUT_TABLES ((0 *3 +0 *5 +0 *7 +255 *11 ) % index_size), &px);
1197
- }
1198
1193
return ;
1199
1194
}
1200
1195
if (b1 == chunk_tag::rgb){
@@ -1244,6 +1239,7 @@ class qoi{
1244
1239
px.b += vg + drb[1 ];
1245
1240
hash = (static_cast <int >(hash)+hash_diff_table[b1]+luma_hash_diff_table[b2]) % index_size;
1246
1241
) QOIXX_HPP_WITHOUT_TABLES (
1242
+ static constexpr std::uint32_t mask_tail_4 = 0b0000'1111u ;
1247
1243
px.r += vg + (b2 >> 4 );
1248
1244
px.g += vg + 8 ;
1249
1245
px.b += vg + (b2 & mask_tail_4);
@@ -1259,6 +1255,7 @@ class qoi{
1259
1255
px.b += drgb[2 ];
1260
1256
hash = (static_cast <int >(hash)+hash_diff_table[b1]) % index_size;
1261
1257
) QOIXX_HPP_WITHOUT_TABLES (
1258
+ static constexpr std::uint32_t mask_tail_2 = 0b0000'0011u ;
1262
1259
px.r += ((b1 >> 4 ) & mask_tail_2) - 2 ;
1263
1260
px.g += ((b1 >> 2 ) & mask_tail_2) - 2 ;
1264
1261
px.b += ( b1 & mask_tail_2) - 2 ;
@@ -1279,9 +1276,8 @@ class qoi{
1279
1276
push<Channels>(pixels, &px);
1280
1277
};
1281
1278
1282
- bool first = true ;
1283
1279
while (px_len--)[[likely]]{
1284
- f (std::exchange (first, false ) );
1280
+ f ();
1285
1281
if (size < sizeof (padding))[[unlikely]]{
1286
1282
throw std::runtime_error (" qoixx::qoi::decode: insufficient input data" );
1287
1283
}
0 commit comments