BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Some little problem with Leunen's 32-bit Bitmap Rotate routi

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Graphics)
View previous topic :: View next topic  
Author Message
kronos
Guest





PostPosted: Wed Feb 14, 2007 9:10 am    Post subject: Some little problem with Leunen's 32-bit Bitmap Rotate routi Reply with quote



Yesterday i implemented Leunen's Bitmap rotate routine and below follow
my results:

1. with 24-bit bitmap image i don't have any problem neither using large
image (about 60 MegaBytes - sixty)

2. with 32-bit bitmap image i saw random behaviour:
a) with little image (70KiloBytes - seventy) there was no problem
b) with size image of about 1 MegaBytes (one megabyte) more
precisely 509 x 509 = 259081 pixels the routine didn't ever worked;
c) with large image (about 60 MegaBytes - sixty) sometimes the
routine worked properly other times no!


From yesterday afternoon i tried to understand the problem but now i
give in!

many thanks in advance.

p.s.: The last code i tested follow below:


// START - UNIT.H

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <math.h>

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TScrollBox *ScrollBox1;
TImage *Image1;
TButton *Button1;
TLabel *Label1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations

void TestRotate01(void);

__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

// END - UNIT.H

// *****************************

// START - UNIT.C

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------

void TForm1::TestRotate01(void)
{
int temp01, temp02, temp03, temp04;

//Source Bitmap
Graphics::TBitmap *SrcBitmap=new Graphics::TBitmap;
//Destination bitmap
Graphics::TBitmap *DestBitmap=new Graphics::TBitmap;


SrcBitmap->LoadFromFile("MY FILE IMAGE NAME");


DestBitmap->PixelFormat=SrcBitmap->PixelFormat;
int angle=45; //45° for example
//Convert degrees to radians
float radians=(2*3.1416*angle)/360;

float cosine=(float)cos(radians);
float sine=(float)sin(radians);

float Point1x=(-SrcBitmap->Height*sine);
float Point1y=(SrcBitmap->Height*cosine);
float Point2x=(SrcBitmap->Width*cosine-SrcBitmap->Height*sine);
float Point2y=(SrcBitmap->Height*cosine+SrcBitmap->Width*sine);
float Point3x=(SrcBitmap->Width*cosine);
float Point3y=(SrcBitmap->Width*sine);

float minx=min((float) 0,min(Point1x,min(Point2x,Point3x)));
float miny=min((float) 0,min(Point1y,min(Point2y,Point3y)));
float maxx=max((float) 0,max(Point1x,max(Point2x,Point3x)));
float maxy=max((float) 0,max(Point1y,max(Point2y,Point3y)));

int DestBitmapWidth=(int)ceil(maxx-minx);
int DestBitmapHeight=(int)ceil(maxy-miny);

DestBitmap->Height=DestBitmapHeight;
DestBitmap->Width=DestBitmapWidth;

//create DIB for SrcBitmap

LPBITMAPINFO srcBmpi=(LPBITMAPINFO)new char[sizeof(BITMAPINFO)];
ZeroMemory(srcBmpi,sizeof(BITMAPINFO));
//init BitmapInfo struct
srcBmpi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
srcBmpi->bmiHeader.biWidth=SrcBitmap->Width;
srcBmpi->bmiHeader.biHeight=SrcBitmap->Height;
srcBmpi->bmiHeader.biPlanes=1;
srcBmpi->bmiHeader.biCompression=BI_RGB;
switch(SrcBitmap->PixelFormat)
{
case pf24bit: srcBmpi->bmiHeader.biBitCount=24; break;
case pf32bit: srcBmpi->bmiHeader.biBitCount=32; break;
}
//Each row is zero padded so that the number of bytes
//per row is divisible by 4
int SrcNumberOfBytesPerRow=
((((SrcBitmap->Width*srcBmpi->bmiHeader.biBitCount)+31)&~31)/Cool;

//use screen DC for GetDIBits
HDC ScreenDC=GetDC(NULL);

//get image size
temp01 =
GetDIBits(ScreenDC,SrcBitmap->Handle,0,srcBmpi->bmiHeader.biHeight,
NULL,srcBmpi,DIB_RGB_COLORS);

//if the driver didn't give the size, calculate it yourselves
if(srcBmpi->bmiHeader.biSizeImage==0)
{
srcBmpi->bmiHeader.biSizeImage=
SrcNumberOfBytesPerRow*SrcBitmap->Height;
}

//Allocate memory for the bits
char* srcbits=new char[srcBmpi->bmiHeader.biSizeImage];

//get the bits
temp02 =
GetDIBits(ScreenDC,SrcBitmap->Handle,0,srcBmpi->bmiHeader.biHeight,
srcbits,srcBmpi,DIB_RGB_COLORS);


//create DIB for DestBitmap
LPBITMAPINFO destBmpi=(LPBITMAPINFO)new char[sizeof(BITMAPINFO)];
ZeroMemory(destBmpi,sizeof(BITMAPINFO));

//init BitmapInfo struct
destBmpi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
destBmpi->bmiHeader.biWidth=DestBitmap->Width;
destBmpi->bmiHeader.biHeight=DestBitmap->Height;
destBmpi->bmiHeader.biPlanes=1;
destBmpi->bmiHeader.biCompression=BI_RGB;
destBmpi->bmiHeader.biBitCount=srcBmpi->bmiHeader.biBitCount;
//Each row is zero padded so that the number of bytes
//per row is divisible by 4
int DestNumberOfBytesPerRow=
((((DestBitmap->Width*destBmpi->bmiHeader.biBitCount)+31)&~31)/Cool;

//get image size
temp03 =
GetDIBits(ScreenDC,DestBitmap->Handle,0,destBmpi->bmiHeader.biHeight,
NULL,destBmpi,DIB_RGB_COLORS);

//if the driver didn't give the size, calculate it ourselves
if(destBmpi->bmiHeader.biSizeImage==0)
{
destBmpi->bmiHeader.biSizeImage=
DestNumberOfBytesPerRow*DestBitmap->Height;
}

//Allocate memory for the bits
char* destbits=new char[destBmpi->bmiHeader.biSizeImage];

//Set bits in destination buffer
//Perform the rotation
for(int y=0;y<DestBitmapHeight;y++)
{
for(int x=0;x<DestBitmapWidth;x++)
{
int SrcBitmapx=(int)((x+minx)*cosine+(y+miny)*sine);
int SrcBitmapy=(int)((y+miny)*cosine-(x+minx)*sine);
if(SrcBitmapx>=0&&SrcBitmapx<SrcBitmap->Width&&SrcBitmapy>=0&&
SrcBitmapy<SrcBitmap->Height)
{
for (int i=0;i<srcBmpi->bmiHeader.biBitCount/8;i++)
{
*(destbits+(DestNumberOfBytesPerRow*y)+
(x*srcBmpi->bmiHeader.biBitCount/8+i))=
*(srcbits+(SrcNumberOfBytesPerRow*SrcBitmapy)+
(SrcBitmapx*srcBmpi->bmiHeader.biBitCount/8+i));
}
}
}
}

//Set the bits in destination bitmap
//Convert destination DIB to a bitmap
temp04 = SetDIBits(ScreenDC,DestBitmap->Handle,0,
destBmpi->bmiHeader.biHeight,destbits,destBmpi,DIB_RGB_COLORS);
Image1->Picture->Bitmap=DestBitmap;

Label1->Caption = AnsiString(temp01) +
" -- " + AnsiString(temp02) +
" -- " + AnsiString(temp03) +
" -- " + AnsiString(temp04);


delete DestBitmap;
delete SrcBitmap;
delete []srcbits;
delete []destbits;
}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
TestRotate01();
}
//---------------------------------------------------------------------------

// END - UNIT.C


// *****************************

// START - UNIT.DFM

object Form1: TForm1
Left = 192
Top = 114
Width = 870
Height = 640
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 80
Top = 8
Width = 32
Height = 13
Caption = 'Label1'
end
object ScrollBox1: TScrollBox
Left = 64
Top = 64
Width = 489
Height = 505
TabOrder = 0
object Image1: TImage
Left = 0
Top = 0
Width = 105
Height = 105
AutoSize = True
end
end
object Button1: TButton
Left = 648
Top = 64
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 1
OnClick = Button1Click
end
end


// END - UNIT.DFM
Back to top
Hans Galema
Guest





PostPosted: Wed Feb 14, 2007 3:17 pm    Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r Reply with quote



kronos wrote:

Quote:
2. with 32-bit bitmap image i saw random behaviour:
a) with little image (70KiloBytes - seventy) there was no problem
b) with size image of about 1 MegaBytes (one megabyte) more precisely
509 x 509 = 259081 pixels the routine didn't ever worked;
c) with large image (about 60 MegaBytes - sixty) sometimes the
routine worked properly other times no!

