Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
102 user(s) are online (83 user(s) are browsing Forums)

Members: 0
Guests: 102

more...

Support us!

Headlines

 
  Register To Post  

Saving a bitmap with datatype (again....)
Not too shy to talk
Not too shy to talk


See User information
Hello

(I know that there was several threads about this topic but reading them again just add to my confusion and headaches and i cant find a real example source that do that effectively just pieces of code and ideas...)

How to save an existing bitmap bm created with AllocBitMap() and based on current Screen depth (that I used for Warp3D off screen rendering) to a an IFF/ILBM file with the datatype's DoDTMethod(dto,NULL,NULL,DTM_WRITE,NULL,fp,DTWM_IFF,NULL);
???

Input: existing bm (certainly 15/16/24/32 bits)
Output: an IFF file called filename

Alain Thellier

Go to top
Re: Saving a bitmap with datatype (again....)
Home away from home
Home away from home


See User information
@thellier

SketchBlock export code.

void DTSaveLayer(struct SketchLayer *sklay,STRPTR filenameBOOL toclip)
{

    
Object *dto NULL;
    
dto  IDataTypes->NewDTObject(NULL,
                
DTA_SourceType,DTST_RAM,
                
DTA_GroupID,GID_PICTURE,
                
TAG_DONE);


    if(
dto)
    {
        
int err;
        
struct pdtBlitPixelArray bpa;
        
struct BitMapHeader *bmhd;
        
        
ARGB32 *tempbuffer Allocmem(sizeof(ARGB32) * sklay->sl_Width sklay->sl_Height,MEMF_CLEAR MEMF_PRIVATE);
        
        if(
tempbuffer)
        {
            
int x,y;
            for(
0sklay->sl_Heighty++)
            {
                for(
x=0;<sklay->sl_Widthx++)
                {
                    
ARGBtoARGB32(&tempbuffer[sklay->sl_Width],&sklay->sl_Buffer[*sklay->sl_Width]);
                }
            }
            
            
bpa.MethodID PDTM_WRITEPIXELARRAY;
    
            
bpa.pbpa_PixelData tempbuffer;
            
bpa.pbpa_PixelFormat PBPAFMT_ARGB;
            
bpa.pbpa_PixelArrayMod sklay->sl_Width sizeof(ARGB32);
            
bpa.pbpa_Left 0;
            
bpa.pbpa_Top 0;
            
bpa.pbpa_Height sklay->sl_Height;
            
bpa.pbpa_Width sklay->sl_Width;
    
    
            if(
IDataTypes->GetDTAttrs(dtoPDTA_BitMapHeader, &bmhdTAG_DONE))
            {
    
                
bmhd->bmh_Left 0;
                
bmhd->bmh_Top 0;
                
bmhd->bmh_Width bmhd->bmh_PageWidth sklay->sl_Width;
                
bmhd->bmh_Height bmhd->bmh_PageHeight sklay->sl_Height;
                
bmhd->bmh_Depth 32;
                
bmhd->bmh_Masking mskHasAlpha ;
            }
    
            
IDataTypes->SetDTAttrs (dtoNULLNULL,
                  
DTA_ObjName,      sklay->sl_Name,
                  
DTA_NominalHorizbmhd->bmh_Width,
                  
DTA_NominalVert,  bmhd->bmh_Height,
                  
PDTA_SourceMode,  PMODE_V43,
                  
TAG_DONE);
    
    
            
IIntuition->IDoMethodA(dto,&bpa);
    
            
IDataTypes->DoDTMethod(dto,NULL,NULL,DTM_CLEARSELECTED,NULL);
            if(!
toclip)
            {
                
IDataTypes->SaveDTObject(dto,NULL,NULL,filename,DTWM_IFF,FALSE,NULL);
            }
            else
            {
                
struct dtGeneral dtm;
                
dtm.MethodID DTM_COPY;
                
dtm.dtg_GInfo filename;
                
IIntuition->IDoMethodA(dto,&dtm);            
            }
            
IDataTypes->DisposeDTObject(dto);
            
            
Freemem(tempbuffer);
        }
    }
    else
    {
        
IDOS->Printf("Bummer\n");
    }
}


