Geant4 Cross Reference

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

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 #ifndef tools_toojpeg
  2 #define tools_toojpeg
  3 
  4 // G.Barrand: pure header version of toojpeg found at https://github.com/stbrumme/toojpeg
  5 //            The original namespace TooJpeg had been changed to tools::toojpeg to avoid
  6 //            clashes with potential other usage of toojpeg within the same software.
  7 
  8 /*
  9 zlib License
 10 
 11 Copyright (c) 2011-2016 Stephan Brumme
 12 
 13 This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
 14 Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
 15 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
 16    If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
 17 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
 18 3. This notice may not be removed or altered from any source distribution.
 19 */
 20 
 21 // //////////////////////////////////////////////////////////
 22 // toojpeg.h
 23 // written by Stephan Brumme, 2018-2019
 24 // see https://create.stephan-brumme.com/toojpeg/
 25 //
 26 
 27 // This is a compact baseline JPEG/JFIF writer, written in C++ (but looks like C for the most part).
 28 // Its interface has only one function: writeJpeg() - and that's it !
 29 
 30 namespace tools {
 31 namespace toojpeg
 32 {
 33   // write one byte (to disk, memory, ...)
 34   typedef void (*WRITE_ONE_BYTE)(unsigned char,void*);
 35   // this callback is called for every byte generated by the encoder and behaves similar to fputc
 36   // if you prefer stylish C++11 syntax then it can be a lambda, too:
 37   // auto myOutput = [](unsigned char oneByte) { fputc(oneByte, output); };
 38 
 39   // output       - callback that stores a single byte (writes to disk, memory, ...)
 40   // pixels       - stored in RGB format or grayscale, stored from upper-left to lower-right
 41   // width,height - image size
 42   // isRGB        - true if RGB format (3 bytes per pixel); false if grayscale (1 byte per pixel)
 43   // quality      - between 1 (worst) and 100 (best)
 44   // downsample   - if true then YCbCr 4:2:0 format is used (smaller size, minor quality loss) instead of 4:4:4, not relevant for grayscale
 45   // comment      - optional JPEG comment (0/NULL if no comment), must not contain ASCII code 0xFF
 46   bool writeJpeg(WRITE_ONE_BYTE output,void*, const void* pixels, unsigned short width, unsigned short height,
 47                  bool isRGB = true, unsigned char quality = 90, bool downsample = false, const char* comment = 0/*nullptr*/);
 48 }}
 49 
 50 // My main inspiration was Jon Olick's Minimalistic JPEG writer
 51 // ( https://www.jonolick.com/code.html => direct link is https://www.jonolick.com/uploads/7/9/2/1/7921194/jo_jpeg.cpp ).
 52 // However, his code documentation is quite sparse - probably because it wasn't written from scratch and is (quote:) "based on a javascript jpeg writer",
 53 // most likely Andreas Ritter's code: https://github.com/eugeneware/jpeg-js/blob/master/lib/encoder.js
 54 //
 55 // Therefore I wrote the whole lib from scratch and tried hard to add tons of comments to my code, especially describing where all those magic numbers come from.
 56 // And I managed to remove the need for any external includes ...
 57 // yes, that's right: my library has no (!) includes at all, not even #include <stdlib.h>
 58 // Depending on your callback WRITE_ONE_BYTE, the library writes either to disk, or in-memory, or wherever you wish.
 59 // Moreover, no dynamic memory allocations are performed, just a few bytes on the stack.
 60 //
 61 // In contrast to Jon's code, compression can be significantly improved in many use cases:
 62 // a) grayscale JPEG images need just a single Y channel, no need to save the superfluous Cb + Cr channels
 63 // b) YCbCr 4:2:0 downsampling is often about 20% more efficient (=smaller) than the default YCbCr 4:4:4 with only little visual loss
 64 //
 65 // TooJpeg 1.2+ compresses about twice as fast as jo_jpeg (and about half as fast as libjpeg-turbo).
 66 // A few benchmark numbers can be found on my website https://create.stephan-brumme.com/toojpeg/#benchmark
 67 //
 68 // Last but not least you can optionally add a JPEG comment.
 69 //
 70 // Your C++ compiler needs to support a reasonable subset of C++11 (g++ 4.7 or Visual C++ 2013 are sufficient).
 71 // I haven't tested the code on big-endian systems or anything that smells like an apple.
 72 //
 73 // USE AT YOUR OWN RISK. Because you are a brave soul :-)
 74 
 75 #include "toojpeg.icc"
 76 
 77 //G.Barrand specific:
 78 
 79 #include "sout"
 80 
 81 #include <cstdio>
 82 #include <ostream>
 83 
 84 namespace tools {
 85 namespace toojpeg {
 86 
 87 inline void write_one_byte(unsigned char a_byte,void* a_tag) {::fputc(a_byte,(FILE*)a_tag);}
 88 
 89 inline bool write(std::ostream& a_out,
 90                   const std::string& a_file,
 91                   unsigned char* a_buffer,
 92                   unsigned int a_width,
 93                   unsigned int a_height,
 94                   unsigned int a_bpp,
 95                   int a_quality) {
 96   if(a_bpp!=3) {
 97     a_out << "tools::toojpeg::write : bpp " << a_bpp << " not handled." << std::endl;
 98     return false;
 99   }     
100   FILE* file = ::fopen(a_file.c_str(),"wb");
101   if(!file) {
102     a_out << "tools::toojpeg::write : can't open file " << sout(a_file) << "." << std::endl;
103     return false;
104   }
105   if(!writeJpeg(write_one_byte,file,a_buffer,(unsigned short)a_width,(unsigned short)a_height,true,(unsigned char)a_quality)) {
106     ::fclose(file);
107     a_out << "tools::toojpeg::write : writeJpeg failed for file " << sout(a_file) << "." << std::endl;
108     return false;
109   }
110   ::fclose(file);
111   return true;
112 }
113 
114 }}
115 
116 #endif