Board index » delphi » loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap

loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap

I need to stitch together a number of 500x500 pixel bitmaps to create a single image that can exceed 10000x10000 pixels.  Windows 98/95/ME has problems with bitmaps >16mb and gives  resource error when you try to define the bitmaps height and width.  I have a feeling there Is there a way to build this bitmap file in memory and save to disk as one huge bitmap from something like a tstream.  Problem is I'm not sure how. The bitmaps come from 65k color jpeg files on disk so I assume they are 24 or 32 bit bmps - if that matters.

Any ideas would be greatly appreciated.

Thanks in advance,

Sean

 

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


Quote
"Sean Roulo" <s...@magicalmaps.com> wrote in message news:3c7ad05c$1_2@dnews...

> I need to stitch together a number of 500x500 pixel bitmaps to create a single image that can

exceed 10000x10000 pixels.  Windows 98/95/ME has problems with bitmaps >16mb and gives  resource
error when you try to define the bitmaps height and width.

You'll have a variety of problems in Windows 9x.  You have a chance in Windows 2000 or XP.
Also see:  http://homepages.borland.com/efg2lab/Graphics/VeryLargeBitmap.htm

--
efg -- Earl F. Glynn, Overland Park, KS  USA
efg's Computer Lab Mirror:  http://homepages.borland.com/efg2lab

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


Earl,

Thanks for your reply and thanks for making that large bitmap demo.  correct me if I'm wrong but your program is designed to test exactly how large of a bitmap your individual windows version/ video adapter/ memory etc. will let tbitmap object create.  What I'm suggesting is rather than try to use the tbitmap object (where I would get trouble from win9x) instead try to build a memory mapped file by hand-calculating the bitmap header and image data bytes by merging the individual bitmap files.  This would require knowing the specific file structure/layout of bitmap files, which I do not.  I imagine there is some kind of header to the file that tells the height and/or width, and  perhaps pixel format, etc.  I just don't really have a clue how to start or where to look for that.  I know there is some folks that could write the routine in about 5 minutes or less and I was hoping they might be reading this message about now.  If so I've got some cash to pay for help writing this.

Thanks,

Sean

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


Well, I stitch together many 1200 x 900 pixel bitmaps, normally 4 x 4 pages max at 4800 x 3600 pixels to as many as 10 x 10 (12,000 x 9,000 pixels).  I have written 20 x 30 page chunks out to a 36 inch plotter with good results.  Although PhotoShop and such can deal with megapixel bitmaps, I think that anything over about 4,000 on a side is the kiss of death for Win 95 machines and am planning my app accordingly.

For producing large bitmaps, an NT class OS is required.  It took under 20 seconds to create a 10K x 10K bitmap in PaintShop Pro, 7 seconds to create a bitmap on a 500 MHz machine with 256 meg memory, using this code:

  Bmp := TBitmap.Create;
  Bmp.PixelFormat := pf24bit;
  Bmp.Width := 10000;
  Bmp.Height := 10000;

It can be slow, even on a gigahertz machine but you can allocate bitmaps hundreds of megs in size.

You can stitch large bitmaps together relatively painlessly by writing to a large format plotter canvas, such as an HP 36 inch roll plotter.  By writing to a file or saving spooler output you get a file of the plot.

I think the stream idea might be feasible.  The images need to be read into a jpeg component to create an available bitmap.  You create a bitmap header and stream it out first.  Next, it will be necessary to know the byte order that the image is loaded in a LoadFromStream.  Let's assume that it fills all columns in a row then loads the next row.  In this case, it would be necessary to load all the tiles ACROSS the output bitmap, then stream all the rows in the bitmap height.  Then, load the next row of images and repeat the
process.  This would avoid a very large buffer call in Win 95.

You need to make sure that the bytes are all properly aligned in the bitmap.  See the documentation of scanline to see how various resolutions may result in pad bytes to round out a video display line.

Quote
Sean Roulo wrote:
> I need to stitch together a number of 500x500 pixel bitmaps to create a single image that can exceed 10000x10000 pixels.  Windows 98/95/ME has problems with bitmaps >16mb and gives  resource error when you try to define the bitmaps height and width.  I have a feeling there Is there a way to build this bitmap file in memory and save to disk as one huge bitmap from something like a tstream.  Problem is I'm not sure how. The bitmaps come from 65k color jpeg files on disk so I assume they are 24 or 32 bit bmps - if that matters.

> Any ideas would be greatly appreciated.

> Thanks in advance,

