home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Enigma Amiga Life 109
/
EnigmaAmiga109CD.iso
/
software
/
utilities
/
jpeg-dt35
/
source
/
dispatcher.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-22
|
7KB
|
295 lines
#include <clib/alib_protos.h>
#include <pragma/datatypes_lib.h>
#include <pragma/dos_lib.h>
#include <pragma/exec_lib.h>
#include <pragma/graphics_lib.h>
#include <pragma/intuition_lib.h>
#include <pragma/jpeg_lib.h>
#include <pragma/utility_lib.h>
#include <datatypes/pictureclass.h>
#include <exec/memory.h>
#include <intuition/icclass.h>
#include <string.h>
#include "class.h"
struct Arg1
{
long *dct,*scale,*quality,*smooth,gray,prog;
};
ULONG SaveJPEG(IClass *cl,Object *obj,dtWrite *msg);
void ReadPrefs(Data *data)
{
char *var;
data->dct=0;
data->scale=1;
data->quality=75;
data->smooth=0;
data->gray=0;
data->prog=0;
if(var=(char *)AllocVec(512,0))
{
if(GetVar("ENV:DataTypes/jpeg.prefs",var,512,LV_VAR|GVF_GLOBAL_ONLY)>=0)
{
RDArgs *rdargs;
if(rdargs=(RDArgs *)AllocDosObject(DOS_RDARGS,0))
{
RDArgs *args;
Arg1 para;
rdargs->RDA_Source.CS_Buffer=var;
rdargs->RDA_Source.CS_Length=strlen(var);
rdargs->RDA_Source.CS_CurChr=0;
memset(¶,0,sizeof(Arg1));
if(args=ReadArgs("DCT/A/N,SCALE/A/N,QUALITY/A/N,SMOOTH/A/N,GRAY/S,PROGRESSIVE/S",(long *)¶,rdargs))
{
data->dct=*para.dct;
if(data->dct<0) data->dct=0;
else if(data->dct>2) data->dct=2;
data->scale=*para.scale;
if(data->scale<0) data->scale=0;
else if(data->scale>3) data->scale=3;
data->scale=1<<data->scale;
data->quality=*para.quality;
if(data->quality<1) data->quality=1;
else if(data->quality>100) data->quality=100;
data->smooth=*para.smooth;
if(data->smooth<0) data->smooth=0;
else if(data->smooth>100) data->smooth=100;
data->gray=para.gray;
data->prog=para.prog;
FreeArgs(args);
}
FreeDosObject(DOS_RDARGS,rdargs);
}
}
FreeVec(var);
}
}
struct JPEGINFO
{
Object *obj;
UBYTE *buffer;
UWORD d,gray;
};
static void _getline(UBYTE *scanline,ULONG y,ULONG numb,JPEGINFO *info)
{
if(info->gray) DoMethod(info->obj,PDTM_WRITEPIXELARRAY,scanline,PBPAFMT_GREY8,numb,0,y,numb,1);
else
{
ULONG w=numb/3;
if(info->d>8) DoMethod(info->obj,PDTM_WRITEPIXELARRAY,scanline,PBPAFMT_RGB,numb,0,y,w,1);
else
{
register ULONG i;
register UBYTE *p1,*p2;
p1=info->buffer+w*y*4;
p2=scanline;
for(i=0;i<w;i++,p1+=4,p2+=3)
{
p1[1]=p2[0];
p1[2]=p2[1];
p1[3]=p2[2];
}
}
}
}
static ULONG getline(register __a0 UBYTE *scanline,register __d0 ULONG line,register __d1 ULONG numb,register __a1 void *userdata)
{
_getline(scanline,line-1,numb,(JPEGINFO *)userdata);
return 0;
}
static void FillBMHD(Object *obj,BitMapHeader *bh,ULONG w,ULONG h,ULONG depth)
{
bh->bmh_Left=0;
bh->bmh_Top=0;
bh->bmh_Width=w;
bh->bmh_Height=h;
bh->bmh_PageWidth=w;
bh->bmh_PageHeight=h;
bh->bmh_Depth=depth;
bh->bmh_Compression=cmpByteRun1;
bh->bmh_XAspect=0;
bh->bmh_YAspect=0;
}
static ULONG GetBody_Gray(JPEGDecHandle *jph,BitMapHeader *bh,Object *obj,Data *data)
{
ULONG error=0;
UBYTE *buffer;
if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
{
if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
{
DoMethod(obj,PDTM_WRITEPIXELARRAY,buffer,PBPAFMT_GREY8,bh->bmh_Width,0,0,bh->bmh_Width,bh->bmh_Height);
}
else error=ERROR_NO_FREE_STORE;
FreeJPEGBuffer(buffer);
}
else
{
JPEGINFO info={0,0,8,1};
if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
else error=ERROR_NO_FREE_STORE;
}
return error;
}
static ULONG GetBody_RGB(JPEGDecHandle *jph,BitMapHeader *bh,Object *obj,Data *data)
{
ULONG error=0;
UBYTE *buffer;
if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
{
if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
DoMethod(obj,PDTM_WRITEPIXELARRAY,buffer,PBPAFMT_RGB,bh->bmh_Width*3,0,0,bh->bmh_Width,bh->bmh_Height);
else error=ERROR_NO_FREE_STORE;
FreeJPEGBuffer(buffer);
}
else
{
JPEGINFO info={obj,0,24,0};
if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
}
return error;
}
static ULONG GetPicture(IClass *cl,Object *obj)
{
ULONG error=0;
long err;
BPTR file;
BitMapHeader *bh;
GetDTAttrs(obj,DTA_Name,&bh,TAG_END);
if(bh) SetDTAttrs(obj,0,0,DTA_ObjName,bh,TAG_END);
GetDTAttrs(obj,DTA_Handle,&file,PDTA_BitMapHeader,&bh,TAG_END);
if(bh)
{
JPEGDecHandle *jph;
if(!file)
{
GetDTAttrs(obj,DTA_SourceType,&err,TAG_END);
if(err!=DTST_RAM) return ERROR_REQUIRED_ARG_MISSING;
else return 0;
}
if(!AllocJPEGDecompress(&jph,JPG_SrcFile,file,TAG_END))
{
UBYTE colorspace;
ULONG w,h,bpp;
Data *data=(Data *)INST_DATA(cl,obj);
ReadPrefs(data);
if(!GetJPEGInfo(jph,JPG_Width,&w,JPG_Height,&h,JPG_ColourSpace,&colorspace,JPG_BytesPerPixel,&bpp,JPG_ScaleDenom,data->scale,TAG_END))
{
bh->bmh_Left=0;
bh->bmh_Top=0;
bh->bmh_Width=w;
bh->bmh_Height=h;
bh->bmh_PageWidth=w;
bh->bmh_PageHeight=h;
bh->bmh_Depth=(colorspace==JPCS_RGB)?24:8;
bh->bmh_Compression=cmpByteRun1;
bh->bmh_XAspect=0;
bh->bmh_YAspect=0;
SetDTAttrs(obj,0,0,DTA_ErrorNumber,&error,DTA_NominalHoriz,w,DTA_NominalVert,h,PDTA_SourceMode,PMODE_V43,PDTA_ModeID,0,TAG_END);
if(!error)
{
switch(colorspace)
{
case JPCS_GRAYSCALE:
error=GetBody_Gray(jph,bh,obj,data);
break;
case JPCS_RGB:
error=GetBody_RGB(jph,bh,obj,data);
break;
default:
error=ERROR_NOT_IMPLEMENTED;
}
}
}
else error=DTERROR_INVALID_DATA;
}
else error=DTERROR_INVALID_DATA;
}
else error=ERROR_NO_FREE_STORE;
return error;
}
static ULONG mNew(IClass *cl,Object *obj,opSet *msg)
{
TagItem *ti;
if(ti=FindTagItem(DTA_SourceType,(((opSet *)msg)->ops_AttrList)))
{
if(ti->ti_Data!=DTST_FILE&&ti->ti_Data!=DTST_CLIPBOARD&&ti->ti_Data!=DTST_RAM)
{
SetIoErr(ERROR_OBJECT_WRONG_TYPE);
return 0;
}
}
if(obj==(Object *)cl)
{
if(obj=(Object *)DoSuperMethodA(cl,obj,Msg(msg)))
{
ULONG error;
if(error=GetPicture(cl,obj))
{
SetIoErr(error);
CoerceMethod(cl,obj,OM_DISPOSE);
obj=0;
}
}
}
else
{
SetIoErr(ERROR_NOT_IMPLEMENTED);
obj=0;
}
return ULONG(obj);
}
static ULONG mSet(IClass *cl,Object *obj,opSet *msg)
{
ULONG retval;
if(retval=DoSuperMethodA(cl,obj,Msg(msg)))
{
RastPort *rp;
if(rp=ObtainGIRPort(msg->ops_GInfo))
{
DoMethod(obj,GM_RENDER,msg->ops_GInfo,rp,GREDRAW_UPDATE);
ReleaseGIRPort(rp);
retval=0;
}
}
return retval;
}
static ULONG mWrite(IClass *cl,Object *obj,dtWrite *msg)
{
return (msg->dtw_Mode==DTWM_IFF)?DoSuperMethodA(cl,obj,Msg(msg)):SaveJPEG(cl,obj,msg);
}
extern "C" ULONG Dispatcher(register __a0 IClass *cl,register __a2 Object *obj,register __a1 Msg msg)
{
ULONG retval;
switch(msg->MethodID)
{
case OM_NEW:
retval=mNew(cl,obj,(opSet *)msg);
break;
case OM_UPDATE:
if(DoMethod(obj,ICM_CHECKLOOP)) break;
case OM_SET:
retval=mSet(cl,obj,(opSet *)msg);
break;
case DTM_WRITE:
retval=mWrite(cl,obj,(dtWrite *)msg);
break;
default:
retval=DoSuperMethodA(cl,obj,msg);
}
return retval;
}