Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Avisynth C Interface Version 0.20
  2. // Copyright 2003 Kevin Atkinson
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
  17. // http://www.gnu.org/copyleft/gpl.html .
  18. //
  19. // As a special exception, I give you permission to link to the
  20. // Avisynth C interface with independent modules that communicate with
  21. // the Avisynth C interface solely through the interfaces defined in
  22. // avisynth_c.h, regardless of the license terms of these independent
  23. // modules, and to copy and distribute the resulting combined work
  24. // under terms of your choice, provided that every copy of the
  25. // combined work is accompanied by a complete copy of the source code
  26. // of the Avisynth C interface and Avisynth itself (with the version
  27. // used to produce the combined work), being distributed under the
  28. // terms of the GNU General Public License plus this exception.  An
  29. // independent module is a module which is not derived from or based
  30. // on Avisynth C Interface, such as 3rd-party filters, import and
  31. // export plugins, or graphical user interfaces.
  32.  
  33. // NOTE: this is a partial update of the Avisynth C interface to recognize
  34. // new color spaces added in Avisynth 2.60. By no means is this document
  35. // completely Avisynth 2.60 compliant.
  36.  
  37. #ifndef __AVISYNTH_C__
  38. #define __AVISYNTH_C__
  39.  
  40. #ifdef __cplusplus
  41. #  define EXTERN_C extern "C"
  42. #else
  43. #  define EXTERN_C
  44. #endif
  45.  
  46. #define AVSC_USE_STDCALL 1
  47.  
  48. #ifndef AVSC_USE_STDCALL
  49. #  define AVSC_CC __cdecl
  50. #else
  51. #  define AVSC_CC __stdcall
  52. #endif
  53.  
  54. #define AVSC_INLINE static __inline
  55.  
  56. #ifdef AVISYNTH_C_EXPORTS
  57. #  define AVSC_EXPORT EXTERN_C
  58. #  define AVSC_API(ret, name) EXTERN_C __declspec(dllexport) ret AVSC_CC name
  59. #else
  60. #  define AVSC_EXPORT EXTERN_C __declspec(dllexport)
  61. #  ifndef AVSC_NO_DECLSPEC
  62. #    define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name
  63. #  else
  64. #    define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func)
  65. #  endif
  66. #endif
  67.  
  68. typedef unsigned char BYTE;
  69. #ifdef __GNUC__
  70. typedef long long int INT64;
  71. #else
  72. typedef __int64 INT64;
  73. #endif
  74.  
  75.  
  76. /////////////////////////////////////////////////////////////////////
  77. //
  78. // Constants
  79. //
  80.  
  81. #ifndef __AVISYNTH_H__
  82. enum { AVISYNTH_INTERFACE_VERSION = 4 };
  83. #endif
  84.  
  85. enum {AVS_SAMPLE_INT8  = 1<<0,
  86.       AVS_SAMPLE_INT16 = 1<<1,
  87.       AVS_SAMPLE_INT24 = 1<<2,
  88.       AVS_SAMPLE_INT32 = 1<<3,
  89.       AVS_SAMPLE_FLOAT = 1<<4};
  90.  
  91. enum {AVS_PLANAR_Y=1<<0,
  92.       AVS_PLANAR_U=1<<1,
  93.       AVS_PLANAR_V=1<<2,
  94.       AVS_PLANAR_ALIGNED=1<<3,
  95.       AVS_PLANAR_Y_ALIGNED=AVS_PLANAR_Y|AVS_PLANAR_ALIGNED,
  96.       AVS_PLANAR_U_ALIGNED=AVS_PLANAR_U|AVS_PLANAR_ALIGNED,
  97.       AVS_PLANAR_V_ALIGNED=AVS_PLANAR_V|AVS_PLANAR_ALIGNED,
  98.       AVS_PLANAR_A=1<<4,
  99.       AVS_PLANAR_R=1<<5,
  100.       AVS_PLANAR_G=1<<6,
  101.       AVS_PLANAR_B=1<<7,
  102.       AVS_PLANAR_A_ALIGNED=AVS_PLANAR_A|AVS_PLANAR_ALIGNED,
  103.       AVS_PLANAR_R_ALIGNED=AVS_PLANAR_R|AVS_PLANAR_ALIGNED,
  104.       AVS_PLANAR_G_ALIGNED=AVS_PLANAR_G|AVS_PLANAR_ALIGNED,
  105.       AVS_PLANAR_B_ALIGNED=AVS_PLANAR_B|AVS_PLANAR_ALIGNED};
  106.  
  107.   // Colorspace properties.
  108. enum {AVS_CS_BGR = 1<<28,
  109.       AVS_CS_YUV = 1<<29,
  110.       AVS_CS_INTERLEAVED = 1<<30,
  111.       AVS_CS_PLANAR = 1<<31,
  112.  
  113.       AVS_CS_SHIFT_SUB_WIDTH   = 0,
  114.       AVS_CS_SHIFT_SUB_HEIGHT  = 1 << 3,
  115.       AVS_CS_SHIFT_SAMPLE_BITS = 1 << 4,
  116.  
  117.       AVS_CS_SUB_WIDTH_MASK    = 7 << AVS_CS_SHIFT_SUB_WIDTH,
  118.       AVS_CS_SUB_WIDTH_1       = 3 << AVS_CS_SHIFT_SUB_WIDTH, // YV24
  119.       AVS_CS_SUB_WIDTH_2       = 0 << AVS_CS_SHIFT_SUB_WIDTH, // YV12, I420, YV16
  120.       AVS_CS_SUB_WIDTH_4       = 1 << AVS_CS_SHIFT_SUB_WIDTH, // YUV9, YV411
  121.  
  122.       AVS_CS_VPLANEFIRST       = 1 << 3, // YV12, YV16, YV24, YV411, YUV9
  123.       AVS_CS_UPLANEFIRST       = 1 << 4, // I420
  124.  
  125.       AVS_CS_SUB_HEIGHT_MASK   = 7 << AVS_CS_SHIFT_SUB_HEIGHT,
  126.       AVS_CS_SUB_HEIGHT_1      = 3 << AVS_CS_SHIFT_SUB_HEIGHT, // YV16, YV24, YV411
  127.       AVS_CS_SUB_HEIGHT_2      = 0 << AVS_CS_SHIFT_SUB_HEIGHT, // YV12, I420
  128.       AVS_CS_SUB_HEIGHT_4      = 1 << AVS_CS_SHIFT_SUB_HEIGHT, // YUV9
  129.  
  130.       AVS_CS_SAMPLE_BITS_MASK  = 7 << AVS_CS_SHIFT_SAMPLE_BITS,
  131.       AVS_CS_SAMPLE_BITS_8     = 0 << AVS_CS_SHIFT_SAMPLE_BITS,
  132.       AVS_CS_SAMPLE_BITS_16    = 1 << AVS_CS_SHIFT_SAMPLE_BITS,
  133.       AVS_CS_SAMPLE_BITS_32    = 2 << AVS_CS_SHIFT_SAMPLE_BITS,
  134.  
  135.       AVS_CS_PLANAR_MASK       = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV | AVS_CS_BGR | AVS_CS_SAMPLE_BITS_MASK | AVS_CS_SUB_HEIGHT_MASK | AVS_CS_SUB_WIDTH_MASK,
  136.       AVS_CS_PLANAR_FILTER     = ~( AVS_CS_VPLANEFIRST | AVS_CS_UPLANEFIRST )};
  137.  
  138.   // Specific colorformats
  139. enum {
  140.   AVS_CS_UNKNOWN = 0,
  141.   AVS_CS_BGR24 = 1<<0 | AVS_CS_BGR | AVS_CS_INTERLEAVED,
  142.   AVS_CS_BGR32 = 1<<1 | AVS_CS_BGR | AVS_CS_INTERLEAVED,
  143.   AVS_CS_YUY2 = 1<<2 | AVS_CS_YUV | AVS_CS_INTERLEAVED,
  144.   //  AVS_CS_YV12  = 1<<3  Reserved
  145.   //  AVS_CS_I420  = 1<<4  Reserved
  146.   AVS_CS_RAW32 = 1<<5 | AVS_CS_INTERLEAVED,
  147.  
  148.   AVS_CS_YV24  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_1,  // YVU 4:4:4 planar
  149.   AVS_CS_YV16  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_2,  // YVU 4:2:2 planar
  150.   AVS_CS_YV12  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2,  // YVU 4:2:0 planar
  151.   AVS_CS_I420  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_UPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2,  // YUV 4:2:0 planar
  152.   AVS_CS_IYUV  = AVS_CS_I420,
  153.   AVS_CS_YV411 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_4,  // YVU 4:1:1 planar
  154.   AVS_CS_YUV9  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_4 | AVS_CS_SUB_WIDTH_4,  // YVU 4:1:0 planar
  155.   AVS_CS_Y8    = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8                                              // Y   4:0:0 planar
  156. };
  157.  
  158. enum {
  159.   AVS_IT_BFF = 1<<0,
  160.   AVS_IT_TFF = 1<<1,
  161.   AVS_IT_FIELDBASED = 1<<2};
  162.  
  163. enum {
  164.   AVS_FILTER_TYPE=1,
  165.   AVS_FILTER_INPUT_COLORSPACE=2,
  166.   AVS_FILTER_OUTPUT_TYPE=9,
  167.   AVS_FILTER_NAME=4,
  168.   AVS_FILTER_AUTHOR=5,
  169.   AVS_FILTER_VERSION=6,
  170.   AVS_FILTER_ARGS=7,
  171.   AVS_FILTER_ARGS_INFO=8,
  172.   AVS_FILTER_ARGS_DESCRIPTION=10,
  173.   AVS_FILTER_DESCRIPTION=11};
  174.  
  175. enum {  //SUBTYPES
  176.   AVS_FILTER_TYPE_AUDIO=1,
  177.   AVS_FILTER_TYPE_VIDEO=2,
  178.   AVS_FILTER_OUTPUT_TYPE_SAME=3,
  179.   AVS_FILTER_OUTPUT_TYPE_DIFFERENT=4};
  180.  
  181. enum {
  182.   AVS_CACHE_NOTHING=0,
  183.   AVS_CACHE_RANGE=1,
  184.   AVS_CACHE_ALL=2,
  185.   AVS_CACHE_AUDIO=3,
  186.   AVS_CACHE_AUDIO_NONE=4,
  187.   AVS_CACHE_AUDIO_AUTO=5
  188.   };
  189.  
  190. #define AVS_FRAME_ALIGN 16
  191.  
  192. typedef struct AVS_Clip AVS_Clip;
  193. typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment;
  194.  
  195. /////////////////////////////////////////////////////////////////////
  196. //
  197. // AVS_VideoInfo
  198. //
  199.  
  200. // AVS_VideoInfo is layed out identicly to VideoInfo
  201. typedef struct AVS_VideoInfo {
  202.   int width, height;    // width=0 means no video
  203.   unsigned fps_numerator, fps_denominator;
  204.   int num_frames;
  205.  
  206.   int pixel_type;
  207.  
  208.   int audio_samples_per_second;   // 0 means no audio
  209.   int sample_type;
  210.   INT64 num_audio_samples;
  211.   int nchannels;
  212.  
  213.   // Imagetype properties
  214.  
  215.   int image_type;
  216. } AVS_VideoInfo;
  217.  
  218. // useful functions of the above
  219. AVSC_INLINE int avs_has_video(const AVS_VideoInfo * p)
  220.         { return (p->width!=0); }
  221.  
  222. AVSC_INLINE int avs_has_audio(const AVS_VideoInfo * p)
  223.         { return (p->audio_samples_per_second!=0); }
  224.  
  225. AVSC_INLINE int avs_is_rgb(const AVS_VideoInfo * p)
  226.         { return !!(p->pixel_type&AVS_CS_BGR); }
  227.  
  228. AVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p)
  229.         { return (p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24; } // Clear out additional properties
  230.  
  231. AVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p)
  232.         { return (p->pixel_type & AVS_CS_BGR32) == AVS_CS_BGR32 ; }
  233.  
  234. AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p)
  235.         { return !!(p->pixel_type&AVS_CS_YUV ); }
  236.  
  237. AVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p)
  238.         { return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; }
  239.  
  240. AVSC_INLINE int avs_is_yv24(const AVS_VideoInfo * p)
  241.         { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV24  & AVS_CS_PLANAR_FILTER); }
  242.  
  243. AVSC_INLINE int avs_is_yv16(const AVS_VideoInfo * p)
  244.         { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV16  & AVS_CS_PLANAR_FILTER); }
  245.  
  246. AVSC_INLINE int avs_is_yv12(const AVS_VideoInfo * p)
  247.         { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV12  & AVS_CS_PLANAR_FILTER); }
  248.  
  249. AVSC_INLINE int avs_is_yv411(const AVS_VideoInfo * p)
  250.         { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV411 & AVS_CS_PLANAR_FILTER); }
  251.  
  252. AVSC_INLINE int avs_is_y8(const AVS_VideoInfo * p)
  253.         { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_Y8    & AVS_CS_PLANAR_FILTER); }
  254.  
  255. AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property)
  256.         { return ((p->pixel_type & property)==property ); }
  257.  
  258. AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p)
  259.         { return !!(p->pixel_type & AVS_CS_PLANAR); }
  260.  
  261. AVSC_INLINE int avs_is_color_space(const AVS_VideoInfo * p, int c_space)
  262.         { return avs_is_planar(p) ? ((p->pixel_type & AVS_CS_PLANAR_MASK) == (c_space & AVS_CS_PLANAR_FILTER)) : ((p->pixel_type & c_space) == c_space); }
  263.  
  264. AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p)
  265.         { return !!(p->image_type & AVS_IT_FIELDBASED); }
  266.  
  267. AVSC_INLINE int avs_is_parity_known(const AVS_VideoInfo * p)
  268.         { return ((p->image_type & AVS_IT_FIELDBASED)&&(p->image_type & (AVS_IT_BFF | AVS_IT_TFF))); }
  269.  
  270. AVSC_INLINE int avs_is_bff(const AVS_VideoInfo * p)
  271.         { return !!(p->image_type & AVS_IT_BFF); }
  272.  
  273. AVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p)
  274.         { return !!(p->image_type & AVS_IT_TFF); }
  275.  
  276. AVSC_INLINE int avs_bits_per_pixel(const AVS_VideoInfo * p)
  277. {
  278.   switch (p->pixel_type) {
  279.       case AVS_CS_BGR24: return 24;
  280.       case AVS_CS_BGR32: return 32;
  281.       case AVS_CS_YUY2:  return 16;
  282.       case AVS_CS_YV12:
  283.       case AVS_CS_I420:  return 12;
  284.       default:           return 0;
  285.     }
  286. }
  287. AVSC_INLINE int avs_bytes_from_pixels(const AVS_VideoInfo * p, int pixels)
  288.         { return pixels * (avs_bits_per_pixel(p)>>3); }   // Will work on planar images, but will return only luma planes
  289.  
  290. AVSC_INLINE int avs_row_size(const AVS_VideoInfo * p)
  291.         { return avs_bytes_from_pixels(p,p->width); }  // Also only returns first plane on planar images
  292.  
  293. AVSC_INLINE int avs_bmp_size(const AVS_VideoInfo * vi)
  294.         { if (avs_is_planar(vi)) {int p = vi->height * ((avs_row_size(vi)+3) & ~3); p+=p>>1; return p;  } return vi->height * ((avs_row_size(vi)+3) & ~3); }
  295.  
  296. AVSC_INLINE int avs_samples_per_second(const AVS_VideoInfo * p)
  297.         { return p->audio_samples_per_second; }
  298.  
  299.  
  300. AVSC_INLINE int avs_bytes_per_channel_sample(const AVS_VideoInfo * p)
  301. {
  302.     switch (p->sample_type) {
  303.       case AVS_SAMPLE_INT8:  return sizeof(signed char);
  304.       case AVS_SAMPLE_INT16: return sizeof(signed short);
  305.       case AVS_SAMPLE_INT24: return 3;
  306.       case AVS_SAMPLE_INT32: return sizeof(signed int);
  307.       case AVS_SAMPLE_FLOAT: return sizeof(float);
  308.       default: return 0;
  309.     }
  310. }
  311. AVSC_INLINE int avs_bytes_per_audio_sample(const AVS_VideoInfo * p)
  312.         { return p->nchannels*avs_bytes_per_channel_sample(p);}
  313.  
  314. AVSC_INLINE INT64 avs_audio_samples_from_frames(const AVS_VideoInfo * p, INT64 frames)
  315.         { return ((INT64)(frames) * p->audio_samples_per_second * p->fps_denominator / p->fps_numerator); }
  316.  
  317. AVSC_INLINE int avs_frames_from_audio_samples(const AVS_VideoInfo * p, INT64 samples)
  318.         { return (int)(samples * (INT64)p->fps_numerator / (INT64)p->fps_denominator / (INT64)p->audio_samples_per_second); }
  319.  
  320. AVSC_INLINE INT64 avs_audio_samples_from_bytes(const AVS_VideoInfo * p, INT64 bytes)
  321.         { return bytes / avs_bytes_per_audio_sample(p); }
  322.  
  323. AVSC_INLINE INT64 avs_bytes_from_audio_samples(const AVS_VideoInfo * p, INT64 samples)
  324.         { return samples * avs_bytes_per_audio_sample(p); }
  325.  
  326. AVSC_INLINE int avs_audio_channels(const AVS_VideoInfo * p)
  327.         { return p->nchannels; }
  328.  
  329. AVSC_INLINE int avs_sample_type(const AVS_VideoInfo * p)
  330.         { return p->sample_type;}
  331.  
  332. // useful mutator
  333. AVSC_INLINE void avs_set_property(AVS_VideoInfo * p, int property)
  334.         { p->image_type|=property; }
  335.  
  336. AVSC_INLINE void avs_clear_property(AVS_VideoInfo * p, int property)
  337.         { p->image_type&=~property; }
  338.  
  339. AVSC_INLINE void avs_set_field_based(AVS_VideoInfo * p, int isfieldbased)
  340.         { if (isfieldbased) p->image_type|=AVS_IT_FIELDBASED; else p->image_type&=~AVS_IT_FIELDBASED; }
  341.  
  342. AVSC_INLINE void avs_set_fps(AVS_VideoInfo * p, unsigned numerator, unsigned denominator)
  343. {
  344.     unsigned x=numerator, y=denominator;
  345.     while (y) {   // find gcd
  346.       unsigned t = x%y; x = y; y = t;
  347.     }
  348.     p->fps_numerator = numerator/x;
  349.     p->fps_denominator = denominator/x;
  350. }
  351.  
  352. AVSC_INLINE int avs_is_same_colorspace(AVS_VideoInfo * x, AVS_VideoInfo * y)
  353. {
  354.         return (x->pixel_type == y->pixel_type)
  355.                 || (avs_is_yv12(x) && avs_is_yv12(y));
  356. }
  357.  
  358. /////////////////////////////////////////////////////////////////////
  359. //
  360. // AVS_VideoFrame
  361. //
  362.  
  363. // VideoFrameBuffer holds information about a memory block which is used
  364. // for video data.  For efficiency, instances of this class are not deleted
  365. // when the refcount reaches zero; instead they're stored in a linked list
  366. // to be reused.  The instances are deleted when the corresponding AVS
  367. // file is closed.
  368.  
  369. // AVS_VideoFrameBuffer is layed out identicly to VideoFrameBuffer
  370. // DO NOT USE THIS STRUCTURE DIRECTLY
  371. typedef struct AVS_VideoFrameBuffer {
  372.   BYTE * data;
  373.   int data_size;
  374.   // sequence_number is incremented every time the buffer is changed, so
  375.   // that stale views can tell they're no longer valid.
  376.   volatile long sequence_number;
  377.  
  378.   volatile long refcount;
  379. } AVS_VideoFrameBuffer;
  380.  
  381. // VideoFrame holds a "window" into a VideoFrameBuffer.
  382.  
  383. // AVS_VideoFrame is layed out identicly to IVideoFrame
  384. // DO NOT USE THIS STRUCTURE DIRECTLY
  385. typedef struct AVS_VideoFrame {
  386.   volatile long refcount;
  387.   AVS_VideoFrameBuffer * vfb;
  388.   int offset, pitch, row_size, height, offsetU, offsetV, pitchUV;  // U&V offsets are from top of picture.
  389.   int row_sizeUV, heightUV;
  390. } AVS_VideoFrame;
  391.  
  392. // Access functions for AVS_VideoFrame
  393. AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) {
  394.         return p->pitch;}
  395.  
  396. AVSC_INLINE int avs_get_pitch_p(const AVS_VideoFrame * p, int plane) {
  397.   switch (plane) {
  398.   case AVS_PLANAR_U: case AVS_PLANAR_V: return p->pitchUV;}
  399.   return p->pitch;}
  400.  
  401. AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) {
  402.         return p->row_size; }
  403.  
  404. AVSC_INLINE int avs_get_row_size_p(const AVS_VideoFrame * p, int plane) {
  405.         int r;
  406.     switch (plane) {
  407.     case AVS_PLANAR_U: case AVS_PLANAR_V:
  408.                 if (p->pitchUV) return p->row_sizeUV;
  409.                 else            return 0;
  410.     case AVS_PLANAR_U_ALIGNED: case AVS_PLANAR_V_ALIGNED:
  411.                 if (p->pitchUV) {
  412.                         r = (p->row_sizeUV+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize
  413.                         if (r < p->pitchUV)
  414.                                 return r;
  415.                         return p->row_sizeUV;
  416.                 } else return 0;
  417.     case AVS_PLANAR_Y_ALIGNED:
  418.                 r = (p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize
  419.                 if (r <= p->pitch)
  420.                         return r;
  421.                 return p->row_size;
  422.     }
  423.     return p->row_size;
  424. }
  425.  
  426. AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) {
  427.         return p->height;}
  428.  
  429. AVSC_INLINE int avs_get_height_p(const AVS_VideoFrame * p, int plane) {
  430.         switch (plane) {
  431.                 case AVS_PLANAR_U: case AVS_PLANAR_V:
  432.                         if (p->pitchUV) return p->heightUV;
  433.                         return 0;
  434.         }
  435.         return p->height;}
  436.  
  437. AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) {
  438.         return p->vfb->data + p->offset;}
  439.  
  440. AVSC_INLINE const BYTE* avs_get_read_ptr_p(const AVS_VideoFrame * p, int plane)
  441. {
  442.         switch (plane) {
  443.                 case AVS_PLANAR_U: return p->vfb->data + p->offsetU;
  444.                 case AVS_PLANAR_V: return p->vfb->data + p->offsetV;
  445.                 default:           return p->vfb->data + p->offset;}
  446. }
  447.  
  448. AVSC_INLINE int avs_is_writable(const AVS_VideoFrame * p) {
  449.         return (p->refcount == 1 && p->vfb->refcount == 1);}
  450.  
  451. AVSC_INLINE BYTE* avs_get_write_ptr(const AVS_VideoFrame * p)
  452. {
  453.         if (avs_is_writable(p)) {
  454.                 ++p->vfb->sequence_number;
  455.                 return p->vfb->data + p->offset;
  456.         } else
  457.                 return 0;
  458. }
  459.  
  460. AVSC_INLINE BYTE* avs_get_write_ptr_p(const AVS_VideoFrame * p, int plane)
  461. {
  462.         if (plane==AVS_PLANAR_Y && avs_is_writable(p)) {
  463.                 ++p->vfb->sequence_number;
  464.                 return p->vfb->data + p->offset;
  465.         } else if (plane==AVS_PLANAR_Y) {
  466.                 return 0;
  467.         } else {
  468.                 switch (plane) {
  469.                         case AVS_PLANAR_U: return p->vfb->data + p->offsetU;
  470.                         case AVS_PLANAR_V: return p->vfb->data + p->offsetV;
  471.                         default:       return p->vfb->data + p->offset;
  472.                 }
  473.         }
  474. }
  475.  
  476.  
  477. AVSC_API(void, avs_release_video_frame)(AVS_VideoFrame *);
  478. // makes a shallow copy of a video frame
  479. AVSC_API(AVS_VideoFrame *, avs_copy_video_frame)(AVS_VideoFrame *);
  480.  
  481. #ifndef AVSC_NO_DECLSPEC
  482. AVSC_INLINE void avs_release_frame(AVS_VideoFrame * f)
  483.   {avs_release_video_frame(f);}
  484. AVSC_INLINE AVS_VideoFrame * avs_copy_frame(AVS_VideoFrame * f)
  485.   {return avs_copy_video_frame(f);}
  486. #endif
  487.  
  488. /////////////////////////////////////////////////////////////////////
  489. //
  490. // AVS_Value
  491. //
  492.  
  493. // Treat AVS_Value as a fat pointer.  That is use avs_copy_value
  494. // and avs_release_value appropiaty as you would if AVS_Value was
  495. // a pointer.
  496.  
  497. // To maintain source code compatibility with future versions of the
  498. // avisynth_c API don't use the AVS_Value directly.  Use the helper
  499. // functions below.
  500.  
  501. // AVS_Value is layed out identicly to AVSValue
  502. typedef struct AVS_Value AVS_Value;
  503. struct AVS_Value {
  504.   short type;  // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong
  505.                // for some function e'rror
  506.   short array_size;
  507.   union {
  508.     void * clip; // do not use directly, use avs_take_clip
  509.     char boolean;
  510.     int integer;
  511.     float floating_pt;
  512.     const char * string;
  513.     const AVS_Value * array;
  514.   } d;
  515. };
  516.  
  517. // AVS_Value should be initilized with avs_void.
  518. // Should also set to avs_void after the value is released
  519. // with avs_copy_value.  Consider it the equalvent of setting
  520. // a pointer to NULL
  521. static const AVS_Value avs_void = {'v'};
  522.  
  523. AVSC_API(void, avs_copy_value)(AVS_Value * dest, AVS_Value src);
  524. AVSC_API(void, avs_release_value)(AVS_Value);
  525.  
  526. AVSC_INLINE int avs_defined(AVS_Value v) { return v.type != 'v'; }
  527. AVSC_INLINE int avs_is_clip(AVS_Value v) { return v.type == 'c'; }
  528. AVSC_INLINE int avs_is_bool(AVS_Value v) { return v.type == 'b'; }
  529. AVSC_INLINE int avs_is_int(AVS_Value v) { return v.type == 'i'; }
  530. AVSC_INLINE int avs_is_float(AVS_Value v) { return v.type == 'f' || v.type == 'i'; }
  531. AVSC_INLINE int avs_is_string(AVS_Value v) { return v.type == 's'; }
  532. AVSC_INLINE int avs_is_array(AVS_Value v) { return v.type == 'a'; }
  533. AVSC_INLINE int avs_is_error(AVS_Value v) { return v.type == 'e'; }
  534.  
  535. AVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *);
  536. AVSC_API(void, avs_set_to_clip)(AVS_Value *, AVS_Clip *);
  537.  
  538. AVSC_INLINE int avs_as_bool(AVS_Value v)
  539.         { return v.d.boolean; }
  540. AVSC_INLINE int avs_as_int(AVS_Value v)
  541.         { return v.d.integer; }
  542. AVSC_INLINE const char * avs_as_string(AVS_Value v)
  543.         { return avs_is_error(v) || avs_is_string(v) ? v.d.string : 0; }
  544. AVSC_INLINE double avs_as_float(AVS_Value v)
  545.         { return avs_is_int(v) ? v.d.integer : v.d.floating_pt; }
  546. AVSC_INLINE const char * avs_as_error(AVS_Value v)
  547.         { return avs_is_error(v) ? v.d.string : 0; }
  548. AVSC_INLINE const AVS_Value * avs_as_array(AVS_Value v)
  549.         { return v.d.array; }
  550. AVSC_INLINE int avs_array_size(AVS_Value v)
  551.         { return avs_is_array(v) ? v.array_size : 1; }
  552. AVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index)
  553.         { return avs_is_array(v) ? v.d.array[index] : v; }
  554.  
  555. // only use these functions on an AVS_Value that does not already have
  556. // an active value.  Remember, treat AVS_Value as a fat pointer.
  557. AVSC_INLINE AVS_Value avs_new_value_bool(int v0)
  558.         { AVS_Value v; v.type = 'b'; v.d.boolean = v0 == 0 ? 0 : 1; return v; }
  559. AVSC_INLINE AVS_Value avs_new_value_int(int v0)
  560.         { AVS_Value v; v.type = 'i'; v.d.integer = v0; return v; }
  561. AVSC_INLINE AVS_Value avs_new_value_string(const char * v0)
  562.         { AVS_Value v; v.type = 's'; v.d.string = v0; return v; }
  563. AVSC_INLINE AVS_Value avs_new_value_float(float v0)
  564.         { AVS_Value v; v.type = 'f'; v.d.floating_pt = v0; return v;}
  565. AVSC_INLINE AVS_Value avs_new_value_error(const char * v0)
  566.         { AVS_Value v; v.type = 'e'; v.d.string = v0; return v; }
  567. #ifndef AVSC_NO_DECLSPEC
  568. AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0)
  569.         { AVS_Value v; avs_set_to_clip(&v, v0); return v; }
  570. #endif
  571. AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size)
  572.         { AVS_Value v; v.type = 'a'; v.d.array = v0; v.array_size = size; return v; }
  573.  
  574. /////////////////////////////////////////////////////////////////////
  575. //
  576. // AVS_Clip
  577. //
  578.  
  579. AVSC_API(void, avs_release_clip)(AVS_Clip *);
  580. AVSC_API(AVS_Clip *, avs_copy_clip)(AVS_Clip *);
  581.  
  582. AVSC_API(const char *, avs_clip_get_error)(AVS_Clip *); // return 0 if no error
  583.  
  584. AVSC_API(const AVS_VideoInfo *, avs_get_video_info)(AVS_Clip *);
  585.  
  586. AVSC_API(int, avs_get_version)(AVS_Clip *);
  587.  
  588. AVSC_API(AVS_VideoFrame *, avs_get_frame)(AVS_Clip *, int n);
  589. // The returned video frame must be released with avs_release_video_frame
  590.  
  591. AVSC_API(int, avs_get_parity)(AVS_Clip *, int n);
  592. // return field parity if field_based, else parity of first field in frame
  593.  
  594. AVSC_API(int, avs_get_audio)(AVS_Clip *, void * buf,
  595.                              INT64 start, INT64 count);
  596. // start and count are in samples
  597.  
  598. AVSC_API(int, avs_set_cache_hints)(AVS_Clip *,
  599.                                    int cachehints, int frame_range);
  600.  
  601. // This is the callback type used by avs_add_function
  602. typedef AVS_Value (AVSC_CC * AVS_ApplyFunc)
  603.                         (AVS_ScriptEnvironment *, AVS_Value args, void * user_data);
  604.  
  605. typedef struct AVS_FilterInfo AVS_FilterInfo;
  606. struct AVS_FilterInfo
  607. {
  608.   // these members should not be modified outside of the AVS_ApplyFunc callback
  609.   AVS_Clip * child;
  610.   AVS_VideoInfo vi;
  611.   AVS_ScriptEnvironment * env;
  612.   AVS_VideoFrame * (AVSC_CC * get_frame)(AVS_FilterInfo *, int n);
  613.   int (AVSC_CC * get_parity)(AVS_FilterInfo *, int n);
  614.   int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf,
  615.                                   INT64 start, INT64 count);
  616.   int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints,
  617.                                         int frame_range);
  618.   void (AVSC_CC * free_filter)(AVS_FilterInfo *);
  619.  
  620.   // Should be set when ever there is an error to report.
  621.   // It is cleared before any of the above methods are called
  622.   const char * error;
  623.   // this is to store whatever and may be modified at will
  624.   void * user_data;
  625. };
  626.  
  627. // Create a new filter
  628. // fi is set to point to the AVS_FilterInfo so that you can
  629. //   modify it once it is initilized.
  630. // store_child should generally be set to true.  If it is not
  631. //    set than ALL methods (the function pointers) must be defined
  632. // If it is set than you do not need to worry about freeing the child
  633. //    clip.
  634. AVSC_API(AVS_Clip *, avs_new_c_filter)(AVS_ScriptEnvironment * e,
  635.                                        AVS_FilterInfo * * fi,
  636.                                        AVS_Value child, int store_child);
  637.  
  638. /////////////////////////////////////////////////////////////////////
  639. //
  640. // AVS_ScriptEnvironment
  641. //
  642.  
  643. // For GetCPUFlags.  These are backwards-compatible with those in VirtualDub.
  644. enum {
  645.                                 /* slowest CPU to support extension */
  646.   AVS_CPU_FORCE        = 0x01,   // N/A
  647.   AVS_CPU_FPU          = 0x02,   // 386/486DX
  648.   AVS_CPU_MMX          = 0x04,   // P55C, K6, PII
  649.   AVS_CPU_INTEGER_SSE  = 0x08,   // PIII, Athlon
  650.   AVS_CPU_SSE          = 0x10,   // PIII, Athlon XP/MP
  651.   AVS_CPU_SSE2         = 0x20,   // PIV, Hammer
  652.   AVS_CPU_3DNOW        = 0x40,   // K6-2
  653.   AVS_CPU_3DNOW_EXT    = 0x80,   // Athlon
  654.   AVS_CPU_X86_64       = 0xA0,   // Hammer (note: equiv. to 3DNow + SSE2,
  655.                                  // which only Hammer will have anyway)
  656.   AVS_CPUF_SSE3       = 0x100,   //  PIV+, K8 Venice
  657.   AVS_CPUF_SSSE3      = 0x200,   //  Core 2
  658.   AVS_CPUF_SSE4       = 0x400,   //  Penryn, Wolfdale, Yorkfield
  659.   AVS_CPUF_SSE4_1     = 0x400,
  660.   AVS_CPUF_SSE4_2     = 0x800,   //  Nehalem
  661. };
  662.  
  663. AVSC_API(const char *, avs_get_error)(AVS_ScriptEnvironment *); // return 0 if no error
  664.  
  665. AVSC_API(long, avs_get_cpu_flags)(AVS_ScriptEnvironment *);
  666. AVSC_API(int, avs_check_version)(AVS_ScriptEnvironment *, int version);
  667.  
  668. AVSC_API(char *, avs_save_string)(AVS_ScriptEnvironment *, const char* s, int length);
  669. AVSC_API(char *, avs_sprintf)(AVS_ScriptEnvironment *, const char * fmt, ...);
  670.  
  671. AVSC_API(char *, avs_vsprintf)(AVS_ScriptEnvironment *, const char * fmt, void* val);
  672.  // note: val is really a va_list; I hope everyone typedefs va_list to a pointer
  673.  
  674. AVSC_API(int, avs_add_function)(AVS_ScriptEnvironment *,
  675.                                 const char * name, const char * params,
  676.                                 AVS_ApplyFunc apply, void * user_data);
  677.  
  678. AVSC_API(int, avs_function_exists)(AVS_ScriptEnvironment *, const char * name);
  679.  
  680. AVSC_API(AVS_Value, avs_invoke)(AVS_ScriptEnvironment *, const char * name,
  681.                                AVS_Value args, const char** arg_names);
  682. // The returned value must be be released with avs_release_value
  683.  
  684. AVSC_API(AVS_Value, avs_get_var)(AVS_ScriptEnvironment *, const char* name);
  685. // The returned value must be be released with avs_release_value
  686.  
  687. AVSC_API(int, avs_set_var)(AVS_ScriptEnvironment *, const char* name, AVS_Value val);
  688.  
  689. AVSC_API(int, avs_set_global_var)(AVS_ScriptEnvironment *, const char* name, const AVS_Value val);
  690.  
  691. //void avs_push_context(AVS_ScriptEnvironment *, int level=0);
  692. //void avs_pop_context(AVS_ScriptEnvironment *);
  693.  
  694. AVSC_API(AVS_VideoFrame *, avs_new_video_frame_a)(AVS_ScriptEnvironment *,
  695.                                           const AVS_VideoInfo * vi, int align);
  696. // align should be at least 16
  697.  
  698. #ifndef AVSC_NO_DECLSPEC
  699. AVSC_INLINE
  700. AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env,
  701.                                      const AVS_VideoInfo * vi)
  702.   {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}
  703.  
  704. AVSC_INLINE
  705. AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env,
  706.                                const AVS_VideoInfo * vi)
  707.   {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}
  708. #endif
  709.  
  710.  
  711. AVSC_API(int, avs_make_writable)(AVS_ScriptEnvironment *, AVS_VideoFrame * * pvf);
  712.  
  713. AVSC_API(void, avs_bit_blt)(AVS_ScriptEnvironment *, BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height);
  714.  
  715. typedef void (AVSC_CC *AVS_ShutdownFunc)(void* user_data, AVS_ScriptEnvironment * env);
  716. AVSC_API(void, avs_at_exit)(AVS_ScriptEnvironment *, AVS_ShutdownFunc function, void * user_data);
  717.  
  718. AVSC_API(AVS_VideoFrame *, avs_subframe)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height);
  719. // The returned video frame must be be released
  720.  
  721. AVSC_API(int, avs_set_memory_max)(AVS_ScriptEnvironment *, int mem);
  722.  
  723. AVSC_API(int, avs_set_working_dir)(AVS_ScriptEnvironment *, const char * newdir);
  724.  
  725. // avisynth.dll exports this; it's a way to use it as a library, without
  726. // writing an AVS script or without going through AVIFile.
  727. AVSC_API(AVS_ScriptEnvironment *, avs_create_script_environment)(int version);
  728.  
  729. // this symbol is the entry point for the plugin and must
  730. // be defined
  731. AVSC_EXPORT
  732. const char * AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env);
  733.  
  734.  
  735. AVSC_API(void, avs_delete_script_environment)(AVS_ScriptEnvironment *);
  736.  
  737.  
  738. AVSC_API(AVS_VideoFrame *, avs_subframe_planar)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV);
  739. // The returned video frame must be be released
  740.  
  741. #ifdef AVSC_NO_DECLSPEC
  742. // use LoadLibrary and related functions to dynamically load Avisynth instead of declspec(dllimport)
  743. /*
  744.   The following functions needs to have been declared, probably from windows.h
  745.  
  746.   void* malloc(size_t)
  747.   void free(void*);
  748.  
  749.   HMODULE LoadLibrary(const char*);
  750.   void* GetProcAddress(HMODULE, const char*);
  751.   FreeLibrary(HMODULE);
  752. */
  753.  
  754.  
  755. typedef struct AVS_Library AVS_Library;
  756.  
  757. #define AVSC_DECLARE_FUNC(name) name##_func name
  758.  
  759. struct AVS_Library {
  760.   HMODULE handle;
  761.  
  762.   AVSC_DECLARE_FUNC(avs_add_function);
  763.   AVSC_DECLARE_FUNC(avs_at_exit);
  764.   AVSC_DECLARE_FUNC(avs_bit_blt);
  765.   AVSC_DECLARE_FUNC(avs_check_version);
  766.   AVSC_DECLARE_FUNC(avs_clip_get_error);
  767.   AVSC_DECLARE_FUNC(avs_copy_clip);
  768.   AVSC_DECLARE_FUNC(avs_copy_value);
  769.   AVSC_DECLARE_FUNC(avs_copy_video_frame);
  770.   AVSC_DECLARE_FUNC(avs_create_script_environment);
  771.   AVSC_DECLARE_FUNC(avs_delete_script_environment);
  772.   AVSC_DECLARE_FUNC(avs_function_exists);
  773.   AVSC_DECLARE_FUNC(avs_get_audio);
  774.   AVSC_DECLARE_FUNC(avs_get_cpu_flags);
  775.   AVSC_DECLARE_FUNC(avs_get_error);
  776.   AVSC_DECLARE_FUNC(avs_get_frame);
  777.   AVSC_DECLARE_FUNC(avs_get_parity);
  778.   AVSC_DECLARE_FUNC(avs_get_var);
  779.   AVSC_DECLARE_FUNC(avs_get_version);
  780.   AVSC_DECLARE_FUNC(avs_get_video_info);
  781.   AVSC_DECLARE_FUNC(avs_invoke);
  782.   AVSC_DECLARE_FUNC(avs_make_writable);
  783.   AVSC_DECLARE_FUNC(avs_new_c_filter);
  784.   AVSC_DECLARE_FUNC(avs_new_video_frame_a);
  785.   AVSC_DECLARE_FUNC(avs_release_clip);
  786.   AVSC_DECLARE_FUNC(avs_release_value);
  787.   AVSC_DECLARE_FUNC(avs_release_video_frame);
  788.   AVSC_DECLARE_FUNC(avs_save_string);
  789.   AVSC_DECLARE_FUNC(avs_set_cache_hints);
  790.   AVSC_DECLARE_FUNC(avs_set_global_var);
  791.   AVSC_DECLARE_FUNC(avs_set_memory_max);
  792.   AVSC_DECLARE_FUNC(avs_set_to_clip);
  793.   AVSC_DECLARE_FUNC(avs_set_var);
  794.   AVSC_DECLARE_FUNC(avs_set_working_dir);
  795.   AVSC_DECLARE_FUNC(avs_sprintf);
  796.   AVSC_DECLARE_FUNC(avs_subframe);
  797.   AVSC_DECLARE_FUNC(avs_subframe_planar);
  798.   AVSC_DECLARE_FUNC(avs_take_clip);
  799.   AVSC_DECLARE_FUNC(avs_vsprintf);
  800. };
  801.  
  802. #undef AVSC_DECLARE_FUNC
  803.  
  804.  
  805. AVSC_INLINE AVS_Library * avs_load_library() {
  806.   AVS_Library *library = (AVS_Library *)malloc(sizeof(AVS_Library));
  807.   if (library == NULL)
  808.     return NULL;
  809.   library->handle = LoadLibrary("avisynth");
  810.   if (library->handle == NULL)
  811.     goto fail;
  812.  
  813. #define __AVSC_STRINGIFY(x) #x
  814. #define AVSC_STRINGIFY(x) __AVSC_STRINGIFY(x)
  815. #define AVSC_LOAD_FUNC(name) {\
  816.   library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\
  817.   if (library->name == NULL)\
  818.     goto fail;\
  819. }
  820.  
  821.   AVSC_LOAD_FUNC(avs_add_function);
  822.   AVSC_LOAD_FUNC(avs_at_exit);
  823.   AVSC_LOAD_FUNC(avs_bit_blt);
  824.   AVSC_LOAD_FUNC(avs_check_version);
  825.   AVSC_LOAD_FUNC(avs_clip_get_error);
  826.   AVSC_LOAD_FUNC(avs_copy_clip);
  827.   AVSC_LOAD_FUNC(avs_copy_value);
  828.   AVSC_LOAD_FUNC(avs_copy_video_frame);
  829.   AVSC_LOAD_FUNC(avs_create_script_environment);
  830.   AVSC_LOAD_FUNC(avs_delete_script_environment);
  831.   AVSC_LOAD_FUNC(avs_function_exists);
  832.   AVSC_LOAD_FUNC(avs_get_audio);
  833.   AVSC_LOAD_FUNC(avs_get_cpu_flags);
  834.   AVSC_LOAD_FUNC(avs_get_error);
  835.   AVSC_LOAD_FUNC(avs_get_frame);
  836.   AVSC_LOAD_FUNC(avs_get_parity);
  837.   AVSC_LOAD_FUNC(avs_get_var);
  838.   AVSC_LOAD_FUNC(avs_get_version);
  839.   AVSC_LOAD_FUNC(avs_get_video_info);
  840.   AVSC_LOAD_FUNC(avs_invoke);
  841.   AVSC_LOAD_FUNC(avs_make_writable);
  842.   AVSC_LOAD_FUNC(avs_new_c_filter);
  843.   AVSC_LOAD_FUNC(avs_new_video_frame_a);
  844.   AVSC_LOAD_FUNC(avs_release_clip);
  845.   AVSC_LOAD_FUNC(avs_release_value);
  846.   AVSC_LOAD_FUNC(avs_release_video_frame);
  847.   AVSC_LOAD_FUNC(avs_save_string);
  848.   AVSC_LOAD_FUNC(avs_set_cache_hints);
  849.   AVSC_LOAD_FUNC(avs_set_global_var);
  850.   AVSC_LOAD_FUNC(avs_set_memory_max);
  851.   AVSC_LOAD_FUNC(avs_set_to_clip);
  852.   AVSC_LOAD_FUNC(avs_set_var);
  853.   AVSC_LOAD_FUNC(avs_set_working_dir);
  854.   AVSC_LOAD_FUNC(avs_sprintf);
  855.   AVSC_LOAD_FUNC(avs_subframe);
  856.   AVSC_LOAD_FUNC(avs_subframe_planar);
  857.   AVSC_LOAD_FUNC(avs_take_clip);
  858.   AVSC_LOAD_FUNC(avs_vsprintf);
  859.  
  860. #undef __AVSC_STRINGIFY
  861. #undef AVSC_STRINGIFY
  862. #undef AVSC_LOAD_FUNC
  863.  
  864.   return library;
  865.  
  866. fail:
  867.   free(library);
  868.   return NULL;
  869. }
  870.  
  871. AVSC_INLINE void avs_free_library(AVS_Library *library) {
  872.   if (library == NULL)
  873.     return;
  874.   FreeLibrary(library->handle);
  875.   free(library);
  876. }
  877. #endif
  878.  
  879. #endif
  880.