jpeg.cpp

00001
00002 /***************************************************************************
00003  *  jpeg.cp - JPEG writer
00004  *
00005  *  Generated: Wed Jun 28 11:36:54 2006 (my brother's 18th birthday)
00006  *  Copyright  2005-2007  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023
00024 #include <core/exception.h>
00025 #include <fvutils/writers/jpeg.h>
00026 #include <fvutils/color/yuvrgb.h>
00027
00028 #include <cstdio>
00029 #include <cerrno>
00030 #include <cstdlib>
00031 #include <cstring>
00032 #include <string.h>
00033 extern "C" {
00034 #include <jpeglib.h>
00035 }
00036
00037 using namespace fawkes;
00038 
00039 /** @class JpegWriter jpeg.h <fvutils/writers/jpeg.h>
00040  * JPEG file writer.
00041  */
00042 
00043 /** Constructor.
00044  * @param quality quality, value between 0 and 100
00045  */
00046 JpegWriter::JpegWriter(int quality)
00047   : Writer("jpg")
00048 {
00049   buffer = NULL;
00050
00051   this->quality  = (quality > 0) ? quality : -quality;
00052 }
00053 
00054 /** Constructor.
00055  * @param filename file name to write to
00056  * @param quality quality, value between 0 and 100
00057  */
00058 JpegWriter::JpegWriter(const char *filename, int quality)
00059   : Writer("jpg")
00060 {
00061   set_filename(filename);
00062
00063   buffer = NULL;
00064
00065   this->quality  = (quality > 0) ? quality : -quality;
00066 }
00067
00068 
00069 /** Destructor. */
00070 JpegWriter::~JpegWriter()
00071 {
00072 }
00073
00074
00075 void
00076 JpegWriter::set_buffer(colorspace_t cspace, unsigned char *buffer)
00077 {
00078   if (cspace == YUV422_PLANAR) {
00079     this->buffer = buffer;
00080   } else {
00081     throw Exception("Incompatible colorspace, can only hand YUV422_PLANAR images");
00082   }
00083 }
00084
00085
00086 void
00087 JpegWriter::write()
00088 {
00089   if ( buffer == NULL ) {
00090     throw Exception("JpegWriter::read() error: buffer == NULL");
00091   }
00092
00093   if ((outfile = fopen(filename, "wb")) == NULL) {
00094     Exception e("Cannot open JPEG file for writing", errno);
00095     e.append("File %s could not be opened", filename);
00096     throw e;
00097   }
00098
00099   int row_stride;
00100   struct jpeg_compress_struct cinfo;
00101   struct jpeg_error_mgr         jerr;
00102
00103   cinfo.err = jpeg_std_error( &jerr );
00104   jpeg_create_compress( &cinfo );
00105   jpeg_stdio_dest( &cinfo, outfile );
00106
00107   cinfo.image_width  = width;
00108   cinfo.image_height = height;
00109   cinfo.input_components = 3;
00110   cinfo.in_color_space = JCS_RGB;
00111
00112   jpeg_set_defaults(&cinfo);
00113   jpeg_set_quality(&cinfo, quality, true /* limit to baseline-JPEG values */);
00114
00115   jpeg_start_compress( &cinfo, true );
00116   row_stride = cinfo.image_width * cinfo.input_components;
00117
00118   row_buffer = (unsigned char *)malloc( row_stride );
00119
00120   while ( cinfo.next_scanline < cinfo.image_height ) {
00121     convert_line_yuv422planar_to_rgb( buffer, row_buffer,
00122                                       cinfo.image_width, cinfo.image_height,
00123                                       cinfo.next_scanline, 0 );
00124     jpeg_write_scanlines( &cinfo, &row_buffer, 1 );
00125   }
00126
00127   free(row_buffer);
00128
00129   jpeg_finish_compress( &cinfo );
00130
00131   jpeg_destroy_compress( &cinfo );
00132   fclose( outfile );
00133
00134 }
00135