RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
BitStreamJPEGUtils.cpp
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2024 Roman Lebedev
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
22#include "adt/Casts.h"
23#include "adt/Invariant.h"
24#include "common/Common.h"
25#include <array>
26#include <cstddef>
27#include <cstdint>
28#include <numeric>
29#include <random>
30#include <vector>
31
32namespace rawspeed {
33
34namespace {
35
36// i'th element is the frequency with which
37// the byte `i` is found in an average JPEG byte stream.
38//
39// NOTE: that `a[0xFF]` means you need to refer to the next table!
40constexpr std::array<uint64_t, 256> ByteFrequency = {
41 10493257, 10784784, 11552191, 11893555, 12613144, 13142898, 12997374,
42 13899275, 12767738, 13768690, 14067759, 14319807, 14298384, 14549654,
43 14787598, 16204120, 12564638, 14704327, 15132777, 14772038, 14721008,
44 16318288, 16165051, 16084372, 14589355, 15975372, 15789517, 16176233,
45 17103573, 16389861, 17178739, 19566197, 12966690, 14939127, 15610587,
46 16752954, 17041360, 16836032, 16076146, 17059902, 14578757, 16091877,
47 16727621, 18080916, 17798565, 17160354, 16884990, 18016216, 13728953,
48 16699694, 17247145, 16535935, 15410093, 17790033, 17505607, 17062629,
49 16204122, 18729168, 17299562, 16769498, 18232031, 18145938, 19781670,
50 21534495, 11331827, 14291644, 14185576, 15783900, 14628539, 16752046,
51 16118713, 18395146, 15623136, 17719214, 16530868, 17731977, 15769435,
52 17046218, 16765658, 18737070, 13228107, 16456840, 16329879, 16995821,
53 15738285, 18833989, 18575650, 19748780, 17437816, 19175677, 17737907,
54 18686908, 17947791, 18231973, 18445785, 21014291, 13778765, 16390784,
55 16945784, 18735616, 17800539, 18504439, 17162043, 18246945, 14580463,
56 17138374, 17246435, 19567468, 18000143, 18165063, 17059260, 18333885,
57 14699997, 18157635, 18494395, 18681789, 16039637, 18755071, 17705487,
58 16502854, 16349978, 19475294, 18135626, 18404224, 19367350, 24366361,
59 20257637, 22731340, 10784899, 12672656, 14185602, 15004113, 13933378,
60 15252018, 15855022, 17094546, 14503399, 16136927, 16968789, 17924243,
61 16261588, 17408400, 18680524, 20524483, 15332344, 17670025, 18742651,
62 18371102, 15933041, 18490712, 18796265, 18818308, 15835711, 17808890,
63 17416555, 18385523, 17848445, 17685419, 19183656, 21453184, 12650093,
64 15036791, 15765357, 17764334, 16308312, 17422027, 16753335, 18445554,
65 15113106, 17233138, 17846593, 20237681, 18808801, 19265405, 19304091,
66 21445005, 16435437, 18992248, 19056275, 18871173, 16314514, 19007013,
67 18667634, 18326497, 16647767, 18446563, 17500274, 17437242, 17638057,
68 18434446, 24246779, 21500863, 12125753, 14904989, 14975537, 17166842,
69 16018526, 18142274, 17551177, 20836099, 17376424, 19394242, 17909585,
70 19873129, 17863152, 18763409, 18746276, 21901307, 14468289, 17073465,
71 17390849, 18194814, 16602085, 19238700, 19504566, 21024483, 17986684,
72 18759080, 17590236, 18305128, 17151973, 16704918, 17577197, 24350469,
73 13246295, 15768268, 17229315, 19654834, 18978722, 19267508, 19459062,
74 22426506, 16951164, 18450043, 18602860, 20972912, 18743890, 17732170,
75 16789701, 23607383, 14314573, 18700611, 19757997, 23215145, 19361294,
76 20804837, 18763614, 23882738, 16663983, 23464670, 22040143, 24327009,
77 20768026, 21851961, 22533160, 22588801};
78
79// i'th element is the frequency with which a sequence `0xFF00` consecutively
80// repeated `i` times is found in an average JPEG byte stream.
81constexpr std::array<uint64_t, 4> NumConsecutive0xFF00Frequency = {0, 22513031,
82 75445, 325};
83
84} // namespace
85
86#pragma GCC diagnostic push
87#pragma GCC diagnostic ignored "-Wpragmas"
88#pragma GCC diagnostic ignored "-Wunknown-warning-option"
89#pragma GCC diagnostic ignored "-Wunknown-pragmas"
90#pragma GCC diagnostic ignored "-Wframe-larger-than="
91#pragma GCC diagnostic ignored "-Wstack-usage="
92__attribute__((noinline)) __attribute__((visibility("default")))
94 const int64_t numBytesMax, bool AppendStuffingByte) {
95 invariant(numBytesMax > 0);
96 const auto expectedOverhead = roundUpDivisionSafe(numBytesMax, 100); // <=1%
97 dataStorage.reserve(implicit_cast<size_t>(numBytesMax + expectedOverhead));
98
99 // Here we only need to differentiate between a normal byte,
100 // and an 0xFF00 sequence, so clump together non-0xFF frequencies.
101 // This makes distribution sampling -40% faster.
102 constexpr uint64_t TotalWeight =
103 std::accumulate(ByteFrequency.begin(), ByteFrequency.end(), uint64_t(0));
104 constexpr uint64_t ControlSequenceStartWeight = ByteFrequency.back();
105
106 std::bernoulli_distribution controlSequenceStartDistribution(
107 implicit_cast<double>(ControlSequenceStartWeight) /
108 implicit_cast<double>(TotalWeight));
109 std::discrete_distribution<uint8_t> numConsecutive0xFF00Distribution(
110 NumConsecutive0xFF00Frequency.begin(),
111 NumConsecutive0xFF00Frequency.end());
112
113 std::random_device rd;
114 std::mt19937_64 gen(rd());
115
116 for (numBytesGenerated = 0; numBytesGenerated < numBytesMax;) {
117 bool isNormalByte = !controlSequenceStartDistribution(gen);
118 if (isNormalByte) {
119 dataStorage.emplace_back(0x00);
120 ++numBytesGenerated;
121 } else {
122 const int len = numConsecutive0xFF00Distribution(gen);
123 invariant(len > 0);
124 for (int i = 0; i != len; ++i) {
125 dataStorage.emplace_back(0xFF);
126 if (AppendStuffingByte)
127 dataStorage.emplace_back(0x00); // This is a no-op stuffing byte.
128 }
129 numBytesGenerated += len;
130 }
131 }
132 invariant(numBytesGenerated >= numBytesMax);
133}
134#pragma GCC diagnostic pop
135
136} // namespace rawspeed
#define invariant(expr)
Definition Invariant.h:27
constexpr std::array< uint64_t, 256 > ByteFrequency
constexpr std::array< uint64_t, 4 > NumConsecutive0xFF00Frequency
constexpr uint64_t RAWSPEED_READNONE roundUpDivisionSafe(uint64_t value, uint64_t div)
Definition Common.h:145
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
__attribute__((noinline)) __attribute__((visibility("default"))) JPEGStuffedByteStreamGenerator