> Sean

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


The fileformats are available at http://www.wotsit.org
And yes, you could have an array[0..9999,0..9999]of integer,
a mere 400 MBytes and move it back and forth from the memory
to the graphics card. A machine of today has at least 512 MB.
Oops, on yesterdays it'll swap a bit.

Rene
--
Ing. Buero R.Tschaggelar - http://www.ibrtses.com

Quote
Sean Roulo wrote:
> Earl,

> Thanks for your reply and thanks for making that large bitmap demo.  correct me if I'm wrong but your program is designed to test exactly how large of a bitmap your individual windows version/ video adapter/ memory etc. will let tbitmap object create.  What I'm suggesting is rather than try to use the tbitmap object (where I would get trouble from win9x) instead try to build a memory mapped file by hand-calculating the bitmap header and image data bytes by merging the individual bitmap files.  This would require knowing the specific file structure/layout of bitmap files, which I do not.  I imagine there is some kind of header to the file that tells the height and/or width, and  perhaps pixel format, etc.  I just don't really have a clue how to start or where to look for that.  I know there is some folks that could write the routine in about 5 minutes or less and I was hoping they might be reading this message about now.  If so I've got some cash to pay for help writing thi
s.

> Thanks,

> Sean

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


If you use CreateDibSection and FileMapping you should be able to write
really huge bitmaps. Using alone CreateDIBSection without FileMapping I was
able to create 6400 by 4800 pix bitmap with no problems on Win98 machine.

All I can say is Best of luck

DP

Quote
"Sean Roulo" <s...@magicalmaps.com> wrote in message

news:3c7ad05c$1_2@dnews...
Quote

> I need to stitch together a number of 500x500 pixel bitmaps to create a

single image that can exceed 10000x10000 pixels.  Windows 98/95/ME has
problems with bitmaps >16mb and gives  resource error when you try to define
the bitmaps height and width.  I have a feeling there Is there a way to
build this bitmap file in memory and save to disk as one huge bitmap from
something like a tstream.  Problem is I'm not sure how. The bitmaps come
from 65k color jpeg files on disk so I assume they are 24 or 32 bit bmps -
if that matters.
Quote

> Any ideas would be greatly appreciated.

> Thanks in advance,

> Sean

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


Quote
>This would require knowing the specific file structure/layout of bitmap files, which I do not.  I imagine there is some
> kind of header to the file that tells the height and/or width, and  perhaps pixel format, etc.  I just don't really

have a clue how to start or where to look for that.  I

hope this simple routine will help you "to start" :)

procedure SaveToFileBMP(const aBmp: TBitmap; aFileName: String);
{ saves 32-bit bitmaps in 24-bit bmp format - some programs (like Adobe Photoshop) dont understand 32-bit .bmp }
var i,n,m,w: Integer;
    f: File;
    bmfh: BITMAPFILEHEADER;
    bmih: BITMAPINFOHEADER;
    p,p1: Pointer;
    pSrc: PIntArray;
begin
  if ExtractFileExt(aFileName) = '' then
    aFileName := aFileName+'.bmp';
  if GetDeviceCaps(aBmp.Canvas.Handle,BITSPIXEL) <> 32 then begin
    aBmp.SaveToFile(aFileName);
    Exit;
    end;

  with bmfh do begin
    bfType := Ord('M') shl 8 or Ord('B');
    bfSize := sizeOf(bmfh) + sizeOf(bmih) + aBmp.Width*aBmp.Height*3;
    bfReserved1 := 0;
    bfReserved2 := 0;
    bfOffBits := sizeOf(bmfh) + sizeOf(bmih);
    end;

  with bmih do begin
    biSize := SizeOf(bmih);
    biWidth := aBmp.Width;
    biHeight := aBmp.Height;
    biPlanes := 1;
    biBitCount := 24;
    biCompression := BI_RGB;
    biSizeImage := 0;
    biXPel{*word*237}eter := 1; //dont care
    biYPel{*word*237}eter := 1; //dont care
    biClrUsed := 0;
    biClrImportant := 0;
    end;

  n := aBmp.Width;
  m := n*3;
  if m mod 4 <> 0 then
    Inc(m,4-(m mod 4));
  GetMem(p,n*3);
  w := abmp.Width;

  BmpToArray(aBmp,Pointer(pSrc));

  AssignFile(f,aFileName);
  Rewrite(f,1);
  BlockWrite(f,bmfh,SizeOf(bmfh));
  BlockWrite(f,bmih,SizeOf(bmih));
  for i := aBmp.Height-1 downto 0 do begin
    p1 := @pSrc[w*i];
    asm
      push esi
      push edi
      mov ecx,n
      mov esi,p1
      mov edi,p

    @L1:
      lodsd
      stosw
      shr eax,16
      stosb
      loop @L1

      pop edi
      pop esi
      end;
    BlockWrite(f,p^,m);
    end;
  CloseFile(f);
  FreeMem(p);
  FreeMem(pSrc);
