Files
FireBee_Setup/sources/z-tools/trunk/zview/pic_save.c

269 lines
6.5 KiB
C

#include "general.h"
#include "pic_load.h"
#include "prefs.h"
#include "ztext.h"
#include "zvdi//color.h"
#include "zvdi//raster.h"
#include "zvdi//vdi.h"
#include "plugins.h"
#include "progress.h"
extern void CDECL ( *decoder_quit) ( IMGINFO);
extern boolean CDECL ( *decoder_read) ( IMGINFO, uint8 *);
extern boolean CDECL ( *decoder_init) ( const char *, IMGINFO);
extern void CDECL ( *encoder_quit) ( IMGINFO);
extern boolean CDECL ( *encoder_write) ( IMGINFO, uint8 *);
extern boolean CDECL ( *encoder_init) ( const char *, IMGINFO);
static boolean encoder_init_done = FALSE;
static int16 setup_encoder ( IMGINFO in_info, IMGINFO out_info, DECDATA data)
{
size_t src_line_size, dst_line_size;
data->IncXfx = 0x10000uL;
src_line_size = ( in_info->width + 15) * in_info->components;
dst_line_size = ( out_info->width + 15) * out_info->components;
data->RowBuf = ( uint8*)gmalloc( src_line_size);
if( data->RowBuf == NULL)
return( 0);
data->DthBuf = NULL;
/* If the image is inverted like in iNTEL format, we must to decompress
the entire picture before to save it */
if( in_info->orientation == DOWN_TO_UP)
{
data->DstBuf = ( uint8*)gmalloc( dst_line_size * ( out_info->height + 1));
}
else
data->DstBuf = ( uint8*)gmalloc( dst_line_size);
if( data->DstBuf == NULL)
return( 0);
data->DthWidth = in_info->width;
data->PixMask = ( 1 << in_info->planes) - 1;
data->LnSize = out_info->width * out_info->components;
switch( out_info->planes)
{
case 24:
if( in_info->planes == 1 && in_info->components == 1)
{
data->Pixel[0] = 0xFFFFFF;
data->Pixel[1] = 0x000000;
raster = raster_24;
}
else if( in_info->indexed_color)
{
cnvpal_true( in_info, data);
raster = raster_24;
}
else
raster = ( in_info->components >= 3 ? dither_24 : gscale_24);
break;
default:
return( 0);
}
return( 1);
}
/*==================================================================================*
* read_img: *
* Read a image and fit the MFDB within IMAGE structur with the data. *
*----------------------------------------------------------------------------------*
* img: The struct. with the MFDB to be fitted. *
* info: The struct. with the line and dither buffer *
*----------------------------------------------------------------------------------*
* returns: - *
*==================================================================================*/
static void write_img( IMGINFO in_info, IMGINFO out_info, DECDATA data)
{
int16 y, img_h = in_info->height;
uint8 *dst = data->DstBuf;
in_info->page_wanted = 0;
if( in_info->orientation == UP_TO_DOWN)
{
for( y = 0; y < img_h; y++)
{
decoder_read( in_info, data->RowBuf);
( *raster)( data, dst);
encoder_write( out_info, dst);
if( show_write_progress_bar)
win_progress(( int16)((( int32)y * 150L) / img_h));
}
}
else /* inversed INTEL format */
{
int16 h = ( img_h << 1); /* image height * 2 . don't worry about this, is only for the progress bar */
dst += data->LnSize * ( in_info->height - 1);
/* First pass, we decode the entire image */
for( y = 0; y < img_h; y++)
{
decoder_read( in_info, data->RowBuf);
( *raster)( data, dst);
dst -= data->LnSize;
if( show_write_progress_bar)
win_progress(( int16)((( int32)y * 75L) / img_h));
}
dst = data->DstBuf;
/* second pass, we encode it */
for( ; y < h; y++)
{
encoder_write( out_info, dst);
dst += data->LnSize;
if( show_write_progress_bar)
win_progress(( int16)((( int32)y * 75L) / img_h));
}
}
}
static void exit_pic_save( IMGINFO in_info, IMGINFO out_info, DECDATA data)
{
if( data->DthBuf)
gfree( data->DthBuf);
if( data->DstBuf)
gfree( data->DstBuf);
if( data->RowBuf)
gfree( data->RowBuf);
if( encoder_init_done)
encoder_quit( out_info);
if( decoder_init_done)
decoder_quit( in_info);
gfree( data);
gfree( out_info);
gfree( in_info);
graf_mouse( ARROW, NULL);
encoder_init_done = FALSE;
decoder_init_done = FALSE;
}
/*==================================================================================*
* pic_load: *
* read a supported picture and fill a IMAGE structure. *
*----------------------------------------------------------------------------------*
* file: The file that will be read. *
* img: The IMAGE struct. that will be filled. *
*----------------------------------------------------------------------------------*
* returns: '0' if error or picture not supported *
*==================================================================================*/
int16 pic_save( const char *in_file, const char *out_file)
{
char extention[4];
IMGINFO in_info = NULL, out_info = NULL;
DECDATA data = NULL;
graf_mouse( BUSYBEE, NULL);
in_info = ( img_info *) gmalloc( sizeof( img_info));
out_info = ( img_info *) gmalloc( sizeof( img_info));
data = ( dec_data *) gmalloc( sizeof( dec_data));
if ( !in_info || !out_info || !data)
{
if ( data)
gfree( data);
if ( out_info)
gfree( out_info);
if ( in_info)
gfree( in_info);
graf_mouse( ARROW, NULL);
errshow( "", ENOMEM);
return( 0);
}
data->DthBuf = NULL;
data->DstBuf = NULL;
data->RowBuf = NULL;
if( show_write_progress_bar)
win_progress_begin( get_string( SAVE_TITLE));
/* We initialise some variables needed by the codecs */
in_info->background_color = 0xFFFFFF;
in_info->thumbnail = FALSE;
/* get the file extention */
strcpy ( extention, in_file + strlen( in_file) - 3);
str2upper( extention);
if(( decoder_init_done = get_pic_info( in_file, extention, in_info)) == FALSE)
{
errshow( in_file, CANT_LOAD_IMG);
exit_pic_save( in_info, out_info, data);
win_progress_end();
graf_mouse( ARROW, NULL);
return ( 0);
}
/* copy information from input's information to output's information struct */
memcpy( out_info, in_info, sizeof( img_info));
if (( encoder_init_done = encoder_init( out_file, out_info)) == FALSE)
{
errshow( NULL, CANT_SAVE_IMG);
exit_pic_save( in_info, out_info, data);
win_progress_end();
graf_mouse( ARROW, NULL);
return ( 0);
}
if( !setup_encoder( in_info, out_info, data))
{
errshow( NULL, ENOMEM);
exit_pic_save( in_info, out_info, data);
win_progress_end();
graf_mouse( ARROW, NULL);
return ( 0);
}
write_img( in_info, out_info, data);
exit_pic_save( in_info, out_info, data);
graf_mouse( ARROW, NULL);
win_progress_end();
return ( 1);
}