connection.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /* A byte source/sink .. it can be a pipe, socket, or perhaps a node.js stream.
  2. *
  3. * J.Cupitt, 19/6/14
  4. */
  5. /*
  6. This file is part of VIPS.
  7. VIPS is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU Lesser General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  18. 02110-1301 USA
  19. */
  20. /*
  21. These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
  22. */
  23. #ifndef VIPS_CONNECTION_H
  24. #define VIPS_CONNECTION_H
  25. #ifdef __cplusplus
  26. extern "C" {
  27. #endif /*__cplusplus*/
  28. #define VIPS_TYPE_CONNECTION (vips_connection_get_type())
  29. #define VIPS_CONNECTION( obj ) \
  30. (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
  31. VIPS_TYPE_CONNECTION, VipsConnection ))
  32. #define VIPS_CONNECTION_CLASS( klass ) \
  33. (G_TYPE_CHECK_CLASS_CAST( (klass), \
  34. VIPS_TYPE_CONNECTION, VipsConnectionClass))
  35. #define VIPS_IS_CONNECTION( obj ) \
  36. (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_CONNECTION ))
  37. #define VIPS_IS_CONNECTION_CLASS( klass ) \
  38. (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_CONNECTION ))
  39. #define VIPS_CONNECTION_GET_CLASS( obj ) \
  40. (G_TYPE_INSTANCE_GET_CLASS( (obj), \
  41. VIPS_TYPE_CONNECTION, VipsConnectionClass ))
  42. /* Communicate with something like a socket or pipe.
  43. */
  44. typedef struct _VipsConnection {
  45. VipsObject parent_object;
  46. /*< private >*/
  47. /* Read/write this fd if connected to a system pipe/socket. Override
  48. * ::read() and ::write() to do something else.
  49. */
  50. int descriptor;
  51. /* A descriptor we close with vips_tracked_close().
  52. */
  53. int tracked_descriptor;
  54. /* A descriptor we close with close().
  55. */
  56. int close_descriptor;
  57. /* If descriptor is a file, the filename we opened. Handy for error
  58. * messages.
  59. */
  60. char *filename;
  61. } VipsConnection;
  62. typedef struct _VipsConnectionClass {
  63. VipsObjectClass parent_class;
  64. } VipsConnectionClass;
  65. GType vips_connection_get_type( void );
  66. const char *vips_connection_filename( VipsConnection *connection );
  67. const char *vips_connection_nick( VipsConnection *connection );
  68. #define VIPS_TYPE_SOURCE (vips_source_get_type())
  69. #define VIPS_SOURCE( obj ) \
  70. (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
  71. VIPS_TYPE_SOURCE, VipsSource ))
  72. #define VIPS_SOURCE_CLASS( klass ) \
  73. (G_TYPE_CHECK_CLASS_CAST( (klass), \
  74. VIPS_TYPE_SOURCE, VipsSourceClass))
  75. #define VIPS_IS_SOURCE( obj ) \
  76. (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_SOURCE ))
  77. #define VIPS_IS_SOURCE_CLASS( klass ) \
  78. (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_SOURCE ))
  79. #define VIPS_SOURCE_GET_CLASS( obj ) \
  80. (G_TYPE_INSTANCE_GET_CLASS( (obj), \
  81. VIPS_TYPE_SOURCE, VipsSourceClass ))
  82. /* Read from something like a socket, file or memory area and present the data
  83. * with a unified seek / read / map interface.
  84. *
  85. * During the header phase, we save data from unseekable sources in a buffer
  86. * so readers can rewind and read again. We don't buffer data during the
  87. * decode stage.
  88. */
  89. typedef struct _VipsSource {
  90. VipsConnection parent_object;
  91. /* We have two phases:
  92. *
  93. * During the header phase, we save bytes read from the input (if this
  94. * is an unseekable source) so that we can rewind and try again, if
  95. * necessary.
  96. *
  97. * Once we reach decode phase, we no longer support rewind and the
  98. * buffer of saved data is discarded.
  99. */
  100. gboolean decode;
  101. /* TRUE if this input is something like a pipe. These don't support
  102. * seek or map -- all you can do is read() bytes sequentially.
  103. *
  104. * If you attempt to map or get the size of a pipe-style input, it'll
  105. * get read entirely into memory. Seeks will cause read up to the seek
  106. * point.
  107. */
  108. gboolean have_tested_seek;
  109. gboolean is_pipe;
  110. /* The current read point and length.
  111. *
  112. * length is -1 for is_pipe sources.
  113. *
  114. * off_t can be 32 bits on some platforms, so make sure we have a
  115. * full 64.
  116. */
  117. gint64 read_position;
  118. gint64 length;
  119. /*< private >*/
  120. /* For sources where we have the whole image in memory (from a memory
  121. * buffer, from mmaping the file, from reading the pipe into memory),
  122. * a pointer to the start.
  123. */
  124. const void *data;
  125. /* For is_pipe sources, save data read during header phase here. If
  126. * we rewind and try again, serve data from this until it runs out.
  127. *
  128. * If we need to force the whole pipe into memory, read everything to
  129. * this and put a copy pf the pointer in data.
  130. */
  131. GByteArray *header_bytes;
  132. /* Save the first few bytes here for file type sniffing.
  133. */
  134. GByteArray *sniff;
  135. /* For a memory source, the blob we read from.
  136. */
  137. VipsBlob *blob;
  138. /* If we mmaped the file, whet we need to unmmap on finalize.
  139. */
  140. void *mmap_baseaddr;
  141. size_t mmap_length;
  142. } VipsSource;
  143. typedef struct _VipsSourceClass {
  144. VipsConnectionClass parent_class;
  145. /* Subclasses can define these to implement other source methods.
  146. */
  147. /* Read from the source into the supplied buffer, args exactly as
  148. * read(2). Set errno on error.
  149. *
  150. * We must return gint64, since ssize_t is often defined as unsigned
  151. * on Windows.
  152. */
  153. gint64 (*read)( VipsSource *, void *, size_t );
  154. /* Seek to a certain position, args exactly as lseek(2). Set errno on
  155. * error.
  156. *
  157. * Unseekable sources should always return -1. VipsSource will then
  158. * seek by _read()ing bytes into memory as required.
  159. *
  160. * We have to use int64 rather than off_t, since we must work on
  161. * Windows, where off_t can be 32-bits.
  162. */
  163. gint64 (*seek)( VipsSource *, gint64, int );
  164. } VipsSourceClass;
  165. GType vips_source_get_type( void );
  166. VipsSource *vips_source_new_from_descriptor( int descriptor );
  167. VipsSource *vips_source_new_from_file( const char *filename );
  168. VipsSource *vips_source_new_from_blob( VipsBlob *blob );
  169. VipsSource *vips_source_new_from_memory( const void *data, size_t size );
  170. VipsSource *vips_source_new_from_options( const char *options );
  171. void vips_source_minimise( VipsSource *source );
  172. int vips_source_unminimise( VipsSource *source );
  173. int vips_source_decode( VipsSource *source );
  174. gint64 vips_source_read( VipsSource *source, void *data, size_t length );
  175. gboolean vips_source_is_mappable( VipsSource *source );
  176. const void *vips_source_map( VipsSource *source, size_t *length );
  177. VipsBlob *vips_source_map_blob( VipsSource *source );
  178. gint64 vips_source_seek( VipsSource *source, gint64 offset, int whence );
  179. int vips_source_rewind( VipsSource *source );
  180. size_t vips_source_sniff_at_most( VipsSource *source,
  181. unsigned char **data, size_t length );
  182. unsigned char *vips_source_sniff( VipsSource *source, size_t length );
  183. gint64 vips_source_length( VipsSource *source );
  184. #define VIPS_TYPE_SOURCE_CUSTOM (vips_source_custom_get_type())
  185. #define VIPS_SOURCE_CUSTOM( obj ) \
  186. (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
  187. VIPS_TYPE_SOURCE_CUSTOM, VipsSourceCustom ))
  188. #define VIPS_SOURCE_CUSTOM_CLASS( klass ) \
  189. (G_TYPE_CHECK_CLASS_CAST( (klass), \
  190. VIPS_TYPE_SOURCE_CUSTOM, VipsSourceCustomClass))
  191. #define VIPS_IS_SOURCE_CUSTOM( obj ) \
  192. (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_SOURCE_CUSTOM ))
  193. #define VIPS_IS_SOURCE_CUSTOM_CLASS( klass ) \
  194. (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_SOURCE_CUSTOM ))
  195. #define VIPS_SOURCE_CUSTOM_GET_CLASS( obj ) \
  196. (G_TYPE_INSTANCE_GET_CLASS( (obj), \
  197. VIPS_TYPE_SOURCE_CUSTOM, VipsSourceCustomClass ))
  198. /* Subclass of source_custom with signals for handlers. This is supposed to be
  199. * useful for language bindings.
  200. */
  201. typedef struct _VipsSourceCustom {
  202. VipsSource parent_object;
  203. } VipsSourceCustom;
  204. typedef struct _VipsSourceCustomClass {
  205. VipsSourceClass parent_class;
  206. /* The action signals clients can use to implement read and seek.
  207. * We must use gint64 everywhere since there's no G_TYPE_SIZE.
  208. */
  209. gint64 (*read)( VipsSourceCustom *, void *, gint64 );
  210. gint64 (*seek)( VipsSourceCustom *, gint64, int );
  211. } VipsSourceCustomClass;
  212. GType vips_source_custom_get_type( void );
  213. VipsSourceCustom *vips_source_custom_new( void );
  214. #define VIPS_TYPE_TARGET (vips_target_get_type())
  215. #define VIPS_TARGET( obj ) \
  216. (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
  217. VIPS_TYPE_TARGET, VipsTarget ))
  218. #define VIPS_TARGET_CLASS( klass ) \
  219. (G_TYPE_CHECK_CLASS_CAST( (klass), \
  220. VIPS_TYPE_TARGET, VipsTargetClass))
  221. #define VIPS_IS_TARGET( obj ) \
  222. (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_TARGET ))
  223. #define VIPS_IS_TARGET_CLASS( klass ) \
  224. (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_TARGET ))
  225. #define VIPS_TARGET_GET_CLASS( obj ) \
  226. (G_TYPE_INSTANCE_GET_CLASS( (obj), \
  227. VIPS_TYPE_TARGET, VipsTargetClass ))
  228. /* PNG writes in 8kb chunks, so we need to be a little larger than that.
  229. */
  230. #define VIPS_TARGET_BUFFER_SIZE (8500)
  231. /* Output to something like a socket, pipe or memory area.
  232. */
  233. typedef struct _VipsTarget {
  234. VipsConnection parent_object;
  235. /*< private >*/
  236. /* This target should write to memory.
  237. */
  238. gboolean memory;
  239. /* The target has been finished and can no longer be written.
  240. */
  241. gboolean finished;
  242. /* Write memory output here.
  243. */
  244. GByteArray *memory_buffer;
  245. /* And return memory via this blob.
  246. */
  247. VipsBlob *blob;
  248. /* Buffer small writes here. write_point is the index of the next
  249. * character to write.
  250. */
  251. unsigned char output_buffer[VIPS_TARGET_BUFFER_SIZE];
  252. int write_point;
  253. } VipsTarget;
  254. typedef struct _VipsTargetClass {
  255. VipsConnectionClass parent_class;
  256. /* Write to output. Args exactly as write(2).
  257. *
  258. * We must return gint64, since ssize_t is often defined as unsigned
  259. * on Windows.
  260. */
  261. gint64 (*write)( VipsTarget *, const void *, size_t );
  262. /* Output has been generated, so do any clearing up,
  263. * eg. copy the bytes we saved in memory to the target blob.
  264. */
  265. void (*finish)( VipsTarget * );
  266. } VipsTargetClass;
  267. GType vips_target_get_type( void );
  268. VipsTarget *vips_target_new_to_descriptor( int descriptor );
  269. VipsTarget *vips_target_new_to_file( const char *filename );
  270. VipsTarget *vips_target_new_to_memory( void );
  271. int vips_target_write( VipsTarget *target, const void *data, size_t length );
  272. void vips_target_finish( VipsTarget *target );
  273. unsigned char *vips_target_steal( VipsTarget *target, size_t *length );
  274. char *vips_target_steal_text( VipsTarget *target );
  275. int vips_target_putc( VipsTarget *target, int ch );
  276. #define VIPS_TARGET_PUTC( S, C ) ( \
  277. (S)->write_point < VIPS_TARGET_BUFFER_SIZE ? \
  278. ((S)->output_buffer[(S)->write_point++] = (C), 0) : \
  279. vips_target_putc( (S), (C) ) \
  280. )
  281. int vips_target_writes( VipsTarget *target, const char *str );
  282. int vips_target_writef( VipsTarget *target, const char *fmt, ... )
  283. __attribute__((format(printf, 2, 3)));
  284. int vips_target_write_amp( VipsTarget *target, const char *str );
  285. #define VIPS_TYPE_TARGET_CUSTOM (vips_target_custom_get_type())
  286. #define VIPS_TARGET_CUSTOM( obj ) \
  287. (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
  288. VIPS_TYPE_TARGET_CUSTOM, VipsTargetCustom ))
  289. #define VIPS_TARGET_CUSTOM_CLASS( klass ) \
  290. (G_TYPE_CHECK_CLASS_CAST( (klass), \
  291. VIPS_TYPE_TARGET_CUSTOM, VipsTargetCustomClass))
  292. #define VIPS_IS_TARGET_CUSTOM( obj ) \
  293. (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_TARGET_CUSTOM ))
  294. #define VIPS_IS_TARGET_CUSTOM_CLASS( klass ) \
  295. (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_TARGET_CUSTOM ))
  296. #define VIPS_TARGET_CUSTOM_GET_CLASS( obj ) \
  297. (G_TYPE_INSTANCE_GET_CLASS( (obj), \
  298. VIPS_TYPE_TARGET_CUSTOM, VipsTargetCustomClass ))
  299. #define VIPS_TARGET_CUSTOM_BUFFER_SIZE (4096)
  300. /* Output to something like a socket, pipe or memory area.
  301. */
  302. typedef struct _VipsTargetCustom {
  303. VipsTarget parent_object;
  304. } VipsTargetCustom;
  305. typedef struct _VipsTargetCustomClass {
  306. VipsTargetClass parent_class;
  307. /* The action signals clients can use to implement write and finish.
  308. * We must use gint64 everywhere since there's no G_TYPE_SIZE.
  309. */
  310. gint64 (*write)( VipsTargetCustom *, const void *, gint64 );
  311. void (*finish)( VipsTargetCustom * );
  312. } VipsTargetCustomClass;
  313. GType vips_target_custom_get_type( void );
  314. VipsTargetCustom *vips_target_custom_new( void );
  315. #ifdef __cplusplus
  316. }
  317. #endif /*__cplusplus*/
  318. #endif /*VIPS_CONNECTION_H*/