Mombu the Programming Forum

Go Back   Mombu the Programming Forum > Programming > Some little problem with Leunen's 32-bit Bitmap Rotate routine
User Name
Password
REGISTER NOW! Mark Forums Read




Reply
1 29th October 23:53
kronos
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routine



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)/8);

//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)/8);

//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_COLO RS);
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
  Reply With Quote


 


2 29th October 23:53
hans galema
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routine



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

Hans.
  Reply With Quote
3 29th October 23:53
kronos
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routineReferences:<45d2d132@newsgroups.borland.com>


Hans Galema ha scritto:


i've just done it.

Thanks for tip!
  Reply With Quote
4 29th October 23:53
bruce salzman
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routine


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
  Reply With Quote
5 29th October 23:53
kronos
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routine


Bruce Salzman ha scritto:


It's the right tip!

Now it's all ok!

many, many thanks!
  Reply With Quote
6 29th October 23:53
bruce salzman
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routine


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

--
Bruce
  Reply With Quote
7 29th October 23:53
kronos
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routine


Bruce Salzman ha scritto:


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!
  Reply With Quote
8 29th October 23:53
jim dodd
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routine


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

Just curious,
Jim Dodd
Onset Computer Corp.
  Reply With Quote
9 29th October 23:53
bruce salzman
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routine


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
  Reply With Quote
10 29th October 23:53
michel leunen
External User
 
Posts: 1
Default Some little problem with Leunen's 32-bit Bitmap Rotate routine


Hi Bruce,


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/
----------------------------------------
  Reply With Quote
Reply


Thread Tools
Display Modes




666