Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/toojpeg.icc

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 ]

Diff markup

Differences between /externals/g4tools/include/tools/toojpeg.icc (Version 11.3.0) and /externals/g4tools/include/tools/toojpeg.icc (Version 10.3.p2)


  1                                                     1 
  2 // G.Barrand: pure header version of toojpeg f    
  3                                                   
  4 // ///////////////////////////////////////////    
  5 // toojpeg.cpp                                    
  6 // written by Stephan Brumme, 2018-2019           
  7 // see https://create.stephan-brumme.com/toojp    
  8 //                                                
  9                                                   
 10 #include <cstddef> //size_t                       
 11                                                   
 12 // - the "official" specifications: https://ww    
 13 // - Wikipedia has a short description of the     
 14 // - the popular STB Image library includes Jo    
 15 // - the most readable JPEG book (from a devel    
 16 //   used copies are really cheap nowadays and    
 17 // - much more detailled is Mitchell/Pennebake    
 18 //   which contains the official JPEG standard    
 19                                                   
 20 namespace tools {                                 
 21 namespace toojpeg {                               
 22 // ////////////////////////////////////////       
 23 // data types                                     
 24 typedef unsigned char uint8_t;                    
 25 typedef unsigned short uint16_t;                  
 26 typedef short int16_t;                            
 27 typedef int int32_t; // at least four bytes       
 28                                                   
 29 // ////////////////////////////////////////       
 30 // constants                                      
 31                                                   
 32 // quantization tables from JPEG Standard, Ann    
 33 const uint8_t DefaultQuantLuminance[8*8] =        
 34     { 16, 11, 10, 16, 24, 40, 51, 61, // there    
 35       12, 12, 14, 19, 26, 58, 60, 55, // e.g.     
 36       14, 13, 16, 24, 40, 57, 69, 56, // btw:     
 37       14, 17, 22, 29, 51, 87, 80, 62,             
 38       18, 22, 37, 56, 68,109,103, 77,             
 39       24, 35, 55, 64, 81,104,113, 92,             
 40       49, 64, 78, 87,103,121,120,101,             
 41       72, 92, 95, 98,112,100,103, 99 };           
 42 const uint8_t DefaultQuantChrominance[8*8] =      
 43     { 17, 18, 24, 47, 99, 99, 99, 99,             
 44       18, 21, 26, 66, 99, 99, 99, 99,             
 45       24, 26, 56, 99, 99, 99, 99, 99,             
 46       47, 66, 99, 99, 99, 99, 99, 99,             
 47       99, 99, 99, 99, 99, 99, 99, 99,             
 48       99, 99, 99, 99, 99, 99, 99, 99,             
 49       99, 99, 99, 99, 99, 99, 99, 99,             
 50       99, 99, 99, 99, 99, 99, 99, 99 };           
 51                                                   
 52 // 8x8 blocks are processed in zig-zag order      
 53 // most encoders use a zig-zag "forward" table    
 54 // note: ZigZagInv[ZigZag[i]] = i                 
 55 const uint8_t ZigZagInv[8*8] =                    
 56     {  0, 1, 8,16, 9, 2, 3,10,   // ZigZag[] =    
 57       17,24,32,25,18,11, 4, 5,   //               
 58       12,19,26,33,40,48,41,34,   //               
 59       27,20,13, 6, 7,14,21,28,   //               
 60       35,42,49,56,57,50,43,36,   //               
 61       29,22,15,23,30,37,44,51,   //               
 62       58,59,52,45,38,31,39,46,   //               
 63       53,60,61,54,47,55,62,63 }; //               
 64                                                   
 65 // static Huffman code tables from JPEG standa    
 66 // - CodesPerBitsize tables define how many Hu    
 67 //   e.g. DcLuminanceCodesPerBitsize[2] = 5 be    
 68 // - Values tables are a list of values ordere    
 69 //   e.g. AcLuminanceValues => Huffman(0x01,0x    
 70                                                   
 71 // Huffman definitions for first DC/AC tables     
 72 const uint8_t DcLuminanceCodesPerBitsize[16]      
 73 const uint8_t DcLuminanceValues         [12]      
 74 const uint8_t AcLuminanceCodesPerBitsize[16]      
 75 const uint8_t AcLuminanceValues        [162]      
 76     { 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,    
 77       0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,    
 78       0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,    
 79       0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,    
 80       0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,    
 81       0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,    
 82       0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,    
 83 // Huffman definitions for second DC/AC tables    
 84 const uint8_t DcChrominanceCodesPerBitsize[16]    
 85 const uint8_t DcChrominanceValues         [12]    
 86 const uint8_t AcChrominanceCodesPerBitsize[16]    
 87 const uint8_t AcChrominanceValues        [162]    
 88     { 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,    
 89       0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,    
 90       0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,    
 91       0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,    
 92       0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,    
 93       0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,    
 94       0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,    
 95 const int16_t CodeWordLimit = 2048; // +/-2^11    
 96                                                   
 97 // ////////////////////////////////////////       
 98 // structs                                        
 99                                                   
100 // represent a single Huffman code                
101 struct BitCode                                    
102 {                                                 
103   //BitCode() = default; // undefined state, m    
104   BitCode():code(0),numBits(0) {}                 
105   BitCode(const BitCode& a_from):code(a_from.c    
106   BitCode& operator=(const BitCode& a_from) {     
107     code = a_from.code;                           
108     numBits = a_from.numBits;                     
109     return *this;                                 
110   }                                               
111                                                   
112   BitCode(uint16_t code_, uint8_t numBits_)       
113   : code(code_), numBits(numBits_) {}             
114   uint16_t code;       // JPEG's Huffman codes    
115   uint8_t  numBits;    // number of valid bits    
116 };                                                
117                                                   
118 // wrapper for bit output operations              
119 struct BitWriter                                  
120 {                                                 
121   // user-supplied callback that writes/stores    
122   WRITE_ONE_BYTE output;                          
123   void* tag;                                      
124   // initialize writer                            
125   explicit BitWriter(WRITE_ONE_BYTE output_,vo    
126     buffer.data = 0;                              
127     buffer.numBits = 0;                           
128   }                                               
129                                                   
130   // store the most recently encoded bits that    
131   struct BitBuffer                                
132   {                                               
133     int32_t data    /*= 0*/; // actually only     
134     uint8_t numBits /*= 0*/; // number of vali    
135   } buffer;                                       
136                                                   
137   // write Huffman bits stored in BitCode, kee    
138   BitWriter& operator<<(const BitCode& data)      
139   {                                               
140     // append the new bits to those bits lefto    
141     buffer.numBits += data.numBits;               
142     buffer.data   <<= data.numBits;               
143     buffer.data    |= data.code;                  
144                                                   
145     // write all "full" bytes                     
146     while (buffer.numBits >= 8)                   
147     {                                             
148       // extract highest 8 bits                   
149       buffer.numBits -= 8;                        
150       uint8_t oneByte = uint8_t(buffer.data >>    
151       output(oneByte,tag);                        
152                                                   
153       if (oneByte == 0xFF) // 0xFF has a speci    
154         output(0,tag);         // therefore pa    
155                                                   
156       // note: I don't clear those written bit    
157       //       if you really want to "clean up    
158       //buffer.bits &= (1 << buffer.numBits) -    
159     }                                             
160     return *this;                                 
161   }                                               
162                                                   
163   // write all non-yet-written bits, fill gaps    
164   void flush()                                    
165   {                                               
166     // at most seven set bits needed to "fill"    
167     *this << BitCode(0x7F, 7); // I should set    
168   }                                               
169                                                   
170   // NOTE: all the following BitWriter functio    
171   // write a single byte                          
172   BitWriter& operator<<(uint8_t oneByte)          
173   {                                               
174     output(oneByte,tag);                          
175     return *this;                                 
176   }                                               
177                                                   
178   // write an array of bytes                      
179   template <typename T, int Size>                 
180   BitWriter& operator<<(T (&manyBytes)[Size])     
181   {                                               
182   //for (auto c : manyBytes)                      
183   //  output(c);                                  
184     for(size_t i=0;i<Size;i++) output(manyByte    
185     return *this;                                 
186   }                                               
187                                                   
188   // start a new JFIF block                       
189   void addMarker(uint8_t id, uint16_t length)     
190   {                                               
191     output(0xFF,tag); output(id,tag);     // I    
192     output(uint8_t(length >> 8),tag); // lengt    
193     output(uint8_t(length & 0xFF),tag);           
194   }                                               
195 };                                                
196                                                   
197 // ////////////////////////////////////////       
198 // functions / templates                          
199                                                   
200 // same as std::min()                             
201 template <typename Number>                        
202 inline Number minimum(Number value, Number max    
203 {                                                 
204   return value <= maximum ? value : maximum;      
205 }                                                 
206                                                   
207 // restrict a value to the interval [minimum,     
208 template <typename Number, typename Limit>        
209 inline Number clamp(Number value, Limit minVal    
210 {                                                 
211   if (value <= minValue) return minValue; // n    
212   if (value >= maxValue) return maxValue; // n    
213   return value;                           // v    
214 }                                                 
215                                                   
216 // convert from RGB to YCbCr, constants are si    
217 inline float rgb2y (float r, float g, float b)    
218 inline float rgb2cb(float r, float g, float b)    
219 inline float rgb2cr(float r, float g, float b)    
220                                                   
221 // forward DCT computation "in one dimension"     
222 inline void DCT(float block[8*8], uint8_t stri    
223 {                                                 
224   const float SqrtHalfSqrt = 1.306562965f; //     
225   const float InvSqrt      = 0.707106781f; //     
226   const float HalfSqrtSqrt = 0.382683432f; //     
227   const float InvSqrtSqrt  = 0.541196100f; //     
228                                                   
229   // modify in-place                              
230   float& block0 = block[0         ];              
231   float& block1 = block[1 * stride];              
232   float& block2 = block[2 * stride];              
233   float& block3 = block[3 * stride];              
234   float& block4 = block[4 * stride];              
235   float& block5 = block[5 * stride];              
236   float& block6 = block[6 * stride];              
237   float& block7 = block[7 * stride];              
238                                                   
239   // based on https://dev.w3.org/Amaya/libjpeg    
240   float add07 = block0 + block7; float sub07 =    
241   float add16 = block1 + block6; float sub16 =    
242   float add25 = block2 + block5; float sub25 =    
243   float add34 = block3 + block4; float sub34 =    
244                                                   
245   float add0347 = add07 + add34; float sub07_3    
246   float add1256 = add16 + add25; float sub16_2    
247                                                   
248   block0 = add0347 + add1256; block4 = add0347    
249                                                   
250   float z1 = (sub16_25 + sub07_34) * InvSqrt;     
251   block2 = sub07_34 + z1; block6 = sub07_34 -     
252                                                   
253   float sub23_45 = sub25 + sub34; // tmp10 ("o    
254   float sub12_56 = sub16 + sub25; // tmp11        
255   float sub01_67 = sub16 + sub07; // tmp12        
256                                                   
257   float z5 = (sub23_45 - sub01_67) * HalfSqrtS    
258   float z2 = sub23_45 * InvSqrtSqrt  + z5;        
259   float z3 = sub12_56 * InvSqrt;                  
260   float z4 = sub01_67 * SqrtHalfSqrt + z5;        
261   float z6 = sub07 + z3; // z11 ("phase 5")       
262   float z7 = sub07 - z3; // z13                   
263   block1 = z6 + z4; block7 = z6 - z4; // "phas    
264   block5 = z7 + z2; block3 = z7 - z2;             
265 }                                                 
266                                                   
267 // run DCT, quantize and write Huffman bit cod    
268 inline int16_t encodeBlock(BitWriter& writer,     
269                     const BitCode huffmanDC[25    
270 {                                                 
271   // "linearize" the 8x8 block, treat it as a     
272   float* block64 = (float*) block;                
273                                                   
274   // DCT: rows                                    
275   for (size_t offset = 0; offset < 8; offset++    
276     DCT(block64 + offset*8, 1);                   
277   // DCT: columns                                 
278   for (size_t offset = 0; offset < 8; offset++    
279     DCT(block64 + offset*1, 8);                   
280                                                   
281   // scale                                        
282   for (size_t i = 0; i < 8*8; i++)                
283     block64[i] *= scaled[i];                      
284                                                   
285   // encode DC (the first coefficient is the "    
286   int DC = int(block64[0] + (block64[0] >= 0 ?    
287                                                   
288   // quantize and zigzag the other 63 coeffici    
289   size_t posNonZero = 0; // find last coeffici    
290   int16_t quantized[8*8];                         
291   for (size_t i = 1; i < 8*8; i++) // start at    
292   {                                               
293     float value = block64[ZigZagInv[i]];          
294     // round to nearest integer                   
295     quantized[i] = int(value + (value >= 0 ? +    
296     // remember offset of last non-zero coeffi    
297     if (quantized[i] != 0)                        
298       posNonZero = i;                             
299   }                                               
300                                                   
301   // same "average color" as previous block ?     
302   int diff = DC - lastDC;                         
303   if (diff == 0)                                  
304     writer << huffmanDC[0x00];   // yes, write    
305   else                                            
306   {                                               
307     const BitCode bits = codewords[diff]; // n    
308     writer << huffmanDC[bits.numBits] << bits;    
309   }                                               
310                                                   
311   // encode ACs (quantized[1..63])                
312   size_t offset = 0; // upper 4 bits count the    
313   for (size_t i = 1; i <= posNonZero; i++) //     
314   {                                               
315     // zeros are encoded in a special way         
316     while (quantized[i] == 0) // found another    
317     {                                             
318       offset    += 0x10; // add 1 to the upper    
319       // split into blocks of at most 16 conse    
320       if (offset > 0xF0) // remember, the coun    
321       {                                           
322         writer << huffmanAC[0xF0]; // 0xF0 is     
323         offset = 0;                               
324       }                                           
325       i++;                                        
326     }                                             
327                                                   
328     const BitCode encoded = codewords[quantize    
329     // combine number of zeros with the number    
330     writer << huffmanAC[offset + encoded.numBi    
331     offset = 0;                                   
332   }                                               
333                                                   
334   // send end-of-block code (0x00), only neede    
335   if (posNonZero < 8*8 - 1) // = 63               
336     writer << huffmanAC[0x00];                    
337                                                   
338   return DC;                                      
339 }                                                 
340                                                   
341 // Jon's code includes the pre-generated Huffm    
342 // I don't like these "magic constants" and co    
343 inline void generateHuffmanTable(const uint8_t    
344 {                                                 
345   // process all bitsizes 1 thru 16, no JPEG H    
346   uint16_t huffmanCode = 0;                       
347   for (uint8_t numBits = 1; numBits <= 16; num    
348   {                                               
349     // ... and each code of these bitsizes        
350     for (uint8_t i = 0; i < numCodes[numBits -    
351       result[*values++] = BitCode(huffmanCode+    
352                                                   
353     // next Huffman code needs to be one bit w    
354     huffmanCode <<= 1;                            
355   }                                               
356 }                                                 
357                                                   
358 // -------------------- externally visible cod    
359                                                   
360 // the only exported function ...                 
361 inline bool writeJpeg(WRITE_ONE_BYTE output, v    
362                bool isRGB, unsigned char quali    
363 {                                                 
364   // reject invalid pointers                      
365   if (output == 0/*nullptr*/ || pixels_ == 0/*    
366     return false;                                 
367   // check image format                           
368   if (width == 0 || height == 0)                  
369     return false;                                 
370                                                   
371   // number of components                         
372   const uint16_t numComponents = isRGB ? 3 : 1    
373   // note: if there is just one component (=gr    
374   //       thus everything related to chromina    
375   //       I still compute a few things, like     
376                                                   
377   // grayscale images can't be downsampled (be    
378   if (!isRGB)                                     
379     downsample = false;                           
380                                                   
381   // wrapper for all output operations            
382   BitWriter bitWriter(output,tag);                
383                                                   
384   // ////////////////////////////////////////     
385   // JFIF headers                                 
386   const uint8_t HeaderJfif[2+2+16] =              
387       { 0xFF,0xD8,         // SOI marker (star    
388         0xFF,0xE0,         // JFIF APP0 tag       
389         0,16,              // length: 16 bytes    
390         'J','F','I','F',0, // JFIF identifier,    
391         1,1,               // JFIF version 1.1    
392         0,                 // no density units    
393         0,1,0,1,           // density: 1 pixel    
394         0,0 };             // no thumbnail (si    
395   bitWriter << HeaderJfif;                        
396                                                   
397   // ////////////////////////////////////////     
398   // comment (optional)                           
399   if (comment != 0/*nullptr*/)                    
400   {                                               
401     // look for zero terminator                   
402     uint16_t length = 0; // = strlen(comment);    
403     while (comment[length] != 0)                  
404       length++;                                   
405                                                   
406     // write COM marker                           
407     bitWriter.addMarker(0xFE, 2+length); // bl    
408     // ... and write the comment itself           
409     for (uint16_t i = 0; i < length; i++)         
410       bitWriter << comment[i];                    
411   }                                               
412                                                   
413   // ////////////////////////////////////////     
414   // adjust quantization tables to desired qua    
415                                                   
416   // quality level must be in 1 ... 100           
417   uint16_t quality = clamp<uint16_t>(quality_,    
418   // convert to an internal JPEG quality facto    
419   quality = quality < 50 ? 5000 / quality : 20    
420                                                   
421   uint8_t quantLuminance  [8*8];                  
422   uint8_t quantChrominance[8*8];                  
423   for (size_t i = 0; i < 8*8; i++)                
424   {                                               
425     int luminance   = (DefaultQuantLuminance      
426     int chrominance = (DefaultQuantChrominance    
427                                                   
428     // clamp to 1..255                            
429     quantLuminance  [i] = clamp(luminance,   1    
430     quantChrominance[i] = clamp(chrominance, 1    
431   }                                               
432                                                   
433   // write quantization tables                    
434   bitWriter.addMarker(0xDB, 2 + (isRGB ? 2 : 1    
435                                                   
436                                                   
437   bitWriter   << 0x00 << quantLuminance;   //     
438   if (isRGB)                                      
439     bitWriter << 0x01 << quantChrominance; //     
440                                                   
441   // ////////////////////////////////////////     
442   // write image infos (SOF0 - start of frame)    
443   bitWriter.addMarker(0xC0, 2+6+3*numComponent    
444                                                   
445   // 8 bits per channel                           
446   bitWriter << 0x08                               
447   // image dimensions (big-endian)                
448             << (height >> 8) << (height & 0xFF    
449             << (width  >> 8) << (width  & 0xFF    
450                                                   
451   // sampling and quantization tables for each    
452   bitWriter << numComponents;       // 1 compo    
453   for (uint16_t id = 1; id <= numComponents; i    
454     bitWriter <<  id                // compone    
455     // bitmasks for sampling: highest 4 bits:     
456               << (id == 1 && downsample ? 0x22    
457               << (id == 1 ? 0 : 1); // use qua    
458                                                   
459   // ////////////////////////////////////////     
460   // Huffman tables                               
461   // DHT marker - define Huffman tables           
462   bitWriter.addMarker(0xC4, isRGB ? (2+208+208    
463                             // 2 bytes for the    
464                             //   1+16+12  for     
465                             //   1+16+162 for     
466                             //   1+16+12  for     
467                             //   1+16+162 for     
468                                                   
469   // store luminance's DC+AC Huffman table def    
470   bitWriter << 0x00 // highest 4 bits: 0 => DC    
471             << DcLuminanceCodesPerBitsize         
472             << DcLuminanceValues;                 
473   bitWriter << 0x10 // highest 4 bits: 1 => AC    
474             << AcLuminanceCodesPerBitsize         
475             << AcLuminanceValues;                 
476                                                   
477   // compute actual Huffman code tables (see J    
478   BitCode huffmanLuminanceDC[256];                
479   BitCode huffmanLuminanceAC[256];                
480   generateHuffmanTable(DcLuminanceCodesPerBits    
481   generateHuffmanTable(AcLuminanceCodesPerBits    
482                                                   
483   // chrominance is only relevant for color im    
484   BitCode huffmanChrominanceDC[256];              
485   BitCode huffmanChrominanceAC[256];              
486   if (isRGB)                                      
487   {                                               
488     // store luminance's DC+AC Huffman table d    
489     bitWriter << 0x01 // highest 4 bits: 0 =>     
490               << DcChrominanceCodesPerBitsize     
491               << DcChrominanceValues;             
492     bitWriter << 0x11 // highest 4 bits: 1 =>     
493               << AcChrominanceCodesPerBitsize     
494               << AcChrominanceValues;             
495                                                   
496     // compute actual Huffman code tables (see    
497     generateHuffmanTable(DcChrominanceCodesPer    
498     generateHuffmanTable(AcChrominanceCodesPer    
499   }                                               
500                                                   
501   // ////////////////////////////////////////     
502   // start of scan (there is only a single sca    
503   bitWriter.addMarker(0xDA, 2+1+2*numComponent    
504                                                   
505                                                   
506   // assign Huffman tables to each component      
507   bitWriter << numComponents;                     
508   for (uint16_t id = 1; id <= numComponents; i    
509     // highest 4 bits: DC Huffman table, lowes    
510     bitWriter << id << (id == 1 ? 0x00 : 0x11)    
511                                                   
512   // constant values for our baseline JPEGs (w    
513   static const uint8_t Spectral[3] = { 0, 63,     
514   bitWriter << Spectral;                          
515                                                   
516   // ////////////////////////////////////////     
517   // adjust quantization tables with AAN scali    
518   float scaledLuminance  [8*8];                   
519   float scaledChrominance[8*8];                   
520   for (size_t i = 0; i < 8*8; i++)                
521   {                                               
522     size_t row    = ZigZagInv[i] / 8; // same     
523     size_t column = ZigZagInv[i] % 8; // same     
524                                                   
525     // scaling constants for AAN DCT algorithm    
526     static const float AanScaleFactors[8] = {     
527     float factor = 1 / (AanScaleFactors[row] *    
528     scaledLuminance  [ZigZagInv[i]] = factor /    
529     scaledChrominance[ZigZagInv[i]] = factor /    
530     // if you really want JPEGs that are bitwi    
531     //static const float aasf[] = { 1.0f * 2.8    
532     //scaledLuminance  [ZigZagInv[i]] = 1 / (q    
533     //scaledChrominance[ZigZagInv[i]] = 1 / (q    
534   }                                               
535                                                   
536   // ////////////////////////////////////////     
537   // precompute JPEG codewords for quantized D    
538   BitCode  codewordsArray[2 * CodeWordLimit];     
539   BitCode* codewords = &codewordsArray[CodeWor    
540   uint8_t numBits = 1; // each codeword has at    
541   int32_t mask    = 1; // mask is always 2^num    
542   for (int16_t value = 1; value < CodeWordLimi    
543   {                                               
544     // numBits = position of highest set bit (    
545     // mask    = (2^numBits) - 1                  
546     if (value > mask) // one more bit ?           
547     {                                             
548       numBits++;                                  
549       mask = (mask << 1) | 1; // append a set     
550     }                                             
551     codewords[-value] = BitCode(mask - value,     
552     codewords[+value] = BitCode(       value,     
553   }                                               
554                                                   
555   // just convert image data from void*           
556   const uint8_t* pixels = (const uint8_t*)pixe    
557                                                   
558   // the next two variables are frequently use    
559   const unsigned short maxWidth  = width  - 1;    
560   const unsigned short maxHeight = height - 1;    
561                                                   
562   // process MCUs (minimum codes units) => ima    
563   const unsigned short sampling = downsample ?    
564   const unsigned short mcuSize  = 8 * sampling    
565                                                   
566   // average color of the previous MCU            
567   int16_t lastYDC = 0, lastCbDC = 0, lastCrDC     
568   // convert from RGB to YCbCr                    
569   float Y[8][8], Cb[8][8], Cr[8][8];              
570                                                   
571   for (unsigned short mcuY = 0; mcuY < height;    
572     for (unsigned short mcuX = 0; mcuX < width    
573     {                                             
574       // YCbCr 4:4:4 format: each MCU is a 8x8    
575       // YCbCr 4:2:0 format: each MCU represen    
576       for (unsigned short blockY = 0; blockY <    
577         for (unsigned short blockX = 0; blockX    
578         {                                         
579           // now we finally have an 8x8 block     
580           for (unsigned short deltaY = 0; delt    
581           {                                       
582             size_t column = minimum(uint16_t(m    
583             size_t row    = minimum(uint16_t(m    
584             for (size_t deltaX = 0; deltaX < 8    
585             {                                     
586               // find actual pixel position wi    
587               size_t pixelPos = row * int(widt    
588               if (column < maxWidth)              
589                 column++;                         
590                                                   
591               // grayscale images have solely     
592               if (!isRGB)                         
593               {                                   
594                 Y[deltaY][deltaX] = pixels[pix    
595                 continue;                         
596               }                                   
597                                                   
598               // RGB: 3 bytes per pixel (where    
599               uint8_t r = pixels[3 * pixelPos     
600               uint8_t g = pixels[3 * pixelPos     
601               uint8_t b = pixels[3 * pixelPos     
602                                                   
603               Y   [deltaY][deltaX] = rgb2y (r,    
604               // YCbCr444 is easy - the more c    
605               if (!downsample)                    
606               {                                   
607                 Cb[deltaY][deltaX] = rgb2cb(r,    
608                 Cr[deltaY][deltaX] = rgb2cr(r,    
609               }                                   
610             }                                     
611           }                                       
612                                                   
613         // encode Y channel                       
614         lastYDC = encodeBlock(bitWriter, Y, sc    
615         // Cb and Cr are encoded about 50 line    
616       }                                           
617                                                   
618       // grayscale images don't need any Cb an    
619       if (!isRGB)                                 
620         continue;                                 
621                                                   
622       // /////////////////////////////////////    
623       // the following lines are only relevant    
624       // average/downsample chrominance of fou    
625       if (downsample)                             
626         for (short deltaY = 7; downsample && d    
627         {                                         
628           size_t row      = minimum(uint16_t(m    
629           size_t column   =         mcuX;         
630           size_t pixelPos = (row * int(width)     
631                                                   
632           // deltas (in bytes) to next row / c    
633           size_t rowStep    = (row    < maxHei    
634           size_t columnStep = (column < maxWid    
635                                                   
636           for (short deltaX = 0; deltaX < 8; d    
637           {                                       
638             // let's add all four samples (2x2    
639             size_t right     = pixelPos + colu    
640             size_t down      = pixelPos +         
641             size_t downRight = pixelPos + colu    
642                                                   
643             // note: cast from 8 bits to >8 bi    
644             short r = short(pixels[pixelPos       
645             short g = short(pixels[pixelPos +     
646             short b = short(pixels[pixelPos +     
647                                                   
648             // convert to Cb and Cr               
649             Cb[deltaY][deltaX] = rgb2cb(r, g,     
650             Cr[deltaY][deltaX] = rgb2cr(r, g,     
651                                                   
652             // step forward to next 2x2 area      
653             pixelPos += 2*3; // 2 pixels => 6     
654             column   += 2;                        
655                                                   
656             // reached right border ?             
657             if (column >= maxWidth)               
658             {                                     
659               columnStep = 0;                     
660               pixelPos = ((row + 1) * int(widt    
661             }                                     
662           }                                       
663         } // end of YCbCr420 code for Cb and C    
664                                                   
665       // encode Cb and Cr                         
666       lastCbDC = encodeBlock(bitWriter, Cb, sc    
667       lastCrDC = encodeBlock(bitWriter, Cr, sc    
668     }                                             
669                                                   
670   bitWriter.flush(); // now image is completel    
671                                                   
672   // ///////////////////////////                  
673   // EOI marker                                   
674   bitWriter << 0xFF << 0xD9; // this marker ha    
675   return true;                                    
676 } // writeJpeg()                                  
677                                                   
678 }}                                                
679