Bump patch version post tag.
[asdcplib.git] / src / JP2K.h
1 /*
2 Copyright (c) 2005-2014, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14    derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 /*! \file    JP2K.h
28     \version $Id$
29     \brief   JPEG 2000 constants and data structures
30
31     This is not a complete enumeration of all things JP2K.  There is just enough here to
32     support parsing picture metadata from a codestream header.
33 */
34
35 #ifndef _JP2K_H_
36 #define _JP2K_H_
37
38 // AS_DCP.h is included only for it's base type definitions.
39 #include <KM_platform.h>
40 #include <KM_util.h>
41 #include <AS_DCP.h>
42 #include <assert.h>
43
44 namespace ASDCP
45 {
46 namespace JP2K
47 {
48   const byte_t Magic[] = {0xff, 0x4f, 0xff};
49
50   enum Marker_t
51     {
52       MRK_NIL = 0,
53       MRK_SOC = 0xff4f, // Start of codestream
54       MRK_SOT = 0xff90, // Start of tile-part
55       MRK_SOD = 0xff93, // Start of data
56       MRK_EOC = 0xffd9, // End of codestream
57       MRK_CAP = 0xff50,  // Extended capabilities
58       MRK_SIZ = 0xff51, // Image and tile size
59       MRK_COD = 0xff52, // Coding style default
60       MRK_COC = 0xff53, // Coding style component
61       MRK_PRF = 0xff56, // Profile
62       MRK_CPF = 0xff59, // Corresponding profile
63       MRK_RGN = 0xff5e, // Region of interest
64       MRK_QCD = 0xff5c, // Quantization default
65       MRK_QCC = 0xff5d, // Quantization component
66       MRK_POC = 0xff5f, // Progression order change
67       MRK_TLM = 0xff55, // Tile-part lengths
68       MRK_PLM = 0xff57, // Packet length, main header
69       MRK_PLT = 0xff58, // Packet length, tile-part header
70       MRK_PPM = 0xff60, // Packed packet headers, main header
71       MRK_PPT = 0xff61, // Packed packet headers, tile-part header
72       MRK_SOP = 0xff91, // Start of packet
73       MRK_EPH = 0xff92, // End of packet header
74       MRK_CRG = 0xff63, // Component registration
75       MRK_COM = 0xff64, // Comment
76     };
77
78   const char* GetMarkerString(Marker_t m);
79
80   //
81   class Marker
82     {
83       KM_NO_COPY_CONSTRUCT(Marker);
84
85     public:
86       Marker_t m_Type;
87       bool     m_IsSegment;
88       ui32_t   m_DataSize;
89       const byte_t* m_Data;
90
91       Marker() : m_Type(MRK_NIL), m_IsSegment(false), m_DataSize(0), m_Data(0) {}
92       ~Marker() {}
93
94       void Dump(FILE* stream = 0) const;
95     };
96
97   //
98   ASDCP::Result_t GetNextMarker(const byte_t**, Marker&);
99
100   // accessor objects for marker segments
101   namespace Accessor
102     {
103       // image size
104       class SIZ
105         {
106           const byte_t* m_MarkerData;
107           KM_NO_COPY_CONSTRUCT(SIZ);
108           SIZ();
109
110         public:
111           SIZ(const Marker& M)
112             {
113               assert(M.m_Type == MRK_SIZ);
114               m_MarkerData = M.m_Data;
115             }
116
117           ~SIZ() {}
118
119           inline ui16_t Rsize()   const { return KM_i16_BE(*(ui16_t*)m_MarkerData); }
120           inline ui32_t Xsize()   const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 2)); }
121           inline ui32_t Ysize()   const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 6)); }
122           inline ui32_t XOsize()  const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 10)); }
123           inline ui32_t YOsize()  const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 14)); }
124           inline ui32_t XTsize()  const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 18)); }
125           inline ui32_t YTsize()  const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 22)); }
126           inline ui32_t XTOsize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 26)); }
127           inline ui32_t YTOsize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 30)); }
128           inline ui16_t Csize()   const { return KM_i16_BE(*(ui16_t*)(m_MarkerData + 34)); }
129           void ReadComponent(const ui32_t index, ImageComponent_t& IC) const;
130           void Dump(FILE* stream = 0) const;
131         };
132
133       const int SGcodOFST = 1;
134       const int SPcodOFST = 5;
135
136       // coding style
137       class COD
138         {
139           const byte_t* m_MarkerData;
140
141           KM_NO_COPY_CONSTRUCT(COD);
142           COD();
143
144         public:
145           COD(const Marker& M)
146             {
147               assert(M.m_Type == MRK_COD);
148               m_MarkerData = M.m_Data;
149             }
150
151           ~COD() {}
152           
153           inline ui8_t  ProgOrder()        const { return *(m_MarkerData + SGcodOFST ); }
154           inline ui16_t Layers()           const { return KM_i16_BE(*(ui16_t*)(m_MarkerData + SGcodOFST + 1));}
155           inline ui8_t  DecompLevels()     const { return *(m_MarkerData + SPcodOFST); }
156           inline ui8_t  CodeBlockWidth()   const { return *(m_MarkerData + SPcodOFST + 1) + 2; }
157           inline ui8_t  CodeBlockHeight()  const { return *(m_MarkerData + SPcodOFST + 2) + 2; }
158           inline ui8_t  CodeBlockStyle()   const { return *(m_MarkerData + SPcodOFST + 3); }
159           inline ui8_t  Transformation()   const { return *(m_MarkerData + SPcodOFST + 4); }
160
161           void Dump(FILE* stream = 0) const;
162         };
163
164       const int SqcdOFST = 1;
165       const int SPqcdOFST = 2;
166
167       enum QuantizationType_t
168       {
169         QT_NONE,
170         QT_DERIVED,
171         QT_EXP
172       };
173
174       const char* GetQuantizationTypeString(const QuantizationType_t m);
175
176       // Quantization default
177       class QCD
178         {
179           const byte_t* m_MarkerData;
180           ui32_t m_DataSize;
181
182           KM_NO_COPY_CONSTRUCT(QCD);
183           QCD();
184
185         public:
186           QCD(const Marker& M)
187             {
188               assert(M.m_Type == MRK_QCD);
189               m_MarkerData = M.m_Data + 2;
190               m_DataSize = M.m_DataSize - 2;
191             }
192
193           ~QCD() {}
194           inline QuantizationType_t QuantizationType() const { return static_cast<QuantizationType_t>(*(m_MarkerData + SqcdOFST) & 0x03); }
195           inline ui8_t  GuardBits() const { return (*(m_MarkerData + SqcdOFST) & 0xe0) >> 5; }
196           void Dump(FILE* stream = 0) const;
197         };
198
199       // a comment
200       class COM
201         {
202           bool          m_IsText;
203           const byte_t* m_MarkerData;
204           ui32_t        m_DataSize;
205
206           KM_NO_COPY_CONSTRUCT(COM);
207           COM();
208
209         public:
210           COM(const Marker& M)
211             {
212               assert(M.m_Type == MRK_COM);
213               m_IsText = M.m_Data[1] == 1;
214               m_MarkerData = M.m_Data + 2;
215               m_DataSize = M.m_DataSize - 2;
216             }
217
218           ~COM() {}
219           
220           inline bool IsText() const { return m_IsText; }
221           inline const byte_t* CommentData() const { return m_MarkerData; }
222           inline ui32_t CommentSize() const { return m_DataSize; }
223           void Dump(FILE* stream = 0) const;
224         };
225
226       // Corresponding Profile
227       class CPF {
228
229           const ui16_t* m_Data;
230                   ui16_t m_N;
231
232           KM_NO_COPY_CONSTRUCT(CPF);
233           CPF();
234
235       public:
236           CPF(const Marker& M) {
237               assert(M.m_Type == MRK_CPF);
238
239               m_Data = (ui16_t*) M.m_Data;
240                           m_N = M.m_DataSize >> 1;
241           }
242
243           ~CPF() {}
244
245           inline ui16_t N() const { return m_N; }
246
247           inline ui16_t pcpf(ui16_t i) const { return KM_i16_BE(m_Data[2 * (i - 1)]); }
248
249           void Dump(FILE* stream = 0) const;
250       };
251
252       // Profile
253       class PRF {
254
255           const ui16_t* m_Data;
256                   ui16_t m_N;
257
258           KM_NO_COPY_CONSTRUCT(PRF);
259           PRF();
260
261       public:
262           PRF(const Marker& M) {
263               assert(M.m_Type == MRK_PRF);
264
265                           m_Data = (ui16_t*) M.m_Data;
266                           m_N = M.m_DataSize >> 1;
267                   }
268
269           ~PRF() {}
270
271           inline ui16_t N() const { return m_N; }
272
273           inline ui16_t pprf(ui16_t i) const { return KM_i16_BE(m_Data[2 * (i - 1)]); }
274
275           void Dump(FILE* stream = 0) const;
276       };
277
278       // Extended capabilities
279       class CAP {
280
281           const ui16_t* m_Data;
282
283                   ui32_t m_Pcap;
284
285                   i8_t m_N;
286
287           KM_NO_COPY_CONSTRUCT(CAP);
288           CAP();
289
290       public:
291           CAP(const Marker& M) {
292               assert(M.m_Type == MRK_CAP);
293
294               m_Data = (ui16_t *) (M.m_Data + 4);
295                           m_Pcap = KM_i32_BE(*(ui32_t*)(M.m_Data));
296                           m_N = (M.m_DataSize - 4) >> 1;
297           }
298
299           ~CAP() {}
300
301           inline ui32_t pcap() const { return m_Pcap; }
302
303                   inline i8_t N() const { return m_N; }
304
305           inline ui16_t ccap(ui16_t i) const { return KM_i16_BE(m_Data[2 * (i - 1)]); }
306
307           void Dump(FILE* stream = 0) const;
308       };
309     } // namespace Accessor
310 } // namespace JP2K
311 } // namespace ASDCP
312
313 #endif // _JP2K_H_
314
315 //
316 // end JP2K.h
317 //