source: trunk/source/visualization/RayTracer/src/G4RTJpegCoder.cc@ 1133

Last change on this file since 1133 was 954, checked in by garnier, 17 years ago

remise a jour

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