end;

if something is unclear, ask
--
Andrew Rybenkov,
  the programmer who walks by himself.

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


I have a library I privatly sell that works with very large bitmaps, jpegs, andd TWAIN sources...

Email for more info

Joe
--
Jimmy Page is having a charity artwork sale: Action For Brazil's Children Trust: http://www.zeppinhood.net/
Whole Lotta Love computing to cure cancer! http://www.wholelottalove.org/

Quote
"Sean Roulo" <s...@magicalmaps.com> wrote in message news:3c7ad05c$1_2@dnews...

> I need to stitch together a number of 500x500 pixel bitmaps to create a single image that can exceed 10000x10000 pixels.  Windows

98/95/ME has problems with bitmaps >16mb and gives  resource error when you try to define the bitmaps height and width.  I have a
feeling there Is there a way to build this bitmap file in memory and save to disk as one huge bitmap from something like a tstream.
Problem is I'm not sure how. The bitmaps come from 65k color jpeg files on disk so I assume they are 24 or 32 bit bmps - if that
matters.
Quote

> Any ideas would be greatly appreciated.

> Thanks in advance,

> Sean

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


Rene,

Thanks for the post and the link (condensed version is attached at bottom of message).  I downloaded the file and I think I have a pretty good grasp on what needs to be done.  It seems I just need to calculate the size of the bitmap in height and width, then calculate the byte size of the header and add that to the number of image pixels times 3(bytes) to get the file size.  Is there an end of file byte and should that be counted in file size?

one thing I am a little bit confused about is when it mentions
'If necessary, a scan line
must be zero-padded to end on a 32-bit boundary. However, segment boundaries
can appear anywhere in the bitmap.'

could anyone out there please enlighten me on what I am supposed to do here.  I assume the file needs to be a size divideable by 32 if not pad the file with #0 (or just 0)?.

Great thanks in advance!

Sean

Quote
Rene Tschaggelar <tschagge...@dplanet.ch> wrote:
>The fileformats are available at http://www.wotsit.org
>And yes, you could have an array[0..9999,0..9999]of integer,
>a mere 400 MBytes and move it back and forth from the memory
>to the graphics card. A machine of today has at least 512 MB.
>Oops, on yesterdays it'll swap a bit.

>Rene
>--
>Ing. Buero R.Tschaggelar - http://www.ibrtses.com

>Sean Roulo wrote:

>> Earl,

>> Thanks for your reply and thanks for making that large bitmap demo.  correct me if I'm wrong but your program is designed to test exactly how large of a bitmap your individual windows version/ video adapter/ memory etc. will let tbitmap object create.  What I'm suggesting is rather than try to use the tbitmap object (where I would get trouble from win9x) instead try to build a memory mapped file by hand-calculating the bitmap header and image data bytes by merging the individual bitmap files.
>This would require knowing the specific file structure/layout of bitmap files, which I do not.  I imagine there is some kind of header to the file that tells the height and/or width, and  perhaps pixel format, etc.  I just don't really have a clue how to start or where to look for that.  I know there is some folks that could write the routine in about 5 minutes or less and I was hoping they might be reading this message about now.  If so I've got some cash to pay for help writing thi
>s.

>> Thanks,

>> Sean

Each bitmap file contains a bitmap-file header, a bitmap-information header,
a color table, and an array of bytes that defines the bitmap bits. The file
has the following form:

BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD          aColors[];
BYTE             aBitmapBits[];

The bitmap-file header contains information about the type, size, and layout
of a device-independent bitmap file. The header is defined as a
BITMAPFILEHEADER structure.

typedef struct tagBITMAPFILEHEADER {    /* bmfh */
    UINT    bfType;
    DWORD   bfSize;
    UINT    bfReserved1;
    UINT    bfReserved2;
    DWORD   bfOffBits;

Quote
} BITMAPFILEHEADER;

The BITMAPFILEHEADER structure contains information about the type, size, and
layout of a device-independent bitmap (DIB) file.

Member          Description

