Geant4  10.01
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: G4RTJpegCoder.cc 66373 2012-12-18 09:41:34Z gcosmo $
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"
40 #include "G4RTJpegCoderTables.hh"
41 
42 
43 G4JpegCoder::G4JpegCoder(u_char* colorR,u_char* colorG,u_char* colorB)
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 
60 void
61 G4JpegCoder::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 
74 int
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);
86  WriteHeader();
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
115 void
117 {
118  for(int n=0; n<4; n++){
119  ForwardDCT(mYBlock[n]);
120  Quantization(0);
121  CodeHuffman(0);
122  }
124  Quantization(1);
125  CodeHuffman(1);
126 
128  Quantization(2);
129  CodeHuffman(2);
130 }
131 
132 void
133 G4JpegCoder::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 
186 void
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 
247 void
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 
257 void
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 
275 void
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
305  mOBSP->SetByte( M_Marker );
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]] ) );
311  mOBSP->SetByte( M_Marker );
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 );
333  mOBSP->SetByte( YSampleF );
334  mOBSP->SetByte( 0 );
335 
336  mOBSP->SetByte( 1 );
337  mOBSP->SetByte( CSampleF );
338 
339  mOBSP->SetByte( 1 );
340  mOBSP->SetByte( 2 );
341  mOBSP->SetByte( CSampleF );
342  mOBSP->SetByte( 1 );
343 
344  //Scan Header
345  mOBSP->SetByte( M_Marker );
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
359 void
361 {
362  mOBSP->SetByte( M_Marker );
363  mOBSP->SetByte( M_EOI );
364 }
365 
366 //SetJpegProperty
367 void
369 {
370  mProperty = aProperty;
371  mProperty.Dimension = 3;
373  mProperty.Format = 1;
376  mProperty.HThumbnail = 0;
377  mProperty.VThumbnail = 0;
378 }
void ForwardDCT(int *picData)
int DoCoding(void)
static const int YEOBidx
int mDCTData[64]
G4JpegCoder(u_char *colorR, u_char *colorG, u_char *colorB)
static const G4HuffmanCodeTable YAcHuffmanT
void CodeHuffman(int cs)
const double DisSqrt2
Definition: G4RTJpeg.hh:47
const double PaiDiv16
Definition: G4RTJpeg.hh:48
void Quantization(int cs)
static const int AcDhtLength
u_char MinorRevisions
Definition: G4RTJpeg.hh:164
void WriteEOI(void)
const u_char YSampleF
void SetWord(u_int dat)
static const int CQuantumT[]
const u_int JFIFVersion
static const u_char CAcDht[]
static const u_char CDcDht[]
void SetByte(u_char dat)
int SamplePrecision
Definition: G4RTJpeg.hh:160
static const G4HuffmanCodeTable CAcHuffmanT
static const int Zigzag[64]
Definition: G4RTJpeg.hh:51
void WriteHeader(void)
int mCbBlock[64]
static const G4HuffmanCodeTable YDcHuffmanT
const G4int n
G4JpegProperty mProperty
int mYBlock[4][64]
static const int YZRLidx
G4OutBitStream * mOBSP
unsigned char u_char
Definition: G4RTJpeg.hh:40
static const int DcDhtLength
void CopyByte(const char *src, int n)
void GetJpegData(char **aJpegData, int &size)
static const u_char YDcDht[]
static const int CZRLidx
static const int CEOBidx
~G4JpegCoder(void)
const u_char CSampleF
const u_int JFIFLength
const char * Comment
Definition: G4RTJpeg.hh:161
static const G4HuffmanCodeTable CDcHuffmanT
double mCosT[8][8]
const char JFIF[]
Definition: G4RTJpeg.hh:43
void makeYCC(int ux, int uy)
int mCrBlock[64]
int GetStreamSize(void)
u_char * mRgb[3]
u_char MajorRevisions
Definition: G4RTJpeg.hh:163
void SetBits(int v, int numBits)
u_char * GetStreamAddress(void)
static const u_char YAcDht[]
void SetJpegProperty(const G4JpegProperty &aProperty)
static const int YQuantumT[]