Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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//
28//
29//
30
31#include <stdlib.h>
32#include <string.h>
33#include <cmath>
34
35#include "G4RTJpeg.hh"
36#include "G4RTOutBitStream.hh"
37#include "G4RTJpegMaker.hh"
38#include "G4RTJpegCoder.hh"
40
41
43{
44 mRgb[0] = colorR;
45 mRgb[1] = colorG;
46 mRgb[2] = colorB;
47
48 mPreDC[0] = mPreDC[1] = mPreDC[2] = 0;
49 mOBSP = 0;
50
51 for(int n=0; n<8; n++)
52 for(int im=0; im<8; im++)
53 mCosT[n][im] = std::cos((2 * im + 1) * n * PaiDiv16);
54}
55
58
59void
60G4JpegCoder::GetJpegData(char** aJpegData, int& size)
61{
62 if (mOBSP != 0){
63 *aJpegData = (char*)mOBSP->GetStreamAddress();
64 size = mOBSP->GetStreamSize();
65 }
66 else{
67 *aJpegData = 0;
68 size = 0;
69 }
70
71}
72
73int
75{
76 mNumVUnits = (mProperty.nRow / 16) + ((mProperty.nRow % 16) ? 1 : 0);
77 mNumHUnits = (mProperty.nColumn / 16) + ((mProperty.nColumn % 16) ? 1 : 0);
78
79 int size = mProperty.nColumn * mProperty.nRow * 3;
80 if(size < 10240)
81 size = 10240;
82
83 try{
84 mOBSP = new G4OutBitStream(size);
86 for(int yu=0; yu<mNumVUnits; yu++){
87 for(int xu=0; xu<mNumHUnits; xu++){
88 makeYCC(xu, yu);
89
90 //mRgb->YCrCb
91 #ifdef GRAY
92 for(int i=0; i<64; i++)
93 mCbBlock[i] = mCrBlock[i] = 0;
94 #endif
95 CodeMCU();
96 }
97 }
98 WriteEOI();
99 return M_NoError;
100 }
101
102 catch(G4MemoryError &me){
103 return M_RuntimeError;
104 }
105 catch(G4BufferError &be){
106 return M_RuntimeError;
107 }
108 catch(G4IndexError &ie){
109 return M_RuntimeError;
110 }
111}
112
113//MCU
114void
116{
117 for(int n=0; n<4; n++){
119 Quantization(0);
120 CodeHuffman(0);
121 }
123 Quantization(1);
124 CodeHuffman(1);
125
127 Quantization(2);
128 CodeHuffman(2);
129}
130
131void
132G4JpegCoder::makeYCC(int ux, int uy)
133{
134 u_char rv, gv, bv;
135 int tCrBlock[4][64];
136 int tCbBlock[4][64];
137
138 for(int u=0; u<4; u++){
139 int *yp = mYBlock[u];
140 int *cbp = tCbBlock[u];
141 int *crp = tCrBlock[u];
142
143 int sx = ux * 16 + ((u&1) ? 8 : 0);
144 int ex = sx + 8;
145 int sy = uy * 16 + ((u>1) ? 8 : 0);
146 int ey = sy + 8;
147
148 for(int iv=sy; iv<ey; iv++){
149 int ii = iv < mProperty.nRow ? iv : mProperty.nRow - 1;
150 for(int ih=sx; ih<ex; ih++){
151 int jj = ih < mProperty.nColumn ? ih : mProperty.nColumn - 1;
152 int index = ii * mProperty.nColumn + jj;
153 rv = mRgb[0][index];
154 gv = mRgb[1][index];
155 bv = mRgb[2][index];
156
157 *yp++ = int((0.2990 * rv) + (0.5870 * gv) + (0.1140 * bv) - 128)
158;
159 *cbp++ = int(-(0.1687 * rv) - (0.3313 * gv) + (0.5000 * bv));
160 *crp++ = int((0.5000 * rv) - (0.4187 * gv) - (0.0813 * bv));
161 } // ih
162 } //iv
163 } //u
164
165 int n = 0;
166 for(int b=0; b<4; b++){
167 switch(b){
168 case 0: n=0; break;
169 case 1: n=4; break;
170 case 2: n=32; break;
171 case 3: n=36;
172 }
173 for(int y=0; y<8; y+=2){
174 for(int x=0; x<8; x+=2){
175 int idx = y * 8 + x;
176 mCrBlock[n] = tCrBlock[b][idx];
177 mCbBlock[n] = tCbBlock[b][idx];
178 n++;
179 }
180 n += 4;
181 }
182 }
183}
184
185void
187{
188 const G4HuffmanCodeTable& dcT = cs ? CDcHuffmanT : YDcHuffmanT;
189 const G4HuffmanCodeTable& acT = cs ? CAcHuffmanT : YAcHuffmanT;
190 const int eobIdx = cs ? CEOBidx : YEOBidx;
191 const int zrlIdx = cs ? CZRLidx : YZRLidx;
192
193 int diff = mDCTData[0] - mPreDC[cs];
194 mPreDC[cs] = mDCTData[0];
195 int absDiff = std::abs(diff);
196 int dIdx = 0;
197
198 while(absDiff > 0){
199 absDiff >>= 1;
200 dIdx++;
201 }
202 if(dIdx > dcT.numOfElement)
203 throw(G4IndexError(dcT.numOfElement, dIdx, "CodeHuffman:DC"));
204 mOBSP->SetBits((dcT.CodeT)[dIdx], (dcT.SizeT)[dIdx]);
205
206 if(dIdx){
207 if(diff < 0)
208 diff--;
209 mOBSP->SetBits(diff, dIdx);
210 }
211
212 int run = 0;
213 for(int n=1; n<64; n++){
214 int absCoefficient = std::abs( mDCTData[ Zigzag[n] ] );
215 if( absCoefficient ){
216 while( run > 15 ){
217 mOBSP->SetBits((acT.CodeT)[zrlIdx], (acT.SizeT)[zrlIdx]);
218 run -= 16;
219 }
220 int is = 0;
221 while( absCoefficient > 0 ){
222 absCoefficient >>= 1;
223 is++;
224 }
225 int aIdx = run * 10 + is + (run == 15);
226 if( aIdx >= acT.numOfElement )
227 throw( G4IndexError( acT.numOfElement, aIdx, "CodeHuffman:AC" )
228 );
229 mOBSP->SetBits( (acT.CodeT)[aIdx], (acT.SizeT)[aIdx] );
230 int v = mDCTData[ Zigzag[n] ];
231 if( v < 0 )
232 v--;
233 mOBSP->SetBits( v, is );
234 run = 0;
235 }
236 else{
237 if(n == 63)
238 mOBSP->SetBits( (acT.CodeT)[eobIdx], (acT.SizeT)[eobIdx] );
239 else
240 run++;
241 }
242 }
243}
244
245
246void
248{
249 int* qt = (int*)(cs ? CQuantumT : YQuantumT);
250 for( int i=0; i<64; i++ ){
251 mDCTData[i] /= qt[i];
252 }
253}
254
255
256void
258{
259 for( int v=0; v<8; v++ ){
260 double cv = v ? 1.0 : DisSqrt2;
261 for( int u=0; u<8; u++ ){
262 double cu = u ? 1.0 : DisSqrt2;
263 double sum = 0;
264 for( int y=0; y<8; y++ )
265 for( int x=0; x<8; x++ )
266 sum += picData[ y * 8 + x ] * mCosT[u][x] * mCosT[v][y];
267 mDCTData[ v * 8 + u ] = int( sum * cu * cv / 4 );
268 }
269 }
270}
271
272
273void
275{
276 int i = 0; //counter
277 //SOI
278 mOBSP->SetByte( M_Marker ); //FF
279 mOBSP->SetByte( M_SOI ); //SOI
280
281 //APP0(JFIF Header)
282 mOBSP->SetByte( M_Marker ); //FF
283 mOBSP->SetByte( M_APP0 ); //APP0
284 mOBSP->SetWord( JFIFLength ); //parameter
285 mOBSP->CopyByte( (char*)JFIF, 5 ); //"JFIF\0"
286 mOBSP->SetWord( JFIFVersion ); //Version
290 mOBSP->SetByte( 0 );
291 mOBSP->SetByte( 0 );
292
293 //comment
294 if( mProperty.Comment != 0 ){
295 mOBSP->SetByte( M_Marker ); //FF
296 mOBSP->SetByte( M_COM ); //comment
297 int length = (int)strlen( mProperty.Comment ) + 1;
298 mOBSP->SetWord( length + 2 );
299 mOBSP->CopyByte( mProperty.Comment, length );
300 }
301
302 //DQT
304 mOBSP->SetByte( M_DQT );
305 mOBSP->SetWord( 67 );
306 mOBSP->SetByte( 0 );
307 for( i=0; i<64; i++ )
308 mOBSP->SetByte( u_char( YQuantumT[Zigzag[i]] ) );
310 mOBSP->SetByte( M_DQT );
311 mOBSP->SetWord( 67 );
312 mOBSP->SetByte( 1 );
313 for( i=0; i<64; i++ )
314 mOBSP->SetByte( u_char( CQuantumT[Zigzag[i]] ) );
315 // DHT
316 mOBSP->CopyByte( (char*)YDcDht, DcDhtLength );
317 mOBSP->CopyByte( (char*)CDcDht, DcDhtLength );
318 mOBSP->CopyByte( (char*)YAcDht, AcDhtLength );
319 mOBSP->CopyByte( (char*)CAcDht, AcDhtLength );
320
321 // Frame Header
322 mOBSP->SetByte( M_Marker ); // FF
323 mOBSP->SetByte( M_SOF0 );
324 mOBSP->SetWord( 3 * mProperty.Dimension + 8 );
329
330 mOBSP->SetByte( 0 );
332 mOBSP->SetByte( 0 );
333
334 mOBSP->SetByte( 1 );
336
337 mOBSP->SetByte( 1 );
338 mOBSP->SetByte( 2 );
340 mOBSP->SetByte( 1 );
341
342 //Scan Header
344 mOBSP->SetByte( M_SOS );
345 mOBSP->SetWord( 2 * mProperty.Dimension + 6 );
347 for( i=0; i<mProperty.Dimension; i++ ){
348 mOBSP->SetByte( i );
349 mOBSP->SetByte( i==0 ? 0 : 0x11 );
350 }
351 mOBSP->SetByte( 0 ); //Ss
352 mOBSP->SetByte( 63 ); //Se
353 mOBSP->SetByte( 0 ); //Ah,Al
354}
355
356//EOI
357void
359{
361 mOBSP->SetByte( M_EOI );
362}
363
364//SetJpegProperty
365void
const u_int JFIFLength
const u_char YSampleF
const u_char CSampleF
const u_int JFIFVersion
@ M_COM
Definition G4RTJpeg.hh:108
@ M_EOI
Definition G4RTJpeg.hh:101
@ M_Marker
Definition G4RTJpeg.hh:134
@ M_DQT
Definition G4RTJpeg.hh:103
@ M_SOI
Definition G4RTJpeg.hh:100
@ M_SOS
Definition G4RTJpeg.hh:102
@ M_SOF0
Definition G4RTJpeg.hh:73
@ M_APP0
Definition G4RTJpeg.hh:110
const double DisSqrt2
Definition G4RTJpeg.hh:46
const double PaiDiv16
Definition G4RTJpeg.hh:47
const char JFIF[]
Definition G4RTJpeg.hh:42
@ M_RuntimeError
Definition G4RTJpeg.hh:65
@ M_NoError
Definition G4RTJpeg.hh:64
unsigned char u_char
Definition G4RTJpeg.hh:39
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]
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)
const char * Comment
Definition G4RTJpeg.hh:160
u_char MinorRevisions
Definition G4RTJpeg.hh:163
u_char MajorRevisions
Definition G4RTJpeg.hh:162