Files
secondo/Tools/Generators/Pictures/checkImage.cpp

321 lines
8.3 KiB
C++
Raw Permalink Normal View History

2026-01-23 17:03:45 +08:00
/*
----
This file is part of SECONDO.
Copyright (C) 2014,
Faculty of Mathematics and Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
*/
extern "C" {
#include <jinclude.h>
#include <jpeglib.h>
}
#include <stdio.h>
typedef struct
{
struct jpeg_source_mgr pub;
/*
public fields
*/
unsigned long src_pos;
unsigned long src_size;
unsigned char *src_buffer;
JOCTET * buffer;
boolean start_of_file;
}
mem_source_mgr;
typedef mem_source_mgr * mem_src_ptr;
#define INPUT_BUF_SIZE 4096
METHODDEF(boolean) mem_fill_input_buffer (j_decompress_ptr cinfo)
{
mem_src_ptr src = (mem_src_ptr) cinfo->src;
size_t nbytes;
nbytes = INPUT_BUF_SIZE;
if (src->src_pos + INPUT_BUF_SIZE > src->src_size)
{
nbytes = src->src_size - src->src_pos;
}
memcpy(src->buffer,
(unsigned char*)((unsigned long)src->src_buffer + src->src_pos),
nbytes);
src->src_pos += nbytes;
src->pub.next_input_byte = src->buffer;
src->pub.bytes_in_buffer = nbytes;
src->start_of_file = FALSE;
return TRUE;
}
METHODDEF(void) mem_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
mem_src_ptr src = (mem_src_ptr) cinfo->src;
/*
Just a dumb implementation for now. Could use ~fseek()~ except
it doesn't work on pipes. Not clear that being smart is worth
any trouble anyway --- large skips are infrequent.
*/
if (num_bytes > 0) {
while (num_bytes > (long) src->pub.bytes_in_buffer) {
num_bytes -= (long) src->pub.bytes_in_buffer;
(void) mem_fill_input_buffer(cinfo);
/*
note we assume that ~fill\_input\_buffer~ will never return ~FALSE~,
so suspension need not be handled.
*/
}
src->pub.next_input_byte += (size_t) num_bytes;
src->pub.bytes_in_buffer -= (size_t) num_bytes;
}
}
unsigned char* getBuffer( char* filename, size_t& size ){
FILE *f;
f = fopen(filename, "rb");
if(f==0){ // file could not be opered
return 0;
}
fseek(f, 0 ,SEEK_END);
size = ftell(f);
fseek(f, 0 ,SEEK_SET);
unsigned char* buffer = new unsigned char[size];
fread(buffer, size, 1, f);
fclose(f);
return buffer;
}
METHODDEF(void) mem_init_source (j_decompress_ptr cinfo)
{
mem_src_ptr src = (mem_src_ptr) cinfo->src;
/*
We reset the empty-input-file flag for each image,
but we don't clear the input buffer.
This is correct behavior for reading a series of images from one source.
*/
src->start_of_file = TRUE;
}
METHODDEF(void) mem_term_source (j_decompress_ptr cinfo)
{
/*
no work necessary here
*/
}
void jpeg_mem_src (j_decompress_ptr cinfo,
unsigned char *JPEGBuffer,
unsigned long JPEGBufferSize)
{
mem_src_ptr src;
/*
The source object and input buffer are made permanent so that a series
of JPEG images can be read from the same file by calling ~jpeg\_stdio\_src~
only before the first one. (If we discarded the buffer at the end of
one image, we'd likely lose the start of the next one.)
This makes it unsafe to use this manager and a different source
manager serially with the same JPEG object. Caveat programmer.
*/
if (cinfo->src == NULL)
{
/*
first time for this JPEG object?
*/
cinfo->src =
(struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) (
(j_common_ptr) cinfo,
JPOOL_PERMANENT,
SIZEOF(mem_source_mgr));
src = (mem_src_ptr) cinfo->src;
src->buffer =
(JOCTET *)
(*cinfo->mem->alloc_small) (
(j_common_ptr) cinfo,
JPOOL_PERMANENT,
INPUT_BUF_SIZE * SIZEOF(JOCTET));
}
src = (mem_src_ptr) cinfo->src;
src->pub.init_source = mem_init_source;
src->pub.fill_input_buffer = mem_fill_input_buffer;
src->pub.skip_input_data = mem_skip_input_data;
src->pub.resync_to_restart = jpeg_resync_to_restart;
src->pub.term_source = mem_term_source;
src->src_buffer = JPEGBuffer;
src->src_size = JPEGBufferSize;
src->src_pos = 0;
src->pub.bytes_in_buffer = 0;
src->pub.next_input_byte = NULL;
}
int ReadJPEGHeader(unsigned char *JPEGBuffer,
unsigned long JPEGBufferSize,
unsigned long *Width,
unsigned long *Height,
bool *GrayScale) {
jpeg_decompress_struct cinfo;
jpeg_error_mgr errorMgr;
memset(&cinfo, 0, sizeof(jpeg_decompress_struct));
memset(&errorMgr, 0, sizeof(jpeg_error_mgr));
cinfo.err = jpeg_std_error(&errorMgr);
jpeg_create_decompress(&cinfo);
// Mem Manager initialisieren
jpeg_mem_src(&cinfo, JPEGBuffer, JPEGBufferSize);
jpeg_read_header(&cinfo, TRUE);
jpeg_destroy_decompress(&cinfo);
if (Width != 0)
{
*Width = cinfo.image_width;
} else {
return 1;
}
if (Height != 0)
{
*Height = cinfo.image_height;
} else {
return 2;
}
if (GrayScale != 0)
{
*GrayScale = false;
if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
{
*GrayScale = true;
}
}
return 0;
}
void CreateRGBBuffer(unsigned char *JPEGBuffer,
unsigned long JPEGBufferSize)
{
unsigned long buffer_pos;
JSAMPARRAY line;
int row_stride;
jpeg_decompress_struct cinfo;
jpeg_error_mgr errorMgr;
memset(&cinfo, 0, sizeof(jpeg_decompress_struct));
memset(&errorMgr, 0, sizeof(jpeg_error_mgr));
cinfo.err = jpeg_std_error(&errorMgr);
jpeg_create_decompress(&cinfo);
// Mem Manager initialisieren
jpeg_mem_src(&cinfo, JPEGBuffer, JPEGBufferSize);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
// Anzahl der Spalten
row_stride = cinfo.output_width * cinfo.output_components;
buffer_pos = 0;
unsigned long m_ulImageBufferSize = cinfo.output_width *
cinfo.output_height *
cinfo.output_components;
unsigned char* m_pucImageBuffer =
new unsigned char[m_ulImageBufferSize + 1];
line = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo,
JPOOL_IMAGE, row_stride, 1);
while (cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, line, 1);
// die einzelnen Blöcke speichern
memcpy((unsigned char*)((unsigned long)m_pucImageBuffer +
buffer_pos), line[0], row_stride);
buffer_pos += row_stride;
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
delete[] m_pucImageBuffer;
}
int main(int argc , char** argv){
if(argc < 1){ // wrong number of arguments
return -1;
}
size_t size;
unsigned char* buffer = getBuffer(argv[1], size);
if(buffer==0){ // file could not be read
return 2;
}
unsigned long w;
unsigned long h;
bool gray;
ReadJPEGHeader(buffer, size, &w, &h, &gray);
CreateRGBBuffer(buffer,size);
delete[] buffer;
}