/*
 * Only some changes by Detlef Wuerkner, undefinded V43_DT and
 * rewrote DTS_ReadIntoBitMap() since macpaint is a different format :-)
 *
 */

/*
**      $VER: libfuncs.c 43.6 (27.3.97)
**
**      datatype functions
**
**      (C) Copyright 1996-97 Andreas R. Kleinert
**      All Rights Reserved.
*/


ULONG __saveds __stdargs DTS_ReadIntoBitMap(struct ClassBase *cb, Object * o, Class *cl, struct TagItem * attrs)
{
 struct BitMapHeader *bmhd;

 BOOL success = TRUE;

 struct RastPort __aligned trp;
 struct RastPort __aligned rp;

 struct BitMap *bm, *tbm;

 ULONG i;

 UBYTE *readname, *buffer;

 struct ColorRegister *cmap;
 LONG *cregs;

 BPTR fh;

 ULONG source_type;

 UBYTE comment[64] = "";

 /* we can't handle clipboard, ram or other access modes */

 source_type = (ULONG) GetTagData (DTA_SourceType, DTST_FILE, attrs);
 if(source_type != DTST_FILE)
  {
   SetIoErr(ERROR_OBJECT_WRONG_TYPE);
   return(FALSE);
  }

 readname = (UBYTE *) GetTagData (DTA_Name, NULL, attrs);
 getdtattrs (cb, o, PDTA_BitMapHeader, &bmhd, TAG_DONE, NULL);


 fh = Open(readname, MODE_OLDFILE);
 if(!fh)
  {
   SetIoErr(ERROR_OBJECT_NOT_FOUND);
   return(FALSE);
  }

 buffer = (APTR) AllocVec(512, MEMF_PUBLIC);
 if(!buffer)
  {
   SetIoErr (ERROR_NO_FREE_STORE);
   Close(fh);
   return(FALSE);
  }

 if(FRead(fh, buffer, 128, 1) != 1)
  {
   Close(fh);
   return(FALSE);
  }

/* Check if 128 bytes resource fork precede the data fork */
 if((buffer[0] == 0) &&				/* First byte is zero */
    (buffer[1] >= 0 && buffer[1] < 64) &&	/* Check for comment */
    (*(ULONG*)&buffer[0x41]==0x504E5447) &&	/* Check for PNTG mark */
    (buffer[0x4b] == 0)				/* Zero check */
   )
  {
   if(buffer[1])
    {
     strncpy(comment, &buffer[2], buffer[1]);
     comment[buffer[1]] = '\0';
    }
   if(FRead(fh, buffer, 512, 1) != 1)
    {
     Close(fh);
     return(FALSE);
    }
  }
 else
  {
   if(FRead(fh, &buffer[128], 384, 1) != 1)
    {
     Close(fh);
     return(FALSE);
    }
  }

 if(*(ULONG *)buffer <= 4)		/* Check header in data fork: Version number */
  {
   /* 204 reserved bytes must be zero */
   for(i = 308; (i < 512) && (success==TRUE); i++)
     if(buffer[i] != 0) success = FALSE;
  }
 else
   success = FALSE;

 if(success == FALSE)
  {
   SetIoErr(ERROR_OBJECT_WRONG_TYPE);
   Close(fh);
   FreeVec(buffer);
   return(FALSE);
  }

 bmhd->bmh_Width  = (bmhd->bmh_PageWidth  = 576);
 bmhd->bmh_Height = (bmhd->bmh_PageHeight = 720);
                     bmhd->bmh_Depth = 1;

 setdtattrs(cb, o, PDTA_NumColors,      2,
                   TAG_DONE,            NULL);
 getdtattrs(cb, o, PDTA_ColorRegisters, (ULONG) &cmap,
                   PDTA_CRegs,          &cregs,
                   TAG_DONE,            NULL);

 if( (!cmap) || (!cregs) )
  {
   success = FALSE;
  }else
  {
   if(tbm = AllocBitMap (bmhd->bmh_Width, 1, bmhd->bmh_Depth, BMF_CLEAR, NULL))
    {
     InitRastPort (&trp);
     trp.BitMap = tbm;
     if (bm = AllocBitMap (bmhd->bmh_Width, bmhd->bmh_Height, bmhd->bmh_Depth, BMF_CLEAR, NULL))
      {
       UBYTE *pbuf = AllocVec(576, MEMF_PUBLIC);
       if (pbuf)
        {
         InitRastPort (&rp);
         rp.BitMap = bm;
         /* Now unpack 720 * 576 bitpacked pixels */
         for(i=0; (i<720) && (success == TRUE); i++)
          {
           UBYTE c,b;
           LONG col = 0;
           LONG j;
           while (col < 72)
            {
             if(FRead(fh, &c, 1, 1) != 1)
              {
               success = FALSE;
               break;
              }
             if(c < 128)
              {
               c++;
               if(FRead(fh, &buffer[col], c, 1) != 1)
                {
                 success = FALSE;
                 break;
                }
               col += c;
              }
             else
              {
               if(FRead(fh, &b, 1, 1) != 1)
                {
                 success = FALSE;
                 break;
                }
               for(j=0; j <= 256 - c; j++)
                 buffer[col++] = b;
              }
            }
           if (col != 72) success = FALSE;
           if (success == TRUE)
            {
               for ( col = 0; col < 72; col++ )
                for ( j = 0; j < 8; j++ )
                 pbuf[col * 8 + j] = ((buffer[col] >> (7 - j)) & 1);
               WritePixelLine8(&rp, 0, i, 572, pbuf, &trp);
            }
          }
         if(success == FALSE)
          {
           SetIoErr(ERROR_OBJECT_WRONG_TYPE);
           FreeVec(pbuf);
           FreeBitMap(tbm);
           Close(fh);
           FreeVec(buffer);
           return(FALSE);
          }
         cmap->red   = 255;
         cmap->green = 255;
         cmap->blue  = 255;
         cmap++;
         cmap->red   = 0;
         cmap->green = 0;
         cmap->blue  = 0;
         cregs[0] = ((LONG)255)<<24;
         cregs[1] = ((LONG)255)<<24;
         cregs[2] = ((LONG)255)<<24;
         cregs[3] = 0;
         cregs[4] = 0;
         cregs[5] = 0;
         setdtattrs (cb, o,
                     DTA_ObjName,       comment[0] ? comment : readname,
                     DTA_NominalHoriz,  bmhd->bmh_Width,
                     DTA_NominalVert,   bmhd->bmh_Height,
                     PDTA_BitMap,       bm,
                     PDTA_ModeID,       DTS_GetBestModeID(bmhd->bmh_Width, bmhd->bmh_Height, 1),
                     TAG_DONE);
         FreeVec(pbuf);
        }else
        {
         success = FALSE;
         SetIoErr (ERROR_NO_FREE_STORE);
        }
      }else
      {
       success = FALSE;
       SetIoErr (ERROR_NO_FREE_STORE);
      }
     FreeBitMap(tbm);
    }else
    {
     success = FALSE;
     SetIoErr (ERROR_NO_FREE_STORE);
    }
  }
 Close(fh);
 FreeVec(buffer);
 return(success);
}
