Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Bytestream functions
  3.  * copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
  4.  * Copyright (c) 2012 Aneesh Dogra (lionaneesh) <lionaneesh@gmail.com>
  5.  *
  6.  * This file is part of FFmpeg.
  7.  *
  8.  * FFmpeg is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  * FFmpeg is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Lesser General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with FFmpeg; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21.  */
  22.  
  23. #ifndef AVCODEC_BYTESTREAM_H
  24. #define AVCODEC_BYTESTREAM_H
  25.  
  26. #include <stdint.h>
  27. #include <string.h>
  28.  
  29. #include "libavutil/avassert.h"
  30. #include "libavutil/common.h"
  31. #include "libavutil/intreadwrite.h"
  32.  
  33. typedef struct GetByteContext {
  34.     const uint8_t *buffer, *buffer_end, *buffer_start;
  35. } GetByteContext;
  36.  
  37. typedef struct PutByteContext {
  38.     uint8_t *buffer, *buffer_end, *buffer_start;
  39.     int eof;
  40. } PutByteContext;
  41.  
  42. #define DEF(type, name, bytes, read, write)                                  \
  43. static av_always_inline type bytestream_get_ ## name(const uint8_t **b)        \
  44. {                                                                              \
  45.     (*b) += bytes;                                                             \
  46.     return read(*b - bytes);                                                   \
  47. }                                                                              \
  48. static av_always_inline void bytestream_put_ ## name(uint8_t **b,              \
  49.                                                      const type value)         \
  50. {                                                                              \
  51.     write(*b, value);                                                          \
  52.     (*b) += bytes;                                                             \
  53. }                                                                              \
  54. static av_always_inline void bytestream2_put_ ## name ## u(PutByteContext *p,  \
  55.                                                            const type value)   \
  56. {                                                                              \
  57.     bytestream_put_ ## name(&p->buffer, value);                                \
  58. }                                                                              \
  59. static av_always_inline void bytestream2_put_ ## name(PutByteContext *p,       \
  60.                                                       const type value)        \
  61. {                                                                              \
  62.     if (!p->eof && (p->buffer_end - p->buffer >= bytes)) {                     \
  63.         write(p->buffer, value);                                               \
  64.         p->buffer += bytes;                                                    \
  65.     } else                                                                     \
  66.         p->eof = 1;                                                            \
  67. }                                                                              \
  68. static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g)  \
  69. {                                                                              \
  70.     return bytestream_get_ ## name(&g->buffer);                                \
  71. }                                                                              \
  72. static av_always_inline type bytestream2_get_ ## name(GetByteContext *g)       \
  73. {                                                                              \
  74.     if (g->buffer_end - g->buffer < bytes)                                     \
  75.         return 0;                                                              \
  76.     return bytestream2_get_ ## name ## u(g);                                   \
  77. }                                                                              \
  78. static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g)      \
  79. {                                                                              \
  80.     if (g->buffer_end - g->buffer < bytes)                                     \
  81.         return 0;                                                              \
  82.     return read(g->buffer);                                                    \
  83. }
  84.  
  85. DEF(uint64_t,     le64, 8, AV_RL64, AV_WL64)
  86. DEF(unsigned int, le32, 4, AV_RL32, AV_WL32)
  87. DEF(unsigned int, le24, 3, AV_RL24, AV_WL24)
  88. DEF(unsigned int, le16, 2, AV_RL16, AV_WL16)
  89. DEF(uint64_t,     be64, 8, AV_RB64, AV_WB64)
  90. DEF(unsigned int, be32, 4, AV_RB32, AV_WB32)
  91. DEF(unsigned int, be24, 3, AV_RB24, AV_WB24)
  92. DEF(unsigned int, be16, 2, AV_RB16, AV_WB16)
  93. DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8)
  94.  
  95. #if HAVE_BIGENDIAN
  96. #   define bytestream2_get_ne16  bytestream2_get_be16
  97. #   define bytestream2_get_ne24  bytestream2_get_be24
  98. #   define bytestream2_get_ne32  bytestream2_get_be32
  99. #   define bytestream2_get_ne64  bytestream2_get_be64
  100. #   define bytestream2_get_ne16u bytestream2_get_be16u
  101. #   define bytestream2_get_ne24u bytestream2_get_be24u
  102. #   define bytestream2_get_ne32u bytestream2_get_be32u
  103. #   define bytestream2_get_ne64u bytestream2_get_be64u
  104. #   define bytestream2_put_ne16  bytestream2_put_be16
  105. #   define bytestream2_put_ne24  bytestream2_put_be24
  106. #   define bytestream2_put_ne32  bytestream2_put_be32
  107. #   define bytestream2_put_ne64  bytestream2_put_be64
  108. #   define bytestream2_peek_ne16 bytestream2_peek_be16
  109. #   define bytestream2_peek_ne24 bytestream2_peek_be24
  110. #   define bytestream2_peek_ne32 bytestream2_peek_be32
  111. #   define bytestream2_peek_ne64 bytestream2_peek_be64
  112. #else
  113. #   define bytestream2_get_ne16  bytestream2_get_le16
  114. #   define bytestream2_get_ne24  bytestream2_get_le24
  115. #   define bytestream2_get_ne32  bytestream2_get_le32
  116. #   define bytestream2_get_ne64  bytestream2_get_le64
  117. #   define bytestream2_get_ne16u bytestream2_get_le16u
  118. #   define bytestream2_get_ne24u bytestream2_get_le24u
  119. #   define bytestream2_get_ne32u bytestream2_get_le32u
  120. #   define bytestream2_get_ne64u bytestream2_get_le64u
  121. #   define bytestream2_put_ne16  bytestream2_put_le16
  122. #   define bytestream2_put_ne24  bytestream2_put_le24
  123. #   define bytestream2_put_ne32  bytestream2_put_le32
  124. #   define bytestream2_put_ne64  bytestream2_put_le64
  125. #   define bytestream2_peek_ne16 bytestream2_peek_le16
  126. #   define bytestream2_peek_ne24 bytestream2_peek_le24
  127. #   define bytestream2_peek_ne32 bytestream2_peek_le32
  128. #   define bytestream2_peek_ne64 bytestream2_peek_le64
  129. #endif
  130.  
  131. static av_always_inline void bytestream2_init(GetByteContext *g,
  132.                                               const uint8_t *buf,
  133.                                               int buf_size)
  134. {
  135.     av_assert0(buf_size >= 0);
  136.     g->buffer       = buf;
  137.     g->buffer_start = buf;
  138.     g->buffer_end   = buf + buf_size;
  139. }
  140.  
  141. static av_always_inline void bytestream2_init_writer(PutByteContext *p,
  142.                                                      uint8_t *buf,
  143.                                                      int buf_size)
  144. {
  145.     av_assert0(buf_size >= 0);
  146.     p->buffer       = buf;
  147.     p->buffer_start = buf;
  148.     p->buffer_end   = buf + buf_size;
  149.     p->eof          = 0;
  150. }
  151.  
  152. static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
  153. {
  154.     return g->buffer_end - g->buffer;
  155. }
  156.  
  157. static av_always_inline unsigned int bytestream2_get_bytes_left_p(PutByteContext *p)
  158. {
  159.     return p->buffer_end - p->buffer;
  160. }
  161.  
  162. static av_always_inline void bytestream2_skip(GetByteContext *g,
  163.                                               unsigned int size)
  164. {
  165.     g->buffer += FFMIN(g->buffer_end - g->buffer, size);
  166. }
  167.  
  168. static av_always_inline void bytestream2_skipu(GetByteContext *g,
  169.                                                unsigned int size)
  170. {
  171.     g->buffer += size;
  172. }
  173.  
  174. static av_always_inline void bytestream2_skip_p(PutByteContext *p,
  175.                                                 unsigned int size)
  176. {
  177.     int size2;
  178.     if (p->eof)
  179.         return;
  180.     size2 = FFMIN(p->buffer_end - p->buffer, size);
  181.     if (size2 != size)
  182.         p->eof = 1;
  183.     p->buffer += size2;
  184. }
  185.  
  186. static av_always_inline int bytestream2_tell(GetByteContext *g)
  187. {
  188.     return (int)(g->buffer - g->buffer_start);
  189. }
  190.  
  191. static av_always_inline int bytestream2_tell_p(PutByteContext *p)
  192. {
  193.     return (int)(p->buffer - p->buffer_start);
  194. }
  195.  
  196. static av_always_inline int bytestream2_size(GetByteContext *g)
  197. {
  198.     return (int)(g->buffer_end - g->buffer_start);
  199. }
  200.  
  201. static av_always_inline int bytestream2_size_p(PutByteContext *p)
  202. {
  203.     return (int)(p->buffer_end - p->buffer_start);
  204. }
  205.  
  206. static av_always_inline int bytestream2_seek(GetByteContext *g,
  207.                                              int offset,
  208.                                              int whence)
  209. {
  210.     switch (whence) {
  211.     case SEEK_CUR:
  212.         offset     = av_clip(offset, -(g->buffer - g->buffer_start),
  213.                              g->buffer_end - g->buffer);
  214.         g->buffer += offset;
  215.         break;
  216.     case SEEK_END:
  217.         offset    = av_clip(offset, -(g->buffer_end - g->buffer_start), 0);
  218.         g->buffer = g->buffer_end + offset;
  219.         break;
  220.     case SEEK_SET:
  221.         offset    = av_clip(offset, 0, g->buffer_end - g->buffer_start);
  222.         g->buffer = g->buffer_start + offset;
  223.         break;
  224.     default:
  225.         return AVERROR(EINVAL);
  226.     }
  227.     return bytestream2_tell(g);
  228. }
  229.  
  230. static av_always_inline int bytestream2_seek_p(PutByteContext *p,
  231.                                                int offset,
  232.                                                int whence)
  233. {
  234.     p->eof = 0;
  235.     switch (whence) {
  236.     case SEEK_CUR:
  237.         if (p->buffer_end - p->buffer < offset)
  238.             p->eof = 1;
  239.         offset     = av_clip(offset, -(p->buffer - p->buffer_start),
  240.                              p->buffer_end - p->buffer);
  241.         p->buffer += offset;
  242.         break;
  243.     case SEEK_END:
  244.         if (offset > 0)
  245.             p->eof = 1;
  246.         offset    = av_clip(offset, -(p->buffer_end - p->buffer_start), 0);
  247.         p->buffer = p->buffer_end + offset;
  248.         break;
  249.     case SEEK_SET:
  250.         if (p->buffer_end - p->buffer_start < offset)
  251.             p->eof = 1;
  252.         offset    = av_clip(offset, 0, p->buffer_end - p->buffer_start);
  253.         p->buffer = p->buffer_start + offset;
  254.         break;
  255.     default:
  256.         return AVERROR(EINVAL);
  257.     }
  258.     return bytestream2_tell_p(p);
  259. }
  260.  
  261. static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
  262.                                                             uint8_t *dst,
  263.                                                             unsigned int size)
  264. {
  265.     int size2 = FFMIN(g->buffer_end - g->buffer, size);
  266.     memcpy(dst, g->buffer, size2);
  267.     g->buffer += size2;
  268.     return size2;
  269. }
  270.  
  271. static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g,
  272.                                                              uint8_t *dst,
  273.                                                              unsigned int size)
  274. {
  275.     memcpy(dst, g->buffer, size);
  276.     g->buffer += size;
  277.     return size;
  278. }
  279.  
  280. static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
  281.                                                             const uint8_t *src,
  282.                                                             unsigned int size)
  283. {
  284.     int size2;
  285.     if (p->eof)
  286.         return 0;
  287.     size2 = FFMIN(p->buffer_end - p->buffer, size);
  288.     if (size2 != size)
  289.         p->eof = 1;
  290.     memcpy(p->buffer, src, size2);
  291.     p->buffer += size2;
  292.     return size2;
  293. }
  294.  
  295. static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p,
  296.                                                              const uint8_t *src,
  297.                                                              unsigned int size)
  298. {
  299.     memcpy(p->buffer, src, size);
  300.     p->buffer += size;
  301.     return size;
  302. }
  303.  
  304. static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
  305.                                                     const uint8_t c,
  306.                                                     unsigned int size)
  307. {
  308.     int size2;
  309.     if (p->eof)
  310.         return;
  311.     size2 = FFMIN(p->buffer_end - p->buffer, size);
  312.     if (size2 != size)
  313.         p->eof = 1;
  314.     memset(p->buffer, c, size2);
  315.     p->buffer += size2;
  316. }
  317.  
  318. static av_always_inline void bytestream2_set_bufferu(PutByteContext *p,
  319.                                                      const uint8_t c,
  320.                                                      unsigned int size)
  321. {
  322.     memset(p->buffer, c, size);
  323.     p->buffer += size;
  324. }
  325.  
  326. static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
  327. {
  328.     return p->eof;
  329. }
  330.  
  331. static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b,
  332.                                                            uint8_t *dst,
  333.                                                            unsigned int size)
  334. {
  335.     memcpy(dst, *b, size);
  336.     (*b) += size;
  337.     return size;
  338. }
  339.  
  340. static av_always_inline void bytestream_put_buffer(uint8_t **b,
  341.                                                    const uint8_t *src,
  342.                                                    unsigned int size)
  343. {
  344.     memcpy(*b, src, size);
  345.     (*b) += size;
  346. }
  347.  
  348. #endif /* AVCODEC_BYTESTREAM_H */
  349.