If you posted those bitmaps in borland.public.attachments more
people could have a look.

Hans.
Back to top
kronos
Guest





PostPosted: Wed Feb 14, 2007 3:52 pm    Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r Reply with quote



Hans Galema ha scritto:
Quote:

If you posted those bitmaps in borland.public.attachments more
people could have a look.

Hans.

i've just done it.

Thanks for tip!
Back to top
Bruce Salzman
Guest





PostPosted: Wed Feb 14, 2007 9:26 pm    Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r Reply with quote

"kronos" <jhdhjsd.sdhjhdssu (AT) sdhdjsh (DOT) dgh> wrote in message
news:45d2d132 (AT) newsgroups (DOT) borland.com...
Quote:
Yesterday i implemented Leunen's Bitmap rotate routine and below
follow my results:


Just a general comment: when calling GDI routines that require memory
pointers, allocate the memory with GlobalAlloc instead of new[]. The
page alignment of memory from the Borland memory manager is not always
aligned correctly as far as GDI is concerned.

--
Bruce
Back to top
kronos
Guest





PostPosted: Wed Feb 14, 2007 9:54 pm    Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r Reply with quote

Bruce Salzman ha scritto:
Quote:
"kronos" <jhdhjsd.sdhjhdssu (AT) sdhdjsh (DOT) dgh> wrote in message
news:45d2d132 (AT) newsgroups (DOT) borland.com...
Yesterday i implemented Leunen's Bitmap rotate routine and below
follow my results:


