Newer
Older
/***************************************************************************
-------------------
begin : Jul 25, 2015
copyright : (C) 2015 by Tomas Oberhuber
email : tomas.oberhuber@fjfi.cvut.cz
***************************************************************************/
/* See Copyright Notice in tnl/Copyright */
inline void my_error_exit( j_common_ptr cinfo )
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_mgr* myerr = ( my_error_mgr* ) cinfo->err;
/* Always display the message. */
/* We could postpone this until after returning, if we chose. */
( *cinfo->err->output_message )( cinfo );
/* Return control to the setjmp point */
longjmp( myerr->setjmp_buffer, 1 );
}
fileOpen( false )
{
}
template< typename Index >
bool
this->jerr.pub.error_exit = my_error_exit;
/****
* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
jpeg_create_decompress( &this->decinfo );
jpeg_stdio_src( &this->decinfo, this->file );
if( jpeg_read_header( &this->decinfo, true ) != JPEG_HEADER_OK )
this->height = this->decinfo.image_height;
this->width = this->decinfo.image_width;
this->components = this->decinfo.num_components;
//this->color_space = this->cinfo.jpeg_color_space;
//cout << this->height << " x " << this->width << " : " << this->components << " " << this->color_space << std::endl;
std::cerr << "TNL was not compiled with support of JPEG. You may still use PGM format." << std::endl;
openForRead( const String& fileName )
{
this->close();
this->file = fopen( fileName.getString(), "r" );
if( ! this->file )
{
std::cerr << "Unable to open the file " << fileName << std::endl;
return false;
}
this->fileOpen = true;
if( ! readHeader() )
return false;
return true;
}
template< typename Index >
JPEGImage< Index >::
read( const RegionOfInterest< Index > roi,
Functions::MeshFunction< Meshes::Grid< 2, MeshReal, Device, Index >, 2, Real >& function )
typedef Meshes::Grid< 2, Real, Device, Index > GridType;
const GridType& grid = function.getMesh();
/****
* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
jpeg_start_decompress( &this->decinfo );
int row_stride = this->decinfo.output_width * this->decinfo.output_components;
JSAMPARRAY row = ( *( this->decinfo.mem->alloc_sarray ) )( ( j_common_ptr ) &this->decinfo,
JPOOL_IMAGE,
row_stride,
1 );
while( this->decinfo.output_scanline < this->decinfo.output_height)
jpeg_read_scanlines( &this->decinfo, row, 1 );
for( j = 0; j < this->width; j ++ )
{
if( !roi.isIn( i, j ) )
continue;
cell.getCoordinates().x() = j - roi.getLeft();
cell.getCoordinates().y() = roi.getBottom() - 1 - i;
//Index cellIndex = grid.getCellIndex( CoordinatesType( j - roi.getLeft(),
// roi.getBottom() - 1 - i ) );
cell.refresh();
unsigned char char_color[ 4 ];
unsigned int int_color[ 4 ];
Real value, r, g, b;
switch( this->components )
case 1:
char_color[ 0 ] = row[ 0 ][ j ];
value = char_color[ 0 ] / ( Real ) 255.0;
function.getData().setElement( cell.getIndex(), value );
case 3:
char_color[ 0 ] = row[ 0 ][ 3 * j ];
char_color[ 1 ] = row[ 0 ][ 3 * j + 1 ];
char_color[ 2 ] = row[ 0 ][ 3 * j + 2 ];
r = char_color[ 0 ] / ( Real ) 255.0;
g = char_color[ 1 ] / ( Real ) 255.0;
b = char_color[ 2 ] / ( Real ) 255.0;
value = 0.2989 * r + 0.5870 * g + 0.1140 * b;
function.getData().setElement( cell.getIndex(), value );
std::cerr << "Unknown JPEG color type." << std::endl;
//cerr << "TNL was not compiled with support of JPEG. You may still use PGM format." << std::endl;
}
template< typename Index >
template< typename Real,
typename Device >
bool
writeHeader( const Meshes::Grid< 2, Real, Device, Index >& grid )
this->cinfo.err = jpeg_std_error( &this->jerr.pub );
jpeg_create_compress( &this->cinfo );
jpeg_stdio_dest( &this->cinfo, this->file );
this->cinfo.image_width = grid.getDimensions().x();
this->cinfo.image_height = grid.getDimensions().y();
this->cinfo.input_components = 1;
this->cinfo.in_color_space = JCS_GRAYSCALE;
jpeg_set_defaults( &this->cinfo );
jpeg_start_compress( &this->cinfo, true );
//cerr << "TNL was not compiled with support of JPEG. You may still use PGM format." << std::endl;
}
template< typename Index >
template< typename Real,
typename Device >
bool
openForWrite( const String& fileName,
{
this->close();
this->file = fopen( fileName.getString(), "w" );
if( ! this->file )
{
std::cerr << "Unable to open the file " << fileName << std::endl;
return false;
}
this->fileOpen = true;
if( ! writeHeader( grid ) )
return false;
return true;
}
template< typename Index >
template< typename Real,
typename Device,
typename Vector >
bool
write( const Meshes::Grid< 2, Real, Device, Index >& grid,
typedef Meshes::Grid< 2, Real, Device, Index > GridType;
row[ 0 ] = new JSAMPLE[ grid.getDimensions().x() ];
// JSAMPLE is unsigned char
while( this->cinfo.next_scanline < this->cinfo.image_height )
{
for( j = 0; j < grid.getDimensions().x(); j ++ )
{
cell.getCoordinates().x() = j;
cell.getCoordinates().y() = grid.getDimensions().y() - 1 - i;
//Index cellIndex = grid.getCellIndex( CoordinatesType( j,
// grid.getDimensions().y() - 1 - i ) );
row[ 0 ][ j ] = 255 * vector.getElement( cell.getIndex() );
jpeg_write_scanlines( &this->cinfo, row, 1 );
i++;
jpeg_finish_compress( &this->cinfo );
jpeg_destroy_compress( &this->cinfo );
delete[] row[ 0 ];
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
template< typename Index >
template< typename MeshReal,
typename Device,
typename Real >
bool
JPEGImage< Index >::
write( const Functions::MeshFunction< Meshes::Grid< 2, MeshReal, Device, Index >, 2, Real >& function )
{
typedef Meshes::Grid< 2, Real, Device, Index > GridType;
const GridType& grid = function.getMesh();
typename GridType::Cell cell( grid );
#ifdef HAVE_JPEG_H
Index i( 0 ), j;
JSAMPROW row[1];
row[ 0 ] = new JSAMPLE[ grid.getDimensions().x() ];
// JSAMPLE is unsigned char
while( this->cinfo.next_scanline < this->cinfo.image_height )
{
for( j = 0; j < grid.getDimensions().x(); j ++ )
{
cell.getCoordinates().x() = j;
cell.getCoordinates().y() = grid.getDimensions().y() - 1 - i;
//Index cellIndex = grid.getCellIndex( CoordinatesType( j,
// grid.getDimensions().y() - 1 - i ) );
row[ 0 ][ j ] = 255 * function.getData().getElement( cell.getIndex() );
}
jpeg_write_scanlines( &this->cinfo, row, 1 );
i++;
}
jpeg_finish_compress( &this->cinfo );
jpeg_destroy_compress( &this->cinfo );
delete[] row[ 0 ];
return true;
#else
return false;
#endif
}
close()
{
if( this->fileOpen )
fclose( file );
this->fileOpen = false;
}
template< typename Index >