bfType          Specifies the type of file. This member must be BM.
bfSize          Specifies the size of the file, in bytes.
bfReserved1     Reserved; must be set to zero.
bfReserved2     Reserved; must be set to zero.
bfOffBits       Specifies the byte offset from the BITMAPFILEHEADER structure
to the actual bitmap data in the file.

Comments

A BITMAPINFO or BITMAPCOREINFO structure immediately follows the
BITMAPFILEHEADER structure in the DIB file.

==============================================================================
BITMAPINFOHEADER (3.0)

typedef struct tagBITMAPINFOHEADER {    /* bmih */
    DWORD   biSize;
    LONG    biWidth;
    LONG    biHeight;
    WORD    biPlanes;
    WORD    biBitCount;
    DWORD   biCompression;
    DWORD   biSizeImage;
    LONG    biXPel{*word*237}eter;
    LONG    biYPel{*word*237}eter;
    DWORD   biClrUsed;
    DWORD   biClrImportant;

Quote
} BITMAPINFOHEADER;

The BITMAPINFOHEADER structure contains information about the dimensions and
color format of a Windows 3.0 or later device-independent bitmap (DIB).

Member          Description

biSize          Specifies the number of bytes required by the
BITMAPINFOHEADER structure.

biWidth         Specifies the width of the bitmap, in pixels.
biHeightSpecifies the height of the bitmap, in pixels.

biPlanesSpecifies the number of planes for the target device. This
member must be set to 1.

biBitCount      Specifies the number of bits per pixel. This value must be 1,
4, 8, or 24.

biCompression   Specifies the type of compression for a compressed bitmap. It
can be one of the following values:

Value           Meaning

BI_RGB          Specifies that the bitmap is not compressed.

BI_RLE8         Specifies a run-length encoded format for bitmaps with 8 bits
per pixel. The compression format is a 2-byte format consisting of a count
byte followed by a byte containing a color index.  For more information, see
the following Comments section.

BI_RLE4         Specifies a run-length encoded format for bitmaps with 4 bits
per pixel. The compression format is a 2-byte format consisting of a count
byte followed by two word-length color indexes.  For more information, see
the following Comments section.

biSizeImage     Specifies the size, in bytes, of the image. It is valid to
set this member to zero if the bitmap is in the BI_RGB format.

biXPel{*word*237}eter Specifies the horizontal resolution, in pixels per meter, of
the target device for the bitmap. An application can use this value to select
a bitmap from a resource group that best matches the characteristics of the
current device.

biYPel{*word*237}eter Specifies the vertical resolution, in pixels per meter, of
the target device for the bitmap.

biClrUsed       Specifies the number of color indexes in the color table
actually used by the bitmap. If this value is zero, the bitmap uses the
maximum number of colors corresponding to the value of the biBitCount member.
For more information on the maximum sizes of the color table, see the
description of the BITMAPINFO structure earlier in this topic.

If the biClrUsed member is nonzero, it specifies the actual number of colors
that the graphics engine or device driver will access if the biBitCount
member is less than 24. If biBitCount is set to 24, biClrUsed specifies the
size of the reference color table used to optimize performance of Windows
color palettes.  If the bitmap is a packed bitmap (that is, a bitmap in which
the bitmap array immediately follows the BITMAPINFO header and which is
referenced by a single pointer), the biClrUsed member must be set to zero or
to the actual size of the color table.

biClrImportant  Specifies the number of color indexes that are considered
important for displaying the bitmap. If this value is zero, all colors are
important.

Comments

The BITMAPINFO structure combines the BITMAPINFOHEADER structure and a color
table to provide a complete definition of the dimensions and colors of a
Windows 3.0 or later DIB. For more information about specifying a Windows 3.0
DIB, see the description of the BITMAPINFO structure.

An application should use the information stored in the biSize member to
locate the color table in a BITMAPINFO structure as follows:

pColor = ((LPSTR) pBitmapInfo + (WORD) (pBitmapInfo->bmiHeader.biSize))

See Also

The bitmap-information header, defined as a BITMAPINFOHEADER structure,
specifies the dimensions, compression type, and color format for the bitmap.

The color table, defined as an array of RGBQUAD structures, contains as many
elements as there are colors in the bitmap. The color table is not present
for bitmaps with 24 color bits because each pixel is represented by 24-bit
red-green-blue (RGB) values in the actual bitmap data area. The colors in the
table should appear in order of importance. This helps a display driver
render a bitmap on a device that cannot display as many colors as there are
in the bitmap. If the DIB is in Windows version 3.0 or later format, the
driver can use the biClrImportant member of the BITMAPINFOHEADER structure to
determine which colors are important.

