home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / new / amigalibdisks / disk945 / iffconvert / src / iffpack.c < prev    next >
C/C++ Source or Header  |  1993-12-21  |  15KB  |  567 lines

  1. #include <intuition/intuition.h>
  2. #include <proto/intuition.h>
  3. #include <graphics/gfx.h>
  4. #include <graphics/gfxbase.h>
  5. #include <proto/graphics.h>
  6. #include <stdio.h>
  7.  
  8. #include "iffpack.h"
  9.  
  10. #define BADFLAGS (SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO)
  11. #define FLAGMASK (~BADFLAGS)
  12. #define CAMGMASK (FLAGMASK & 0xffffL)
  13.  
  14. #define ID(a,b,c,d) ((((a)<<8|(b))<<8|(c))<<8|(d))
  15.  
  16. void SetRGB32( struct ViewPort *, ULONG, ULONG, ULONG, ULONG );
  17. void GetRGB32( struct ColorMap *, ULONG, ULONG, ULONG *);
  18.  
  19. #pragma libcall GfxBase SetRGB32 354 3210805
  20. #pragma libcall GfxBase GetRGB32 384 910804
  21.  
  22. extern struct GfxBase *GfxBase;
  23.  
  24. struct BMHD {
  25.    ULONG  Size;
  26.    USHORT Width,Height;
  27.    SHORT  LeftEdge,TopEdge;
  28.    UBYTE  Depth;
  29.    UBYTE  Mask;
  30.    UBYTE  Compression;
  31.    UBYTE  Pad;
  32.    USHORT Transparent;
  33.    UBYTE  XAspect,YAspect;
  34.    SHORT  ScrWidth,ScrHeight;
  35. };
  36.  
  37. static int buf[256];
  38. static short count,runlen,ptr;
  39.  
  40. static short rows,bytes,depth;
  41. static cmode;
  42.  
  43. static short TempY=0,TempX=0;
  44. static struct BitMap MyBm;
  45. static struct RastPort MyRast;
  46. static short anzcolors;
  47.  
  48. /* static ULONG colors[256]; */
  49.  
  50. static UBYTE red[256],green[256],blue[256];
  51.  
  52. /* Prototypes */
  53. static ReadHeader(FILE *fp,struct BMHD *bmhd,USHORT *viewmode);
  54. static ReadBMHD(FILE *fp,struct BMHD *bmhd,USHORT *vmode);
  55. static ReadCMAP(FILE *fp);
  56. static ReadCAMG(FILE *fp,USHORT *vmode);
  57. static WriteBMHD(struct Window *w,FILE *fp,short mode);
  58. static WriteCMAP(struct Screen *s,FILE *fp,int);
  59. static WriteCAMG(struct Screen *s,FILE *fp);
  60. static WriteBODY(struct Window *w,FILE *fp,short mode);
  61. static compline(FILE *fp,short bytes,short y,short p);
  62. static comprow(FILE *fp,short rows,short x,short p);
  63. static initcomp(short width,short height,short depth,short mode);
  64. static compget(FILE *fp);
  65.  
  66.  
  67. #define RED(c) (((c)>>16)&0xff)
  68. #define BLUE(c) (((c)>>8)&0xff)
  69. #define GREEN(c) ((c)&0xff)
  70.  
  71.  
  72. #define COLOR32(c) ((c)|((c)<<8)|((c)<<16)|((c)<<24))
  73.  
  74.  
  75. void SetColors(struct ViewPort *vp)
  76. {
  77.    short a;
  78.    if(GfxBase->LibNode.lib_Version<39) {
  79.       for(a=0;a<anzcolors;a++) {
  80.          SetRGB4(vp,a,red[a]>>4,green[a]>>4,blue[a]>>4);
  81.       }
  82.    } else {
  83.       for(a=0;a<anzcolors;a++) {
  84.          SetRGB32(vp,a,COLOR32(red[a]),COLOR32(green[a]),COLOR32(blue[a]));
  85.       }
  86.    }
  87. }
  88. ReadPicSize(FILE *fp,SHORT *winx,SHORT *winy,SHORT *scrx,SHORT *scry,SHORT *depth,USHORT *vmode)
  89. {
  90.    struct BMHD bmhd;
  91.    int err;
  92.    if(err=ReadHeader(fp,&bmhd,vmode)) return(err);
  93.    *winx=bmhd.Width;
  94.    *winy=bmhd.Height;
  95.    *scrx=bmhd.ScrWidth;
  96.    *scry=bmhd.ScrHeight;
  97.    *depth=bmhd.Depth;
  98.    return(0);
  99. }
  100. ReadBody(struct RastPort *rp,FILE *fp)
  101. {
  102.    long size;
  103.    short x,y,p;
  104.    int c;
  105.  
  106.    if(!fread(&size,4,1,fp)) return(BAD_IFF);
  107.  
  108.    if(cmode==0) {
  109.       for(y=0;y<rows;y++) {
  110.          for(p=0;p<depth;p++) {
  111.             for(x=0;x<bytes;x++) {
  112.                if((c=getc(fp))==EOF) return(BAD_IFF);
  113.                MyBm.Planes[p][x]=c;
  114.             }
  115.          }
  116.          ClipBlit(&MyRast,0L,0L,rp,0L,(long)y,(long)TempX,1L,192L);
  117.          WaitBlit();
  118.       }
  119.    } else if(cmode==1) {
  120.       for(y=0;y<rows;y++) {
  121.          for(p=0;p<depth;p++) {
  122.             for(x=0;x<bytes;x++) {
  123.                if((c=compget(fp))==EOF) return(BAD_IFF);
  124.                if(c<256) {
  125.                   MyBm.Planes[p][x]=c;
  126.                }
  127.             }
  128.          }
  129.          ClipBlit(&MyRast,0L,0L,rp,0L,(long)y,(long)TempX,1L,192L);
  130.          WaitBlit();
  131.       }
  132.    } else if(cmode==2) {
  133.       for(x=0;x<bytes;x++) {
  134.          for(p=0;p<depth;p++) {
  135.             for(y=0;y<rows;y++) {
  136.                if((c=compget(fp))==EOF) return(BAD_IFF);
  137.                if(c<256) {
  138.                   MyBm.Planes[p][y<<1]=c;
  139.                }
  140.             }
  141.          }
  142.          ClipBlit(&MyRast,0L,0L,rp,(long)(x<<3),0L,8L,(long)TempY,192L);
  143.          WaitBlit();
  144.       }
  145.    }
  146.    IFFCleanup();
  147.    return(0);
  148. }
  149. WriteWindow(FILE *fp,struct Window *w,int mode,int LastColors)
  150. {
  151.    if(mode<0 || mode>2) return(UNKNOWN_COMPRESSION);
  152.    if(WriteBMHD(w,fp,mode)) return(WRITE_ERROR);
  153.    if(WriteCMAP(w->WScreen,fp,LastColors)) return(WRITE_ERROR);
  154.    if(WriteCAMG(w->WScreen,fp)) return(WRITE_ERROR);
  155.    if(initcomp((short)w->Width,(short)w->Height,(short)w->WScreen->BitMap.Depth,
  156.           mode)) return(NO_MEMORY);
  157.    if(WriteBODY(w,fp,mode)) return(WRITE_ERROR);
  158.    IFFCleanup();
  159.    return(0);
  160. }
  161. void IFFCleanup(void)
  162. {
  163.    short a;
  164.    if(TempX) {
  165.       for(a=0;a<8;a++) {
  166.          if(MyBm.Planes[a])
  167.                  FreeRaster(MyBm.Planes[a],(long)TempX,(long)TempY);
  168.       }
  169.    }
  170.    TempX=TempY=0;
  171. }
  172.  
  173. static ReadHeader(FILE *fp,struct BMHD *bmhd,USHORT *viewmode)
  174. {
  175.    short status=0;
  176.    long id[3],sid,size;
  177.    if(!fread(id,12,1,fp)) return(BAD_IFF);
  178.    if(id[0]!=ID('F','O','R','M')) return(BAD_IFF);
  179.    if(id[2]!=ID('I','L','B','M')) return(BAD_IFF);
  180.    *viewmode=0;
  181.    do {
  182.       if(!fread(&sid,4,1,fp)) return(BAD_IFF);
  183.       if(sid==ID('C','M','A','P')) {
  184.          if(status&1) return(BAD_IFF); /* doppelt */
  185.          if(ReadCMAP(fp)) return(BAD_IFF);
  186.          status|=1;
  187.       } else if(sid==ID('C','A','M','G')) {
  188.          if(status&2) return(BAD_IFF); /* doppelt */
  189.          if(ReadCAMG(fp,viewmode)) return(BAD_IFF);
  190.          status|=2;
  191.       } else if(sid==ID('B','M','H','D')) {
  192.          if(status&4) return(BAD_IFF); /* doppelt */
  193.          if(ReadBMHD(fp,bmhd,viewmode)) return(BAD_IFF);
  194.          status|=4;
  195.       } else if(sid!=ID('B','O','D','Y')) {
  196.          if(!fread(&size,4,1,fp)) return(BAD_IFF);
  197.          size+=size&1;
  198.          if(fseek(fp,size,1)) return(BAD_IFF);
  199.       }
  200.    } while(sid!=ID('B','O','D','Y'));
  201.    if(!(status&1) || !(status&4)) return(BAD_IFF); /* Daten fehlen */
  202.    if(initcomp((short)bmhd->Width,(short)bmhd->Height,(short)bmhd->Depth,
  203.             (short)bmhd->Compression)) return(NO_MEMORY);
  204.    rows=bmhd->Height;
  205.    bytes=((bmhd->Width+15)>>3)&0xfffe;
  206.    depth=bmhd->Depth;
  207.    cmode=bmhd->Compression;
  208.    if(cmode<0 || cmode>2) return(UNKNOWN_COMPRESSION);
  209.    return(0);
  210. }
  211. static ReadBMHD(FILE *fp,struct BMHD *bmhd,USHORT *vmode)
  212. {
  213.    if(!fread(bmhd,sizeof(struct BMHD),1,fp)) return(BAD_IFF);
  214.    if(bmhd->Size!=20) return(BAD_IFF);
  215.    *vmode=0;
  216.    if(bmhd->Width>400 && bmhd->Depth<=4) *vmode|=HIRES;
  217.    if(bmhd->Height>300) *vmode|=LACE;
  218.    if(bmhd->Depth>6) *vmode|=HAM;
  219.    return(0);
  220. }
  221. static ReadCMAP(FILE *fp)
  222. {
  223.    long size;
  224.    short a;
  225.    int r,g,b;
  226.    if(!fread(&size,4,1,fp)) return(1);
  227.    if(size % 3) return(1);
  228.    size/=3;
  229.    if(size>256) return(1);
  230.    anzcolors=size;
  231.    for(a=0;a<size;a++) {
  232.       if((r=getc(fp))==EOF) return(1);
  233.       if((g=getc(fp))==EOF) return(1);
  234.       if((b=getc(fp))==EOF) return(1);
  235.  
  236.       red[a]=r;
  237.       green[a]=g;
  238.       blue[a]=b;
  239.    }
  240.    return(0);
  241. }
  242. static ReadCAMG(FILE *fp,USHORT *vmode)
  243. {
  244.    long a;
  245.    long size;
  246.    if(!fread(&size,4,1,fp)) return(1);
  247.    if(size!=4) return(1);
  248.    if(!fread(&a,4,1,fp)) return(1);
  249.    *vmode=a&CAMGMASK;
  250.    return(0);
  251. }
  252.  
  253. static WriteBMHD(struct Window *w,FILE *fp,short mode)
  254. {
  255.    struct BMHD bm;
  256.    if(!fwrite("FORM    ILBMBMHD",16,1,fp)) return(1);
  257.    bm.Size=20;
  258.    bm.Width=w->Width;
  259.    bm.Height=w->Height;
  260.    bm.ScrWidth=w->WScreen->Width;
  261.    bm.ScrHeight=w->WScreen->Height;
  262.    bm.LeftEdge=bm.TopEdge=0;
  263.    bm.Depth=w->WScreen->BitMap.Depth;
  264.    bm.Mask=bm.Pad=0;
  265.    bm.Compression=mode;
  266.    bm.Transparent=0;
  267.    bm.YAspect=11;
  268.    bm.XAspect=10;
  269.    if((w->WScreen->ViewPort.Modes&LACE) && !(w->WScreen->ViewPort.Modes&HIRES)) bm.XAspect=20;
  270.    if(!(w->WScreen->ViewPort.Modes&LACE) && (w->WScreen->ViewPort.Modes&HIRES)) bm.XAspect=5;
  271.    if(!fwrite(&bm,sizeof(struct BMHD),1,fp)) return(1);
  272.    return(0);
  273. }
  274. static WriteCMAP(struct Screen *s,FILE *fp,int LastColors)
  275. {
  276.    long size;
  277.    short anz,col;
  278.    short i;
  279.    struct ViewPort *vp;
  280.    ULONG ColorSet[3];
  281.  
  282.    vp=&s->ViewPort;
  283.  
  284.    if(!fwrite("CMAP",4,1,fp)) return(1);
  285.    anz=s->BitMap.Depth;
  286.    anz=1<<anz;
  287.  
  288.    if(vp->Modes&HAM) { /* HAM-Screen */
  289.       if(anz<256) anz=16; else anz=64;
  290.    }
  291.  
  292.    if(vp->Modes&EXTRA_HALFBRITE) anz=32;
  293.  
  294.    size=3*anz;
  295.    if(!fwrite(&size,4,1,fp)) return(1);
  296.  
  297.    if(!LastColors || anz>anzcolors) {
  298.       if(GfxBase->LibNode.lib_Version<39) {
  299.  
  300.          for(i=0;i<anz;i++) {
  301.             col=GetRGB4(vp->ColorMap,(long)i);
  302.             red[i]=((col>>8)&0xf)<<4;
  303.             green[