Skip to content

Commit

Permalink
Image.save uses open/save/close
Browse files Browse the repository at this point in the history
  • Loading branch information
dk committed Nov 1, 2023
1 parent d0c2c2b commit e35656b
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 90 deletions.
4 changes: 4 additions & 0 deletions class/Image.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ Image_done( Handle self)
apc_img_close_load((PImgLoadFileInstance) var-> loading_session);
var-> loading_session = NULL;
}
if ( var-> saving_session ) {
apc_img_close_save((PImgSaveFileInstance) var-> saving_session, false);
var-> saving_session = NULL;
}

if ( var-> regionData ) {
free(var->regionData);
Expand Down
1 change: 1 addition & 0 deletions class/Image.cls
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ object Prima::Image( Prima::Drawable)
int updateLock;
int extraROP;
void *loading_session;
void *saving_session;

property Bool antialias;
property Rect clipRect;
Expand Down
187 changes: 107 additions & 80 deletions class/Image/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,27 +77,60 @@ img_perlio_error( void * f)
#endif
}

static ImgIORequest perl_ioreq = {
img_perlio_read,
img_perlio_write,
img_perlio_seek,
img_perlio_tell,
img_perlio_flush,
img_perlio_error
};

static ImgIORequest*
fill_ioreq( SV * sv, ImgFileIOCommon *req )
{
FileStream f = NULL;
ImgIORequest *pioreq;

if ( SvROK(sv) && SvTYPE( SvRV( sv)) == SVt_PVGV)
f = IoIFP(sv_2io(sv));

if ( f != NULL) {
pioreq = &req->sioreq;
req->sioreq = perl_ioreq;
req->sioreq.handle = f;
req->fileName = NULL;
req->is_utf8 = false;
} else {
req->fileName = ( char *) SvPV_nolen(sv);
req->is_utf8 = prima_is_utf8_sv(sv);
pioreq = NULL;
}

return pioreq;
}

XS( Image_load_FROMPERL)
{
dPROFILE;
dXSARGS;
Handle self;
SV * sv;
HV *profile;
char *fn;
PList ret = NULL;
Bool err = false, is_utf8;
FileStream f = NULL;
ImgIORequest ioreq, *pioreq;
Bool err = false;
ImgIORequest *pioreq;
ImgFileIOCommon sioreq;
char error[256];
Bool open_load = false, load_next_frame = false, close_load = false;

if (( items < 2) || (( items % 2) != 0))
croak("Invalid usage of Prima::Image::load");

self = gimme_the_mate( ST( 0));
sv = ST(1);
self = gimme_the_mate( ST( 0));
sv = ST(1);
profile = parse_hv( ax, sp, items, mark, 2, "Image::load");
pioreq = fill_ioreq(sv, &sioreq);

if ( pexist(session) && pget_B(session)) {
if ( !self )
Expand All @@ -108,19 +141,13 @@ XS( Image_load_FROMPERL)

load_next_frame = true;
if ( pexist(rewind)) {
if ( !apc_img_rewind_to_frame(( PImgLoadFileInstance) var-> loading_session, pget_i(rewind))) {
strcpy(error, "Frame index out of range");
err = true;
}
(( PImgLoadFileInstance) var-> loading_session)->frame = pget_i(rewind);
pdelete(rewind);
}
} else
open_load = true;
}

if ( SvROK(sv) && SvTYPE( SvRV( sv)) == SVt_PVGV)
f = IoIFP(sv_2io(ST(1)));

if ( !pexist( className) && !load_next_frame)
pset_c( className, self ? my-> className : ( char*) SvPV_nolen( ST( 0)));
pset_i( eventMask, self ? var-> eventMask2 : 0);
Expand All @@ -134,48 +161,27 @@ XS( Image_load_FROMPERL)
croak("Not enough memory");
obj = apc_img_load_next_frame( NULL_HANDLE, fi, profile, error);
if ( obj == NULL_HANDLE ) {
list_add( ret, NULL_HANDLE );
err = true;
close_load = true;
} else {
list_add( ret, obj );
} else
fi-> frame++;
}
} else {
if ( f != NULL) {
pioreq = &ioreq;
ioreq. handle = f;
ioreq. read = img_perlio_read;
ioreq. write = img_perlio_write;
ioreq. seek = img_perlio_seek;
ioreq. tell = img_perlio_tell;
ioreq. flush = img_perlio_flush;
ioreq. error = img_perlio_error;
fn = NULL;
is_utf8 = false;
} else {
fn = ( char *) SvPV_nolen( ST( 1));
is_utf8 = prima_is_utf8_sv(ST(1));
pioreq = NULL;
}

if ( open_load ) {
PImgLoadFileInstance fi;
fi = apc_img_open_load( fn, is_utf8, pioreq, profile, error);
if ( fi ) {
if ( fi-> loadExtras ) {
HV * extras = newHV();
SV * sv = newRV_noinc(( SV *) extras);
apc_img_profile_add( extras, fi->fileProperties, fi->fileProperties);
(void) hv_store(( HV* )SvRV(var->mate), "extras", 6, newSVsv(sv), 0);
sv_free( sv);
}
var-> loading_session = (void*) fi;
} else
err = true;
list_add( ret, obj );
} else if ( open_load ) {
PImgLoadFileInstance fi;
fi = apc_img_open_load( sioreq.fileName, sioreq.is_utf8, pioreq, profile, error);
if ( fi ) {
if ( fi-> loadExtras ) {
HV * extras = newHV();
SV * sv = newRV_noinc(( SV *) extras);
apc_img_profile_add( extras, fi->fileProperties, fi->fileProperties);
(void) hv_store(( HV* )SvRV(var->mate), "extras", 6, newSVsv(sv), 0);
sv_free( sv);
}
var-> loading_session = (void*) fi;
} else
ret = apc_img_load( self, fn, is_utf8, pioreq, profile, error);
}
err = true;
} else
ret = apc_img_load( self, sioreq.fileName, sioreq.is_utf8, pioreq, profile, error);

