269 lines
6.5 KiB
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);
|
|
}
|