home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
011.lha
/
IFF
/
iffencode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-10
|
8KB
|
366 lines
/*
* IFFENCODE
*
* COMPILE W/ASTARTUP.OBJ and MY.LIB
*
* Grabs the highest screen and dumps it to a file in IFF.
*
* Screen-Finding routine taken from Carolyn's Printer Dump source.
*
*
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>
#include <graphics/gfx.h>
#include <graphics/view.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#define FLAG_NOCOMP 0x01
#define FLAG_NOLACE 0x02
#define FLAG_DEBUG 0x04
typedef struct IntuitionBase IBASE;
typedef struct GfxBase GFXBASE;
typedef struct Window WIN;
typedef struct Screen SCR;
typedef struct ViewPort VP;
typedef struct RastPort RP;
typedef struct ColorMap CM;
typedef struct BitMap BM;
IBASE *IntuitionBase;
GFXBASE *GfxBase;
main(ac, av)
char *av[];
{
char notdone = 1;
char buf[80];
char flags = 0;
int i;
VP *vp;
RP *rp;
CM *cm;
for (i = 1; i < ac; ++i) {
if (strcmp(av[i], "NOLACE") == 0)
flags |= FLAG_NOLACE;
else if (strcmp(av[i], "NOCOMP") == 0)
flags |= FLAG_NOCOMP;
else if (strcmp(av[i], "DEBUG") == 0)
flags |= FLAG_DEBUG;
else {
puts ("iffencode [NOLACE][NOCOMP]");
puts ("(c)1986 Matthew Dillon. Public Domain V1.00");
puts ("");
puts ("NOLACE -save only top half of screen if in interlace");
puts ("NOCOMP -do NOT use BYTERUN1 compression");
exit(1);
}
}
if ((IntuitionBase=(IBASE *)OpenLibrary("intuition.library",0)) == NULL)
cleanexit("Can't open Intuition.\n");
if ((GfxBase=(GFXBASE *)OpenLibrary("graphics.library",0)) == NULL)
cleanexit("Can't open Graphics.\nn");
do_imopts(&vp, &cm, &rp);
while(notdone) {
printf("\nSELECT: <W>rite, <N>ewImage, <Q>uit ?");
switch (getch()) {
case 'W':
printf ("\nWrite to file (leave blank to abort):");
gets(buf);
if (buf[0]) {
long fi = xopen(buf, "w", 8192);
if (fi) {
xasync(fi, 1);
do_write(flags, vp, cm, rp, fi);
xclose(fi);
if (checkbreak()) {
puts ("*BREAK*, file deleted");
resetbreak();
DeleteFile(buf);
}
puts ("done");
} else {
puts ("could not open file");
}
}
break;
case 'N':
do_imopts(&vp, &cm, &rp);
break;
case 'Q':
notdone = 0;
break;
}
}
cleanup();
}
do_imopts(r_vp, r_cm, r_rp)
VP **r_vp;
CM **r_cm;
RP **r_rp;
{
puts ("Move Screens so Screen to grab is highest.");
printf("press <RET> when ready: ");
getch();
getPointers(r_vp, r_cm, r_rp);
}
getPointers(r_vp, r_cm, r_rp)
VP **r_vp;
CM **r_cm;
RP **r_rp;
{
SCR *firstscreen, *nextscreen, *highscreen;
int topEdge;
Forbid();
firstscreen = IntuitionBase->FirstScreen;
topEdge = 9999;
nextscreen = highscreen = firstscreen;
while(nextscreen) {
if(nextscreen->TopEdge < topEdge) {
topEdge = nextscreen->TopEdge;
highscreen = nextscreen;
}
nextscreen = nextscreen->NextScreen;
}
Permit();
*r_vp = &(highscreen->ViewPort);
*r_cm = (*r_vp)->ColorMap;
*r_rp = &(highscreen->RastPort);
}
getch()
{
char scr[80];
if (gets(scr)) {
if (scr[0] >= 'a' && scr[0] <= 'z')
scr[0] = scr[0] - 'a' + 'A';
return ((int)scr[0]);
}
return(' ');
}
cleanexit(errMsg)
char *errMsg;
{
printf(errMsg);
cleanup();
exit(-1);
}
cleanup()
{
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (GfxBase) CloseLibrary(GfxBase);
}
/*
* Dump rastport in IFF.
*/
#include "iff.h"
do_write(flags, vp, cm, rp, fi)
VP *vp;
CM *cm;
RP *rp;
long fi;
{
BM *bm = rp->BitMap;
X_BMHD x_bmhd;
X_CMAP x_cmap[32];
X_CAMG x_camg;
int cme, i, j;
x_bmhd.w = bm->BytesPerRow << 3;
x_bmhd.h = bm->Rows;
x_bmhd.x = x_bmhd.y = 0;
x_bmhd.planes = bm->Depth;
x_bmhd.masking= MA_NONE;
x_bmhd.compression = (flags & FLAG_NOCOMP) ? CP_NONE : CP_BYTERUN1;
x_bmhd.transparent_color = 0;
x_bmhd.xaspect = 10;
x_bmhd.yaspect = 11;
x_bmhd.pagewidth = x_bmhd.w;
x_bmhd.pageheight= x_bmhd.h;
j = 1 << x_bmhd.planes;
if (j == 64)
j = 32;
if (j > 32) {
printf ("Illegal #colors/#planes: %ld/%ld\n", j, x_bmhd.planes);
return(0);
}
{
UWORD *w;
for (i = 0, w = (UWORD *)cm->ColorTable; i < j; ++i, ++w) {
x_cmap[i][0] = ((*w >> 8) & 0x0F) << 4;
x_cmap[i][1] = ((*w >> 4) & 0x0F) << 4;
x_cmap[i][2] = ((*w) & 0x0F) << 4;
}
cme = j;
}
x_camg.vpmodes = vp->Modes & (PFBA|DUALPF|HIRES|LACE|HAM);
if ((flags & FLAG_NOLACE) && (x_camg.vpmodes & LACE)) {
x_camg.vpmodes &= ~LACE;
x_bmhd.h >>= 1;
x_bmhd.pageheight = x_bmhd.h;
}
printf ("vpmode = (%ldx%ldx%ld) %8lx\n", x_bmhd.w, x_bmhd.h, x_bmhd.planes, x_camg.vpmodes);
iff_chunk(fi, IFF_FORM);
iff_type (fi, TYPE_ILBM);
iff_chunk(fi, ILBM_BMHD);
xwrite(fi, &x_bmhd, sizeof(x_bmhd));
iff_chunk(fi, 0);
iff_chunk(fi, ILBM_CMAP);
xwrite(fi, &x_cmap, sizeof(X_CMAP) * cme);
iff_chunk(fi, 0);
iff_chunk(fi, ILBM_CAMG);
xwrite(fi, &x_camg, sizeof(x_camg));
iff_chunk(fi, 0);
iff_chunk(fi, ILBM_BODY);
for (i = 0; i < x_bmhd.h; ++i) {
for (j = 0; j < x_bmhd.planes; ++j) {
dumprow(fi, bm->Planes[j]+(i*bm->BytesPerRow), bm->BytesPerRow, flags);
if (checkbreak())
goto outall;
}
}
outall:
iff_chunk(fi, 0);
iff_chunk(fi, 0);
}
dumprow(fi, ptr, bytes, flags)
UBYTE *ptr;
{
int i, j, k; /* base, literal end, replicate end */
UBYTE ch;
if (flags & FLAG_NOCOMP)
return(xwrite(fi, ptr, bytes));
if (flags & FLAG_DEBUG)
puts ("SCANLINE");
i = j = k = 0;
while (j < bytes) {
if (checkbreak())
return(0);
for (k = j; k < bytes && ptr[j] == ptr[k]; ++k);
if (k - j >= 3) {
while (j - i >= 128) {
ch = 127;
xwrite(fi, &ch, 1);
xwrite(fi, ptr + i, 128);
i += 128;
}
if (j - i > 0) {
ch = (j - i - 1);
xwrite(fi, &ch, 1);
xwrite(fi, ptr + i, j - i);
}
while (k - j >= 128) {
ch = -127;
xwrite(fi, &ch, 1);
xwrite(fi, ptr + j, 1);
j += 128;
}
if (k - j > 0) {
ch = -(k - j - 1);
xwrite(fi, &ch, 1);
xwrite(fi, ptr + j, 1);
}
i = j = k;
} else {
j = k;
}
}
/* NOTE: i=start */
while (bytes - i >= 128) {
ch = 127;
xwrite(fi, &ch, 1);
xwrite(fi, ptr + i, 128);
i += 128;
}
if (bytes - i > 0) {
ch = (j - i - 1);
xwrite(fi, &ch, 1);
xwrite(fi, ptr + i, bytes - i);
}
/*
if (xseek(fi, 0, 0) & 1) {
ch = 0x80;
xwrite(fi, &ch, 1);
}
*/
return (1);
}
iff_type(fi, type)
{
xwrite(fi, &type, 4);
}
iff_chunk(fi, type)
{
static long seeka[128];
static int idx;
long zero = 0;
long bytes;
long oldpos;
if (type) {
xwrite(fi, &type, 4);
xwrite(fi, &zero, 4);
seeka[idx++] = xseek(fi, 0, 0);
} else {
if (idx) {
--idx;
oldpos = xseek(fi, 0, 0);
bytes = oldpos - seeka[idx];
if (oldpos & 1) {
xwrite(fi, &zero, 1);
++oldpos;
}
xseek(fi, seeka[idx] - 4, -1);
xwrite(fi, &bytes, 4);
xseek(fi, oldpos, -1);
}
}
}