Replace the ARGBtoARGB32 loop with a ReadPixelArray variant to extract the data from your bitmap.

You might well be able to use the bitmap directly without that step, not sure.

Result will be a 32bit ILBM



Go to top
Re: Saving a bitmap with datatype (again....)
Home away from home
Home away from home


See User information
@thellier

Note I'm using SaveDTObject() rather than DTM_WRITE directly.


Go to top
Re: Saving a bitmap with datatype (again....)
Home away from home
Home away from home


See User information
@broadblues

Quote:
Result will be a 32bit ILBM


Some of the datatypes include encoders, so it should be possible to save in other formats. I have no idea how to detect which ones have the encoders, though.

Hans

Join Kea Campus' Amiga Corner and support Amiga content creation
https://keasigmadelta.com/ - see more of my work
Go to top
Re: Saving a bitmap with datatype (again....)
Amigans Defender
Amigans Defender


See User information
@thellier

Have a look at bitmap_save here too: http://git.netsurf-browser.org/netsur ... /tree/amiga/bitmap.c#n150

@Hans

A black art. I wrote how to do it in a thread on the official forums. Not about to try and find it on a phone but it's there somewhere.

Go to top
Re: Saving a bitmap with datatype (again....)
Not too shy to talk
Not too shy to talk


See User information
AAAARGHHH after several tests it is still not working
HEEELP
DoDTMethod result is 1 , iff file is empty (size 0)

I also tried
result=DoDTMethod(dto,NULL,NULL,DTM_WRITE,NULL,fp,DTWM_IFF,NULL);
after loading with datatype a jpg and it works


This my code
Some specificity (that works in other part of my sources):
MyDoMethodA is needed cause i dont use libamiga
BmReadPixelArray : to avoid a missing registers error with gcc
MMfree/MMalloc: are my tracked memory functions


/*==================================================================================*/
inline ULONG MyDoMethodA(Object * obj,Msg msg)
{
ULONG result=0;
Class * cl;

if(obj==NULL)
return(result);
cl = OCLASS(obj);

if(cl==NULL)
return(result);

result =CallHookPkt(&cl->cl_Dispatcher,obj,msg);
return(result);
}
/*==================================================================================*/
void BmReadPixelArray(UBYTE *buf,void *rast,ULONG width,ULONG height)
{
ReadPixelArray(buf,0,0,(width*24/8),rast,0,0,width,height,RECTFMT_RGB);
}
/*==================================================================================*/
void SaveBitmap(Scene3D *S,UBYTE *filename)
{
Object *dto=NULL;
UBYTE *buf=NULL;
BPTR fp=NULL;
struct BitMap *bm;
struct pdtBlitPixelArray bpa;
APTR bitMapHandle;
ULONG width,height;
ULONG result;

bm=S->bufferrastport.BitMap;
Libprintf("SaveBitmap bm %ld \n",bm);

bitMapHandle = LockBitMapTags(bm, LBMI_WIDTH, (ULONG)&width, LBMI_HEIGHT, (ULONG)&height,TAG_END);
if(!bitMapHandle) goto panic;
UnLockBitMap(bitMapHandle);

dto = NewDTObject(NULL, DTA_SourceType,DTST_RAM, DTA_GroupID,GID_PICTURE, TAG_DONE);
if(!dto) goto panic;

buf = MMmalloc(24/8*width*height,"buf");
if(!buf) goto panic;

BmReadPixelArray(buf,&S->bufferrastport,width,height);

result=SetDTAttrs (dto, NULL, NULL,
DTA_ObjName, (ULONG)"Microbe3D grab",
DTA_NominalHoriz, width,
DTA_NominalVert, height,
PDTA_SourceMode, PMODE_V43,
TAG_DONE);
if(result) goto panic;

bpa.MethodID = PDTM_WRITEPIXELARRAY;
bpa.pbpa_PixelData = buf;
bpa.pbpa_PixelFormat = PBPAFMT_RGB;
bpa.pbpa_PixelArrayMod = width*24/8;
bpa.pbpa_Left = 0;
bpa.pbpa_Top = 0;
bpa.pbpa_Height = height;
bpa.pbpa_Width = width;
result=MyDoMethodA(dto,(Msg)&bpa);
if(result) goto panic;

result=DoDTMethod(dto,NULL,NULL,DTM_CLEARSELECTED,NULL);
if(result) goto panic;

fp=Open(filename,MODE_NEWFILE);
if(!fp) goto panic;
result=DoDTMethod(dto,NULL,NULL,DTM_WRITE,NULL,fp,DTWM_IFF,NULL);
Libprintf(" result:%ld for buf %ld %ldX%ld (bm %ld dto %ld fp %ld)\n",result,buf,width,height,bm,dto,fp);
panic:
if(fp) Close(fp);
if(dto) DisposeDTObject(dto);
if(buf) MMfree(buf);
}
/*==================================================================================*/

