gd_io_ss.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * io_ss.c
  3. *
  4. * Implements the Source/Sink interface.
  5. *
  6. * As will all I/O modules, most functions are for local use only (called
  7. * via function pointers in the I/O context).
  8. *
  9. * The Source/Sink model is the primary 'user' interface for alternate data
  10. * sources; the IOCtx interface is intended (at least in version 1.5) to be
  11. * used internally until it settles down a bit.
  12. *
  13. * This module just layers the Source/Sink interface on top of the IOCtx; no
  14. * support is provided for tell/seek, so GD2 writing is not possible, and
  15. * retrieving parts of GD2 files is also not possible.
  16. *
  17. * A new SS context does not need to be created with both a Source and a Sink.
  18. *
  19. * Written/Modified 1999, Philip Warner.
  20. *
  21. */
  22. #include <math.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include "gd.h"
  26. #include "gdhelpers.h"
  27. /* this is used for creating images in main memory */
  28. typedef struct ssIOCtx
  29. {
  30. gdIOCtx ctx;
  31. gdSourcePtr src;
  32. gdSinkPtr snk;
  33. } ssIOCtx;
  34. typedef struct ssIOCtx *ssIOCtxPtr;
  35. gdIOCtx *gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk);
  36. static int sourceGetbuf (gdIOCtx *, void *, int);
  37. static int sourceGetchar (gdIOCtx * ctx);
  38. static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size);
  39. static void sinkPutchar (gdIOCtx * ctx, int a);
  40. static void gdFreeSsCtx (gdIOCtx * ctx);
  41. /* return data as a dynamic pointer */
  42. gdIOCtx * gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk)
  43. {
  44. ssIOCtxPtr ctx;
  45. ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx));
  46. ctx->src = src;
  47. ctx->snk = snk;
  48. ctx->ctx.getC = sourceGetchar;
  49. ctx->ctx.getBuf = sourceGetbuf;
  50. ctx->ctx.putC = sinkPutchar;
  51. ctx->ctx.putBuf = sinkPutbuf;
  52. ctx->ctx.tell = NULL;
  53. ctx->ctx.seek = NULL;
  54. ctx->ctx.gd_free = gdFreeSsCtx;
  55. return (gdIOCtx *) ctx;
  56. }
  57. static void gdFreeSsCtx (gdIOCtx * ctx)
  58. {
  59. gdFree(ctx);
  60. }
  61. static int sourceGetbuf (gdIOCtx * ctx, void *buf, int size)
  62. {
  63. ssIOCtx *lctx;
  64. int res;
  65. lctx = (ssIOCtx *) ctx;
  66. res = ((lctx->src->source) (lctx->src->context, buf, size));
  67. /*
  68. * Translate the return values from the Source object:
  69. * 0 is EOF, -1 is error
  70. */
  71. if (res == 0) {
  72. return EOF;
  73. } else if (res < 0) {
  74. return 0;
  75. } else {
  76. return res;
  77. }
  78. }
  79. static int sourceGetchar (gdIOCtx * ctx)
  80. {
  81. int res;
  82. unsigned char buf;
  83. res = sourceGetbuf (ctx, &buf, 1);
  84. if (res == 1) {
  85. return buf;
  86. } else {
  87. return EOF;
  88. }
  89. }
  90. static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size)
  91. {
  92. ssIOCtxPtr lctx;
  93. int res;
  94. lctx = (ssIOCtx *) ctx;
  95. res = (lctx->snk->sink) (lctx->snk->context, buf, size);
  96. if (res <= 0) {
  97. return 0;
  98. } else {
  99. return res;
  100. }
  101. }
  102. static void sinkPutchar (gdIOCtx * ctx, int a)
  103. {
  104. unsigned char b;
  105. b = a;
  106. sinkPutbuf (ctx, &b, 1);
  107. }