home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 2 / MECOMP-CD-II.iso / amiga / datatypes / gifanim_datatype / prefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-24  |  16.2 KB  |  509 lines

  1.  
  2. /*
  3. **
  4. **  $VER: prefs.c 2.3 (24.5.98)
  5. **  gifanim.datatype 2.3
  6. **
  7. **  Preferences
  8. **
  9. **  Written 1997/1998 by Roland 'Gizzy' Mainz
  10. **  Original example source from David N. Junod
  11. **
  12. */
  13.  
  14. /* main includes */
  15. #include "classbase.h"
  16. #include "classdata.h"
  17. #include "encoder.h"
  18.  
  19. /* ansi includes */
  20. #include <limits.h>
  21.  
  22. /*****************************************************************************/
  23.  
  24. /* local prototypes */
  25. static STRPTR GetPrefsVar( struct ClassBase *, STRPTR );
  26. static BOOL   matchstr( struct ClassBase *, STRPTR, STRPTR );
  27.  
  28. /*****************************************************************************/
  29.  
  30. /****** gifanim.datatype/preferences *****************************************
  31. *
  32. *   NAME
  33. *       preferences
  34. *
  35. *   DESCRIPTION
  36. *       The "ENV:Classes/DataTypes/gifanim.prefs" file contains global
  37. *       settings for the datatype.
  38. *       The preferences file is an ASCII file containing one line where the
  39. *       preferences can be set.
  40. *       It can be superset by a local variable with the same name.
  41. *
  42. *       Each line can contain settings, special settings for some projects
  43. *       can be set using the MATCHPROJECT option.
  44. *       Lines beginning with a '#' or ';' chars are treated as comments.
  45. *       Lines are limitted to 256 chars.
  46. *
  47. *   TEMPLATE
  48. *       MATCHPROJECT/K,VERBOSE/S,NOVERBOSE/S,STRICTSYNTAX/S,NOSTRICTSYNTAX/S,
  49. *       MODEID/K/N,16BITCHUNKY=24BITCHUNKY=TRUECOLOR/S,
  50. *       NO16BITCHUNKY=NO24BITCHUNKY=NOTRUECOLOR/S,FPS/K/N,
  51. *       SAMPLE/K,SAMPLESPERFRAME=SPF/K/N,VOLUME/K/N,LOADALL/S,
  52. *       NOLOADALL/S,ENC_INTERLACE/S,ENC_NO_INTERLACE/S,
  53. *       ENC_BACKGROUNDPEN=ENC_BG/K/N,ENC_TRANSPARENTPEN=ENC_TRANSPARENT/K/N
  54. *
  55. *       MATCHPROJECT -- The settings in this line belongs only to this
  56. *           project(s), e.g. if the case-insensitive pattern does not match,
  57. *           this line is ignored.
  58. *           The maximum length of the pattern is 128 chars.
  59. *           Defaults to #?, which matches any project.
  60. *
  61. *       VERBOSE -- Print information about the animation. Currently
  62. *          the frame numbers and the used compression are printed, after all
  63. *          number of scanned/loaded frames, set FPS rate, dimensions (width/
  64. *          height/depth), sample information etc.
  65. *
  66. *       NOVERBOSE -- Turns verbose output and error messages OFF.
  67. *          Be carefull, you won't see any error messages any more !!!
  68. *
  69. *       STRICTSYNTAX -- Prompt syntax errors in the gif streams.
  70. *
  71. *       NOSTRICTSYNTAX -- Turns STRICTSYNTAX off
  72. *
  73. *       MODEID -- Select screen mode id of datatype (will be stored in
  74. *           ADTA_ModeID). Note that the DOS ReadArgs function used for parsing
  75. *           fetches a SIGNED long. The bit 31 will be represented by minus
  76. *           '-'. (example: "MODEID=266240" sets the mode to the A2024 screen
  77. *           mode id)
  78. *           Defaults to -1, which means: Use the best screenmode available for
  79. *           the given width, height and depth.
  80. *
  81. *       16BITCHUNKY
  82. *       24BITCHUNKY
  83. *       TRUECOLOR -- Create 24 bit chunky bitmaps, if possible.
  84. *           Note that the 16BITCHUNKY and the 24BITCHUNKY options will be
  85. *           seperated in the future. The TRUECOLOR option selects the
  86. *           best truecolor depth in this case...
  87. *
  88. *       NO16BITCHUNKY
  89. *       NO24BITCHUNKY
  90. *       NOTRUECOLOR -- Turns 24BITCHUNKY option off. (Default)
  91. *           Note that the 16BITCHUNKY and the 24BITCHUNKY options will be
  92. *           seperated in the future. The TRUECOLOR option selects the
  93. *           best truecolor depth in this case...
  94. *
  95. *       FPS -- Frames Per Second
  96. *           A value of 0 here means: Use default FPS.
  97. *
  98. *       SAMPLE -- Attach the given sample to the animation. The sample will
  99. *           be loaded using datatypes (GID_SOUND).
  100. *           Only one sample can be attached to one animation stream, any
  101. *           following attempt to attach a sample will be ignored.
  102. *
  103. *       SAMPLESPERFRAME -- Set samples per frame rate for sound. This
  104. *           overrides the own internal calculations to get rid of rounding
  105. *           errors.
  106. *
  107. *       VOLUME -- Volume of the sound when playing.
  108. *           Defaults to 64, which is the maximum. A value greater than 64 will
  109. *           be set to 64.
  110. *
  111. *       LOADALL -- Load all frames into memory.
  112. *
  113. *       NOLOADALL -- Turns off the LOADALL flag, which may be set in a prefs-
  114. *           line before. This switch is set per default, and can be turned off
  115. *           by the LOADALL option, later it can be turned on again by this
  116. *           option.
  117. *
  118. *       Encoder related options:
  119. *       ENC_INTERLACE    - create interlaced gif animation
  120. *
  121. *       ENC_NO_INTERLACE - create non-interlaced gif animation 
  122. *           (set per default).
  123. *
  124. *       ENC_BACKGROUNDPEN
  125. *       ENC_BG           - background pen number
  126. *           Defaults to 0 (e.g. default bg pen)
  127. *
  128. *       ENC_TRANSPARENTPEN
  129. *       ENC_TRANSPARENT - transparent pen number
  130. *           Defaults to -1 (means: no transparent pen).
  131. *
  132. *
  133. *   NOTE
  134. *       - An invalid prefs file line will be ignored and forces the VERBOSE
  135. *         output.
  136. *
  137. *   BUGS
  138. *       - Low memory may cause that the prefs file won't be parsed.
  139. *
  140. *       - Lines are limitted to 256 chars
  141. *
  142. *       - An invalid prefs file line will be ignored.
  143. *
  144. *       - The sample path length is limitted to 200 chars. A larger
  145. *         value may crash the machine if an error occurs.
  146. *
  147. ******************************************************************************
  148. *
  149. */
  150.  
  151.  
  152. static
  153. STRPTR GetPrefsVar( struct ClassBase *cb, STRPTR name )
  154. {
  155.           STRPTR buff;
  156.     const ULONG  buffsize = 16UL;
  157.  
  158.     if( buff = (STRPTR)AllocVec( (buffsize + 2UL), (MEMF_PUBLIC | MEMF_CLEAR) ) )
  159.     {
  160.       if( GetVar( name, buff, buffsize, GVF_BINARY_VAR ) != (-1L) )
  161.       {
  162.         ULONG varsize = IoErr();
  163.  
  164.         varsize += 2UL;
  165.  
  166.         if( varsize > buffsize )
  167.         {
  168.           FreeVec( buff );
  169.  
  170.           if( buff = (STRPTR)AllocVec( (varsize + 2UL), (MEMF_PUBLIC | MEMF_CLEAR) ) )
  171.           {
  172.             if( GetVar( name, buff, varsize, GVF_BINARY_VAR ) != (-1L) )
  173.             {
  174.               return( buff );
  175.             }
  176.           }
  177.         }
  178.         else
  179.         {
  180.           return( buff );
  181.         }
  182.       }
  183.  
  184.       FreeVec( buff );
  185.     }
  186.  
  187.     return( NULL );
  188. }
  189.  
  190.  
  191. static
  192. BOOL matchstr( struct ClassBase *cb, STRPTR pat, STRPTR s )
  193. {
  194.     TEXT buff[ 512 ];
  195.  
  196.     if( pat && s )
  197.     {
  198.       if( ParsePatternNoCase( pat, buff, (sizeof( buff ) - 1) ) != (-1L) )
  199.       {
  200.         if( MatchPatternNoCase( buff, s ) )
  201.         {
  202.           return( TRUE );
  203.         }
  204.       }
  205.     }
  206.  
  207.     return( FALSE );
  208. }
  209.  
  210.  
  211. void ReadENVPrefs( struct ClassBase *cb, struct GIFAnimInstData *gaid, struct GIFEncoder *genc )
  212. {
  213.     struct RDArgs envvarrda =
  214.     {
  215.       NULL,
  216.       256L,
  217.       0L,
  218.       0L,
  219.       NULL,
  220.       0L,
  221.       NULL,
  222.       RDAF_NOPROMPT
  223.     };
  224.  
  225.     struct
  226.     {
  227.       STRPTR  matchproject;
  228.       long   *verbose;
  229.       long   *noverbose;
  230.       long   *strictsyntax;
  231.       long   *nostrictsyntax;
  232.       long   *modeid;
  233.       long   *use24bitchunky;
  234.       long   *nouse24bitchunky;
  235.       long   *fps;
  236.       STRPTR  sample;
  237.       long   *samplesperframe;
  238.       long   *volume;
  239.       long   *loadall;
  240.       long   *noloadall;
  241.       long   *enc_interlace;
  242.       long   *enc_no_interlace;
  243.       long   *enc_backgroundpen;
  244.       long   *enc_transparentpen;
  245.     } gifanimargs;
  246.  
  247.     TEXT   varbuff[ 258 ];
  248.     STRPTR var;
  249.  
  250.     if( var = GetPrefsVar( cb, "Classes/DataTypes/gifanim.prefs" ) )
  251.     {
  252.       STRPTR prefsline      = var,
  253.              nextprefsline;
  254.       ULONG  linecount      = 1UL;
  255.  
  256.       /* Be sure that "var" contains at least one break-char */
  257.       strcat( var, "\n" );
  258.  
  259.       while( nextprefsline = strpbrk( prefsline, "\n" ) )
  260.       {
  261.         stccpy( varbuff, prefsline, (int)MIN( (sizeof( varbuff ) - 2UL), (((ULONG)(nextprefsline - prefsline)) + 1UL) ) );
  262.  
  263.         /* be sure that this line isn't a comment line or an empty line */
  264.         if( (varbuff[ 0 ] != '#') && (varbuff[ 0 ] != ';') && (varbuff[ 0 ] != '\n') && (strlen( varbuff ) > 2UL) )
  265.         {
  266.           /* Prepare ReadArgs processing */
  267.           strcat( varbuff, "\n" );                                       /* Add NEWLINE-char            */
  268.           envvarrda . RDA_Source . CS_Buffer = varbuff;                  /* Buffer                      */
  269.           envvarrda . RDA_Source . CS_Length = strlen( varbuff ) + 1UL;  /* Set up input buffer length  */
  270.           envvarrda . RDA_Source . CS_CurChr = 0L;
  271.           envvarrda . RDA_Buffer = NULL;
  272.           envvarrda . RDA_BufSiz = 0L;
  273.           memset( (void *)(&gifanimargs), 0, sizeof( gifanimargs ) );          /* Clear result array          */
  274.  
  275.           if( ReadArgs( "MATCHPROJECT/K,"
  276.                         "VERBOSE/S,"
  277.                         "NOVERBOSE/S,"
  278.                         "STRICTSYNTAX/S,"
  279.                         "NOSTRICTSYNTAX/S,"
  280.                         "MODEID/K/N,"
  281.                         "16BITCHUNKY=24BITCHUNKY=TRUECOLOR/S,"
  282.                         "NO16BITCHUNKY=NO24BITCHUNKY=NOTRUECOLOR/S,"
  283.                         "FPS/K/N,"
  284.                         "SAMPLE/K,"
  285.                         "SAMPLESPERFRAME=SPF/K/N,"
  286.                         "VOLUME/K/N,"
  287.                         "LOADALL/S,"
  288.                         "NOLOADALL/S,"
  289.                         "ENC_INTERLACE/S,"
  290.                         "ENC_NO_INTERLACE/S,"
  291.                         "ENC_BACKGROUNDPEN=ENC_BG/K/N,"
  292.                         "ENC_TRANSPARENTPEN=ENC_TRANSPARENT/K/N", (LONG *)(&gifanimargs), (&envvarrda) ) )
  293.           {
  294.             BOOL noignore = TRUE;
  295.  
  296.             if( (gifanimargs . matchproject) && (gaid -> gaid_ProjectName) )
  297.             {
  298.               noignore = matchstr( cb, (gifanimargs . matchproject), (gaid -> gaid_ProjectName) );
  299.             }
  300.  
  301.             if( noignore )
  302.             {
  303.               /* Read encoder prefs ? */
  304.               if( genc )
  305.               {
  306.                 if( gifanimargs . enc_interlace )
  307.                 {
  308.                   genc -> interlace = TRUE;
  309.                 }
  310.  
  311.                 if( gifanimargs . enc_no_interlace )
  312.                 {
  313.                   genc -> interlace = FALSE;
  314.                 }
  315.  
  316.                 if( gifanimargs . enc_backgroundpen )
  317.                 {
  318.                   genc -> backgroundpen = (WORD)(*(gifanimargs . enc_backgroundpen));
  319.                 }
  320.  
  321.                 if( gifanimargs . enc_transparentpen )
  322.                 {
  323.                   genc -> transparentpen = (WORD)(*(gifanimargs . enc_transparentpen));
  324.                 }
  325.               }
  326.               else
  327.               {
  328.                 if( gifanimargs . verbose )
  329.                 {
  330.                   OpenLogfile( cb, gaid );
  331.                 }
  332.  
  333.                 if( gifanimargs . noverbose )
  334.                 {
  335.                   if( (gaid -> gaid_VerboseOutput) && ((gaid -> gaid_VerboseOutput) != -1L) )
  336.                   {
  337.                     Close( (gaid -> gaid_VerboseOutput) );
  338.                   }
  339.  
  340.                   gaid -> gaid_VerboseOutput = -1L;
  341.                 }
  342.  
  343.                 if( gifanimargs . strictsyntax )
  344.                 {
  345.                   gaid -> gaid_StrictSyntax = TRUE;
  346.                 }
  347.  
  348.                 if( gifanimargs . nostrictsyntax )
  349.                 {
  350.                   gaid -> gaid_StrictSyntax = FALSE;
  351.                 }
  352.  
  353.                 if( gifanimargs . modeid )
  354.                 {
  355.                   gaid -> gaid_ModeID = *(gifanimargs . modeid);
  356.                 }
  357.  
  358.                 if( gifanimargs . use24bitchunky )
  359.                 {
  360.                   /* Check if we have animation.datatype V41 (or higher) as superclass */
  361.                   if( (cb -> cb_SuperClassBase -> lib_Version) >= 41U )
  362.                   {
  363.                     /* Check here if we opened the cybergraphics.library. After this point, I'll assume
  364.                      * that (gaid_UseChunkyMap == TRUE) implies a opened CyberGfxBase !!
  365.                      */
  366.                     if( CyberGfxBase )
  367.                     {
  368.                       gaid -> gaid_UseChunkyMap = TRUE;
  369.                     }
  370.                     else
  371.                     {
  372.                       error_printf( cb, gaid, "no cybergraphics.library available, can't output a 24 bit chunky map\n" );
  373.                     }
  374.                   }
  375.                   else
  376.                   {
  377.                     error_printf( cb, gaid, "Requires at least animation.datatype V41 for non-planar bitmap support\n" );
  378.                   }
  379.                 }
  380.  
  381.                 if( gifanimargs . nouse24bitchunky )
  382.                 {
  383.                   gaid -> gaid_UseChunkyMap = FALSE;
  384.                 }
  385.  
  386.                 if( gifanimargs . fps )
  387.                 {
  388.                   gaid -> gaid_FPS = *(gifanimargs . fps);
  389.                 }
  390.  
  391.                 if( gifanimargs . loadall )
  392.                 {
  393.                   gaid -> gaid_LoadAll = TRUE;
  394.                 }
  395.  
  396.                 if( gifanimargs . noloadall )
  397.                 {
  398.                   gaid -> gaid_LoadAll = FALSE;
  399.                 }
  400.  
  401.                 if( (gifanimargs . sample) && ((gaid -> gaid_Sample) == NULL) )
  402.                 {
  403.                   Object *so;
  404.                   LONG    ioerr = 0L;
  405.  
  406.                   verbose_printf( cb, gaid, "loading sample \"%s\"...\n", (gifanimargs . sample) );
  407.  
  408.                   if( so = NewDTObject( (gifanimargs . sample), DTA_GroupID, GID_SOUND, TAG_DONE ) )
  409.                   {
  410.                     BYTE  *sample;
  411.                     ULONG  length;
  412.                     ULONG  period;
  413.  
  414.                     /* Get sample data from object */
  415.                     if( GetDTAttrs( so, SDTA_Sample,       (&sample),
  416.                                         SDTA_SampleLength, (&length),
  417.                                         SDTA_Period,       (&period),
  418.                                         TAG_DONE ) == 3UL )
  419.                     {
  420.                       if( gaid -> gaid_Sample = (STRPTR)AllocPooled( (gaid -> gaid_Pool), (length + 1UL) ) )
  421.                       {
  422.                         /* Copy sample and context */
  423.                         CopyMem( (APTR)sample, (APTR)(gaid -> gaid_Sample), length );
  424.                         gaid -> gaid_SampleLength = length;
  425.                         gaid -> gaid_Period       = period;
  426.                       }
  427.                       else
  428.                       {
  429.                         /* Can't alloc sample */
  430.                         ioerr = ERROR_NO_FREE_STORE;
  431.                       }
  432.                     }
  433.                     else
  434.                     {
  435.                       /* Object does not support the requested attributes */
  436.                       ioerr = ERROR_OBJECT_WRONG_TYPE;
  437.                     }
  438.  
  439.                     DisposeDTObject( so );
  440.                   }
  441.                   else
  442.                   {
  443.                     /* NewDTObjectA failed, cannot load sample... */
  444.                     ioerr = IoErr();
  445.                   }
  446.  
  447.                   if( (gaid -> gaid_Sample) == NULL )
  448.                   {
  449.                     TEXT errbuff[ 256 ];
  450.  
  451.                     if( ioerr >= DTERROR_UNKNOWN_DATATYPE )
  452.                     {
  453.                       mysprintf( cb, errbuff, GetDTString( ioerr ), (gifanimargs . sample) );
  454.                     }
  455.                     else
  456.                     {
  457.                       Fault( ioerr, (gifanimargs . sample), errbuff, sizeof( errbuff ) );
  458.                     }
  459.  
  460.                     error_printf( cb, gaid, "can't load sample: \"%s\" line %lu\n", errbuff, linecount );
  461.                   }
  462.                 }
  463.  
  464.                 if( gifanimargs . samplesperframe )
  465.                 {
  466.                   gaid -> gaid_SamplesPerFrame = *(gifanimargs . samplesperframe);
  467.                 }
  468.  
  469.                 if( gifanimargs . volume )
  470.                 {
  471.                   gaid -> gaid_Volume = *(gifanimargs . volume);
  472.  
  473.                   if( (gaid -> gaid_Volume) > 64UL )
  474.                   {
  475.                     gaid -> gaid_Volume = 64UL;
  476.                   }
  477.                 }
  478.               }
  479.             }
  480.             else
  481.             {
  482.               verbose_printf( cb, gaid, "prefs line %lu ignored\n", linecount );
  483.             }
  484.  
  485.             FreeArgs( (&envvarrda) );
  486.           }
  487.           else
  488.           {
  489.             LONG ioerr = IoErr();
  490.             TEXT errbuff[ 256 ];
  491.  
  492.             Fault( ioerr, "Classes/DataTypes/gifanim.prefs", errbuff, (LONG)sizeof( errbuff ) );
  493.  
  494.             error_printf( cb, gaid, "preferences \"%s\" line %lu\n", errbuff, linecount );
  495.           }
  496.         }
  497.  
  498.         prefsline = ++nextprefsline;
  499.         linecount++;
  500.       }
  501.  
  502.       FreeVec( var );
  503.     }
  504. }
  505.  
  506.  
  507.  
  508.  
  509.