home *** CD-ROM | disk | FTP | other *** search
- /*
- * MAGIC Image Tester - creates a small public MAGIC image with
- * a teeny tiny interface.
- *
- * Written by Thomas Krehbiel
- *
- * (This requires 2.0, BTW.)
- *
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <intuition/intuition.h>
- #include <libraries/gadtools.h>
- #include <clib/exec_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/gadtools_protos.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <stdio.h>
-
- #include <magic/magic.h>
- #include <magic/magic_protos.h>
- #include <magic/magic_pragmas.h>
-
- struct Library *IntuitionBase;
- struct Library *GfxBase;
- struct Library *GadToolsBase;
-
- struct MagicBase *MagicBase;
-
- UBYTE *planes[4] = { NULL, NULL, NULL, NULL };
- struct MagicImage *mi;
- struct MagicHandle *mh;
- struct MsgPort *hostport;
-
-
- void message (char *, ...);
-
-
- #define WIDTH 320
- #define HEIGHT 200
- #define DEPTH 3 /* color */
-
- short real_width, real_height;
-
- BOOL alloc_planes (UBYTE **planes, int depth)
- {
- int i;
-
- for (i = 0; i < depth; i++) planes[i] = NULL;
-
- for (i = 0; i < depth; i++) {
- if (!(planes[i] = AllocMem(WIDTH * HEIGHT, MEMF_CLEAR | MEMF_PUBLIC))) {
- return(FALSE);
- }
- }
-
- /* gradient from black to light violet */
- for (i = 0; i < HEIGHT; i++) {
- memset(planes[0] + (WIDTH * i), i * 255 / (HEIGHT-1), WIDTH);
- memset(planes[1] + (WIDTH * i), i * 127 / (HEIGHT-1), WIDTH);
- memset(planes[2] + (WIDTH * i), i * 255 / (HEIGHT-1), WIDTH);
- }
-
- real_width = WIDTH;
- real_height = HEIGHT;
-
- return(TRUE);
- }
-
- void free_planes (UBYTE **planes, int depth)
- {
- int i;
-
- for (i = 0; i < depth; i++) {
- if (planes[i]) {
- FreeMem(planes[i], real_width * real_height);
- planes[i] = NULL;
- }
- }
- }
-
-
- static
- BOOL __saveds PutData (struct MagicImage *pi, LONG offset, LONG rows, LONG *tags)
- {
- UBYTE *tagdata;
- LONG byte;
- UBYTE *ptr;
- int i;
-
- while (*tags != TAG_END) {
- tagdata = (UBYTE *)tags[1];
- switch (*tags) {
- case TAG_IGNORE :
- break;
- case GMI_Red :
- CopyMem(tagdata, planes[0] + (offset * WIDTH), WIDTH * rows);
- break;
- case GMI_Green :
- CopyMem(tagdata, planes[1] + (offset * WIDTH), WIDTH * rows);
- break;
- case GMI_Blue :
- CopyMem(tagdata, planes[2] + (offset * WIDTH), WIDTH * rows);
- break;
- case GMI_RGB :
- byte = offset * WIDTH;
- ptr = (UBYTE *)tagdata;
- for (i = 0; i < WIDTH; i++) {
- planes[0][byte] = *ptr++;
- planes[1][byte] = *ptr++;
- planes[2][byte++] = *ptr++;
- }
- break;
- case GMI_ARGB :
- byte = offset * WIDTH;
- ptr = (UBYTE *)tagdata;
- for (i = 0; i < WIDTH; i++) {
- ptr++; /* skip alpha */
- planes[0][byte] = *ptr++;
- planes[1][byte] = *ptr++;
- planes[2][byte++] = *ptr++;
- }
- break;
- default :
- break;
- }
- tags += 2;
- }
- return(TRUE);
- }
-
- static
- BOOL __saveds GetData (struct MagicImage *pi, LONG offset, LONG rows, LONG *tags)
- {
- UBYTE *tagdata;
- LONG byte;
- UBYTE *ptr;
- int i;
-
- while (*tags != TAG_END) {
- tagdata = (UBYTE *)tags[1];
- switch (*tags) {
- case TAG_IGNORE :
- break;
- case GMI_Red :
- CopyMem(planes[0] + (offset * WIDTH), tagdata, WIDTH * rows);
- break;
- case GMI_Green :
- CopyMem(planes[1] + (offset * WIDTH), tagdata, WIDTH * rows);
- break;
- case GMI_Blue :
- CopyMem(planes[2] + (offset * WIDTH), tagdata, WIDTH * rows);
- break;
- case GMI_RGB :
- byte = offset * WIDTH;
- ptr = (UBYTE *)tagdata;
- for (i = 0; i < WIDTH; i++) {
- *ptr++ = planes[0][byte];
- *ptr++ = planes[1][byte];
- *ptr++ = planes[2][byte++];
- }
- break;
- case GMI_ARGB :
- byte = offset * WIDTH;
- ptr = (UBYTE *)tagdata;
- for (i = 0; i < WIDTH; i++) {
- *ptr++ = 255;
- *ptr++ = planes[0][byte];
- *ptr++ = planes[1][byte];
- *ptr++ = planes[2][byte++];
- }
- break;
- default :
- break;
- }
- tags += 2;
- }
- return(TRUE);
- }
-
- BOOL init_magic (void)
- {
- if (!(MagicBase = (struct MagicBase *)OpenLibrary(MAGIC_NAME, 34)))
- return(FALSE);
-
- return(TRUE);
- }
-
- void close_magic (void)
- {
- if (mh) {
- CloseMagicImage(mh);
- mh = NULL;
- }
- if (mi) {
- while (!RemMagicImage(mi)) {
- message("Image in use!");
- Delay(50);
- }
- FreeMagicImage(mi);
- free_planes(planes, DEPTH);
- mi = NULL;
- }
- }
-
- void cleanup_magic (void)
- {
- close_magic();
- CloseLibrary((struct Library *)MagicBase);
- }
-
- void new_magic (void)
- {
- close_magic();
-
- if (alloc_planes(planes, DEPTH)) {
- if (mi = AllocMagicImage(AMI_Width, WIDTH,
- AMI_Height, HEIGHT,
- AMI_Depth, DEPTH,
- AMI_Red, planes[0],
- AMI_Green, planes[1],
- AMI_Blue, planes[2],
- AMI_GetDataCode, GetData,
- AMI_PutDataCode, PutData,
- AMI_OwnerName, "MagicDemo",
- TAG_END)) {
- if (AddMagicImage(mi)) {
- /*
- * Even the owner of an image must open it! Remember to use
- * OMI_OwnerPort instead of OMI_MsgPort.
- */
- if (mh = OpenMagicImage(mi, NULL, OMI_OwnerPort, hostport, TAG_END)) {
- message("Magic image created.");
- return;
- }
- RemMagicImage(mi);
- }
- FreeMagicImage(mi);
- }
- free_planes(planes, DEPTH);
- }
-
- mi = NULL;
- mh = NULL;
- }
-
- struct NewMenu newMenus[] = {
- { NM_TITLE, "Project", NULL, 0, 0, 0 },
- { NM_ITEM, "New", "N", 0, 0, 0 },
- { NM_ITEM, "Open...", "O", 0, 0, 0 },
- { NM_ITEM, NM_BARLABEL, NULL, 0, 0, 0 },
- { NM_ITEM, "Manipulate", "M", 0, 0, 0 },
- { NM_ITEM, NM_BARLABEL, NULL, 0, 0, 0 },
- { NM_ITEM, "Cycle", "C", 0, 0, 0 },
- { NM_ITEM, NM_BARLABEL, NULL, 0, 0, 0 },
- { NM_ITEM, "Quit", "Q", 0, 0, 0 },
- { NM_END }
- };
-
- struct Window *win;
- struct Menu *menus;
- APTR vi;
-
- BOOL init_gui (void)
- {
- struct Screen *scr;
-
- IntuitionBase = OpenLibrary("intuition.library", 37);
- GfxBase = OpenLibrary("graphics.library", 37);
- GadToolsBase = OpenLibrary("gadtools.library", 37);
- /* (yes, I know, but it's just a demo) */
-
- scr = LockPubScreen(NULL);
- if (scr == NULL) return(FALSE);
-
- if (!(win = OpenWindowTags(NULL,
- WA_Title, "MAGIC Testerosa",
- WA_InnerWidth, 200,
- WA_Height, 115 + scr->WBorTop + scr->Font->ta_YSize + 1 + scr->WBorBottom + scr->RastPort.TxHeight + 2,
- WA_Left, 20,
- WA_Top, 20,
- WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR |
- WFLG_DEPTHGADGET |
- WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH |
- WFLG_ACTIVATE,
- WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK,
- WA_NewLookMenus, TRUE,
- TAG_END))) goto err1;
-
- menus = CreateMenus(newMenus, TAG_END);
- if (menus == NULL) goto err2;
-
- vi = GetVisualInfo(scr, TAG_END);
- if (vi == NULL) goto err3;
-
- LayoutMenus(menus, vi, GTMN_NewLookMenus, TRUE, TAG_END);
-
- SetMenuStrip(win, menus);
-
- UnlockPubScreen(NULL, scr);
-
- return(TRUE);
-
- err3:
- FreeMenus(menus);
- err2:
- CloseWindow(win);
- err1:
- UnlockPubScreen(NULL, scr);
- return(FALSE);
- }
-
- void cleanup_gui (void)
- {
- ClearMenuStrip(win);
- FreeVisualInfo(vi);
- FreeMenus(menus);
- CloseWindow(win);
- CloseLibrary(GadToolsBase);
- CloseLibrary(GfxBase);
- CloseLibrary(IntuitionBase);
- }
-
- /* 4x4 dispersed dot ordered dither pattern. */
- static
- UBYTE dith[4][4] = {
- 1, 15, 2, 12,
- 9, 5, 10, 7,
- 3, 13, 0, 14,
- 11, 7, 8, 4
- };
-
- void redraw (void)
- {
- UBYTE *outpix;
- UBYTE *rgb;
- int w, h, le, te;
- struct MagicImage *mi;
- struct RastPort temprp;
- struct BitMap tempbm;
- int i, j, x, y;
- short v;
-
- w = win->Width - win->BorderLeft - win->BorderRight - 4;
- h = win->Height - win->BorderTop - win->BorderBottom - 2 - win->RPort->TxHeight - 2;
- le = win->BorderLeft + 2;
- te = win->BorderTop + win->RPort->TxHeight + 3;
-
- if (!mh) {
- SetAPen(win->RPort, 0);
- RectFill(win->RPort, le, te, le + w - 1, te + h - 1);
- return;
- }
-
- mi = mh->Object;
-
- outpix = AllocMem(((w+15)>>4)<<4, MEMF_CLEAR);
- if (outpix == NULL) return;
-
- rgb = AllocMem(mi->Width * 3, MEMF_CLEAR);
- if (rgb == NULL) return;
-
- InitRastPort(&temprp);
- InitBitMap(&tempbm, win->RPort->BitMap->Depth, w, 1);
- temprp.BitMap = &tempbm;
- for (i = 0; i < tempbm.Depth; i++) {
- tempbm.Planes[i] = AllocRaster(w, 1);
- /* ick */
- }
-
- for (j = 0; j < h; j++) {
-
- y = j * (mi->Height-1) / (h-1);
- GetMagicImageData(mh, y, 1, GMI_RGB, rgb, TAG_END);
-
- for (i = 0; i < w; i++) {
- x = (i * (mi->Width-1) / (w-1)) * 3;
- v = ((rgb[x] + rgb[x+1] + rgb[x+2]) / 3) >> 4;
- if (v > dith[j&3][i&3]) outpix[i] = 2;
- else outpix[i] = 1;
- }
-
- WritePixelLine8(win->RPort, le, te + j, w, outpix, &temprp);
-
- }
-
- for (i = 0; i < tempbm.Depth; i++) {
- FreeRaster(tempbm.Planes[i], w, 1);
- }
-
- FreeMem(rgb, mi->Width * 3);
- FreeMem(outpix, ((w+15)>>4)<<4);
- }
-
- struct MagicImage *pick_magic (void)
- {
- struct MagicImage *m = NULL;
-
-
- m = PickMagicImage(NULL,
- PMI_ExcludeOwner, "MagicDemo",
- PMI_ShowSize, TRUE,
- PMI_ShowOwner, TRUE,
- TAG_END);
-
- if (m) {
- close_magic();
-
- if (mh = OpenMagicImage(m, NULL, OMI_MsgPort, hostport, TAG_END)) {
- message("Magic Image opened.");
- }
- }
-
- return(m);
- }
-
- void message (char *txt, ...)
- {
- struct RastPort *rp = win->RPort;
- char buf[80];
- va_list va;
-
- va_start(va, txt);
- vsprintf(buf, txt, va);
- va_end(va);
-
- SetAPen(rp, 0);
- SetDrMd(rp, JAM1);
- RectFill(rp,
- win->BorderLeft,
- win->BorderTop,
- win->Width - win->BorderRight - 1,
- win->BorderTop + rp->TxHeight);
-
- SetAPen(rp, 1);
- SetDrMd(rp, JAM1);
- Move(rp, win->BorderLeft + 2, win->BorderTop + rp->TxBaseline + 1);
- Text(rp, buf, strlen(buf));
- }
-
-
- void __regargs negative (UBYTE *data, int width)
- {
- while (width--) {
- *data = 255 - *data;
- data++;
- }
- }
-
- /* do something interesting to the image buffer. yeah, right */
-
- void manipulate (void)
- {
- struct MagicImage *mi;
- UBYTE *buf;
- int j, p;
- LONG tag[3] = { GMI_Red, GMI_Green, GMI_Blue };
-
- if (mh) {
- if (!AttemptLockMagicImage(mh, LMI_Write)) {
- message("Image is locked.");
- return;
- }
- mi = mh->Object;
- if (buf = AllocMem(mi->Width, MEMF_CLEAR)) {
-
- message("Processing...");
- if (!mi) SaveMagicImage(mh, 0, 0, mi->Width, mi->Height);
- for (j = 0; j < mi->Height; j++) {
- for (p = 0; p < mi->Depth; p++) {
- GetMagicImageData(mh, j, 1, tag[p], buf, TAG_END);
- negative(buf, mi->Width);
- PutMagicImageData(mh, j, 1, tag[p], buf, TAG_END);
- }
- }
- RedrawMagicImage(mh, 0, 0, mi->Width, mi->Height);
- message("Image manipulated.");
-
- FreeMem(buf, mi->Width);
- }
-
- UnlockMagicImage(mh);
- }
- }
-
- void halve (void)
- {
- #if 0
- UBYTE *newplane;
- int neww, newh;
-
- if (mi) {
- neww = real_width / 2;
- newh = real_height / 2;
- for (p = 0; p < 3; p++) {
- newplane = AllocMem(neww * newh, MEMF_CLEAR);
- if (newplane == NULL) break; /* crash city */
- /* FINISH THIS! */
- }
- }
- else {
- message("Can't resize foreign images.");
- }
- #endif
- }
-
-
- void event_loop (void)
- {
- struct IntuiMessage *msg;
- struct MagicMessage *mmsg;
- ULONG wsig, hsig, sigs;
- BOOL quit = FALSE;
- int oldpri;
-
- message("Standing by...");
-
- wsig = 1 << win->UserPort->mp_SigBit;
- hsig = 1 << hostport->mp_SigBit;
-
- while (!quit) {
-
- sigs = Wait(wsig | hsig);
-
- if (sigs & wsig) {
- while (msg = (struct IntuiMessage *)GetMsg(win->UserPort)) {
- switch(msg->Class) {
- case IDCMP_CLOSEWINDOW :
- quit = TRUE;
- break;
- case IDCMP_MENUPICK :
- switch(ITEMNUM(msg->Code)) {
- case 0 : new_magic(); redraw(); break;
- case 1 : pick_magic(); redraw(); break;
- case 3 : manipulate(); redraw(); break;
- case 5 : if (mh) CycleMagicImage(mh); break;
- case 7 : quit = TRUE; break;
- default: break;
- }
- break;
- default :
- break;
- }
- ReplyMsg((struct Message *)msg);
- }
- }
-
- if (sigs & hsig) {
- while (mmsg = (struct MagicMessage *)GetMsg(hostport)) {
- mmsg->Result = 0;
- switch(mmsg->Action) {
- case MMSG_UPDATE :
- message("Update");
- break;
- case MMSG_REDRAW :
- message("Redraw %ld %ld %ld %ld",
- mmsg->Args[0], mmsg->Args[1], mmsg->Args[2], mmsg->Args[3]);
- oldpri = SetTaskPri(FindTask(NULL), -1);
- redraw();
- SetTaskPri(FindTask(NULL), oldpri);
- break;
- case MMSG_TOFRONT :
- message("To Front");
- ScreenToFront(win->WScreen);
- WindowToFront(win);
- ActivateWindow(win);
- break;
- case MMSG_SAVEUNDO :
- message("Save Undo");
- break;
- case MMSG_RESTOREUNDO :
- message("Restore Undo");
- break;
- case MMSG_CLOSE :
- message("Hit The Road");
- close_magic();
- redraw();
- break;
- default :
- mmsg->Result = -1;
- break;
- }
- ReplyMsg((struct Message *)mmsg);
- }
- }
-
- if (quit) {
- if (mi && mi->OpenCount > 1) {
- message("No way - image in use.");
- quit = FALSE;
- }
- }
-
- }
- }
-
-
- void main (int argc, char **argv)
- {
- struct Task *task = FindTask(NULL);
-
- task->tc_Node.ln_Name = "Magic Demo";
-
- if (hostport = CreatePort(NULL, 0)) {
- if (init_gui()) {
- if (init_magic()) {
- event_loop();
- cleanup_magic();
- }
- cleanup_gui();
- }
- DeletePort(hostport);
- }
- }
-