The BITMAPINFO structure can be used to represent a combined
bitmap-information header and color table.  The bitmap bits, immediately
following the color table, consist of an array of BYTE values representing
consecutive rows, or "scan lines," of the bitmap. Each scan line consists of
consecutive bytes representing the pixels in the scan line, in left-to-right
order. The number of bytes representing a scan line depends on the color
format and the width, in pixels, of the bitmap. If necessary, a scan line
must be zero-padded to end on a 32-bit boundary. However, segment boundaries
can appear anywhere in the bitmap. The scan lines in the bitmap are stored
from bottom up. This means that the first byte in the array represents the
pixels in the lower-left corner of the bitmap and the last byte represents
the pixels in the upper-right corner.

The biBitCount member of the BITMAPINFOHEADER structure determines the number
of bits that define each pixel and the maximum number of colors in the
bitmap. These members can have any of the following values:

Value   Meaning

1       Bitmap is monochrome and the color table contains two entries. Each
bit in the bitmap array represents a pixel. If the bit is clear, the pixel is
displayed with the color of the first entry in the color table. If the bit is
set, the pixel has the color of the second entry in the table.

4       Bitmap has a maximum of 16 colors. Each pixel in the bitmap is
represented by a 4-bit index into the color table. For example, if the first
byte in the bitmap is 0x1F, the byte represents two pixels. The first pixel
contains the color in the second table entry, and the second pixel contains
the color in the six{*word*249}th table entry.

8       Bitmap has a maximum of 256 colors. Each
...

read more »

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


Andrew,

WOW. thanks for the post.  I do have a couple of questions. :)

bfType := Ord('M') shl 8 or Ord('B');
I understand the UINT type is 4 bytes. but how you assign a value to this as you have done 'confuses' me.

then comes the asm :( part.  I don't know asm so I'm kind of in the dark here.  Think I understand the following

Quote

>  n := aBmp.Width;
>  m := n*3;
>  if m mod 4 <> 0 then
>    Inc(m,4-(m mod 4));
>  GetMem(p,n*3);
>  w := abmp.Width;

this makes sure the row width is a factor of 4 if not, it bumps up m until it is a factor of 4 (rather 4 is a factor).  Does your asm code pad a zero at the end of each line?  it seems that this would need to be done from the text about 32 bit boundaries in my last post to rene.  if so I would need to remove it from the asm code because I would be calling that in a loop for each horizontal tile and I would only want to pad the record for each complete file row, not each horizontal tile's row - if that makes sense. then pointer p is pointed to a reserved block of memory to hold an entire file the row of pixels- the byes added to make the row div 4.

also if you are feeling really generous -if you could give me a step by step comment on the asm code that would be way cool and probably more than I deserve! :)

Thanks,

Sean

Quote
"Andrew Rybenkov" <aryben...@hotmail.com> wrote:
>>This would require knowing the specific file structure/layout of bitmap files, which I do not.  I imagine there is some
>> kind of header to the file that tells the height and/or width, and  perhaps pixel format, etc.  I just don't really
>have a clue how to start or where to look for that.  I

>hope this simple routine will help you "to start" :)

>procedure SaveToFileBMP(const aBmp: TBitmap; aFileName: String);
>{ saves 32-bit bitmaps in 24-bit bmp format - some programs (like Adobe Photoshop) dont understand 32-bit .bmp }
>var i,n,m,w: Integer;
>    f: File;
>    bmfh: BITMAPFILEHEADER;
>    bmih: BITMAPINFOHEADER;
>    p,p1: Pointer;
>    pSrc: PIntArray;
>begin
>  if ExtractFileExt(aFileName) = '' then
>    aFileName := aFileName+'.bmp';
>  if GetDeviceCaps(aBmp.Canvas.Handle,BITSPIXEL) <> 32 then begin
>    aBmp.SaveToFile(aFileName);
>    Exit;
>    end;

>  with bmfh do begin
>    bfType := Ord('M') shl 8 or Ord('B');
>    bfSize := sizeOf(bmfh) + sizeOf(bmih) + aBmp.Width*aBmp.Height*3;
>    bfReserved1 := 0;
>    bfReserved2 := 0;
>    bfOffBits := sizeOf(bmfh) + sizeOf(bmih);
>    end;

