home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / oct93 / graphics / readdctv.lha / ReadDCTV / ReadDCTV.c < prev    next >
C/C++ Source or Header  |  1993-06-27  |  7KB  |  288 lines

  1. /*  ReadDCTV     by Garrick Meeker  */
  2.  
  3. #include <dos/dos.h>
  4. #include <exec/memory.h>
  5. #include <iffp/ilbmapp.h>
  6. #include <iffp/packer.h>
  7. #include <libraries/dctv.h>
  8. #include <libraries/iffparse.h>
  9. #include <math.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #include <clib/dctv_protos.h>
  15. #include <clib/exec_protos.h>
  16. #include <clib/graphics_protos.h>
  17. #include <clib/iffparse_protos.h>
  18.  
  19. #include <pragmas/dctv_pragmas.h>
  20. #include <pragmas/exec_pragmas.h>
  21. #include <pragmas/graphics_pragmas.h>
  22. #include <pragmas/iffparse_pragmas.h>
  23.  
  24. char *vers = "\0$VER: ReadDCTV 1.0";
  25. char *Copyright = "ReadDCTV v1.0 by Garrick Meeker";
  26. char *usage = "Usage: ReadDCTV dctvfile iff24file";
  27.  
  28. char *write_err = "Error writing file";
  29.  
  30. LONG Convert(void);
  31. struct IFFHandle *OpenOutfile(void);
  32. BOOL WriteRGB(struct IFFHandle *iff24, struct DCTVCvtHandle *cvt);
  33. BOOL WriteChunkyLine(struct IFFHandle *iff,UBYTE *chunks,int width);
  34. void ConvertPlane(UBYTE planemask, UBYTE *line, int width);
  35. void CloseOutfile(struct IFFHandle *iff24);
  36. void bye(UBYTE *s, int e);
  37. void cleanup(void);
  38.  
  39. struct Library *DCTVBase = NULL;
  40. struct Library *GfxBase = NULL;
  41. struct Library *IFFParseBase = NULL;
  42.  
  43. struct ILBMInfo ilbm = {0};
  44.  
  45. LONG error=NULL;
  46. UBYTE *infile=NULL;
  47. UBYTE *outfile=NULL;
  48.  
  49. UWORD *plane=NULL;
  50. BYTE *compressed=NULL;
  51.  
  52. LONG ilbmprops[] = {
  53.     ID_ILBM, ID_BMHD,
  54.     ID_ILBM, ID_CMAP,
  55.     ID_ILBM, ID_CAMG,
  56.     TAG_DONE
  57. };
  58.  
  59. LONG ilbmstops[] = {
  60.     ID_ILBM, ID_BODY,
  61.     TAG_DONE
  62. };
  63. void main(int argc, char **argv)
  64. {
  65.  
  66.     if((argc<3)||(argv[argc-1][0]=='?'))
  67.     {
  68.         printf("%s\n%s\n",Copyright,usage);
  69.         bye("",RETURN_OK);
  70.     }
  71.     
  72.     infile = argv[1];
  73.     outfile = argv[2];
  74.     
  75.     if(!(GfxBase = OpenLibrary("graphics.library", 0)))
  76.       bye("Unable to open graphics.library.\n",RETURN_WARN);
  77.     
  78.     if(!(IFFParseBase = OpenLibrary("iffparse.library",0)))
  79.       bye("Unable to open iffparse.library.\n",RETURN_WARN);
  80.     
  81.     if(!(DCTVBase = OpenLibrary("dctv.library",3)))
  82.       bye("Unable to open dctv.library v3.\n",RETURN_WARN);
  83.     
  84. /* Load image */
  85.  
  86.     ilbm.ParseInfo.propchks = ilbmprops;
  87.     ilbm.ParseInfo.stopchks = ilbmstops;
  88.     if(!(ilbm.ParseInfo.iff = AllocIFF()))
  89.       bye(IFFerr(IFFERR_NOMEM),RETURN_FAIL);
  90.     
  91.     if (error = loadbrush(&ilbm,infile))
  92.     {
  93.         printf("Unable to load ilbm \"%s\", ifferr=%s\n",infile,IFFerr(error));
  94.         bye("",RETURN_WARN);
  95.     }
  96.     error=Convert();
  97.     
  98.     unloadbrush(&ilbm);
  99.     bye("",error);
  100. }
  101.     
  102. /* Convert to 24 bit */
  103. LONG Convert()
  104. {
  105.     struct IFFHandle *iff24 = NULL;
  106.     struct DCTVCvtHandle *cvt = NULL;
  107.  
  108.     if(!(TestDCTVSignature(ilbm.brbitmap))) {
  109.         puts("This is not a DCTV picture.");
  110.         return RETURN_WARN;
  111.     }
  112.     
  113.     if (!(cvt = AllocDCTVCvtTags(        ilbm.brbitmap,
  114.             DCTVCVTA_Type,        (ULONG)DCTVCVTT_DCTVtoRGB,
  115.             DCTVCVTA_Width,        (ULONG)((ilbm.brbitmap->BytesPerRow)<<3),
  116.             DCTVCVTA_Height,    (ULONG)ilbm.brbitmap->Rows,
  117.             DCTVCVTA_Flags,        (ULONG)((ilbm.camg & LACE) ? DCTVCVTF_Lace : 0),
  118.             DCTVCVTA_ColorTable,    ilbm.colortable,
  119.             DCTVCVTA_ErrorCode,    &error,
  120.             TAG_END))) {
  121.         printf("DCTV conversion failed %lu\n",error);
  122.         error=RETURN_WARN;
  123.         goto abortconvert;
  124.     }
  125.  
  126.     if (!(plane=(AllocMem(ilbm.brbitmap->BytesPerRow,MEMF_ANY)))) {
  127.         puts("Out of memory.");
  128.         error=RETURN_WARN;
  129.         goto abortconvert;
  130.     }
  131.     
  132.     if (!(compressed=(AllocMem(MaxPackedSize(ilbm.brbitmap->BytesPerRow),MEMF_ANY)))) {
  133.         puts("Out of memory.");
  134.         error=RETURN_WARN;
  135.         goto abortconvert;
  136.     }
  137.     
  138.     if (!(iff24=OpenOutfile())) {
  139.         puts("Unable to open output file.");
  140.         error=RETURN_FAIL;
  141.         goto abortconvert;
  142.     }
  143.     
  144.     while (cvt->DstLineNum < cvt->Height) {
  145.         /* Break on Ctrl-C */
  146.         if (SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) return RETURN_WARN;
  147.         CvtDCTVLine(cvt);
  148.         if(cvt->DstLineNum>0)
  149.           if(!(WriteRGB(iff24,cvt))) {
  150.             printf("%s\n",write_err);
  151.             error=RETURN_FAIL;
  152.             goto abortconvert;
  153.         }
  154.     }
  155.  
  156.     if(PopChunk(iff24)) {    /* Close BODY chunk */
  157.         printf("%s\n",write_err);
  158.         error=RETURN_FAIL;
  159.         goto abortconvert;
  160.     }
  161.     
  162.     if(PopChunk(iff24)) {    /* Close FORM */
  163.         printf("%s\n",write_err);
  164.         error=RETURN_FAIL;
  165.         goto abortconvert;
  166.     }
  167.     
  168.     error = RETURN_OK;
  169. abortconvert:
  170.     if(compressed)    FreeMem(compressed,MaxPackedSize(ilbm.brbitmap->BytesPerRow));
  171.     if(plane)    FreeMem(plane,ilbm.brbitmap->BytesPerRow);
  172.     if(cvt)        FreeDCTVCvt(cvt);
  173.     CloseOutfile(iff24);
  174.     return error;
  175. }
  176.  
  177. /* Open 24-bit IFF */
  178. struct IFFHandle *OpenOutfile()
  179. {
  180.     struct IFFHandle *iff=NULL;
  181.     BitMapHeader bmhd;
  182.     
  183.     if (!(iff = AllocIFF())) return NULL;
  184.     if (!(iff->iff_Stream=Open(outfile,MODE_NEWFILE)))
  185.         goto abortopen;
  186.     InitIFFasDOS(iff);
  187.     if (OpenIFF(iff,IFFF_WRITE)) goto abortopen;
  188.     
  189.     /* Write header */
  190.     if (PushChunk(iff,ID_ILBM,ID_FORM,IFFSIZE_UNKNOWN))
  191.         goto abortopen;
  192.     
  193. /* Write BMHD */
  194.     if (PushChunk(iff,ID_ILBM,ID_BMHD,sizeof(BitMapHeader)))
  195.         goto abortopen;
  196.     /* Set BMHD values */
  197.     CopyMem(&ilbm.Bmhd,&bmhd,sizeof(bmhd));
  198.     bmhd.nPlanes=24;
  199.     bmhd.masking=mskNone;
  200.     bmhd.compression=cmpByteRun1;
  201.     bmhd.reserved1=0;
  202.     
  203.     if (WriteChunkBytes(iff,&bmhd,sizeof(bmhd)) != sizeof(bmhd))
  204.         goto abortopen;
  205.     if (PopChunk(iff))
  206.         goto abortopen;
  207.     
  208. /* Write BODY header */
  209.     if (PushChunk(iff,ID_ILBM,ID_BODY,IFFSIZE_UNKNOWN))
  210.         goto abortopen;
  211.     return iff;
  212.  
  213. abortopen:
  214.     CloseOutfile(iff);
  215.     return NULL;
  216. }
  217.     
  218. void CloseOutfile(struct IFFHandle *iff)
  219. {
  220.     if(iff) {
  221.         CloseIFF(iff);
  222.         if (iff->iff_Stream)
  223.             Close(iff->iff_Stream);
  224.         FreeIFF(iff);
  225.     }
  226. }
  227.     
  228. BOOL WriteRGB(struct IFFHandle *iff, struct DCTVCvtHandle *cvt)
  229. {
  230.     if (!(WriteChunkyLine(iff,cvt->Red,cvt->Width)!=cvt->Width))
  231.       return FALSE;
  232.     if (!(WriteChunkyLine(iff,cvt->Green,cvt->Width)!=cvt->Width))
  233.       return FALSE;
  234.     if (!(WriteChunkyLine(iff,cvt->Blue,cvt->Width)!=cvt->Width))
  235.       return FALSE;
  236.     return TRUE;
  237. }
  238.  
  239. /* Write one line of a primary color */
  240. BOOL WriteChunkyLine(struct IFFHandle *iff,UBYTE *chunks,int width)
  241. {
  242.     UBYTE    i;
  243.     LONG    length;
  244.     /* Pointers are incremented by packrow() so we use a copy */
  245.     BYTE    *temp_plane;
  246.     BYTE    *temp_comp;
  247.     
  248.     /* Ends when i overflows */
  249.     for (i=1; i!=0; i+=i) {
  250.         temp_plane=(BYTE *)plane;
  251.         temp_comp=compressed;
  252.         ConvertPlane(i, chunks, width);
  253.         length=packrow(&temp_plane,&temp_comp,(LONG)ilbm.brbitmap->BytesPerRow);
  254.         if (WriteChunkBytes(iff,compressed,length)!=length)
  255.               return FALSE;
  256.     }
  257.     return TRUE;
  258. }
  259.  
  260. void ConvertPlane(UBYTE planemask, UBYTE *line, int width)
  261. {
  262.     int i,j,end;
  263.     UWORD currbit;
  264.     
  265.     for (i=0,j=0; i<width; j++) {
  266.         for (plane[j]=0,currbit=0x8000,end=min(width,i+16); i<end; i++,currbit=currbit>>1) {
  267.             if (line[i]&planemask)
  268.                 plane[j] |= currbit;
  269.         }
  270.     }
  271. }
  272.  
  273. void bye(UBYTE *s, int e)
  274. {
  275.     if(s&&(*s)) printf("%s\n",s);
  276.     cleanup();
  277.     exit(e);
  278. }
  279.  
  280. void cleanup()
  281. {
  282.     if(ilbm.ParseInfo.iff)    FreeIFF(ilbm.ParseInfo.iff);
  283.     if(IFFParseBase)    CloseLibrary(IFFParseBase);
  284.     if(GfxBase)        CloseLibrary(GfxBase);
  285.     if(DCTVBase)        CloseLibrary(DCTVBase);
  286. }
  287.  
  288.