2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
6 /**********************************************************************/
12 #include <exec/types.h>
13 #include <exec/memory.h>
14 #include <dos/dostags.h>
15 #include <graphics/gfxbase.h>
16 #include <graphics/rpattr.h>
17 #include <cybergraphx/cybergraphics.h>
18 #include <intuition/imageclass.h>
19 #include <intuition/icclass.h>
20 #include <intuition/gadgetclass.h>
21 #include <intuition/cghooks.h>
22 #include <datatypes/datatypesclass.h>
23 #include <datatypes/pictureclass.h>
25 #include <clib/alib_protos.h>
26 #include <proto/exec.h>
27 #include <proto/dos.h>
28 #include <proto/intuition.h>
29 #include <proto/graphics.h>
30 #include <proto/utility.h>
31 #include <proto/iffparse.h>
32 #include <proto/datatypes.h>
34 #include <aros/symbolsets.h>
41 ADD2LIBS("datatypes/picture.datatype", 0, struct Library
*, PictureBase
);
43 /**************************************************************************************************/
45 #define FILEBUFSIZE 65536
49 struct IFFHandle
*filehandle
;
66 WORD bfType
; // 0 ASCII "BM"
67 ULONG bfSize
; // 2 Size in bytes of the file
68 WORD bfReserved1
; // 6 Zero
69 WORD bfReserved2
; // 8 Zero
70 ULONG bfOffBits
; // 10 Byte offset in files where image begins
71 } FileBitMapHeader
__attribute__((packed
)); // 14
75 ULONG biSize
; // 0 Size of this header, 40 bytes
76 LONG biWidth
; // 4 Image width in pixels
77 LONG biHeight
; // 8 Image height in pixels
78 WORD biPlanes
; // 12 Number of image planes, must be 1
79 WORD biBitCount
; // 14 Bits per pixel, 1, 4, 8, 24, or 32
80 ULONG biCompression
; // 16 Compression type, below
81 ULONG biSizeImage
; // 20 Size in bytes of compressed image, or zero
82 LONG biXPelsPerMeter
; // 24 Horizontal resolution, in pixels/meter
83 LONG biYPelsPerMeter
; // 28 Vertical resolution, in pixels/meter
84 ULONG biClrUsed
; // 32 Number of colors used, below
85 ULONG biClrImportant
; // 36 Number of "important" colors
86 } BitmapInfoHeader
__attribute__((packed
)); // 40
88 /* "BM" backwards, due to LE byte order */
89 #define BITMAP_ID "MB"
91 /**************************************************************************************************/
93 static void BMP_Exit(BmpHandleType
*bmphandle
, LONG errorcode
)
95 D(if (errorcode
) bug("bmp.datatype/BMP_Exit() --- IoErr %ld\n", errorcode
));
96 if (bmphandle
->filebuf
)
98 FreeMem(bmphandle
->filebuf
, bmphandle
->filebufsize
);
100 if (bmphandle
->linebuf
)
102 FreeMem(bmphandle
->linebuf
, bmphandle
->linebufsize
);
104 if (bmphandle
->codecvars
)
106 FreeVec(bmphandle
->codecvars
);
111 /**************************************************************************************************/
113 /* buffered file access, useful for RLE */
114 BOOL
SaveBMP_EmptyBuf(BmpHandleType
*bmphandle
, long minbytes
)
116 long bytes
, bytestowrite
;
118 bytestowrite
= bmphandle
->filebufsize
- (bmphandle
->filebufbytes
+ minbytes
);
119 D(bug("bmp.datatype/SaveBMP_EmptyBuf() --- minimum %ld bytes, %ld bytes to write\n", (long)minbytes
, (long)bytestowrite
));
120 bytes
= Write(bmphandle
->filehandle
, bmphandle
->filebuf
, bytestowrite
);
121 if ( bytes
< bytestowrite
)
123 D(bug("bmp.datatype/SaveBMP_EmptyBuf() --- writing failed, wrote %ld bytes\n", (long)bytes
));
126 bmphandle
->filebufpos
= bmphandle
->filebuf
;
127 bmphandle
->filebufbytes
= bmphandle
->filebufsize
- minbytes
;
128 D(bug("bmp.datatype/SaveBMP_EmptyBuf() --- wrote %ld bytes\n", (long)bytes
));
132 /* buffered file access, useful for RLE */
133 BOOL
LoadBMP_FillBuf(BmpHandleType
*bmphandle
, long minbytes
)
137 //D(bug("bmp.datatype/LoadBMP_FillBuf() --- minimum %ld bytes of %ld (%ld) bytes\n", (long)minbytes, (long)bmphandle->filebufbytes, (long)(bmphandle->filebufsize-(bmphandle->filebufpos-bmphandle->filebuf)) ));
138 if ( bmphandle
->filebufbytes
>= 0 )
140 bytes
= bmphandle
->filebufbytes
+ minbytes
;
141 //D(bug("bmp.datatype/LoadBMP_FillBuf() --- %ld bytes requested, %ld bytes left\n", (long)minbytes, (long)bytes));
144 //D(bug("bmp.datatype/LoadBMP_FillBuf() --- existing %ld old bytes\n", (long)bytes));
145 for (i
=0; i
<bytes
; i
++) /* copy existing bytes to start of buffer */
146 bmphandle
->filebuf
[i
] = bmphandle
->filebufpos
[i
];
148 bmphandle
->filebufpos
= bmphandle
->filebuf
;
149 bytes
= Read(bmphandle
->filehandle
, bmphandle
->filebuf
+ bytes
, bmphandle
->filebufsize
- bytes
);
150 if (bytes
< 0 ) bytes
= 0;
151 bmphandle
->filebufbytes
+= bytes
;
152 //D(bug("bmp.datatype/LoadBMP_FillBuf() --- read %ld bytes, remaining new %ld bytes\n", (long)bytes, (long)bmphandle->filebufbytes));
153 //D(bug("bmp.datatype/LoadBMP_FillBuf() --- >minimum %ld bytes of %ld (%ld) bytes\n", (long)minbytes, (long)bmphandle->filebufbytes, (long)(bmphandle->filebufsize-(bmphandle->filebufpos-bmphandle->filebuf)) ));
154 if (bmphandle
->filebufbytes
>= 0)
159 static BOOL
LoadBMP_Colormap(BmpHandleType
*bmphandle
, int numcolors
,
160 struct ColorRegister
*colormap
, ULONG
*colregs
)
164 if (numcolors
&& numcolors
<= MAXCOLORS
)
167 for (i
= 0; i
< numcolors
; i
++)
169 if ( (bmphandle
->filebufbytes
-= 4) < 0 && !LoadBMP_FillBuf(bmphandle
, 4) )
171 D(bug("bmp.datatype/LoadBMP_Colormap() --- colormap loading failed\n"));
174 /* BGR0 format for MS Win files, BGR format for OS/2 files */
175 colormap
[i
].blue
= *(bmphandle
->filebufpos
)++;
176 colormap
[i
].green
= *(bmphandle
->filebufpos
)++;
177 colormap
[i
].red
= *(bmphandle
->filebufpos
)++;
178 bmphandle
->filebufpos
++;
179 colregs
[j
++] = ((ULONG
)colormap
[i
].red
)<<24;
180 colregs
[j
++] = ((ULONG
)colormap
[i
].green
)<<24;
181 colregs
[j
++] = ((ULONG
)colormap
[i
].blue
)<<24;
182 // D(if (i<5) bug("gif r %02lx g %02lx b %02lx\n", colormap[i].red, colormap[i].green, colormap[i].blue));
184 D(bug("bmp.datatype/LoadBMP_Colormap() --- %d colors loaded\n", numcolors
));
189 /**************************************************************************************************/
190 static BOOL
LoadBMP(struct IClass
*cl
, Object
*o
)
192 BmpHandleType
*bmphandle
;
195 ULONG bfSize
, bfOffBits
;
196 ULONG biSize
, biWidth
, biHeight
, biCompression
;
197 ULONG biClrUsed
, biClrImportant
;
198 UWORD biPlanes
, biBitCount
;
199 ULONG alignwidth
, alignbytes
, pixelfmt
;
202 struct BitMapHeader
*bmhd
;
203 struct ColorRegister
*colormap
;
207 D(bug("bmp.datatype/LoadBMP()\n"));
209 if( !(bmphandle
= AllocMem(sizeof(BmpHandleType
), MEMF_ANY
)) )
211 SetIoErr(ERROR_NO_FREE_STORE
);
214 bmphandle
->filebuf
= NULL
;
215 bmphandle
->linebuf
= NULL
;
216 bmphandle
->codecvars
= NULL
;
219 if( GetDTAttrs(o
, DTA_SourceType
, (IPTR
)&sourcetype
,
220 DTA_Handle
, (IPTR
)&(bmphandle
->filehandle
),
221 PDTA_BitMapHeader
, (IPTR
)&bmhd
,
224 BMP_Exit(bmphandle
, ERROR_OBJECT_NOT_FOUND
);
228 if ( sourcetype
== DTST_RAM
&& bmphandle
->filehandle
== NULL
&& bmhd
)
230 D(bug("bmp.datatype/LoadBMP() --- Creating an empty object\n"));
231 BMP_Exit(bmphandle
, 0);
234 if ( sourcetype
!= DTST_FILE
|| !bmphandle
->filehandle
|| !bmhd
)
236 D(bug("bmp.datatype/LoadBMP() --- unsupported mode\n"));
237 BMP_Exit(bmphandle
, ERROR_NOT_IMPLEMENTED
);
241 /* initialize buffered file reads */
242 bmphandle
->filebufbytes
= 0;
243 bmphandle
->filebufsize
= FILEBUFSIZE
;
244 if( !(bmphandle
->filebuf
= bmphandle
->filebufpos
= AllocMem(bmphandle
->filebufsize
, MEMF_ANY
)) )
246 BMP_Exit(bmphandle
, ERROR_NO_FREE_STORE
);
250 /* load FileBitmapHeader from file, make sure, there are at least 14 bytes in buffer */
251 if ( (bmphandle
->filebufbytes
-= 14) < 0 && !LoadBMP_FillBuf(bmphandle
, 14) )
253 D(bug("bmp.datatype/LoadBMP() --- filling buffer with header failed\n"));
254 BMP_Exit(bmphandle
, ERROR_OBJECT_WRONG_TYPE
);
257 filebuf
= bmphandle
->filebufpos
; /* this makes things easier */
258 bmphandle
->filebufpos
+= 14;
259 if( filebuf
[0] != 'B' && filebuf
[1] != 'M' )
261 D(bug("bmp.datatype/LoadBMP() --- header type mismatch\n"));
262 BMP_Exit(bmphandle
, ERROR_OBJECT_WRONG_TYPE
);
265 /* byte-wise access isn't elegant, but it is endianess-safe */
266 bfSize
= (filebuf
[5]<<24) | (filebuf
[4]<<16) | (filebuf
[3]<<8) | filebuf
[2];
267 bfOffBits
= (filebuf
[13]<<24) | (filebuf
[12]<<16) | (filebuf
[11]<<8) | filebuf
[10];
268 D(bug("bmp.datatype/LoadBMP() --- bfSize %ld bfOffBits %ld\n", bfSize
, bfOffBits
));
270 /* load BitmapInfoHeader from file, make sure, there are at least 40 bytes in buffer */
271 if ( (bmphandle
->filebufbytes
-= 40) < 0 && !LoadBMP_FillBuf(bmphandle
, 40) )
273 D(bug("bmp.datatype/LoadBMP() --- filling buffer with header 2 failed\n"));
274 BMP_Exit(bmphandle
, ERROR_OBJECT_WRONG_TYPE
);
277 filebuf
= bmphandle
->filebufpos
; /* this makes things easier */
278 bmphandle
->filebufpos
+= 40;
280 /* get image size attributes */
281 biSize
= (filebuf
[3]<<24) | (filebuf
[2]<<16) | (filebuf
[1]<<8) | filebuf
[0];
282 biWidth
= (filebuf
[7]<<24) | (filebuf
[6]<<16) | (filebuf
[5]<<8) | filebuf
[4];
283 biHeight
= (filebuf
[11]<<24) | (filebuf
[10]<<16) | (filebuf
[9]<<8) | filebuf
[8];
284 biPlanes
= (filebuf
[13]<<8) | filebuf
[12];
285 biBitCount
= (filebuf
[15]<<8) | filebuf
[14];
286 biCompression
= (filebuf
[19]<<24) | (filebuf
[18]<<16) | (filebuf
[17]<<8) | filebuf
[16];
287 biClrUsed
= (filebuf
[35]<<24) | (filebuf
[34]<<16) | (filebuf
[33]<<8) | filebuf
[32];
288 biClrImportant
= (filebuf
[39]<<24) | (filebuf
[38]<<16) | (filebuf
[37]<<8) | filebuf
[36];
289 D(bug("bmp.datatype/LoadBMP() --- BMP-Screen %ld x %ld x %ld, %ld (%ld) colors, compression %ld, type %ld\n",
290 biWidth
, biHeight
, (long)biBitCount
, biClrUsed
, biClrImportant
, biCompression
, biSize
));
291 if (biSize
!= 40 || biPlanes
!= 1 || biCompression
!= 0)
293 D(bug("bmp.datatype/LoadBMP() --- Image format not supported\n"));
294 BMP_Exit(bmphandle
, ERROR_NOT_IMPLEMENTED
);
298 /* check color mode */
299 pixelfmt
= PBPAFMT_LUT8
;
303 alignwidth
= (biWidth
+ 31) & ~31UL;
304 alignbytes
= alignwidth
/ 8;
307 alignwidth
= (biWidth
+ 7) & ~7UL;
308 alignbytes
= alignwidth
/ 2;
311 alignwidth
= (biWidth
+ 3) & ~3UL;
312 alignbytes
= alignwidth
;
315 alignbytes
= (biWidth
+ 3) & ~3UL;
316 alignwidth
= alignbytes
* 3;
317 pixelfmt
= PBPAFMT_RGB
;
320 D(bug("bmp.datatype/LoadBMP() --- unsupported color depth\n"));
321 BMP_Exit(bmphandle
, ERROR_NOT_IMPLEMENTED
);
324 D(bug("bmp.datatype/LoadBMP() --- align: pixels %ld bytes %ld\n", alignwidth
, alignbytes
));
326 /* set BitMapHeader with image size */
327 bmhd
->bmh_Width
= bmhd
->bmh_PageWidth
= biWidth
;
328 bmhd
->bmh_Height
= bmhd
->bmh_PageHeight
= biHeight
;
329 bmhd
->bmh_Depth
= biBitCount
;
331 /* get empty colormap, then fill in colormap to use*/
332 if (biBitCount
!= 24)
334 if( !(GetDTAttrs(o
, PDTA_ColorRegisters
, (IPTR
)&colormap
,
335 PDTA_CRegs
, (IPTR
)&colorregs
,
337 !(colormap
&& colorregs
) )
339 D(bug("bmp.datatype/LoadBMP() --- got no colormap\n"));
340 BMP_Exit(bmphandle
, ERROR_OBJECT_WRONG_TYPE
);
343 if( !LoadBMP_Colormap(bmphandle
, biClrUsed
, colormap
, colorregs
) )
345 BMP_Exit(bmphandle
, ERROR_OBJECT_WRONG_TYPE
);
350 bfOffBits
= bfOffBits
- 14 - 40 - biClrUsed
*4;
351 D(bug("bmp.datatype/LoadBMP() --- remaining offset %ld\n", bfOffBits
));
352 if ( bfOffBits
< 0 ||
353 ( (bmphandle
->filebufbytes
-= bfOffBits
) < 0 && !LoadBMP_FillBuf(bmphandle
, bfOffBits
) ) )
355 D(bug("bmp.datatype/LoadBMP() --- cannot skip offset\n"));
356 BMP_Exit(bmphandle
, ERROR_OBJECT_WRONG_TYPE
);
359 bmphandle
->filebufpos
+= bfOffBits
;
361 /* Pass attributes to picture.datatype */
362 GetDTAttrs( o
, DTA_Name
, (IPTR
)&name
, TAG_DONE
);
363 SetDTAttrs(o
, NULL
, NULL
, PDTA_NumColors
, biClrUsed
,
364 DTA_NominalHoriz
, biWidth
,
365 DTA_NominalVert
, biHeight
,
366 DTA_ObjName
, (IPTR
)name
,
369 /* Now decode the picture data into a chunky buffer; and pass it to Bitmap line-by-line */
370 bmphandle
->linebufsize
= bmphandle
->linebufbytes
= alignwidth
;
371 if (! (bmphandle
->linebuf
= bmphandle
->linebufpos
= AllocMem(bmphandle
->linebufsize
, MEMF_ANY
)) )
373 BMP_Exit(bmphandle
, ERROR_NO_FREE_STORE
);
377 //D(bug("bmp.datatype/LoadBMP() --- bytes of %ld (%ld) bytes\n", (long)bmphandle->filebufbytes, (long)(bmphandle->filebufsize-(bmphandle->filebufpos-bmphandle->filebuf)) ));
379 for (y
=biHeight
-1; y
>=0 && cont
; y
--)
383 bmphandle
->linebufpos
= bmphandle
->linebuf
;
384 if (biBitCount
== 24)
386 if ( (bmphandle
->filebufbytes
-= alignwidth
) < 0 && !LoadBMP_FillBuf(bmphandle
, alignwidth
) )
388 D(bug("bmp.datatype/LoadBMP() --- early end of bitmap data, x %ld y %ld\n", x
, y
));
389 //BMP_Exit(bmphandle, ERROR_OBJECT_WRONG_TYPE);
393 for (x
=0; x
<alignbytes
; x
++)
395 b
= *(bmphandle
->filebufpos
)++;
396 g
= *(bmphandle
->filebufpos
)++;
397 r
= *(bmphandle
->filebufpos
)++;
398 *(bmphandle
->linebufpos
)++ = r
;
399 *(bmphandle
->linebufpos
)++ = g
;
400 *(bmphandle
->linebufpos
)++ = b
;
405 for (x
=0; x
<alignbytes
; x
++)
407 if ( (bmphandle
->filebufbytes
-= 1) < 0 && !LoadBMP_FillBuf(bmphandle
, 1) )
409 D(bug("bmp.datatype/LoadBMP() --- early end of bitmap data, x %ld y %ld\n", x
, y
));
410 //BMP_Exit(bmphandle, ERROR_OBJECT_WRONG_TYPE);
415 byte
= *(bmphandle
->filebufpos
)++;
421 *(bmphandle
->linebufpos
)++ = (byte
& 0x80) ? 1 : 0;
426 *(bmphandle
->linebufpos
)++ = (byte
& 0xf0) >> 4;
427 *(bmphandle
->linebufpos
)++ = (byte
& 0x0f);
430 *(bmphandle
->linebufpos
)++ = byte
;
433 *(bmphandle
->linebufpos
)++ = byte
;
440 !DoSuperMethod(cl
, o
,
441 PDTM_WRITEPIXELARRAY
, /* Method_ID */
442 (IPTR
)bmphandle
->linebuf
, /* PixelData */
443 pixelfmt
, /* PixelFormat */
444 alignwidth
, /* PixelArrayMod (number of bytes per row) */
448 1 /* Height (here: one line) */
452 D(bug("bmp.datatype/LoadBMP() --- WRITEPIXELARRAY failed !\n"));
453 BMP_Exit(bmphandle
, ERROR_OBJECT_WRONG_TYPE
);
457 //D(bug("bmp.datatype/LoadBMP() --- bytes of %ld (%ld) bytes\n", (long)bmphandle->filebufbytes, (long)(bmphandle->filebufsize-(bmphandle->filebufpos-bmphandle->filebuf)) ));
459 D(bug("bmp.datatype/LoadBMP() --- Normal Exit\n"));
460 BMP_Exit(bmphandle
, 0);
464 /**************************************************************************************************/
466 static BOOL
SaveBMP(struct IClass
*cl
, Object
*o
, struct dtWrite
*dtw
)
468 BmpHandleType
*bmphandle
;
470 unsigned int width
, height
, widthxheight
, numplanes
, numcolors
;
471 struct BitMapHeader
*bmhd
;
477 D(bug("bmp.datatype/SaveBMP()\n"));
479 if( !(bmphandle
= AllocMem(sizeof(BmpHandleType
), MEMF_ANY
)) )
481 SetIoErr(ERROR_NO_FREE_STORE
);
484 bmphandle
->filebuf
= NULL
;
485 bmphandle
->linebuf
= NULL
;
486 bmphandle
->codecvars
= NULL
;
488 /* A NULL file handle is a NOP */
489 if( !dtw
->dtw_FileHandle
)
491 D(bug("bmp.datatype/SaveBMP() --- empty Filehandle - just testing\n"));
492 BMP_Exit(bmphandle
, 0);
495 bmphandle
->filehandle
= dtw
->dtw_FileHandle
;
497 /* Get BitMap and color palette */
498 if( GetDTAttrs( o
, PDTA_BitMapHeader
, (IPTR
)&bmhd
,
499 PDTA_BitMap
, (IPTR
)&bm
,
500 PDTA_CRegs
, (IPTR
)&colorregs
,
501 PDTA_NumColors
, (IPTR
)&numcolors
,
503 !bmhd
|| !bm
|| !colorregs
|| !numcolors
)
505 D(bug("bmp.datatype/SaveBMP() --- missing attributes\n"));
506 BMP_Exit(bmphandle
, ERROR_OBJECT_NOT_FOUND
);
510 /* Check if this is a standard BitMap */
511 if( !( GetBitMapAttr(bm
, BMA_FLAGS
) & BMF_STANDARD
) )
513 D(bug("bmp.datatype/SaveBMP() --- wrong BitMap type\n"));
514 BMP_Exit(bmphandle
, ERROR_OBJECT_WRONG_TYPE
);
518 /* initialize buffered file reads */
519 bmphandle
->filebufsize
= FILEBUFSIZE
;
520 bmphandle
->filebufbytes
= bmphandle
->filebufsize
;
521 if( !(bmphandle
->filebuf
= bmphandle
->filebufpos
= AllocMem(bmphandle
->filebufsize
, MEMF_ANY
)) )
523 BMP_Exit(bmphandle
, ERROR_NO_FREE_STORE
);
527 /* write BMP 87a header to file, make sure, there are at least 13 bytes in buffer */
528 if ( (bmphandle
->filebufbytes
-= 13) < 0 && !SaveBMP_EmptyBuf(bmphandle
, 13) )
530 D(bug("bmp.datatype/SaveBMP() --- filling buffer with header failed\n"));
531 BMP_Exit(bmphandle
, ERROR_NO_FREE_STORE
);
534 filebuf
= bmphandle
->filebufpos
; /* this makes things easier */
535 bmphandle
->filebufpos
+= 13;
537 /* set screen descriptor attributes (from BitMapHeader) */
538 width
= bmhd
->bmh_PageWidth
;
539 height
= bmhd
->bmh_PageHeight
;
540 numplanes
= bmhd
->bmh_Depth
- 1;
541 numcolors
= 1 << (numplanes
+ 1);
542 D(bug("bmp.datatype/SaveBMP() --- BMP-Image %d x %d x %d, cols %d\n", width
, height
, numplanes
+1, numcolors
));
543 filebuf
[6] = width
& 0xff;
544 filebuf
[7] = width
>> 8;
545 filebuf
[8] = height
& 0xff;
546 filebuf
[9] = height
>> 8;
547 filebuf
[10] = 0x80 | ((numplanes
& 0x07) << 4) | (numplanes
& 0x07) ; /* set numplanes, havecolmap=1 */
548 filebuf
[11] = 0; /* this is fillcolor */
549 filebuf
[12] = 0; /* this is pixel aspect ratio, 0 means unused */
551 /* write screen colormap, we don't use an image colormap */
552 for (i
= 0; i
< numcolors
*3; i
+= 3)
554 if ( (bmphandle
->filebufbytes
-= 3) < 0 && !SaveBMP_EmptyBuf(bmphandle
, 3) )
556 BMP_Exit(bmphandle
, ERROR_NO_FREE_STORE
);
559 *(bmphandle
->filebufpos
)++ = colorregs
[i
] >> 24;
560 *(bmphandle
->filebufpos
)++ = colorregs
[i
+1] >> 24;
561 *(bmphandle
->filebufpos
)++ = colorregs
[i
+2] >> 24;
564 /* write image header, image has same size as screen */
565 if ( (bmphandle
->filebufbytes
-= 10) < 0 && !SaveBMP_EmptyBuf(bmphandle
, 10) )
567 BMP_Exit(bmphandle
, ERROR_NO_FREE_STORE
);
570 filebuf
= bmphandle
->filebufpos
; /* this makes things easier */
571 bmphandle
->filebufpos
+= 10;
572 filebuf
[0] = ','; /* header ID */
573 filebuf
[1] = filebuf
[2] = 0; /* no left edge */
574 filebuf
[3] = filebuf
[4] = 0; /* no top edge */
575 filebuf
[5] = width
& 0xff;
576 filebuf
[6] = width
>> 8;
577 filebuf
[7] = height
& 0xff;
578 filebuf
[8] = height
>> 8;
579 filebuf
[9] = numplanes
& 0x07; /* set numplanes, havecolmap=0, interlaced=0 */
581 /* Now read the picture data from the bitplanes and write it to a chunky buffer */
582 /* For now, we use a full picture pixel buffer, not a single line */
583 widthxheight
= width
*height
;
584 bmphandle
->linebufsize
= bmphandle
->linebufbytes
= widthxheight
;
585 if (! (bmphandle
->linebuf
= bmphandle
->linebufpos
= AllocMem(bmphandle
->linebufsize
, MEMF_ANY
)) )
587 BMP_Exit(bmphandle
, ERROR_NO_FREE_STORE
);
592 for (j
=0; j
<height
; j
++)
594 for (i
=0; i
<width
; i
++)
596 ret
= (UBYTE
)ReadPixel(&rp
, i
, j
); /* very slow, to be changed */
597 *(bmphandle
->linebufpos
)++ = ret
;
600 bmphandle
->linebufpos
= bmphandle
->linebuf
;
602 /* write the chunky buffer to file, after encoding */
604 /* write end-of-BMP marker */
605 if ( !bmphandle
->filebufbytes
-- && !SaveBMP_EmptyBuf(bmphandle
, 1) )
607 BMP_Exit(bmphandle
, ERROR_NO_FREE_STORE
);
610 *(bmphandle
->filebufpos
)++ = ';';
612 /* flush write buffer to file and exit */
613 SaveBMP_EmptyBuf(bmphandle
, 0);
614 D(bug("bmp.datatype/SaveBMP() --- Normal Exit\n"));
615 BMP_Exit(bmphandle
, 0);
621 /**************************************************************************************************/
623 IPTR
BMP__OM_NEW(Class
*cl
, Object
*o
, Msg msg
)
627 D(bug("bmp.datatype/DT_Dispatcher: Method OM_NEW\n"));
629 newobj
= (Object
*)DoSuperMethodA(cl
, o
, msg
);
632 if (!LoadBMP(cl
, newobj
))
634 CoerceMethod(cl
, newobj
, OM_DISPOSE
);
642 /**************************************************************************************************/
644 IPTR
BMP__DTM_WRITE(Class
*cl
, Object
*o
, struct dtWrite
*dtw
)
646 D(bug("bmp.datatype/DT_Dispatcher: Method DTM_WRITE\n"));
647 if( (dtw
-> dtw_Mode
) == DTWM_RAW
)
649 /* Local data format requested */
650 return SaveBMP(cl
, o
, dtw
);
654 /* Pass msg to superclass (which writes an IFF ILBM picture)... */
655 return DoSuperMethodA( cl
, o
, (Msg
)dtw
);