1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
#include <config.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <errno.h>
#include "GFile_JPEG.h"
extern "C" {
#include <jpeglib.h>
}
/* GFile (ie. GImage) decendent for reading JPEG files.
*
* Written by: Chris Studholme
* Last Update: 28-May-2000
* Copyright: GPL (http://www.fsf.org/copyleft/gpl.html)
*/
/* ================ GFile_JPEG methods ================ */
GFile_JPEG::GFile_JPEG(const char* filename, bool fast) {
red=green=blue=NULL;
w=h=0;
// allocate and initialize a JPEG compression object
jpeg_decompress_struct cinfo;
jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
// specify the source for the compressed data
FILE* infile;
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return;
}
jpeg_stdio_src(&cinfo, infile);
// call jpeg_read_header() to obtain image info
jpeg_read_header(&cinfo, TRUE);
// set parameters for decompression
cinfo.dct_method = JDCT_FLOAT;
// jpeg_start_decompress(...);
jpeg_start_decompress(&cinfo);
w=cinfo.output_width;
h=cinfo.output_height;
if (cinfo.output_components!=3) {
fprintf(stderr,"GFile_JPEG: only full color JPEG images are supported\n");
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return;
}
int row_stride = cinfo.output_width * cinfo.output_components;
/* Make a one-row-high sample array that will go away when done with image */
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
unsigned char* r = new unsigned char[w*h];
unsigned char* g = new unsigned char[w*h];
unsigned char* b = new unsigned char[w*h];
// while (scan lines remain to be read)
for (int y=0; y<h; ++y) {
// jpeg_read_scanlines(...);
jpeg_read_scanlines(&cinfo,buffer,1);
for (int x=0; x<w; ++x) {
r[y*w+x] = buffer[0][3*x+0];
g[y*w+x] = buffer[0][3*x+1];
b[y*w+x] = buffer[0][3*x+2];
}
}
memset(histogram,0,sizeof(histogram));
addToHistogram(histogram,r,w*h);
addToHistogram(histogram,g,w*h);
addToHistogram(histogram,b,w*h);
// jpeg_finish_decompress(...);
jpeg_finish_decompress(&cinfo);
// release the JPEG decompression object
jpeg_destroy_decompress(&cinfo);
fclose(infile);
// create linear mapping
fprintf(stderr,"Initializing linear matrix... ");
red = new GImageComponent0(r,w,h,fast?-1:0);
delete[] r;
fprintf(stderr,"red... ");
green = new GImageComponent0(g,w,h,fast?-1:0);
delete[] g;
fprintf(stderr,"green... ");
blue = new GImageComponent0(b,w,h,fast?-1:0);
delete[] b;
fprintf(stderr,"blue, done.\n");
if (!fast)
fprintf(stderr,"Total Error is %g\n",red->getTotalError()+
green->getTotalError()+blue->getTotalError());
}
GFile_JPEG::~GFile_JPEG() {
if (red)
delete red;
if (green)
delete green;
if (blue)
delete blue;
}
bool GFile_JPEG::supportsFile(FILE* file) {
if (fseek(file,0,SEEK_SET)!=0) {
fprintf(stderr,"GFile_JPEG::supportsFile() fseek() failed %d\n",errno);
return false;
}
unsigned char header[2];
if (fread(header,sizeof(header),1,file)!=1) {
fprintf(stderr,"GFile_JPEG::supportsFile() fread() failed %d\n",errno);
return false;
}
return ((header[0]==0x0FF)&&(header[1]==0x0D8));
}
|