Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4RTJpegCoder.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id$
28//
29//
30//
31
32#include <stdlib.h>
33#include <string.h>
34#include <cmath>
35
36#include "G4RTJpeg.hh"
37#include "G4RTOutBitStream.hh"
38#include "G4RTJpegMaker.hh"
39#include "G4RTJpegCoder.hh"
41
42
44{
45 mRgb[0] = colorR;
46 mRgb[1] = colorG;
47 mRgb[2] = colorB;
48
49 mPreDC[0] = mPreDC[1] = mPreDC[2] = 0;
50 mOBSP = 0;
51
52 for(int n=0; n<8; n++)
53 for(int im=0; im<8; im++)
54 mCosT[n][im] = std::cos((2 * im + 1) * n * PaiDiv16);
55}
56
58{}
59
60void
61G4JpegCoder::GetJpegData(char** aJpegData, int& size)
62{
63 if (mOBSP != 0){
64 *aJpegData = (char*)mOBSP->GetStreamAddress();
65 size = mOBSP->GetStreamSize();
66 }
67 else{
68 *aJpegData = 0;
69 size = 0;
70 }
71
72}
73
74int
76{
77 mNumVUnits = (mProperty.nRow / 16) + ((mProperty.nRow % 16) ? 1 : 0);
78 mNumHUnits = (mProperty.nColumn / 16) + ((mProperty.nColumn % 16) ? 1 : 0);
79
80 int size = mProperty.nColumn * mProperty.nRow * 3;
81 if(size < 10240)
82 size = 10240;
83
84 try{
85 mOBSP = new G4OutBitStream(size);
87 for(int yu=0; yu<mNumVUnits; yu++){
88 for(int xu=0; xu<mNumHUnits; xu++){
89 makeYCC(xu, yu);
90
91 //mRgb->YCrCb
92 #ifdef GRAY
93 for(int i=0; i<64; i++)
94 mCbBlock[i] = mCrBlock[i] = 0;
95 #endif
96 CodeMCU();
97 }
98 }
99 WriteEOI();
100 return M_NoError;
101 }
102
103 catch(G4MemoryError &me){
104 return M_RuntimeError;
105 }
106 catch(G4BufferError &be){
107 return M_RuntimeError;
108 }
109 catch(G4IndexError &ie){
110 return M_RuntimeError;
111 }
112}
113
114//MCU
115void
117{
118 for(int n=0; n<4; n++){
120 Quantization(0);
121 CodeHuffman(0);
122 }
124 Quantization(1);
125 CodeHuffman(1);
126
128 Quantization(2);
129 CodeHuffman(2);
130}
131
132void
133G4JpegCoder::makeYCC(int ux, int uy)
134{
135 u_char rv, gv, bv;
136 int tCrBlock[4][64];
137 int tCbBlock[4][64];
138
139 for(int u=0; u<4; u++){
140 int *yp = mYBlock[u];
141 int *cbp = tCbBlock[u];
142 int *crp = tCrBlock[u];
143
144 int sx = ux * 16 + ((u&1) ? 8 : 0);
145 int ex = sx + 8;
146 int sy = uy * 16 + ((u>1) ? 8 : 0);
147 int ey = sy + 8;
148
149 for(int iv=sy; iv<ey; iv++){
150 int ii = iv < mProperty.nRow ? iv : mProperty.nRow - 1;
151 for(int ih=sx; ih<ex; ih++){
152 int jj = ih < mProperty.nColumn ? ih : mProperty.nColumn - 1;
153 int index = ii * mProperty.nColumn + jj;
154 rv = mRgb[0][index];
155 gv = mRgb[1][index];
156 bv = mRgb[2][index];
157
158 *yp++ = int((0.2990 * rv) + (0.5870 * gv) + (0.1140 * bv) - 128)
159;
160 *cbp++ = int(-(0.1687 * rv) - (0.3313 * gv) + (0.5000 * bv));
161 *crp++ = int((0.5000 * rv) - (0.4187 * gv) - (0.0813 * bv));
162 } // ih
163 } //iv
164 } //u
165
166 int n = 0;
167 for(int b=0; b<4; b++){
168 switch(b){
169 case 0: n=0; break;
170 case 1: n=4; break;
171 case 2: n=32; break;
172 case 3: n=36;
173 }
174 for(int y=0; y<8; y+=2){
175 for(int x=0; x<8; x+=2){
176 int idx = y * 8 + x;
177 mCrBlock[n] = tCrBlock[b][idx];
178 mCbBlock[n] = tCbBlock[b][idx];
179 n++;
180 }
181 n += 4;
182 }
183 }
184}
185
186void
188{
189 const G4HuffmanCodeTable& dcT = cs ? CDcHuffmanT : YDcHuffmanT;
190 const G4HuffmanCodeTable& acT = cs ? CAcHuffmanT : YAcHuffmanT;
191 const int eobIdx = cs ? CEOBidx : YEOBidx;
192 const int zrlIdx = cs ? CZRLidx : YZRLidx;
193
194 int diff = mDCTData[0] - mPreDC[cs];
195 mPreDC[cs] = mDCTData[0];
196 int absDiff = std::abs(diff);
197 int dIdx = 0;
198
199 while(absDiff > 0){
200 absDiff >>= 1;
201 dIdx++;
202 }
203 if(dIdx > dcT.numOfElement)
204 throw(G4IndexError(dcT.numOfElement, dIdx, "CodeHuffman:DC"));
205 mOBSP->SetBits((dcT.CodeT)[dIdx], (dcT.SizeT)[dIdx]);
206
207 if(dIdx){
208 if(diff < 0)
209 diff--;
210 mOBSP->SetBits(diff, dIdx);
211 }
212
213 int run = 0;
214 for(int n=1; n<64; n++){
215 int absCoefficient = std::abs( mDCTData[ Zigzag[n] ] );
216 if( absCoefficient ){
217 while( run > 15 ){
218 mOBSP->SetBits((acT.CodeT)[zrlIdx], (acT.SizeT)[zrlIdx]);
219 run -= 16;
220 }
221 int is = 0;
222 while( absCoefficient > 0 ){
223 absCoefficient >>= 1;
224 is++;
225 }
226 int aIdx = run * 10 + is + (run == 15);
227 if( aIdx >= acT.numOfElement )
228 throw( G4IndexError( acT.numOfElement, aIdx, "CodeHuffman:AC" )
229 );
230 mOBSP->SetBits( (acT.CodeT)[aIdx], (acT.SizeT)[aIdx] );
231 int v = mDCTData[ Zigzag[n] ];
232 if( v < 0 )
233 v--;
234 mOBSP->SetBits( v, is );
235 run = 0;
236 }
237 else{
238 if(n == 63)
239 mOBSP->SetBits( (acT.CodeT)[eobIdx], (acT.SizeT)[eobIdx] );
240 else
241 run++;
242 }
243 }
244}
245
246
247void
249{
250 int* qt = (int*)(cs ? CQuantumT : YQuantumT);
251 for( int i=0; i<64; i++ ){
252 mDCTData[i] /= qt[i];
253 }
254}
255
256
257void
259{
260 for( int v=0; v<8; v++ ){
261 double cv = v ? 1.0 : DisSqrt2;
262 for( int u=0; u<8; u++ ){
263 double cu = u ? 1.0 : DisSqrt2;
264 double sum = 0;
265
266 for( int y=0; y<8; y++ )
267 for( int x=0; x<8; x++ )
268 sum += picData[ y * 8 + x ] * mCosT[u][x] * mCosT[v][y];
269 mDCTData[ v * 8 + u ] = int( sum * cu * cv / 4 );
270 }
271 }
272}
273
274
275void
277{
278 int i = 0; //counter
279 //SOI
280 mOBSP->SetByte( M_Marker ); //FF
281 mOBSP->SetByte( M_SOI ); //SOI
282
283 //APP0(JFIF Header)
284 mOBSP->SetByte( M_Marker ); //FF
285 mOBSP->SetByte( M_APP0 ); //APP0
286 mOBSP->SetWord( JFIFLength ); //parameter
287 mOBSP->CopyByte( (char*)JFIF, 5 ); //"JFIF\0"
288 mOBSP->SetWord( JFIFVersion ); //Version
292 mOBSP->SetByte( 0 );
293 mOBSP->SetByte( 0 );
294
295 //comment
296 if( mProperty.Comment != 0 ){
297 mOBSP->SetByte( M_Marker ); //FF
298 mOBSP->SetByte( M_COM ); //comment
299 int length = strlen( mProperty.Comment ) + 1;
300 mOBSP->SetWord( length + 2 );
301 mOBSP->CopyByte( mProperty.Comment, length );
302 }
303
304 //DQT
306 mOBSP->SetByte( M_DQT );
307 mOBSP->SetWord( 67 );
308 mOBSP->SetByte( 0 );
309 for( i=0; i<64; i++ )
310 mOBSP->SetByte( u_char( YQuantumT[Zigzag[i]] ) );
312 mOBSP->SetByte( M_DQT );
313 mOBSP->SetWord( 67 );
314 mOBSP->SetByte( 1 );
315 for( i=0; i<64; i++ )
316 mOBSP->SetByte( u_char( CQuantumT[Zigzag[i]] ) );
317 // DHT
318 mOBSP->CopyByte( (char*)YDcDht, DcDhtLength );
319 mOBSP->CopyByte( (char*)CDcDht, DcDhtLength );
320 mOBSP->CopyByte( (char*)YAcDht, AcDhtLength );
321 mOBSP->CopyByte( (char*)CAcDht, AcDhtLength );
322
323 // Frame Header
324 mOBSP->SetByte( M_Marker ); // FF
325 mOBSP->SetByte( M_SOF0 );
326 mOBSP->SetWord( 3 * mProperty.Dimension + 8 );
331
332 mOBSP->SetByte( 0 );
334 mOBSP->SetByte( 0 );
335
336 mOBSP->SetByte( 1 );
338
339 mOBSP->SetByte( 1 );
340 mOBSP->SetByte( 2 );
342 mOBSP->SetByte( 1 );
343
344 //Scan Header
346 mOBSP->SetByte( M_SOS );
347 mOBSP->SetWord( 2 * mProperty.Dimension + 6 );
349 for( i=0; i<mProperty.Dimension; i++ ){
350 mOBSP->SetByte( i );
351 mOBSP->SetByte( i==0 ? 0 : 0x11 );
352 }
353 mOBSP->SetByte( 0 ); //Ss
354 mOBSP->SetByte( 63 ); //Se
355 mOBSP->SetByte( 0 ); //Ah,Al
356}
357
358//EOI
359void
361{
363 mOBSP->SetByte( M_EOI );
364}
365
366//SetJpegProperty
367void
369{
370 mProperty = aProperty;
373 mProperty.Format = 1;
378}
const u_int JFIFLength
const u_char YSampleF
const u_char CSampleF
const u_int JFIFVersion
@ M_COM
Definition: G4RTJpeg.hh:109
@ M_EOI
Definition: G4RTJpeg.hh:102
@ M_Marker
Definition: G4RTJpeg.hh:135
@ M_DQT
Definition: G4RTJpeg.hh:104
@ M_SOI
Definition: G4RTJpeg.hh:101
@ M_SOS
Definition: G4RTJpeg.hh:103
@ M_SOF0
Definition: G4RTJpeg.hh:74
@ M_APP0
Definition: G4RTJpeg.hh:111
const double DisSqrt2
Definition: G4RTJpeg.hh:47
const double PaiDiv16
Definition: G4RTJpeg.hh:48
const char JFIF[]
Definition: G4RTJpeg.hh:43
@ M_RuntimeError
Definition: G4RTJpeg.hh:66
@ M_NoError
Definition: G4RTJpeg.hh:65
unsigned char u_char
Definition: G4RTJpeg.hh:40
G4OutBitStream * mOBSP
void CodeHuffman(int cs)
double mCosT[8][8]
void makeYCC(int ux, int uy)
void GetJpegData(char **aJpegData, int &size)
int mDCTData[64]
int DoCoding(void)
void ForwardDCT(int *picData)
void WriteHeader(void)
void SetJpegProperty(const G4JpegProperty &aProperty)
void WriteEOI(void)
G4JpegCoder(u_char *colorR, u_char *colorG, u_char *colorB)
u_char * mRgb[3]
~G4JpegCoder(void)
int mCrBlock[64]
int mCbBlock[64]
G4JpegProperty mProperty
void Quantization(int cs)
int mYBlock[4][64]
void CopyByte(const char *src, int n)
void SetWord(u_int dat)
void SetByte(u_char dat)
u_char * GetStreamAddress(void)
void SetBits(int v, int numBits)
int GetStreamSize(void)
int SamplePrecision
Definition: G4RTJpeg.hh:160
const char * Comment
Definition: G4RTJpeg.hh:161
u_char MinorRevisions
Definition: G4RTJpeg.hh:164
u_char MajorRevisions
Definition: G4RTJpeg.hh:163