// This is a hack into octave // based on jpgwrite.c by jpgread by Drea Thomas, The Mathworks, and the // examples in the IJG distribution. // // (C) 1998 Andy Adler. This code is in the public domain // USE THIS CODE AT YOUR OWN RISK // // $Id: jpgwrite.cc,v 1.3 2002/11/02 10:40:31 pkienzle Exp $ // #include #include #ifdef __cplusplus extern "C" { #endif #include "jpeglib.h" #ifdef __cplusplus } //extern "C" #endif #define GRAYIMAGES /* * Simple jpeg writing MEX-file. * * Synopsis: * jpgwrite(filename,r,g,b,quality) * * Compilation: * First, try * mkoctfile jpgwrite.cc -ljpeg * * If this doesn't work, then do * * Calls the jpeg library which is part of * "The Independent JPEG Group's JPEG software" collection. * * The jpeg library came from, * * ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6.tar.gz */ DEFUN_DLD (jpgwrite, args, , "JPGWRITE Write a JPEG file to disk.\n\ jpgwrite('filename',R,G,B,quality) writes the specified file\n\ using the Red, Green, and Blue intensity matrices, at the given quality.\n\ \n\ jpgwrite('filename',M,quality) writes a grey-scale image.\n\ \n\ Data must be [0 255] or the high bytes will be lost\n\ \n\ If specified, quality should be in the range 1-100 and will default to \n\ 75 if not specified. 100 is best quality, 1 is best compression.\n\ \n\ See also JPGREAD") { octave_value_list retval; int nargin = args.length(); FILE * outfile; JSAMPARRAY buffer; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; int quality=75; //default value // // We bail out if the input parameters are bad // if (nargin < 2 || !args(0).is_string() ) { print_usage ("jpgwrite"); return retval; } // // Open jpg file // std::string filename = args(0).string_value(); if ((outfile = fopen(filename.c_str(), "wb")) == NULL) { error("Couldn't open file"); return retval; } // // Set Jpeg parameters // if (nargin == 3) { quality= (int) args(2).double_value(); } else if (nargin == 5) { quality= (int) args(4).double_value(); } // // Initialize the jpeg library // Read the jpg header to get info about size and color depth // cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, outfile); // // set parameters for compression // if ( nargin <= 3 ) { // // we're here because only one matrix of grey scale values was provided // Matrix avg= args(1).matrix_value(); long image_width = args(1).columns(); long image_height = args(1).rows(); cinfo.image_width = image_width; /* image width and height, in pixels */ cinfo.image_height = image_height; #ifdef GRAYIMAGES cinfo.input_components = 1; cinfo.input_components = JCS_GRAYSCALE; #else cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; #endif jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); // // start compressor // jpeg_start_compress(&cinfo, TRUE); // // Allocate buffer for one scan line // long row_stride = image_width * cinfo.input_components ; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); // // Now, loop thru each of the scanlines. For each, copy the image // data from the buffer, data must be [0 255] // for( long j=0; cinfo.next_scanline < cinfo.image_height; j++) { for(unsigned long i=0; ialloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); // // Now, loop thru each of the scanlines. For each, copy the image // data from the buffer, data must be [0 255] // for( long j=0; cinfo.next_scanline < cinfo.image_height; j++) { for(unsigned long i=0; i 3 // // Clean up // jpeg_finish_compress(&cinfo); fclose(outfile); jpeg_destroy_compress(&cinfo); return retval; }