 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
kronos Guest
|
Posted: Wed Feb 14, 2007 9:10 am Post subject: Some little problem with Leunen's 32-bit Bitmap Rotate routi |
|
|
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)/ ;
//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)/ ;
//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
|
Posted: Wed Feb 14, 2007 3:17 pm Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r |
|
|
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
|
Posted: Wed Feb 14, 2007 3:52 pm Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r |
|
|
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
|
Posted: Wed Feb 14, 2007 9:26 pm Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r |
|
|
"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
|
Posted: Wed Feb 14, 2007 9:54 pm Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r |
|
|
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
|
Posted: Wed Feb 14, 2007 10:03 pm Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r |
|
|
"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
|
Posted: Wed Feb 14, 2007 10:16 pm Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r |
|
|
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
|
Posted: Thu Feb 15, 2007 12:28 am Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r |
|
|
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
|
Posted: Thu Feb 15, 2007 2:21 am Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r |
|
|
"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
|
Posted: Thu Feb 15, 2007 2:45 am Post subject: Re: Some little problem with Leunen's 32-bit Bitmap Rotate r |
|
|
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 |
|
 |
|
|
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
|
|