home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / example_c_dt / dt_source / libfuncs.c < prev    next >
C/C++ Source or Header  |  1997-06-24  |  13KB  |  617 lines

  1. /*
  2. **      $VER: libfuncs.c 43.8 (24.6.97)
  3. **
  4. **      datatype functions
  5. **
  6. **      (C) Copyright 1996-97 Andreas R. Kleinert
  7. **      All Rights Reserved.
  8. */
  9.  
  10.  
  11. #define V43_DT         /* yes, we make use of the new V43 API here */
  12.  
  13.  
  14. #define __USE_SYSBASE
  15.  
  16. #ifndef EXEC_TYPES_H
  17. #include <exec/types.h>
  18. #endif /* EXEC_TYPES_H */
  19.  
  20. #ifndef EXEC_MEMORY_H
  21. #include <exec/memory.h>
  22. #endif /* EXEC_MEMORY_H */
  23.  
  24. #ifndef GRAPHICS_GFXBASE_H
  25. #include <graphics/gfxbase.h>
  26. #endif /* GRAPHICS_GFXBASE_H */
  27.  
  28. #ifndef GRAPHICS_VIEW_H
  29. #include <graphics/view.h>
  30. #endif /* GRAPHICS_VIEW_H */
  31.  
  32. #include <intuition/icclass.h>
  33. #include <datatypes/pictureclass.h>
  34.  
  35. #ifdef V43_DT
  36. #include <cybergraphics/cybergraphics.h>  /* CyberGraphX */
  37. #include <datatypes/PictureClassExt.h>    /* pic-dt V43  */
  38. #endif /* V43_DT */
  39.  
  40. #include <proto/exec.h>
  41. #include <proto/dos.h>
  42. #include <proto/intuition.h>
  43. #include <proto/graphics.h>
  44. #include <proto/utility.h>
  45. #include <proto/datatypes.h>
  46.  
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50.  
  51. #include <class/classbase.h>
  52. #include "libfuncs.h"
  53.  
  54.  
  55. #define LibVer(x) ( ((struct Library *) x)->lib_Version )
  56.  
  57.  
  58. Class * __saveds __asm ObtainPicClass ( register __a6 struct ClassBase *cb)
  59. {
  60.  return (cb->cb_Class);
  61. }
  62.  
  63. ULONG __inline setdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
  64. {
  65.  return (SetDTAttrsA (o, NULL, NULL, (struct TagItem *) & data));
  66. }
  67.  
  68. ULONG __inline getdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
  69. {
  70.  return (GetDTAttrsA (o, (struct TagItem *) & data));
  71. }
  72.  
  73.  
  74. extern char __aligned ExLibName [];
  75.  
  76. Class *initClass (struct ClassBase * cb)
  77. {
  78.  Class *cl;
  79.  
  80.  if (cl = MakeClass (&ExLibName[0], PICTUREDTCLASS, NULL, NULL, 0L))
  81.   {
  82.    cl->cl_Dispatcher.h_Entry = (HOOKFUNC) Dispatch;
  83.    cl->cl_UserData = (ULONG) cb;
  84.    AddClass (cl);
  85.   }
  86.  
  87.  return (cl);
  88. }
  89.  
  90. ULONG __saveds __asm Dispatch ( register __a0 Class * cl, register __a2 Object * o, register __a1 Msg msg)
  91. {
  92.  struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  93.  ULONG retval;
  94.  
  95.  switch (msg->MethodID)
  96.   {
  97.    case OM_NEW:
  98.     {
  99.      struct TagItem *ti;
  100.  
  101.      if( ti = FindTagItem( DTA_SourceType, (((struct opSet *)msg) -> ops_AttrList) ) )
  102.       {
  103.        if(ti->ti_Data != DTST_FILE)
  104.         {
  105.          SetIoErr( ERROR_OBJECT_WRONG_TYPE );
  106.  
  107.          break;
  108.         }
  109.       }
  110.  
  111.      if (retval = DoSuperMethodA (cl, o, msg))
  112.       {
  113.        if (!GetGfxData (cb, cl, (Object *) retval, ((struct opSet *) msg)->ops_AttrList))
  114.         {
  115.          CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
  116.  
  117.          return(NULL);
  118.         }
  119.       }
  120.      break;
  121.     }
  122. /*
  123.    case OM_UPDATE: DoMethod( o, ICM_CHECKLOOP); break;
  124.    case OM_SET:
  125.     {
  126.      if( retval = DoSuperMethodA( cl, o, msg ) )
  127.       {
  128.        struct RastPort *rp;
  129.  
  130.        if( rp = ObtainGIRPort( (((struct opSet *)msg)->ops_GInfo) ) )
  131.         {
  132.          struct gpRender gpr;
  133.  
  134.          gpr.MethodID   = GM_RENDER;
  135.          gpr.gpr_GInfo  = ((struct opSet *)msg)->ops_GInfo;
  136.          gpr.gpr_RPort  = rp;
  137.          gpr.gpr_Redraw = GREDRAW_UPDATE;
  138.  
  139.          DoMethodA( o, (Msg)(&gpr) );
  140.  
  141.          ReleaseGIRPort( rp );
  142.  
  143.          retval = 0UL;
  144.         }
  145.       }
  146.  
  147.      break;
  148.     }
  149. */
  150.    case DTM_WRITE:
  151.     {
  152.      struct dtWrite *dtw;
  153.  
  154.      dtw = (struct dtWrite *)msg;
  155.  
  156.      if( (dtw -> dtw_Mode) == DTWM_RAW )    /* local */
  157.       {
  158.        SetIoErr( ERROR_NOT_IMPLEMENTED );
  159.       }else                                 /* IFF-ILBM */
  160.       {
  161.        retval = DoSuperMethodA( cl, o, msg );
  162.       }
  163.  
  164.      break;
  165.     }
  166.    default:
  167.     {
  168.      retval = (ULONG) DoSuperMethodA (cl, o, msg);
  169.      break;
  170.     }
  171.   }
  172.  
  173.  return (retval);
  174. }
  175.  
  176. ULONG __saveds __stdargs DTS_ReadIntoBitMap(struct ClassBase *cb, Object * o, Class *cl, struct TagItem * attrs);
  177. ULONG __saveds __stdargs DTS_ReadIntoBitMap43(struct ClassBase *cb, Object * o, Class *cl, struct TagItem * attrs);
  178.  
  179. ULONG __saveds __asm GetGfxData ( register __a6 struct ClassBase * cb, register __a0 Class * cl, register __a2 Object * o, register __a1 struct TagItem * attrs)
  180. {
  181.  ULONG retval;
  182.  extern struct Library *SuperClassBase;
  183.  
  184. #ifdef V43_DT
  185.  
  186.  if(LibVer(SuperClassBase) > 42) retval = DTS_ReadIntoBitMap43(cb, o, cl, attrs);
  187.   else                           retval = DTS_ReadIntoBitMap(  cb, o, cl, attrs);
  188.  
  189. #else
  190.  
  191.  retval = DTS_ReadIntoBitMap(  cb, o, cl, attrs);
  192.  
  193. #endif /* V43_DT */
  194.  
  195.  return(retval);
  196. }
  197.  
  198. ULONG __saveds __stdargs DTS_GetBestModeID(ULONG width, ULONG height, ULONG depth);
  199. ULONG __saveds __stdargs DTS_SkipComment(BPTR handle, UBYTE *buf);
  200.  
  201. ULONG __saveds __stdargs DTS_ReadIntoBitMap(struct ClassBase *cb, Object * o, Class *cl, struct TagItem * attrs)
  202. {
  203.  struct BitMapHeader *bmhd;
  204.  
  205.  BOOL success = TRUE;
  206.  
  207.  struct RastPort __aligned trp;
  208.  struct RastPort __aligned rp;
  209.  
  210.  struct BitMap *bm, *tbm;
  211.  
  212.  ULONG i, width, height, depth, maxval;
  213.  
  214.  UBYTE *readname, *buffer, *id;
  215.  
  216.  struct ColorRegister *cmap;
  217.  LONG *cregs;
  218.  
  219.  BPTR fh;
  220.  
  221.  UBYTE wstr[16], hstr[16], dstr[16];
  222.  UWORD ID = (UWORD) 0;
  223.  ULONG source_type;
  224.  
  225.  
  226.  /* we can't handle clipboard, ram or other access modes */
  227.  
  228.  source_type = (ULONG) GetTagData (DTA_SourceType, DTST_FILE, attrs);
  229.  if(source_type != DTST_FILE)
  230.   {
  231.    SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  232.    return(FALSE);
  233.   }
  234.  
  235.  readname = (UBYTE *) GetTagData (DTA_Name, NULL, attrs);
  236.  getdtattrs (cb, o, PDTA_BitMapHeader, &bmhd, TAG_DONE, NULL);
  237.  
  238.  
  239.  fh = Open(readname, MODE_OLDFILE);
  240.  if(!fh)
  241.   {
  242.    SetIoErr(ERROR_OBJECT_NOT_FOUND);
  243.    return(FALSE);
  244.   }
  245.  
  246.  FRead(fh, &ID, 2, 1);
  247.  FRead(fh, &wstr[0], 1, 1); /* filter CR */
  248.  
  249.  id = (UBYTE *) &ID;
  250.  if(id[1] != '5')
  251.   {
  252.    SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  253.    Close(fh);
  254.    return(FALSE);
  255.   }
  256.  
  257.  
  258.  /* get Width */
  259.  
  260.  for(i=0; i<16; i++)
  261.   {
  262.    if(!FRead(fh, &wstr[i], 1, 1))
  263.     {
  264.      Close(fh);
  265.      return(FALSE);
  266.     }
  267.  
  268.    if(  wstr[i]=='#') i = DTS_SkipComment(fh, wstr);
  269.    if( (wstr[i]==' ') || (wstr[i]==0xa) || (wstr[i]==13) )
  270.     {
  271.      wstr[i] = (UBYTE) '\0';
  272.      break;
  273.     }
  274.   }
  275.  
  276.  /* get Height */
  277.  
  278.  for(i=0; i<16; i++)
  279.   {
  280.    if(!FRead(fh, &hstr[i], 1, 1))
  281.     {
  282.      Close(fh);
  283.      return(FALSE);
  284.     }
  285.  
  286.    if(  hstr[i]=='#') i = DTS_SkipComment(fh, hstr);
  287.    if( (hstr[i]==' ') || (hstr[i]==0xa) || (hstr[i]==13) )
  288.     {
  289.      hstr[i] = (UBYTE) '\0';
  290.      break;
  291.     }
  292.   }
  293.  
  294.  /* Maxval */
  295.  
  296.  for(i=0; i<16; i++)
  297.   {
  298.    if(!FRead(fh, &dstr[i], 1, 1))
  299.     {
  300.      Close(fh);
  301.      return(FALSE);
  302.     }
  303.  
  304.    if(  dstr[i]=='#') i = DTS_SkipComment(fh, dstr);
  305.    if( (dstr[i]==' ') || (dstr[i]==0xa) || (dstr[i]==13) )
  306.     {
  307.      dstr[i] = (UBYTE) '\0';
  308.      break;
  309.     }
  310.   }
  311.  
  312.  width  = (ULONG) atol(wstr);
  313.  height = (ULONG) atol(hstr);
  314.  maxval = (ULONG) atol(dstr);
  315.  if(maxval > 255)
  316.   {
  317.    Close(fh);
  318.    return(FALSE);
  319.   }
  320.  
  321.  bmhd->bmh_Width  = (bmhd->bmh_PageWidth  = width);
  322.  bmhd->bmh_Height = (bmhd->bmh_PageHeight = height);
  323.  depth            = (bmhd->bmh_Depth = 8);
  324.  
  325.  setdtattrs(cb, o, PDTA_NumColors,      256,
  326.                    TAG_DONE,            NULL);
  327.  
  328.  getdtattrs(cb, o, PDTA_ColorRegisters, (ULONG) &cmap,
  329.                    PDTA_CRegs,          &cregs,
  330.                    TAG_DONE,            NULL);
  331.  
  332.  if( (!cmap) || (!cregs) )
  333.   {
  334.    success = FALSE;
  335.   }else
  336.   {
  337.    if(tbm = AllocBitMap (bmhd->bmh_Width, 1, bmhd->bmh_Depth, BMF_CLEAR, NULL))
  338.     {
  339.      InitRastPort (&trp);
  340.      trp.BitMap = tbm;
  341.  
  342.      if (bm = AllocBitMap (bmhd->bmh_Width, bmhd->bmh_Height, bmhd->bmh_Depth, BMF_CLEAR, NULL))
  343.       {
  344.        InitRastPort (&rp);
  345.        rp.BitMap = bm;
  346.  
  347.        buffer = (APTR) AllocVec(width + 1024, MEMF_CLEAR|MEMF_PUBLIC);
  348.        if(buffer)
  349.         {
  350.          for(i=0; i<height; i++)
  351.           {
  352.            FRead(fh, buffer, width, 1);
  353.  
  354.            WritePixelLine8(&rp, 0, i, width, buffer, &trp);
  355.           }
  356.  
  357.          for(i=0; i<maxval; i++)
  358.           {
  359.            cmap->red   = i * (256 / maxval);
  360.            cmap->green = i * (256 / maxval);
  361.            cmap->blue  = i * (256 / maxval);
  362.            cmap++;
  363.  
  364.            cregs[i * 3    ] = ((LONG)i * (256 / maxval))<<24;
  365.            cregs[i * 3 + 1] = ((LONG)i * (256 / maxval))<<24;
  366.            cregs[i * 3 + 2] = ((LONG)i * (256 / maxval))<<24;
  367.           }
  368.  
  369.          cmap->red   = 255;
  370.          cmap->green = 255;
  371.          cmap->blue  = 255;
  372.          cmap++;
  373.  
  374.          cregs[i * 3    ] = ((LONG)255)<<24;
  375.          cregs[i * 3 + 1] = ((LONG)255)<<24;
  376.          cregs[i * 3 + 2] = ((LONG)255)<<24;
  377.  
  378.          setdtattrs (cb, o,
  379.                      DTA_ObjName,       readname,
  380.                      DTA_NominalHoriz,  bmhd->bmh_Width,
  381.                      DTA_NominalVert,   bmhd->bmh_Height,
  382.                      PDTA_BitMap,       bm,
  383.                      PDTA_ModeID,       DTS_GetBestModeID(bmhd->bmh_Width, bmhd->bmh_Height, 8),
  384.                      TAG_DONE);
  385.  
  386.          FreeVec(buffer);
  387.         }else
  388.         {
  389.          FreeBitMap(bm);
  390.  
  391.          success = FALSE;
  392.          SetIoErr (ERROR_NO_FREE_STORE);
  393.         }
  394.  
  395.       }else
  396.       {
  397.        success = FALSE;
  398.        SetIoErr (ERROR_NO_FREE_STORE);
  399.       }
  400.  
  401.      FreeBitMap(tbm);
  402.     }else
  403.     {
  404.      success = FALSE;
  405.      SetIoErr (ERROR_NO_FREE_STORE);
  406.     }
  407.   }
  408.  
  409.  Close(fh);
  410.  
  411.  return(success);
  412. }
  413.  
  414. #ifdef V43_DT
  415.  
  416. ULONG __saveds __stdargs DTS_ReadIntoBitMap43(struct ClassBase *cb, Object * o, Class *cl, struct TagItem * attrs)
  417. {
  418.  struct BitMapHeader *bmhd;
  419.  
  420.  BOOL success = TRUE;
  421.  
  422.  ULONG i, width, height, depth, maxval;
  423.  
  424.  UBYTE *readname, *buffer;
  425.  
  426.  BPTR fh;
  427.  
  428.  UBYTE wstr[16], hstr[16], dstr[16], *id;
  429.  UWORD ID;
  430.  ULONG source_type;
  431.  
  432.  
  433.  /* we can't handle clipboard, ram or other access modes */
  434.  
  435.  source_type = (ULONG) GetTagData (DTA_SourceType, DTST_FILE, attrs);
  436.  if(source_type != DTST_FILE)
  437.   {
  438.    SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  439.    return(FALSE);
  440.   }
  441.  
  442.  readname = (UBYTE *) GetTagData (DTA_Name, NULL, attrs);
  443.  getdtattrs (cb, o, PDTA_BitMapHeader, &bmhd, TAG_DONE, NULL);
  444.  
  445.  
  446.  fh = Open(readname, MODE_OLDFILE);
  447.  if(!fh)
  448.   {
  449.    SetIoErr(ERROR_OBJECT_NOT_FOUND);
  450.    return(FALSE);
  451.   }
  452.  
  453.  FRead(fh, &ID, 2, 1);
  454.  FRead(fh, &wstr[0], 1, 1); /* filter CR */
  455.  
  456.  
  457.  id = (UBYTE *) &ID;
  458.  if(id[1] == '5')
  459.   {
  460.    /* for P5 with 256 grayscales, the V40 code does suffice */
  461.  
  462.    Close(fh);
  463.    return( DTS_ReadIntoBitMap(cb, o, cl, attrs) );
  464.   }
  465.  
  466.  /* get Width */
  467.  
  468.  for(i=0; i<16; i++)
  469.   {
  470.    if(!FRead(fh, &wstr[i], 1, 1))
  471.     {
  472.      Close(fh);
  473.      return(FALSE);
  474.     }
  475.  
  476.    if(  wstr[i]=='#') i = DTS_SkipComment(fh, wstr);
  477.    if( (wstr[i]==' ') || (wstr[i]==0xa) || (wstr[i]==13) )
  478.     {
  479.      wstr[i] = (UBYTE) '\0';
  480.      break;
  481.     }
  482.   }
  483.  
  484.  /* get Height */
  485.  
  486.  for(i=0; i<16; i++)
  487.   {
  488.    if(!FRead(fh, &hstr[i], 1, 1))
  489.     {
  490.      Close(fh);
  491.      return(FALSE);
  492.     }
  493.  
  494.    if(  hstr[i]=='#') i = DTS_SkipComment(fh, hstr);
  495.    if( (hstr[i]==' ') || (hstr[i]==0xa) || (hstr[i]==13) )
  496.     {
  497.      hstr[i] = (UBYTE) '\0';
  498.      break;
  499.     }
  500.   }
  501.  
  502.  /* Maxval */
  503.  
  504.  for(i=0; i<16; i++)
  505.   {
  506.    if(!FRead(fh, &dstr[i], 1, 1))
  507.     {
  508.      Close(fh);
  509.      return(FALSE);
  510.     }
  511.  
  512.    if(  dstr[i]=='#') i = DTS_SkipComment(fh, dstr);
  513.    if( (dstr[i]==' ') || (dstr[i]==0xa) || (dstr[i]==13) )
  514.     {
  515.      dstr[i] = (UBYTE) '\0';
  516.      break;
  517.     }
  518.   }
  519.  
  520.  width  = (ULONG) atol(wstr);
  521.  height = (ULONG) atol(hstr);
  522.  maxval = (ULONG) atol(dstr);
  523.  if(maxval > 255)
  524.   {
  525.    Close(fh);
  526.    return(FALSE);
  527.   }
  528.  
  529.  bmhd->bmh_Width  = (bmhd->bmh_PageWidth  = width);
  530.  bmhd->bmh_Height = (bmhd->bmh_PageHeight = height);
  531.  depth            = (bmhd->bmh_Depth = 24);
  532.  
  533.  setdtattrs(cb, o,
  534.             DTA_ObjName,      readname,
  535.             DTA_NominalHoriz, bmhd->bmh_Width,
  536.             DTA_NominalVert,  bmhd->bmh_Height,
  537.             PDTA_SourceMode,  MODE_V43,
  538.             PDTA_ModeID,      DTS_GetBestModeID(bmhd->bmh_Width, bmhd->bmh_Height, 8),
  539.             TAG_DONE);
  540.  
  541.  
  542.  buffer = (APTR) AllocVec(width*3 + 1024, MEMF_CLEAR|MEMF_PUBLIC);
  543.  if(buffer)
  544.   {
  545.    ULONG i;
  546.  
  547.    for(i=0; i<height; i++)
  548.     {
  549.      FRead(fh, buffer, width*3, 1);
  550.      DoSuperMethod(cl, o, DTM_WRITEPIXELARRAY, buffer, RECTFMT_RGB, width*3, 0, i, width, 1);
  551.     }
  552.  
  553.    FreeVec(buffer);
  554.   }else
  555.   {
  556.    success = FALSE;
  557.    SetIoErr (ERROR_NO_FREE_STORE);
  558.   }
  559.  
  560.  Close(fh);
  561.  
  562.  return(success);
  563. }
  564.  
  565. #endif /* V43_DT */
  566.  
  567. ULONG __saveds __stdargs DTS_GetBestModeID(ULONG width, ULONG height, ULONG depth)
  568. {
  569.  ULONG mode_id = NULL;
  570.  
  571.  mode_id = BestModeID(BIDTAG_NominalWidth,  width,
  572.                       BIDTAG_NominalHeight, height,
  573.                       BIDTAG_DesiredWidth,  width,
  574.                       BIDTAG_DesiredHeight, height,
  575.                       BIDTAG_Depth,         depth,
  576.                       TAG_END);
  577.  
  578.  if(mode_id == INVALID_ID)
  579.   {
  580.    /* Uses OverScan values for checking. */
  581.    /* Assumes an ECS-System.             */
  582.  
  583.         if((width > 724) && (depth < 3)) mode_id = SUPER_KEY;
  584.    else if((width > 362) && (depth < 5)) mode_id = HIRES_KEY;
  585.    else                                  mode_id = LORES_KEY;
  586.  
  587.    if(!ModeNotAvailable(mode_id | PAL_MONITOR_ID))    /* for PAL  Systems */
  588.     {
  589.      if(height > 283) mode_id |= LACE;
  590.  
  591.      mode_id |= PAL_MONITOR_ID;
  592.     }else
  593.     {
  594.      if(!ModeNotAvailable(mode_id | NTSC_MONITOR_ID)) /* for NTSC Systems */
  595.       {
  596.        if(height > 241) mode_id |= LACE;
  597.  
  598.        mode_id |= NTSC_MONITOR_ID;
  599.       }
  600.     }
  601.   }
  602.  
  603.  return(mode_id);
  604. }
  605.  
  606. ULONG __saveds __stdargs DTS_SkipComment(BPTR handle, UBYTE *buf)
  607. {
  608.  do
  609.   {
  610.    FRead(handle, buf, 1, 1);
  611.   } while( (*buf!=0xa) && (*buf!=13) );
  612.  
  613.  FRead(handle, buf, 1, 1);
  614.  
  615.  return(0L);
  616. }
  617.