Go to top
Re: Saving a bitmap with datatype (again....)
Home away from home
Home away from home


See User information
@thellier

You don't appear to have setup the Bitmap Header

THis section in my code

            if(IDataTypes->GetDTAttrs(dto, PDTA_BitMapHeader, &bmhd, TAG_DONE))
            {
    
                bmhd->bmh_Left = 0;
                bmhd->bmh_Top = 0;
                bmhd->bmh_Width = bmhd->bmh_PageWidth = sklay->sl_Width;
                bmhd->bmh_Height = bmhd->bmh_PageHeight = sklay->sl_Height;
                bmhd->bmh_Depth = 32;
                bmhd->bmh_Masking = mskHasAlpha ;
            }


Go to top
Re: Saving a bitmap with datatype (again....)
Just can't stay away
Just can't stay away


See User information
@thellier

Quote:

dto = NewDTObject(NULL, DTA_SourceType,DTST_RAM, DTA_GroupID,GID_PICTURE, TAG_DONE);


You should specify DTA_BaseName here instead of DTA_GroupID.

dto IDataTypes->NewDTObject(NULL,
    
DTA_SourceTypeDTST_RAM,
    
DTA_BaseName"ilbm",
    
PDTA_DestModePMODE_V43,
    
TAG_END);


Also unless you have ilbm.datatype version 53.3, which AFAIK is only available to beta testers, it won't work because older versions do not support DTST_RAM.

Go to top
Re: Saving a bitmap with datatype (again....)
Not too shy to talk
Not too shy to talk


See User information
Thanks Broadblues
With this part it works now on OS4 but still not on OS3
@Salass00
You seems to be right for OS3 not OS4
Curious : I was thinking that IFF/ILBM writing was supported as it is the Amiga "standard" format
A kind of SaveBitmapAsIff(bm,filename) should be an AmigaOS function

Alain

Joined the source that "Save a bitmap with DataType"