Just a general comment: when calling GDI routines that require memory
pointers, allocate the memory with GlobalAlloc instead of new[]. The
page alignment of memory from the Borland memory manager is not always
aligned correctly as far as GDI is concerned.


It's the right tip!

Now it's all ok!

many, many thanks!
Back to top
Bruce Salzman
Guest





PostPosted: Wed Feb 14, 2007 10:03 pm    Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r Reply with quote

"kronos" <jhdhjsd.sdhjhdssu (AT) sdhdjsh (DOT) dgh> wrote in message
news:45d3309e$1 (AT) newsgroups (DOT) borland.com...
Quote:
Bruce Salzman ha scritto:
Just a general comment: when calling GDI routines that require
memory pointers, allocate the memory with GlobalAlloc instead of
new[]. The page alignment of memory from the Borland memory manager
is not always aligned correctly as far as GDI is concerned.


It's the right tip!

Now it's all ok!

many, many thanks!

Glad to hear it. I guess I should put that one in QC. It's been a
problem for years.

--
Bruce
Back to top
kronos
Guest





PostPosted: Wed Feb 14, 2007 10:16 pm    Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r Reply with quote

Bruce Salzman ha scritto:
Quote:
"kronos" <jhdhjsd.sdhjhdssu (AT) sdhdjsh (DOT) dgh> wrote in message
news:45d3309e$1 (AT) newsgroups (DOT) borland.com...
Bruce Salzman ha scritto:
Just a general comment: when calling GDI routines that require
memory pointers, allocate the memory with GlobalAlloc instead of
new[]. The page alignment of memory from the Borland memory manager
is not always aligned correctly as far as GDI is concerned.

It's the right tip!

Now it's all ok!

many, many thanks!

Glad to hear it. I guess I should put that one in QC. It's been a
problem for years.


When i gave in i saw, tests after tests, strange things about "new"
function but i thought i was wrong but now it'a all straightforward!

byby

thanks again!
Back to top
Jim Dodd
Guest





PostPosted: Thu Feb 15, 2007 12:28 am    Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r Reply with quote

Bruce Salzman wrote:
Quote:
"kronos" <jhdhjsd.sdhjhdssu (AT) sdhdjsh (DOT) dgh> wrote in message
news:45d3309e$1 (AT) newsgroups (DOT) borland.com...
Bruce Salzman ha scritto:
Just a general comment: when calling GDI routines that require
memory pointers, allocate the memory with GlobalAlloc instead of
new[]. The page alignment of memory from the Borland memory manager
is not always aligned correctly as far as GDI is concerned.

It's the right tip!

Now it's all ok!

many, many thanks!

Glad to hear it. I guess I should put that one in QC. It's been a
problem for years.


Is this still true with BDS2006 which uses the new FastMM memory
allocation routines?

Just curious,
Jim Dodd
Onset Computer Corp.
Back to top
Bruce Salzman
Guest





PostPosted: Thu Feb 15, 2007 2:21 am    Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r Reply with quote

"Jim Dodd" <bcbuilderboy (AT) yahoo (DOT) com> wrote in message
news:45d3549e (AT) newsgroups (DOT) borland.com...

Quote:
Is this still true with BDS2006 which uses the new FastMM memory
allocation routines?

Just curious,
Jim Dodd
Onset Computer Corp.

Well, I just tried kronos's code and bitmaps in BDS2006 and they
worked with new[]! I forgot about the switch to FastMM. Thanks for the
reminder.

--
Bruce
Back to top
Michel Leunen
Guest





PostPosted: Thu Feb 15, 2007 2:45 am    Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r Reply with quote

Hi Bruce,

Bruce Salzman wrote:

Quote:
Just a general comment: when calling GDI routines that require memory
pointers, allocate the memory with GlobalAlloc instead of new[]. The
page alignment of memory from the Borland memory manager is not always
aligned correctly as far as GDI is concerned.

Thanks for remembering me that point. It was reported to me a long time
ago but I never updated my article. Sorry.

Michel
--
----------------------------------------
Michel Leunen
mailto: see my homepage.
C++Builder, BCC5.5.1 Web site:
http://www.leunen.com/
----------------------------------------
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Graphics) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.