>  with bmih do begin
>    biSize := SizeOf(bmih);
>    biWidth := aBmp.Width;
>    biHeight := aBmp.Height;
>    biPlanes := 1;
>    biBitCount := 24;
>    biCompression := BI_RGB;
>    biSizeImage := 0;
>    biXPel{*word*237}eter := 1; //dont care
>    biYPel{*word*237}eter := 1; //dont care
>    biClrUsed := 0;
>    biClrImportant := 0;
>    end;

>  n := aBmp.Width;
>  m := n*3;
>  if m mod 4 <> 0 then
>    Inc(m,4-(m mod 4));
>  GetMem(p,n*3);
>  w := abmp.Width;

>  BmpToArray(aBmp,Pointer(pSrc));

>  AssignFile(f,aFileName);
>  Rewrite(f,1);
>  BlockWrite(f,bmfh,SizeOf(bmfh));
>  BlockWrite(f,bmih,SizeOf(bmih));
>  for i := aBmp.Height-1 downto 0 do begin
>    p1 := @pSrc[w*i];
>    asm
>      push esi
>      push edi
>      mov ecx,n
>      mov esi,p1
>      mov edi,p

>    @L1:
>      lodsd
>      stosw
>      shr eax,16
>      stosb
>      loop @L1

>      pop edi
>      pop esi
>      end;
>    BlockWrite(f,p^,m);
>    end;
>  CloseFile(f);
>  FreeMem(p);
>  FreeMem(pSrc);
>end;

>if something is unclear, ask
>--
>Andrew Rybenkov,
>  the programmer who walks by himself.

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


Quote
> bfType := Ord('M') shl 8 or Ord('B');
> I understand the UINT type is 4 bytes. but how you assign a value to this as you have done 'confuses' me.

bfType is Word

Quote
> >  GetMem(p,n*3);

replace with GetMem(p,m)
just because of specifics of GetMem this bug did not affected execution of the routine, and I saw it only now.

Quote
> this makes sure the row width is a factor of 4 if not, it bumps up m until it is a factor of 4 (rather 4 is a factor).

Does your asm code pad a zero at the

Quote
> end of each line?

no, asm block sends n colors.
it is BlockWrite(f,p^,m); where padding is done

Quote
> it seems that this would need to be done from the text about 32 bit boundaries in my last post to rene.  if so I would
need to remove it
> from the asm code because I would be calling that in a loop for each horizontal tile and I would only want to pad the

record for each complete file row, not
Quote
> each horizontal tile's row - if that makes sense. then pointer p is pointed to a reserved block of memory to hold an

entire file the row of pixels- the byes

Quote
> added to make the row div 4.

of course you do not need pad a tile's row - only whole scanline as BMP format requires.

Quote
> also if you are feeling really generous -if you could give me a step by step comment on the asm code

not a problem

  for i := aBmp.Height-1 downto 0 do begin        // saving from bottom scanline to top
                                                                    // because we set positive height value biHeight :=
aBmp.Height
    p1 := @pSrc[w*i];    // let Delphi calculates necessary address of current scanline
    asm
      push esi               // we must preserve all registers we use except EAX, EDX, ECX
      push edi

      mov ecx,n            // ECX <-- count of colors in a scanline
      mov esi,p1           // ESI <-- address of source (32-bit) scanline  --   format of color 'ARGB'
      mov edi,p             // EDI <-- address of destination (24-bit) scanline  --   format of color 'RGB'

    @L1:
      lodsd                  // EAX <-- source color 'ARGB'
      stosw                 // sending AX register with 'GB' part
      shr eax,16          // AX = 'AR'
      stosb                 // sending AL register with 'R' part
      loop @L1           // decrement counter (ECX) and jump @1 if not zero

      pop edi              // restoring "spoiled" registers
      pop esi
      end;

    BlockWrite(f,p^,m);   // while we sent n colors, to file we write m colors, thus doing padding
                                  // values of additional bytes do not matter
    end;

hope this helps.
--
Andrew Rybenkov,
  the programmer who walks by himself.

Re:loading LARGE bitmaps, stitching them, then saving result in 1 file w/o tbitmap


It just means that your scanlines must always be a multiple of 4 bytes.

True color bitmaps seem to work no other way anyhow so it should not be a
problem. Just make sure you assign 4 bytes instead of 3 for each pixel,
being Blue-Green-Red-Empty.

Kind regards,
Nils Haeck
www.abc-view.com

Quote
Sean Roulo <s...@magicalmaps.com> wrote in message

news:3c7bd499$1_1@dnews...
Quote

> Rene,

