Warning, /include/Geant4/tools/toojpeg is written in an unsupported language. File is not indexed.
0001 #ifndef tools_toojpeg
0002 #define tools_toojpeg
0003
0004 // G.Barrand: pure header version of toojpeg found at https://github.com/stbrumme/toojpeg
0005 // The original namespace TooJpeg had been changed to tools::toojpeg to avoid
0006 // clashes with potential other usage of toojpeg within the same software.
0007
0008 /*
0009 zlib License
0010
0011 Copyright (c) 2011-2016 Stephan Brumme
0012
0013 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.
0014 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:
0015 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
0016 If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
0017 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
0018 3. This notice may not be removed or altered from any source distribution.
0019 */
0020
0021 // //////////////////////////////////////////////////////////
0022 // toojpeg.h
0023 // written by Stephan Brumme, 2018-2019
0024 // see https://create.stephan-brumme.com/toojpeg/
0025 //
0026
0027 // This is a compact baseline JPEG/JFIF writer, written in C++ (but looks like C for the most part).
0028 // Its interface has only one function: writeJpeg() - and that's it !
0029
0030 namespace tools {
0031 namespace toojpeg
0032 {
0033 // write one byte (to disk, memory, ...)
0034 typedef void (*WRITE_ONE_BYTE)(unsigned char,void*);
0035 // this callback is called for every byte generated by the encoder and behaves similar to fputc
0036 // if you prefer stylish C++11 syntax then it can be a lambda, too:
0037 // auto myOutput = [](unsigned char oneByte) { fputc(oneByte, output); };
0038
0039 // output - callback that stores a single byte (writes to disk, memory, ...)
0040 // pixels - stored in RGB format or grayscale, stored from upper-left to lower-right
0041 // width,height - image size
0042 // isRGB - true if RGB format (3 bytes per pixel); false if grayscale (1 byte per pixel)
0043 // quality - between 1 (worst) and 100 (best)
0044 // 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
0045 // comment - optional JPEG comment (0/NULL if no comment), must not contain ASCII code 0xFF
0046 bool writeJpeg(WRITE_ONE_BYTE output,void*, const void* pixels, unsigned short width, unsigned short height,
0047 bool isRGB = true, unsigned char quality = 90, bool downsample = false, const char* comment = 0/*nullptr*/);
0048 }}
0049
0050 // My main inspiration was Jon Olick's Minimalistic JPEG writer
0051 // ( https://www.jonolick.com/code.html => direct link is https://www.jonolick.com/uploads/7/9/2/1/7921194/jo_jpeg.cpp ).
0052 // However, his code documentation is quite sparse - probably because it wasn't written from scratch and is (quote:) "based on a javascript jpeg writer",
0053 // most likely Andreas Ritter's code: https://github.com/eugeneware/jpeg-js/blob/master/lib/encoder.js
0054 //
0055 // 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.
0056 // And I managed to remove the need for any external includes ...
0057 // yes, that's right: my library has no (!) includes at all, not even #include <stdlib.h>
0058 // Depending on your callback WRITE_ONE_BYTE, the library writes either to disk, or in-memory, or wherever you wish.
0059 // Moreover, no dynamic memory allocations are performed, just a few bytes on the stack.
0060 //
0061 // In contrast to Jon's code, compression can be significantly improved in many use cases:
0062 // a) grayscale JPEG images need just a single Y channel, no need to save the superfluous Cb + Cr channels
0063 // 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
0064 //
0065 // TooJpeg 1.2+ compresses about twice as fast as jo_jpeg (and about half as fast as libjpeg-turbo).
0066 // A few benchmark numbers can be found on my website https://create.stephan-brumme.com/toojpeg/#benchmark
0067 //
0068 // Last but not least you can optionally add a JPEG comment.
0069 //
0070 // Your C++ compiler needs to support a reasonable subset of C++11 (g++ 4.7 or Visual C++ 2013 are sufficient).
0071 // I haven't tested the code on big-endian systems or anything that smells like an apple.
0072 //
0073 // USE AT YOUR OWN RISK. Because you are a brave soul :-)
0074
0075 #include "toojpeg.icc"
0076
0077 //G.Barrand specific:
0078
0079 #include "sout"
0080
0081 #include <cstdio>
0082 #include <ostream>
0083
0084 namespace tools {
0085 namespace toojpeg {
0086
0087 inline void write_one_byte(unsigned char a_byte,void* a_tag) {::fputc(a_byte,(FILE*)a_tag);}
0088
0089 inline bool write(std::ostream& a_out,
0090 const std::string& a_file,
0091 unsigned char* a_buffer,
0092 unsigned int a_width,
0093 unsigned int a_height,
0094 unsigned int a_bpp,
0095 int a_quality) {
0096 if(a_bpp!=3) {
0097 a_out << "tools::toojpeg::write : bpp " << a_bpp << " not handled." << std::endl;
0098 return false;
0099 }
0100 FILE* file = ::fopen(a_file.c_str(),"wb");
0101 if(!file) {
0102 a_out << "tools::toojpeg::write : can't open file " << sout(a_file) << "." << std::endl;
0103 return false;
0104 }
0105 if(!writeJpeg(write_one_byte,file,a_buffer,(unsigned short)a_width,(unsigned short)a_height,true,(unsigned char)a_quality)) {
0106 ::fclose(file);
0107 a_out << "tools::toojpeg::write : writeJpeg failed for file " << sout(a_file) << "." << std::endl;
0108 return false;
0109 }
0110 ::fclose(file);
0111 return true;
0112 }
0113
0114 }}
0115
0116 #endif