/* Pro2IFF.c - converts Amiga 3-D Professional RGB files to 24-bit
   ILBM format - djh */
   
#include <stdio.h>
#include <stdlib.h>
#include "iff.h"

void *GfxBase;

#define PROIDLEN 9
#define STD_METHOD 1
#define RGBSIZE 3 /* Aztec pads sizeof(rgb) to 4! */

typedef struct {
  /*char identifier[9];*/
  short width,height,vxoff,vyoff,
        vwidth,vheight;
  long dflags,method;
} ProRGBHeader;

typedef struct {
  unsigned char r,g,b;
} rgb;

SafeRead2(FILE *fp,char *buf,int len)
{
  if (fread(buf,1,len,fp)!=len) {
    puts("\nError while reading file.\n");
    return(TRUE);
  }

  return(FALSE);
}

  void
MyInitBitMap(struct BitMap *bm,int pl,int w,int h)
{
  /* Looks, smells, tastes like InitBitMap, but supports 24-bit. Note
     that the 24-bit BitMap structures used here are always embedded
     within a PicMap, which lengthens it by 16 extra planes. */

  memset(bm,0,sizeof(*bm));

  bm->Depth=pl;
  bm->BytesPerRow=w/8;
  bm->Rows=h;
}

  void
split_row24(struct PicMap *picmap,int y,UBYTE *buf)
{
  ULONG offset,color;
  UWORD index,pixels,plane;
  short bit;
  UBYTE value;

  pixels=picmap->BitMap.BytesPerRow*8;
  offset=picmap->BitMap.BytesPerRow*y;

  bit=7;

  /* Read 3-byte rgb line from image and break apart into
     separate bitplanes. Yes, this is relatively slow. */

  for (index=0;index<pixels;index++) {
    color  =  *buf++;		/* red */
    color |= (*buf++ << 8);	/* green */
    color |= (*buf++ << 16);	/* blue */

    value=1<<bit;

    for (plane=0;plane<24;plane++)
      if (color & (1<<plane))
        picmap->BitMap.Planes[plane][offset] |= value;

    if (--bit < 0) {
      bit=7;
      offset++;
    }
  }
}

Pro2ILBM24(FILE *fp,struct PicMap *dst)
{
  ProRGBHeader pro_hdr;
  static char pro_id[PROIDLEN+1];
  UBYTE buf[1024*3];
  UWORD w,h;
  int linesize,i;
 
  memset(dst,0,sizeof(*dst));

  if (SafeRead2(fp,pro_id,PROIDLEN)) return(DISK_ERR);
  if (SafeRead2(fp,(char *)&pro_hdr,sizeof(pro_hdr))) return(DISK_ERR);

  if (pro_hdr.method!=STD_METHOD) {
    printf("\nError: storage method %d not recognized!\n",pro_hdr.method);
    return(DISK_ERR);
  }

  w=pro_hdr.width,h=pro_hdr.height,linesize=w*3;
  printf("Converting [Width=%d,Height=%d]... ",w,h);

  MyInitBitMap(&dst->BitMap,24,(long)w,(long)h);

  /* note that we're not allocating CHIP_MEM here! */

  for (i=0;i<24;i++)
    if (!(dst->BitMap.Planes[i]=AllocMem(RASSIZE(w,h),MEMF_PUBLIC|MEMF_CLEAR))) {
      FreeBitMap(&dst->BitMap);
      return(OUT_OF_MEM);
    }

  linesize=pro_hdr.width*RGBSIZE;

  for (i=0;i<pro_hdr.height;i++) {
    if (SafeRead2(fp,(char *)buf,linesize)) return(DISK_ERR);
    split_row24(dst,i,buf);
  }

  return(0);
}

main(argc,argv)
int argc;
char *argv[];
{
  struct PicMap dstmap;
  FILE *fp=NULL;

  puts("Pro2IFF: 3-D Professional to 24-bit Windows converter");
  puts("         Copyright (c) 1991 Dallas J. Hodgson\n");

  if (argc<3) {  
    puts("Usage: Pro2IFF <infile> <outfile>");
    goto cleanup;
  }

  if (!(fp=fopen(argv[1],"r"))) {
    printf("Error: couldn't open ProRGB file %s for reading.\n",argv[1]);
    goto cleanup;
  }

  if (Pro2ILBM24(fp,&dstmap)) {
    puts("not enough memory!");
    goto cleanup;
  }

  if (WriteILBM(argv[2],&dstmap)) {
    printf("Couldn't write file %s.\n",argv[2]);
    goto cleanup;
  }

  puts("Done!");
  
cleanup:
  FreeBitMap(&dstmap.BitMap);
  if (fp) fclose(fp);

  return(0);
}