/*==================================================================================*/
inline ULONG MyDoMethodA(Object * obj,Msg msg)
{
ULONG result=0;
Class * cl;

if(obj==NULL)
return(result);
cl = OCLASS(obj);

if(cl==NULL)
return(result);

result =CallHookPkt(&cl->cl_Dispatcher,obj,msg);
return(result);
}
/*==================================================================================*/
#define RECTFMT_RGB 0
#define RECTFMT_RGBA 1
#define RECTFMT_ARGB 2
#define LBMI_WIDTH 0x84001001
#define LBMI_HEIGHT 0x84001002
/*==================================================================================*/
void BmReadPixelArray(UBYTE *buf,void *rast,ULONG width,ULONG height)
{
ReadPixelArray(buf,0,0,(width*24/8),rast,0,0,width,height,RECTFMT_RGB);
}
/*==================================================================================*/
void SaveBitmap(Scene3D *S,UBYTE *filename)
{
Object *dto=NULL;
UBYTE *buf=NULL;
BPTR fp=NULL;
struct BitMap *bm;
struct pdtBlitPixelArray bpa;
struct BitMapHeader *bmhd;
APTR bitMapHandle;
ULONG width,height;
ULONG result;

bm=S->window->RPort->BitMap;
Libprintf("SaveBitmap bm %ld %s\n",bm,filename);

bitMapHandle = LockBitMapTags(bm, LBMI_WIDTH, (ULONG)&width, LBMI_HEIGHT, (ULONG)&height,TAG_END);
if(!bitMapHandle) goto panic;
UnLockBitMap(bitMapHandle);

dto = NewDTObject(NULL, DTA_SourceType,DTST_RAM, DTA_GroupID,GID_PICTURE, TAG_DONE);
if(!dto) goto panic;

buf = MMmalloc(24/8*width*height,"buf");
if(!buf) goto panic;

BmReadPixelArray(buf,&S->bufferrastport,width,height);


result=GetDTAttrs(dto, PDTA_BitMapHeader, (ULONG)&bmhd, TAG_DONE);
bmhd->bmh_Left = 0;
bmhd->bmh_Top = 0;
bmhd->bmh_Width = bmhd->bmh_PageWidth = width;
bmhd->bmh_Height = bmhd->bmh_PageHeight = height;
bmhd->bmh_Depth = 24;
bmhd->bmh_Masking = 0*mskHasAlpha ;

result=SetDTAttrs (dto, NULL, NULL,
DTA_ObjName, (ULONG)"Microbe3D grab",
DTA_NominalHoriz, width,
DTA_NominalVert, height,
PDTA_SourceMode, PMODE_V43,
TAG_DONE);

bpa.MethodID = PDTM_WRITEPIXELARRAY;
bpa.pbpa_PixelData = buf;
bpa.pbpa_PixelFormat = PBPAFMT_RGB;
bpa.pbpa_PixelArrayMod = width*24/8;
bpa.pbpa_Left = 0;
bpa.pbpa_Top = 0;
bpa.pbpa_Height = height;
bpa.pbpa_Width = width;
result=MyDoMethodA(dto,(Msg)&bpa);

result=DoDTMethod(dto,NULL,NULL,DTM_CLEARSELECTED,NULL);

fp=Open(filename,MODE_NEWFILE);
result=DoDTMethod(dto,NULL,NULL,DTM_WRITE,NULL,fp,DTWM_IFF,NULL);
Libprintf(" result:%ld for buf %ld %ldX%ld (bm %ld dto %ld fp %ld)\n",result,buf,width,height,bm,dto,fp);
panic:
if(fp) Close(fp);
if(dto) DisposeDTObject(dto);
if(buf) MMfree(buf);

}
/*==================================================================================*/

Go to top
Re: Saving a bitmap with datatype (again....)
Just can't stay away
Just can't stay away


See User information
@thellier

Quote:

@Salass00
You seems to be right for OS3 not OS4


Well it might be that the way you do it, it creates the datatype object using the picture.datatype base class directly and that's why it works for you.

Go to top
Re: Saving a bitmap with datatype (again....)
Home away from home
Home away from home


See User information
@thellier

if you want os3 what version of datatype do you have installed?

the above code needs at least datatype version 43


Go to top
Re: Saving a bitmap with datatype (again....)
Not too shy to talk
Not too shy to talk


See User information
@broadblues

With picture.datatype 45.17 (from os3.9) it works on OS3 too

So the last code given above do the job "Save a bitmap with DataType" on OS3 & OS4

Case closed : I am happy

Thanks to all
Alain Thellier




Go to top

  Register To Post

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2024 The XOOPS Project