BitMapSaver's doc $VER: Bitmapsaver 1.3 (06/15/96) Author of documention and object file: Jörg van de Loo. Date: 06/19/93 (updated 06/15/1996) FORMAT: BITMAPSAVER {}TO{}[OPT CMAP|SPRITE|C|QUICK|RAW|PEN|RAWHDR|SEPRIT|RGB32] FROM/A,TO/K,OPT/K/M,CMAP/S,SPRITE/S,C/S,QUICK/S,RAW/S,PEN/S,RAWHDR/S,SEPRIT/S,RGB32/S Description: Within this little program it's possible to translate any IFF-ILBM file with less or equal 8 bitplanes to an assembler or C source which can be directly included. It's a quite old tool but one that can be used today from within a Shell- script. --------------------------------- C Make code for the C-language, default assembler. SPRITE Store datas in the format needed by a SPRITE-object, default BitMaps. PEN Store datas as 8-bit pen-array instead of BitPlanes or sprite-object. RAW Generate binary datas only. CMAP Store 4-bit RGB colourtable, default none. RGB32 Store colour-values as V39 and up RGB32 colour format when option CMAP was chosen, default 4-bit. SEPRIT Split RAW-file, when option CMAP was chosen, into image and cmap-file. RAWHDR Write binary raw-file header instead of none if option RAW was chosen. QUICK Do it faster. Example: 4> bitmapsaver "work:dtp/pictures/gsx-r 750.iff" RAM:bike.c opt c cmap Will generate a file which can be used for the C-language, the datas will be stored as bitplanes (each plane after another), the BitMap-structure is initialized but without pointed planes to it, the colourmap is stored, too. ---- Generated code... ---- C-language code ... #ifndef GRAPHICS_GFX_H #include "graphics/gfx.h" #endif #ifndef EXEC_TYPES_H #include "exec/types.h" #endif struct BitMap NewBitMap = { 76, /* Bytes per row */ 60, /* Height */ 0, /* Flags */ 4, /* Depth */ 0, /* Strictly for longword adjustment */ 0, /* Pointer to plane 1 */ 0, /* Pointer to plane 2 */ 0, /* Pointer to plane 3 */ 0, /* Pointer to plane 4 */ 0, /* Pointer to plane 5 */ 0, /* Pointer to plane 6 */ 0, /* Pointer to plane 7 */ 0 /* Pointer to plane 8 */ }; UWORD BitMap_Data[] = /* Important Note: You have to force the datas on your own to chip-memory! Also you have to set the address of each plane to the Bitmap structure! */ { /* Plane1 */ ...., /* Plane2 */ ...., /* Plane3 */ ...., /* Plane4 */ .... }; UWORD Colors[16] = { 0x0AAA,0x0000,0x0EEE,0x068B,0x0E44,0x05D5,0x004D,0x0E90,0x0F60,0x0555, 0x0FE0,0x0080,0x00D0,0x00CC,0x006F,0x000A }; Asm-language code ... _Bitmap dc.w 76 ; Bytes per row dc.w 60 ; Number of lines ds.b 1 ; Flags dc.b 4 ; Depth ds.w 1 ; Strictly for longword alignment dc.l _Plane1 ; Pointer to plane 1 dc.l _Plane2 ; Pointer to plane 2 dc.l _Plane3 ; Pointer to plane 3 dc.l _Plane4 ; Pointer to plane 4 dc.l 0 ; Pointer to plane 5 dc.l 0 ; Pointer to plane 6 dc.l 0 ; Pointer to plane 7 dc.l 0 ; Pointer to plane 8 SECTION "BITMAP",DATA_C ; Forced to chip memory _Plane1 dc.w .... _Plane2 dc.w .... _Plane3 dc.w .... _Plane4 dc.w .... SECTION "RGBColorTable",DATA _ColorTable dc.w $0AAA,$0000,$0EEE,$068B,$0E44,$05D5,$004D,$0E90,$0F60,$0555 dc.w $0FE0,$0080,$00D0,$00CC,$006F,$000A _CMAPNumEntries dc.w 16 ; Number of words The reason why the BitPlane-pointers aren't initialized for the C-language is because not all C-compilers/linkers support direct hunk-chip sections. Look into the file Box.c how to initialize them on your own. --------------------------------- Sprites: Until Kickstart 3.0 a sprite had a maximum of 16 pixel width, up from this Kickstart the maximum-width for a sprite has grown to 64 pixels. Because sprites have a maximum of 4 colours (depth=2 - without tricks!) BitMapSaver ever and only takes the first 2 bitplanes for the spriteimage, the other are ignored. --------------------------------- Images: Images have almost the same binary format like bitplanes, only that image-bitplane-datas are combined within one memory block, i.e. the normal and the select image can only lie after each other in memory: Image: 48 * 32 pixel, 3 bitplanes (8 colours) Thus the normal image is stored first into memory: 48 / 8 * 32 * 3 = 576 bytes and right after this the select image is stored: 48 / 8 * 32 * 3 = 576 bytes makes a total of 1152 for both images. If you use a brush with more than one image, you have to reorder the bitplane format to the image format on your own, perhaps a future version of BitMapSaver should do the work? Taken out of "intuition/intuition.h|i" STRUCT(URE) Image(,0) WORD ig_LeftEdge ; starting offset relative to rastport's X offset (normally zero) WORD ig_TopEdge ; starting offset relative to rastport's Y offset (normally zero) WORD ig_Width ; width in pixels (must! be word-aligned) WORD ig_Height ; number of lines (rows) WORD ig_Depth ; depth (number of planes) APTR ig_ImageData ; pointer to the actual image datas (Chip-RAM) BYTE ig_PlanePick ; bitmask for "plane(x) has to blit to display" BYTE ig_PlaneOnOff ; bitmask for plane datas all one (1) or all zero (0) APTR ig_NextImage ; pointer to the next image or nil (LABEL ig_SIZEOF) To make pixel-width word-aligned (boundray 16) : C: width = ((width + 7) & -8); ASM: move.w width,d0 addq.w #7,d0 andi.w #-8,d0 move.w d0,width PlanePick = 13 = % 00001101 - means: blit datas as plane 0, 2, 3 but not plane 1! PlaneOnOff = 0 = % 00000000 - means: clear all datas of plane 1 or PlaneOnOff = 2 = % 00000010 - means: set all datas of plane 1 to one In this example the image has only 3 bitplanes where the image structure says there are four. This means that the image itself ( ImageData ) has only 3 planes. So in our example plane 0, 2 and 3 will be blitted to the corresponding bitplanes of the RastPort. If PlaneOnOff is set to zero, the concerned RastPort area of bitplane 1 is cleared, or if PlaneOnOff is set to 2, this area datas will be set to one. For plain images use: PlanePick %00001111 = 15 PlaneOnOff %00000000 = 0 - means blit plane 0,1,2 and 3 - PlaneOnOff unused. Resume: Only where PlanePick's bitplanes are set to zero, PlaneOnOff is taken to check for set or unset bits. In our example this means in a 16 colour display all 4 bitplanes will be blitted to the display, if the display has less colours, only the affected bitplanes will be blitted. But, if the display has more colours (e.g. 256) the upper 4 bitplanes which are set to zero (%0000 0000 - PlaneOnOff) are cleared in the display. ¯¯¯¯ Example for a 16 colour image: PlanePick %00001111 = 15 OR PlaneOnOff %00000000 = 0 -- 15 - OK. PlanePick %00001111 = 15 OR PlaneOnOff %00001111 = 15 -- 15 - Also OK. PlanePick %00001111 = 15 OR PlaneOnOff %11111111 = 255 --- 255 - Wrong !!!! - means 256 colours. PlanePick %00001111 = 15 OR PlaneOnOff %00010000 = 16 -- 31 - Also wrong !!!! 32 colours. --------------------------------- QUICK: This option is only suitable when writing C- or assembler source codes. It will allocate a buffer (20 KB) where the datas are written to. When now this buffer is full, the contents of it are saved to disk. This gains a lot of time even if you are writing your datas to a fast medium (e.g. RAM DISK). --------------------------------- RAW: Sometimes it is not suitable to generate a source-code for images, e.g. when the images are so tall that MBs are needed to include them, e.g. a picture of 960*724 width and 8 planes will need 2,296,046 bytes of memory in ASCII form. Instead of it you may include directly the binary image datas - here 695,552 bytes. You have to force those converted datas on your own to Chip-memory (if required); also you have to create on your own a bitmap-structure (if needed) and compute each address for the bitplanes. --------------------------------- PEN: This option is available when generating source codes ( C or asm) and when writing raw-datas. Instead of the output-data format "Bitplanes" it will force the datas to an 8-bit pen array which can "blitted" to the display (virtual screen) via: OS 1.x and up SetAPen()/WritePixel() OS 2.x and up WritePixelArray8() WritePixelLine8() OS 3.1 and up WriteChunkyPixels() This option is indeed useful if you have installed a 3rd party graphic board or - if you are in a surround of OS 3 and you want to adjust the pens to those of that screen. Even when you write games it is easier to use this format instead of bitplanes to let the background shine through a specified colour. Altough I know how to decode bitplane colour index' to the true-colour format I don't know if I should implement it into BitMapSaver, i.e. I have a written a utility (labelled Viewer) that already de- and encodes picture of 24 bit depth (including HAM6 and HAM8 images) to the true-colour format (RGB). If you are interested in such a conversion tell me. --------------------------------- CMAP: Using this option enables the storing of the 4-bit colour values either in the ASCII- or binary file. --------------------------------- RGB32: If the option "CMAP" was not chosen, this statement (RGB32) has no effect. It does only work in conjunction with the option "CMAP". If both are set (CMAP and! RGB32) the colourtable is stored as 8-bit colour index which can be directly used by OS 3.x and up function LoadRGB32() or tag-item SA_Colors32. --------------------------------- SEPRIT: When you have chosen the options "RAW" and "CMAP" for one image, the colour- table for this file is stored right behind the image data area. When now this connected file is loded into Chip-memory, the RGB-colourtable lies in Chip-memory, too. To avoid this, you may split this file into two; one will contain the image datas, the other the colour-datas. The keyword to do this is "SEPRIT". A file with the suffix ".cmap" is saved in the same directory as the file containing the image datas, - when your image-file is named with a suffix, right in front of your suffix a second is stored, e.g. 4> bitmapsaver box.bsh to ram:Box.bin opt cmap raw seprit Result: RAM Disk:Box.bin RAM Disk:Box-cmap.bin or: 4> bitmapsaver box.bsh to ram:box opt cmap raw seprit Result: RAM Disk:box RAM Disk:box.cmap --------------------------------- RAWHDR: RAWHDR means RAW-HEADER and will allow you to save the important informations of the image along with the raw-file when option RAW was chosen. The basic structure (header) is 16 bytes in size: struct RAWHEADER STRUCTURE RAWHEADER,0 { ULONG ID; ULONG rwh_ID UWORD ImageWidth; UWORD rwh_ImageWidth UWORD ImageHeight; UWORD rwh_ImageHeight UBYTE Depth; UBYTE rwh_Depth UBYTE kludgefill_0; UBYTE rwh_kludgefill_0 UWORD Flags; UWORD rwh_Flags UWORD BMWidth; UWORD rwh_BMWidth UWORD Colors; UWORD rwh_Colors }; LABEL rwh_SIZEOF ID = BMAP for non-interleaved bitmap datas ID = PARY for pen array datas ImageWidth = real image's width, e.g. 17 (0x11) ImageHeight = number of rows, e.g. 15 (0xF) Depth = number of bitplanes, e.g. 3 (0x3) kludgefill_0 = (ever) zero Flags = bit 0 set when this raw-data file contains a colourmap at its end = bit 7 set when the colourmap is stored in the RGB32 format BMWidth = boundary 16 of ImageWidth, 0x11 to 0x20 Colors = Number of used colours In our example an image of 17 * 15 pixel and 3 bitplanes without a colormap would look like this: BMAP 0011 000F 03 00 0000 0020 0008 or PARY 0011 000F 03 00 0000 0020 0008 When saved along with a colourmap it could look like this: BMAP 0011 000F 03 00 0001 0020 0008 or PARY 0011 000F 03 00 0001 0020 0008 When the colourmap is in the RGB32 format it would like this: BMAP 0011 000F 03 00 0081 0020 0008 or PARY 0011 000F 03 00 0081 0020 0008 NOTE: The BMAP type is ever aligned to a boundary of 16: (0x11 + 15) & -16 = 0x20 In our example (0x20 / 8 * 3) * 0xF = 180 bytes of pure datas! [ 0x20 = aligned size of 0x11 = number of pixel in one row ] [ 8 = 1 byte of memory can hold 8 pixel ] [ 3 = three bitplanes ] [ 0xF = 15 rows ] The PARY type is not! aligned!!! 0x11 * 0xF = 255 bytes of pure datas! To make the confusion perfect: the colourmap can lie at an odd offset; in our example at offset (255 + 16 =) 271!!!! A good thing is to use DOS-function Read(): Read first 16 bytes of file! Check type: if BMAP compute length: BMWidth / 8 * Depth * ImageHeight Read the amount computed datas into data-buffer Check Flags for colourmap if 4-bit colourmap: Double Colors, since WORDs have been stored (Colors * 2) Read amount computed datas into colour-buffer if 8-bit colourmap compute: Colors * 3 * 4 + 8 (e.g.: 8 colours = 8 * 3 = 24 LONG WORDs 24 LONG WORDs * 4 = 96 bytes plus 8 bytes (2 LONG WORDs) makes a total of 104 bytes ) Read amount computed datas into colour-buffer if PARY compute length: ImageWidth * ImageHeight Read the amount computed datas into data-buffer Check Flags for colourmap if 4-bit colourmap: Double Colors, since WORDs have been stored (Colors * 2) Read amount computed datas into colour-buffer if 8-bit colourmap compute: Colors * 3 * 4 + 8 (e.g.: 8 colours = 8 * 3 = 24 LONG WORDs 24 LONG WORDs * 4 = 96 bytes plus 8 bytes (2 LONG WORDs) makes a total of 104 bytes ) Read amount computed datas into colour-buffer --------------------------------- By the way: BitMapSaver is a reentrant code, you may use command resident. Up from Workbench 2.1 or Kickstart 3.0 the dos-errors will appear in your native-language. Copyright: BitMapSaver's object file and the source-code are FreeWare. Although it's strictly forbidden to spread the source-code to other public-domain series as those created by Fred Fish. It's allowed to upload it to Aminet. It's not allowed to enclose the Amiga load-file called BitMapSaver to commercial programs without my written permission. Needless to say that I can't be held for any errors may happen using BitMapSaver. (C) 1993 - 1996 J.v.d.Loo (ONIX)