home *** CD-ROM | disk | FTP | other *** search
- /*
- dt2macpict
-
- Reads a picture (by the datatypes system) and
- writes a 256 colors picture in Macintosh Pict2 format.
-
- Made by Erik Engdahl 1998. The code is FREEWARE.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- v1.0 Initial version, 1998-02-28
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <dos/dos.h>
- #include <dos/rdargs.h>
- #include <graphics/gfx.h>
- #include <datatypes/datatypes.h>
- #include <datatypes/datatypesclass.h>
- #include <datatypes/pictureclass.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/graphics.h>
- #include <proto/datatypes.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- #define HEADER_SIZE 512
- #define PICT_clipRgn 0x01
- #define PICT_picVersion 0x11
- #define PICT_PackBitsRect 0x98
- #define PICT_EndOfPicture 0xFF
- #define PICT_headerOp 0x0C00
-
- int openLibs(void);
- void closeLibs(void);
-
- struct Library* DosBase = NULL;
- struct GfxBase *GfxBase = NULL;
- struct Library *DataTypesBase = NULL;
-
- static char *verstr="$VER: dt2macpict 1.0 by Erik Engdahl\0";
-
- struct {
- char *from;
- char *to;
- BOOL nopack;
- } args;
-
- #define NUM_OPTS 3
-
- #define TEMPLATE "INFILE/A,OUTFILE/A,NOPACK/S"
-
- UWORD headdata[26] = {
- 0, 0, 0, 2, 16, PICT_picVersion, 0x02ff, PICT_headerOp,
- 0xffff, 0xffff, 0, 0, 0, 0, 16, 0,
- 2, 0, 0, 0, PICT_clipRgn, 10, 0, 0,
- 16, 2
- };
-
- UWORD pbdata[27] = {
- PICT_PackBitsRect, 0x8016, 0, 0, 2, 16, 0, 0,
- 0, 0, 72, 0, 72, 0, 0, 8,
- 1, 8, 0, 0, 0, 0, 0, 0,
- 0, 0, 0
- };
-
-
- void putWord(BPTR fh, UWORD data, UWORD num)
- {
- UWORD i;
-
- for(i = 0; i < num; i++)
- {
- FWrite(fh, &data, sizeof(UWORD), 1);
- }
- } /* putWord */
-
- UWORD packrow(UBYTE *inbuf, ULONG width, UBYTE *outbuf, BOOL nopack)
- {
- UWORD outlen, inpos;
- UWORD i, imax;
- UBYTE n, len;
-
- outlen = 0;
- inpos = 0;
-
- /* Should we pack the row? */
- if(!nopack)
- {
- while(inpos < width)
- {
- if((imax = width - inpos)> 0x7f)
- {
- imax = 0x7f;
- }
-
- /* Possible to pack? */
- len = 0;
- for(i = 1; (i < imax); i++)
- {
- if(inbuf[inpos] == inbuf[inpos + i])
- {
- len = i;
- }
- else break;
- }
-
- /* OK pack */
- if(len > 0x2)
- {
- len++;
- n = (len^255) + 2;
- outbuf[outlen++] = n;
- outbuf[outlen++] = inbuf[inpos];
- inpos += len;
- }
- /* NO packing */
- else
- {
- len = 0;
- for(i = 1; (i < imax); i++)
- {
- if(inbuf[inpos + i] != inbuf[inpos + i + 1])
- {
- len = i;
- }
- else
- {
- /* if there are just 2 identical bytes breaking
- a series of different bytes then ignore it
- ex "a b c c d a c b"
- */
- if(inbuf[inpos + i] == inbuf[inpos + i + 2])
- {
- break;
- }
- }
- }
- outbuf[outlen++] = len;
- imax = (UWORD) (len + 1);
- for(i = 0; i < imax; i++)
- {
- outbuf[outlen++] = inbuf[inpos++];
- }
- }
- }
- }
- /* No packing requested, simple */
- else
- {
- while(inpos < width)
- {
- n = width - inpos;
- if(n >= 0x80)
- {
- n = 0x7f;
- }
- outbuf[outlen++] = n;
-
- for(i = 0; i <= n; i++)
- {
- outbuf[outlen++] = inbuf[inpos++];
- }
- }
- }
- return outlen;
- } /* packrow */
-
- int savebody(BPTR fh, struct BitMap *bm,
- ULONG width, ULONG height, ULONG depth)
- {
- struct BitMap *tbm;
- struct RastPort __aligned trp;
- struct RastPort __aligned rp;
- UBYTE *buf, *outbuf;
- LONG count;
- ULONG row;
- UWORD rowlen;
- UBYTE shortrow;
- int res;
-
-
- buf = (UBYTE *) AllocVec(width + 0x80UL, (MEMF_CHIP | MEMF_CLEAR));
- outbuf = (UBYTE *) AllocVec(width + 0x200UL, MEMF_CLEAR);
-
- tbm = AllocBitMap( width + 16UL, 1UL, depth, BMF_CLEAR, NULL);
-
- if(tbm && buf && outbuf)
- {
- InitRastPort (&trp);
- trp.BitMap = tbm;
- InitRastPort (&rp);
- rp.BitMap = bm;
-
- /* Source and Destination Rectangle + Mode */
- putWord(fh, 0, 2);
- putWord(fh, (UWORD)height, 1);
- putWord(fh, (UWORD)width, 1);
- putWord(fh, 0, 2);
- putWord(fh, (UWORD)height, 1);
- putWord(fh, (UWORD)width, 1);
- putWord(fh, 0, 1);
-
- for(row = 0; row < height; row++)
- {
- count = ReadPixelLine8(&rp, 0, row, width, buf, &trp);
- rowlen = packrow(buf, count, outbuf, args.nopack);
-
- /* Write number of (packed) bytes in this row */
- if(width > 250)
- {
- putWord(fh, rowlen, 1);
- }
- else
- {
- shortrow = (UBYTE) rowlen;
- FWrite(fh, &shortrow, sizeof(UBYTE), 1);
- }
-
- /* Write the bytes */
- FWrite(fh, outbuf, sizeof(UBYTE), (ULONG)(rowlen));
-
- }
-
- /* Word align */
- count = Seek(fh, 0, OFFSET_CURRENT);
- if(count & 1)
- {
- FWrite(fh, buf, sizeof(UBYTE), 1);
- }
-
- res = (int) row;
- }
- else
- {
- printf("Couldn't allocate memory and/or bitmap\n");
- res = -1;
- }
-
- /* Free the memory */
- if(tbm) FreeBitMap(tbm);
- if(buf) FreeVec(buf);
- if(outbuf) FreeVec(outbuf);
-
- return res;
- } /* savebody */
-
- /* Open the libraries and return TRUE if ok */
- int openLibs(void)
- {
- if((DosBase = OpenLibrary("dos.library", 39)) == NULL)
- {
- fprintf(stderr, "Sorry, couldn't open dos.library\n");
- return FALSE;
- }
- if((GfxBase = (struct GfxBase *)
- OpenLibrary("graphics.library", 39)) == NULL)
- {
- fprintf(stderr, "Sorry, couldn't open graphics.library\n");
- return FALSE;
- }
- if((DataTypesBase = OpenLibrary("datatypes.library", 39)) == NULL)
- {
- fprintf(stderr, "Sorry, couldn't open datatypes.library\n");
- return FALSE;
- }
- return TRUE;
- } /* openLibs */
-
- /* Close libraries */
- void closeLibs(void)
- {
- CloseLibrary(DosBase);
- CloseLibrary((struct Library *)GfxBase);
- CloseLibrary(DataTypesBase);
- } /* closeLibs */
-
-
- int main(int argc, char *argv[])
- {
- Object *pic;
- struct BitMapHeader *bmhd;
- struct BitMap *bm;
- struct gpLayout dtlayout;
- ULONG *cregs, tlong;
- UWORD i, numcolors;
- BPTR fh;
- int exitstatus = EXIT_SUCCESS;
- struct RDArgs *rdargs = NULL;
- LONG options[NUM_OPTS];
-
- if(argc == 0)
- {
- fprintf(stderr, "Must be started from Shell\n");
- return EXIT_FAILURE;
- }
-
- if(!openLibs())
- {
- closeLibs();
- return EXIT_FAILURE;
- }
-
- memset(options, 0, sizeof(options));
-
- if(rdargs = ReadArgs(TEMPLATE, options, NULL))
- {
- if(options[0]) args.from = (char *)options[0];
- if(options[1]) args.to = (char *)options[1];
- if(options[2]) args.nopack = TRUE;
-
- if(pic = NewDTObject( args.from,
- DTA_SourceType, DTST_FILE,
- DTA_GroupID, GID_PICTURE,
- PDTA_Remap, FALSE,
- TAG_END))
- {
- /* Make sure the object is rendered */
- dtlayout.MethodID = DTM_PROCLAYOUT;
- dtlayout.gpl_GInfo = NULL;
- dtlayout.gpl_Initial = TRUE;
-
- if (DoDTMethodA(pic, NULL, NULL, (Msg)&dtlayout))
- {
- /* Get bitmap and colors */
- if (GetDTAttrs( pic,
- PDTA_BitMapHeader, &bmhd,
- PDTA_BitMap, &bm,
- PDTA_CRegs, &cregs,
- PDTA_NumColors, &tlong,
- TAG_DONE) == 4)
- {
- numcolors = (UWORD) tlong;
-
- printf("Colors: %d\n",numcolors);
- printf("Size: %d x %d\n", bmhd->bmh_Width, bmhd->bmh_Height);
- printf("Wait a while, this can take some time...\n");
-
- fh = Open(args.to, MODE_NEWFILE);
- if(fh)
- {
- /* Save file header */
- putWord(fh, 0, (HEADER_SIZE/2));
-
- /* Fill in dimensions and write picture header */
- headdata[4] = headdata[14] = headdata[24] =
- bmhd->bmh_Width;
- headdata[3] = headdata[16] = headdata[25] =
- bmhd->bmh_Height;
-
- FWrite(fh, headdata, sizeof(UWORD), 26);
-
- /* Save bitmap packbits header */
- pbdata[1] = bmhd->bmh_Width | 0x8000;
- pbdata[4] = bmhd->bmh_Height;
- pbdata[5] = bmhd->bmh_Width;
- FWrite(fh, pbdata, sizeof(UWORD), 27);
-
- /* Save colormap */
- putWord(fh, (numcolors - 1), 1);
- for(i = 0; i < numcolors; i++)
- {
- putWord(fh, i, 1);
- tlong = cregs[3 * i ] >> 16;
- putWord(fh, (UWORD)(tlong), 1);
- tlong = cregs[3 * i + 1] >> 16;
- putWord(fh, (UWORD)(tlong), 1);
- tlong = cregs[3 * i + 2] >> 16;
- putWord(fh, (UWORD)(tlong), 1);
- }
-
- /* Save the bitmap */
- savebody(fh, bm, (ULONG) bmhd->bmh_Width,
- (ULONG) bmhd->bmh_Height,
- (ULONG) bmhd->bmh_Depth);
-
- /* Put end-mark in file */
- putWord(fh, PICT_EndOfPicture, 1);
-
- /* Write size (excluding empty header) */
- tlong = Seek(fh, 0, OFFSET_CURRENT);
- i = (UWORD)(tlong - HEADER_SIZE);
- Seek(fh, HEADER_SIZE, OFFSET_BEGINNING);
- putWord(fh, i, 1);
-
- /* Done! */
- Close(fh);
- }
- else
- {
- printf("Couldn't open file %s for writing\n",
- args.to);
- exitstatus = EXIT_FAILURE;
- }
- }
- else
- {
- printf("Couldn't get information about the picture\n");
- exitstatus = EXIT_FAILURE;
- }
- }
- DisposeDTObject(pic);
- }
- FreeArgs (rdargs);
- rdargs = NULL;
- }
- else {
- printf("%s\n", &verstr[6]);
- printf("Usage: %s " TEMPLATE "\n", argv[0]);
- }
-
- closeLibs();
- return exitstatus;
- }