1
0

source.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "source.h"
  2. // --- async source ----------------------------------------------------------------------
  3. // define glib subtype for vips async source
  4. #define VIPS_TYPE_ASYNC_SOURCE (vips_async_source_get_type())
  5. G_DEFINE_FINAL_TYPE(VipsAsyncSource, vips_async_source, VIPS_TYPE_SOURCE)
  6. extern void closeAsyncReader(uintptr_t handle);
  7. extern gint64 asyncReaderSeek(uintptr_t handle, gint64 offset, int whence);
  8. extern gint64 asyncReaderRead(uintptr_t handle, gpointer buffer, gint64 size);
  9. // loads jpeg from a source
  10. int
  11. vips_jpegloadsource_go(VipsAsyncSource *source, int shrink, VipsImage **out)
  12. {
  13. if (shrink > 1)
  14. return vips_jpegload_source(VIPS_SOURCE(source), out, "shrink", shrink,
  15. NULL);
  16. return vips_jpegload_source(VIPS_SOURCE(source), out, NULL);
  17. }
  18. // dereferences source
  19. void
  20. unref_source(VipsAsyncSource *source)
  21. {
  22. VIPS_UNREF(source);
  23. }
  24. // read function for vips async source
  25. static gint64
  26. vips_async_source_read(VipsSource *source, void *buffer, size_t length)
  27. {
  28. VipsAsyncSource *self = (VipsAsyncSource *) source;
  29. gint64 read_length = asyncReaderRead(self->readerHandle, buffer, length);
  30. if (read_length < 0) {
  31. vips_error("vips_async_source_read", "failed to read from async source");
  32. }
  33. return read_length;
  34. }
  35. // seek function for vips async source. whence can be SEEK_SET (0), SEEK_CUR (1), or SEEK_END (2).
  36. static gint64
  37. vips_async_source_seek(VipsSource *source, gint64 offset, int whence)
  38. {
  39. VipsAsyncSource *self = (VipsAsyncSource *) source;
  40. gint64 actual_offset = asyncReaderSeek(self->readerHandle, offset, whence);
  41. if (actual_offset < 0) {
  42. vips_error("vips_async_source_seek", "failed to seek in async source");
  43. }
  44. return actual_offset;
  45. }
  46. static void
  47. vips_async_source_dispose(GObject *gobject)
  48. {
  49. VipsAsyncSource *source = (VipsAsyncSource *) gobject;
  50. closeAsyncReader(source->readerHandle);
  51. G_OBJECT_CLASS(vips_async_source_parent_class)->dispose(gobject);
  52. }
  53. // attaches seek/read handlers to the async source class
  54. static void
  55. vips_async_source_class_init(VipsAsyncSourceClass *klass)
  56. {
  57. GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
  58. VipsObjectClass *object_class = VIPS_OBJECT_CLASS(klass);
  59. VipsSourceClass *source_class = VIPS_SOURCE_CLASS(klass);
  60. object_class->nickname = "async_source";
  61. object_class->description = "async input source";
  62. gobject_class->dispose = vips_async_source_dispose;
  63. source_class->read = vips_async_source_read;
  64. source_class->seek = vips_async_source_seek;
  65. }
  66. // initializes the async source (nothing to do here yet)
  67. static void
  68. vips_async_source_init(VipsAsyncSource *source)
  69. {
  70. }
  71. // creates a new async source with the given reader handle
  72. VipsAsyncSource *
  73. vips_new_async_source(uintptr_t readerHandle)
  74. {
  75. VipsAsyncSource *source = g_object_new(VIPS_TYPE_ASYNC_SOURCE, NULL);
  76. source->readerHandle = readerHandle;
  77. return source;
  78. }