sv_free(( SV *) profile);
SPAGAIN;
Expand Down Expand Up @@ -236,53 +242,74 @@ Image_load( SV * who, SV *filename, HV * profile)
return ret;
}


XS( Image_save_FROMPERL)
{
dPROFILE;
dXSARGS;
Handle self;
HV *profile;
char *fn;
int ret;
SV *sv;
int ret = 0;
char error[256];
FileStream f = NULL;
SV * sv;
Bool is_utf8;
ImgIORequest ioreq, *pioreq;
ImgIORequest *pioreq;
ImgFileIOCommon sioreq;
Bool open_save = false, save_next_frame = false, close_save = false;

if (( items < 2) || (( items % 2) != 0))
croak("Invalid usage of Prima::Image::save");

self = gimme_the_mate( ST( 0));

sv = ST(1);
if ( SvROK(sv) && SvTYPE( SvRV( sv)) == SVt_PVGV)
f = IoIFP(sv_2io(ST(1)));
self = gimme_the_mate( ST( 0));
sv = ST(1);
profile = parse_hv( ax, sp, items, mark, 2, "Image::save");
pioreq = fill_ioreq(sv, &sioreq );

if ( f != NULL) {
pioreq = &ioreq;
ioreq. handle = f;
ioreq. read = img_perlio_read;
ioreq. write = img_perlio_write;
ioreq. seek = img_perlio_seek;
ioreq. tell = img_perlio_tell;
ioreq. flush = img_perlio_flush;
ioreq. error = img_perlio_error;
fn = NULL;
is_utf8 = false;
} else {
fn = ( char *) SvPV_nolen( ST( 1));
is_utf8 = prima_is_utf8_sv( ST(1) );
pioreq = NULL;
if ( pexist(session) && pget_B(session)) {
if ( !self )
croak("Cannot start saving session without an object");
if ( var-> saving_session ) {
if ( SvOK(sv))
croak("Another saving session is in progress");
save_next_frame = true;
} else
open_save = true;
}

profile = parse_hv( ax, sp, items, mark, 2, "Image::save");
ret = apc_img_save( self, fn, is_utf8, pioreq, profile, error);
if ( save_next_frame ) {
Handle obj;
PImgSaveFileInstance fi = (PImgSaveFileInstance) var-> saving_session;

if ( !pexist(image))
croak("`image' option expected");
obj = pget_H(image);
if ( !obj || !kind_of(obj, CImage))
croak("Bad image passed");

if (apc_img_save_next_frame( obj, fi, profile, error))
ret = 1;
else
close_save = true;
} else if ( open_save ) {
if ( !pexist(frames))
croak("`frames' option expected");
if (( var-> saving_session = apc_img_open_save(
sioreq.fileName, sioreq.is_utf8,
pget_i(frames),
pioreq, profile, error
)))
ret = 1;
} else
ret = apc_img_save( self, sioreq.fileName, sioreq.is_utf8, pioreq, profile, error);

sv_free(( SV *) profile);
SPAGAIN;
SP -= items;
XPUSHs( sv_2mortal( newSViv(( ret > 0) ? ret : -ret)));

if ( close_save ) {
apc_img_close_save(( PImgSaveFileInstance) var-> saving_session, false );
var-> saving_session = NULL;
}

/* This code breaks exception propagation chain
since it uses $@ for its own needs */
if ( ret <= 0)
Expand Down
18 changes: 9 additions & 9 deletions img/load.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,15 +432,6 @@ EXIT_NOW:;
return fi;
}

Bool
apc_img_rewind_to_frame( PImgLoadFileInstance fi, int frame )
{
if (frame < 0 || frame >= fi->frameCount)
return false;
fi-> frame = frame;
return true;
}

Handle
apc_img_load_next_frame( Handle target, PImgLoadFileInstance fi, HV * profile, char * error )
{
Expand All @@ -456,6 +447,11 @@ apc_img_load_next_frame( Handle target, PImgLoadFileInstance fi, HV * profile, c
fi->errbuf[0] = 0;
fi->object = NULL_HANDLE;

if ( fi-> frame < 0 )
out("Bad frame index");
if ( fi-> frameCount >= 0 && fi->frame >= fi->frameCount)
out("Frame index out of range");

/* query profile */
save[0] = fi->loadExtras;
save[1] = fi->noImageData;
Expand Down Expand Up @@ -871,6 +867,10 @@ apc_img_open_save( char * fileName, Bool is_utf8, int n_frames, PImgIORequest io
if ( error ) strcpy(error, "Not enough memory");
return NULL;
}
if (n_frames <= 0) {
if ( error ) strcpy(error, "Bad n_frames");
return NULL;
}

memset( fi, 0, sizeof( ImgSaveFileInstance));

Expand Down
1 change: 0 additions & 1 deletion include/img.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ extern PImgLoadFileInstance
extern Handle
apc_img_load_next_frame( Handle target, PImgLoadFileInstance fi, HV * profile, char * error );
extern void apc_img_close_load( PImgLoadFileInstance fi );
extern Bool apc_img_rewind_to_frame( PImgLoadFileInstance fi, int frame );

extern int apc_img_save( Handle self, char * fileName, Bool is_utf8, PImgIORequest ioreq, HV * profile, char * error);
extern PImgSaveFileInstance
Expand Down

0 comments on commit e35656b

Please sign in to comment.