Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/RayTracer/src/G4RTJpegCoder.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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"
 39 #include "G4RTJpegCoderTables.hh"
 40 
 41 
 42 G4JpegCoder::G4JpegCoder(u_char* colorR,u_char* colorG,u_char* colorB)
 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 
 56 G4JpegCoder::~G4JpegCoder(void)
 57 {}
 58 
 59 void
 60 G4JpegCoder::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 
 73 int
 74 G4JpegCoder::DoCoding(void)
 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);
 85            WriteHeader();
 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
114 void
115 G4JpegCoder::CodeMCU(void)
116 {
117   for(int n=0; n<4; n++){
118                 ForwardDCT(mYBlock[n]);
119                 Quantization(0);
120                 CodeHuffman(0);
121   }
122   ForwardDCT(mCbBlock);
123   Quantization(1);
124   CodeHuffman(1);
125 
126   ForwardDCT(mCrBlock);
127   Quantization(2);
128   CodeHuffman(2);
129 }
130 
131 void
132 G4JpegCoder::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 
185 void
186 G4JpegCoder::CodeHuffman(int cs)
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 
246 void
247 G4JpegCoder::Quantization(int cs)
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 
256 void
257 G4JpegCoder::ForwardDCT(int* picData)
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 
273 void
274 G4JpegCoder::WriteHeader( void )
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
287   mOBSP->SetByte( mProperty.Units );
288   mOBSP->SetWord( mProperty.HDensity );
289   mOBSP->SetWord( mProperty.VDensity );
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
303   mOBSP->SetByte( M_Marker );
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]] ) );
309   mOBSP->SetByte( M_Marker );
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 );
325   mOBSP->SetByte( mProperty.SamplePrecision );
326   mOBSP->SetWord( mProperty.nRow );
327   mOBSP->SetWord( mProperty.nColumn );
328   mOBSP->SetByte( mProperty.Dimension );
329 
330   mOBSP->SetByte( 0 );
331   mOBSP->SetByte( YSampleF );
332   mOBSP->SetByte( 0 );
333 
334   mOBSP->SetByte( 1 );
335   mOBSP->SetByte( CSampleF );
336 
337   mOBSP->SetByte( 1 );
338   mOBSP->SetByte( 2 );
339   mOBSP->SetByte( CSampleF );
340   mOBSP->SetByte( 1 );
341 
342   //Scan Header
343   mOBSP->SetByte( M_Marker );
344   mOBSP->SetByte( M_SOS );
345   mOBSP->SetWord( 2 * mProperty.Dimension + 6 );
346   mOBSP->SetByte( mProperty.Dimension );
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
357 void
358 G4JpegCoder::WriteEOI( void )
359 {
360   mOBSP->SetByte( M_Marker );
361   mOBSP->SetByte( M_EOI );
362 }
363 
364 //SetJpegProperty
365 void
366 G4JpegCoder::SetJpegProperty(const G4JpegProperty& aProperty )
367 {
368   mProperty = aProperty;
369   mProperty.Dimension = 3;
370   mProperty.SamplePrecision = 8;
371   mProperty.Format = 1;
372   mProperty.MajorRevisions = 1;
373   mProperty.MinorRevisions = 2;
374   mProperty.HThumbnail = 0;
375   mProperty.VThumbnail = 0;
376 }
377