> Thanks for the post and the link (condensed version is attached at bottom

of message).  I downloaded the file and I think I have a pretty good grasp
on what needs to be done.  It seems I just need to calculate the size of the
bitmap in height and width, then calculate the byte size of the header and
add that to the number of image pixels times 3(bytes) to get the file size.
Is there an end of file byte and should that be counted in file size?
Quote

> one thing I am a little bit confused about is when it mentions
> 'If necessary, a scan line
> must be zero-padded to end on a 32-bit boundary. However, segment
boundaries
> can appear anywhere in the bitmap.'

> could anyone out there please enlighten me on what I am supposed to do

here.  I assume the file needs to be a size divideable by 32 if not pad the
file with #0 (or just 0)?.
Quote

> Great thanks in advance!

> Sean

> Rene Tschaggelar <tschagge...@dplanet.ch> wrote:
> >The fileformats are available at http://www.wotsit.org
> >And yes, you could have an array[0..9999,0..9999]of integer,
> >a mere 400 MBytes and move it back and forth from the memory
> >to the graphics card. A machine of today has at least 512 MB.
> >Oops, on yesterdays it'll swap a bit.

> >Rene
> >--
> >Ing. Buero R.Tschaggelar - http://www.ibrtses.com

> >Sean Roulo wrote:

> >> Earl,

> >> Thanks for your reply and thanks for making that large bitmap demo.

correct me if I'm wrong but your program is designed to test exactly how
large of a bitmap your individual windows version/ video adapter/ memory
etc. will let tbitmap object create.  What I'm suggesting is rather than try
to use the tbitmap object (where I would get trouble from win9x) instead try
to build a memory mapped file by hand-calculating the bitmap header and
image data bytes by merging the individual bitmap files.
Quote
> >This would require knowing the specific file structure/layout of bitmap

files, which I do not.  I imagine there is some kind of header to the file
that tells the height and/or width, and  perhaps pixel format, etc.  I just
don't really have a clue how to start or where to look for that.  I know
there is some folks that could write the routine in about 5 minutes or less
and I was hoping they might be reading this message about now.  If so I've
got some cash to pay for help writing thi

- Show quoted text -

Quote
> >s.

> >> Thanks,

> >> Sean

> Each bitmap file contains a bitmap-file header, a bitmap-information
header,
> a color table, and an array of bytes that defines the bitmap bits. The
file
> has the following form:

> BITMAPFILEHEADER bmfh;
> BITMAPINFOHEADER bmih;
> RGBQUAD          aColors[];
> BYTE             aBitmapBits[];

> The bitmap-file header contains information about the type, size, and
layout
> of a device-independent bitmap file. The header is defined as a
> BITMAPFILEHEADER structure.

> typedef struct tagBITMAPFILEHEADER {    /* bmfh */
>     UINT    bfType;
>     DWORD   bfSize;
>     UINT    bfReserved1;
>     UINT    bfReserved2;
>     DWORD   bfOffBits;
> } BITMAPFILEHEADER;

> The BITMAPFILEHEADER structure contains information about the type, size,
and
> layout of a device-independent bitmap (DIB) file.

> Member          Description

> bfType          Specifies the type of file. This member must be BM.
> bfSize          Specifies the size of the file, in bytes.
> bfReserved1     Reserved; must be set to zero.
> bfReserved2     Reserved; must be set to zero.
> bfOffBits       Specifies the byte offset from the BITMAPFILEHEADER
structure
> to the actual bitmap data in the file.

> Comments

> A BITMAPINFO or BITMAPCOREINFO structure immediately follows the
> BITMAPFILEHEADER structure in the DIB file.

============================================================================
==

- Show quoted text -

Quote
> BITMAPINFOHEADER (3.0)

> typedef struct tagBITMAPINFOHEADER {    /* bmih */
>     DWORD   biSize;
>     LONG    biWidth;
>     LONG    biHeight;
>     WORD    biPlanes;
>     WORD    biBitCount;
>     DWORD   biCompression;
>     DWORD   biSizeImage;
>     LONG    biXPel{*word*237}eter;
>     LONG    biYPel{*word*237}eter;
>     DWORD   biClrUsed;
>     DWORD   biClrImportant;
> } BITMAPINFOHEADER;

> The BITMAPINFOHEADER structure contains information about the dimensions
and
> color format of a Windows 3.0 or later device-independent bitmap (DIB).

> Member          Description

> biSize          Specifies the number of bytes required by the
> BITMAPINFOHEADER structure.

