home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_progs
/
graphics
/
hampics.lzh
/
HAMPICS
/
SOURCE
/
LOADPIC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-16
|
7KB
|
326 lines
/*
* loadpic.c - ILBM loader which runs from the workbench
*
* Written by Jonathan Hue - if you decide to steal some of this
* code (yeah, like anyone would want to), give me credit.
*/
#include <exec/types.h>
#include <workbench/startup.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>
#include <graphics/view.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <libraries/dosextens.h>
#include <stdio.h>
#include "types.h"
#include "ilbm.h"
extern struct WBStartup *WBenchMsg;
void LoadPic(), ChkRead(), ErrExit(), cleanup(), ReadPic();
int WaitForMouseClick();
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
extern struct ColorMap *GetColorMap();
extern struct FileLock *Lock(), *CurrentDir();
extern struct Window *OpenWindow();
struct View v;
struct ViewPort vp;
struct ColorMap *cm;
struct BitMap b;
BitMapHeader bm;
short WinWidth, WinHeight; /* Trust me, you don't want to know what */
struct Preferences prefs; /* I want these for... */
main(argc, argv)
int argc;
char **argv;
{
struct WBArg *arg;
struct FileLock *lock, *olddir;
register int i;
if ((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0)) ==
NULL)
ErrExit("Couldn't open graphics library");
if ((IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 0)) == NULL)
ErrExit("Couldn't open graphics library");
WinWidth = GfxBase->NormalDisplayColumns;
WinHeight = GfxBase->NormalDisplayRows;
GetPrefs(&prefs, sizeof(prefs));
puts("Press Left Mouse Button to Exit");
fflush(stdout); /* stdout should be line buffered */
if (argc > 0)
{
while (--argc)
LoadPic(*++argv);
}
else
{
for (i = 1, arg = WBenchMsg->sm_ArgList; i < WBenchMsg->sm_NumArgs;
i++)
{
++arg;
if (arg->wa_Lock == NULL)
continue;
olddir = CurrentDir(arg->wa_Lock);
if ((lock = Lock(arg->wa_Name, SHARED_LOCK)) == NULL)
{
CurrentDir(olddir);
continue;
}
LoadPic(arg->wa_Name);
UnLock(lock);
CurrentDir(olddir);
}
}
cleanup();
}
void
LoadPic(PicName)
char *PicName;
{
register FILE *fp;
u_long form, ilbm, id, nbytes, ViewMode = 0;
register short i;
register u_short *ColorMapPtr, ColorValue;
short GotBody = 0, GotHdr = 0, plane;
struct View *oldview;
struct RasInfo ri;
if ((fp = fopen(PicName, "r")) == NULL)
{
fprintf(stderr, "Couldn't open %s\n", PicName);
return;
}
ChkRead(fp, &form, sizeof(form));
fseek(fp, 4L, 1);
ChkRead(fp, &ilbm, sizeof(ilbm));
if ((form != ID_FORM) || (ilbm != ID_ILBM))
ErrExit("Sorry, I can't read this file");
while (1)
{
ChkRead(fp, &id, sizeof(id));
ChkRead(fp, &nbytes, sizeof(nbytes));
switch(id)
{
case ID_BMHD:
GotHdr++;
if (nbytes != sizeof(bm))
ErrExit("Short header length");
ChkRead(fp, &bm, sizeof(bm));
break;
case ID_CMAP:
cm = GetColorMap(nbytes / 3);
ColorMapPtr = (u_short *) cm->ColorTable;
for (i = 0; i < nbytes / 3; i++)
{
ColorValue = (getc(fp) >> 4) << 8;
ColorValue |= (getc(fp) >> 4) << 4;
ColorValue |= (getc(fp) >> 4);
*ColorMapPtr++ = ColorValue;
}
if (nbytes & 1)
getc(fp);
break;
case ID_CAMG:
ChkRead(fp, &ViewMode, sizeof(ViewMode));
break;
case ID_BODY:
if (!GotHdr)
ErrExit("Found BODY before BMHD!!!");
GotBody = 1;
break;
case ID_GRAB:
case ID_DEST:
default:
fseek(fp, nbytes, 1);
break;
}
if (GotBody)
break;
}
oldview = GfxBase->ActiView;
InitView(&v);
InitVPort(&vp);
v.ViewPort = &vp;
InitBitMap(&b, bm.bm_numplanes, bm.bm_width, bm.bm_height);
ri.BitMap = &b;
ri.RxOffset = 0;
ri.RyOffset = 0;
vp.DWidth = bm.bm_width;
vp.DHeight = bm.bm_height;
vp.RasInfo = &ri;
vp.ColorMap = cm;
for (plane = 0; plane < bm.bm_numplanes; plane++)
if ((b.Planes[plane] = (PLANEPTR) AllocRaster(bm.bm_width,
bm.bm_height)) == NULL)
ErrExit("Couldn't allocate enough screen memory");
if (bm.bm_width > 384) /* should be set */
ViewMode |= HIRES;
if (bm.bm_height > 240)
ViewMode |= LACE;
if (ViewMode & LACE)
v.Modes |= LACE;
vp.Modes = ViewMode;
if (ViewMode & HIRES) /* center */
vp.DxOffset = (640 - bm.bm_width) / 2;
else
vp.DxOffset = (320 - bm.bm_width) / 2;
if (ViewMode & LACE)
vp.DyOffset = ((2 * WinHeight) - bm.bm_height) / 2;
else
vp.DyOffset = ((2 * WinHeight) - bm.bm_height) / 2;
MakeVPort(&v, &vp);
MrgCop(&v);
ReadPic(fp, &bm, &b);
LoadView(&v);
WaitForMouseClick();
LoadView(oldview);
for (i = 0; i < bm.bm_numplanes; i++)
{
FreeRaster(b.Planes[i], bm.bm_width, bm.bm_height);
b.Planes[i] = NULL;
}
FreeColorMap(cm);
cm = NULL;
FreeVPortCopLists(&vp);
FreeCprList(v.LOFCprList);
FreeCprList(v.SHFCprList);
}
void
ReadPic(fp, bmhdr, bm)
register FILE *fp;
register BitMapHeader *bmhdr;
register struct BitMap *bm;
{
register u_char Pixel, *PixelPtr;
register short plane, row, nbytes, count;
if (bmhdr->bm_compression == 1)
{
for (row = 0; row < bmhdr->bm_height; row++)
{
for (plane = 0; plane < bmhdr->bm_numplanes; plane++)
{
PixelPtr = bm->Planes[plane] + (row * bm->BytesPerRow);
nbytes = bm->BytesPerRow;
while (nbytes > 0)
{
count = (char) getc(fp); /* might be negative */
if (count >= 0) /* copy n+1 literal */
{
count++;
nbytes -= count;
while (count--)
*PixelPtr++ = getc(fp);
}
else if (count >= -127) /* repeat next -n+1 times */
{
count = 1 - count;
nbytes -= count;
Pixel = getc(fp);
while (count--)
*PixelPtr++ = Pixel;
}
}
}
}
}
else
{
for (row = 0; row < bmhdr->bm_height; row++)
for (plane = 0; plane < bmhdr->bm_numplanes; plane++)
ChkRead(fp, bm->Planes[plane] + (row * bm->BytesPerRow),
bm->BytesPerRow);
}
}
void
ChkRead(fp, buf, nbytes)
FILE *fp;
char *buf;
int nbytes;
{
if (fread(buf, nbytes, 1, fp) != 1)
ErrExit("Short read");
}
void
ErrExit(s)
char *s;
{
char b[10];
fprintf(stderr, "%s\nPress RETURN", s);
gets(b);
cleanup();
exit(10);
}
int
WaitForMouseClick()
{
static struct NewWindow CheeseWhiz = {
0, 0, /* position in upper left */
0, 0, /* don't init yet */
-1, -1, /* default pens */
MOUSEBUTTONS,
BORDERLESS | ACTIVATE,
NULL, NULL, NULL,
NULL, NULL,
0, 0, 0, 0,
WBENCHSCREEN
};
struct IntuiMessage *message;
struct Window *win;
CheeseWhiz.Width = WinWidth;
CheeseWhiz.Height = WinHeight;
if (prefs.LaceWB)
CheeseWhiz.Height += WinHeight;
if ((win = OpenWindow(&CheeseWhiz)) == NULL)
return(-1);
Wait(1 << win->UserPort->mp_SigBit);
message = (struct IntuiMessage *) GetMsg(win->UserPort);
ReplyMsg(message);
CloseWindow(win);
return(0);
}
void
cleanup()
{
register short i;
if (cm) /* forget about the other bits */
FreeColorMap(cm);
for (i = 0; i < bm.bm_numplanes; i++)
{
if (b.Planes[i])
FreeRaster(b.Planes[i], bm.bm_width, bm.bm_height);
}
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
fclose(stdin);
fclose(stdout);
fclose(stderr);
rbrk();
}