Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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