> biWidth         Specifies the width of the bitmap, in pixels.
> biHeightSpecifies the height of the bitmap, in pixels.

> biPlanesSpecifies the number of planes for the target device. This
> member must be set to 1.

> biBitCount      Specifies the number of bits per pixel. This value must be
1,
> 4, 8, or 24.

> biCompression   Specifies the type of compression for a compressed bitmap.
It
> can be one of the following values:

> Value           Meaning

> BI_RGB          Specifies that the bitmap is not compressed.

> BI_RLE8         Specifies a run-length encoded format for bitmaps with 8
bits
> per pixel. The compression format is a 2-byte format consisting of a count
> byte followed by a byte containing a color index.  For more information,
see
> the following Comments section.

> BI_RLE4         Specifies a run-length encoded format for bitmaps with 4
bits
> per pixel. The compression format is a 2-byte format consisting of a count
> byte followed by two word-length color indexes.  For more information, see
> the following Comments section.

> biSizeImage     Specifies the size, in bytes, of the image. It is valid to
> set this member to zero if the bitmap is in the BI_RGB format.

> biXPel{*word*237}eter Specifies the horizontal resolution, in pixels per meter,
of
> the target device for the bitmap. An application can use this value to
select
> a bitmap from a resource group that best matches the characteristics of
the
> current device.

> biYPel{*word*237}eter Specifies the vertical resolution, in pixels per meter, of
> the target device for the bitmap.

> biClrUsed       Specifies the number of color indexes in the color table
> actually used by the bitmap. If this value is zero, the bitmap uses the
> maximum number of colors corresponding to the value of the biBitCount
member.
> For more information on the maximum sizes of the color table, see the
> description of the BITMAPINFO structure earlier in this topic.

> If the biClrUsed member is nonzero, it specifies the actual number of
colors
> that the graphics engine or device driver will access if the biBitCount
> member is less than 24. If biBitCount is set to 24, biClrUsed specifies
the
> size of the reference color table used to optimize performance of Windows
> color palettes.  If the bitmap is a packed bitmap (that is, a bitmap in
which
> the bitmap array immediately follows the BITMAPINFO header and which is
> referenced by a single pointer), the biClrUsed member must be set to zero
or
> to the actual size of the color table.

> biClrImportant  Specifies the number of color indexes that are considered
> important for displaying the bitmap. If this value is zero, all colors are
> important.

> Comments

> The BITMAPINFO structure combines the BITMAPINFOHEADER structure and a
color
> table to provide a complete definition of the dimensions and colors of a
> Windows 3.0 or later DIB. For more information about specifying a Windows
3.0
> DIB, see the description of the BITMAPINFO structure.

> An application should use the information stored in the biSize member to
> locate the color table in a BITMAPINFO structure as follows:

> pColor = ((LPSTR) pBitmapInfo + (WORD) (pBitmapInfo->bmiHeader.biSize))

> See Also

> The bitmap-information header, defined as a BITMAPINFOHEADER structure,
> specifies the dimensions, compression type, and color format for the
bitmap.

> The color table, defined as an array of RGBQUAD structures, contains as
many
> elements as there are colors in the bitmap. The color table is not present
> for bitmaps with 24 color bits because each pixel is represented by 24-bit
> red-green-blue (RGB) values in the actual bitmap data area. The colors in
the
> table should appear in order of importance. This helps a display driver
> render a bitmap on a device that cannot display as many colors as there
are
> in the bitmap. If the DIB is in Windows version 3.0 or later format, the
> driver can use the biClrImportant member of the BITMAPINFOHEADER structure
to
> determine which colors are important.

> The BITMAPINFO structure can be used to represent a combined
> bitmap-information header and color table.  The bitmap bits, immediately
> following the color table, consist of an array of BYTE values representing
> consecutive rows, or "scan lines," of the bitmap. Each scan line consists
of
> consecutive bytes representing the pixels in the scan line, in
left-to-right
> order. The number of bytes representing a scan line depends on the color
> format and the width, in pixels, of the bitmap. If necessary, a scan line
> must be zero-padded to end on a 32-bit boundary. However, segment
boundaries
> can appear anywhere in the bitmap. The scan lines in the bitmap are stored
> from bottom up. This means that the first byte in the array represents the
> pixels in the lower-left corner of the bitmap and the last byte represents
> the pixels in the upper-right corner.

> The biBitCount member of the BITMAPINFOHEADER structure determines the
number
> of bits that define each pixel and the maximum number of colors in the
> bitmap. These members can have

...

read more »

Other Threads