Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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.         g->buffer = g->buffer_end;                                             \
  76.         return 0;                                                              \
  77.     }                                                                          \
  78.     return bytestream2_get_ ## name ## u(g);                                   \
  79. }                                                                              \
  80. static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g)      \
  81. {                                                                              \
  82.     if (g->buffer_end - g->buffer < bytes)                                     \
  83.         return 0;                                                              \
  84.     return read(g->buffer);                                                    \
  85. }
  86.  
  87. DEF(uint64_t,     le64, 8, AV_RL64, AV_WL64)
  88. DEF(unsigned int, le32, 4, AV_RL32, AV_WL32)
  89. DEF(unsigned int, le24, 3, AV_RL24, AV_WL24)
  90. DEF(unsigned int, le16, 2, AV_RL16, AV_WL16)
  91. DEF(uint64_t,     be64, 8, AV_RB64, AV_WB64)
  92. DEF(unsigned int, be32, 4, AV_RB32, AV_WB32)
  93. DEF(unsigned int, be24, 3, AV_RB24, AV_WB24)
  94. DEF(unsigned int, be16, 2, AV_RB16, AV_WB16)
  95. DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8)
  96.  
  97. #if HAVE_BIGENDIAN
  98. #   define bytestream2_get_ne16  bytestream2_get_be16
  99. #   define bytestream2_get_ne24  bytestream2_get_be24
  100. #   define bytestream2_get_ne32  bytestream2_get_be32
  101. #   define bytestream2_get_ne64  bytestream2_get_be64
  102. #   define bytestream2_get_ne16u bytestream2_get_be16u
  103. #   define bytestream2_get_ne24u bytestream2_get_be24u
  104. #   define bytestream2_get_ne32u bytestream2_get_be32u
  105. #   define bytestream2_get_ne64u bytestream2_get_be64u
  106. #   define bytestream2_put_ne16  bytestream2_put_be16
  107. #   define bytestream2_put_ne24  bytestream2_put_be24
  108. #   define bytestream2_put_ne32  bytestream2_put_be32
  109. #   define bytestream2_put_ne64  bytestream2_put_be64
  110. #   define bytestream2_peek_ne16 bytestream2_peek_be16
  111. #   define bytestream2_peek_ne24 bytestream2_peek_be24
  112. #   define bytestream2_peek_ne32 bytestream2_peek_be32
  113. #   define bytestream2_peek_ne64 bytestream2_peek_be64
  114. #else
  115. #   define bytestream2_get_ne16  bytestream2_get_le16
  116. #   define bytestream2_get_ne24  bytestream2_get_le24
  117. #   define bytestream2_get_ne32  bytestream2_get_le32
  118. #   define bytestream2_get_ne64  bytestream2_get_le64
  119. #   define bytestream2_get_ne16u bytestream2_get_le16u
  120. #   define bytestream2_get_ne24u bytestream2_get_le24u
  121. #   define bytestream2_get_ne32u bytestream2_get_le32u
  122. #   define bytestream2_get_ne64u bytestream2_get_le64u
  123. #   define bytestream2_put_ne16  bytestream2_put_le16
  124. #   define bytestream2_put_ne24  bytestream2_put_le24
  125. #   define bytestream2_put_ne32  bytestream2_put_le32
  126. #   define bytestream2_put_ne64  bytestream2_put_le64
  127. #   define bytestream2_peek_ne16 bytestream2_peek_le16
  128. #   define bytestream2_peek_ne24 bytestream2_peek_le24
  129. #   define bytestream2_peek_ne32 bytestream2_peek_le32
  130. #   define bytestream2_peek_ne64 bytestream2_peek_le64
  131. #endif
  132.  
  133. static av_always_inline void bytestream2_init(GetByteContext *g,
  134.                                               const uint8_t *buf,
  135.                                               int buf_size)
  136. {
  137.     av_assert0(buf_size >= 0);
  138.     g->buffer       = buf;
  139.     g->buffer_start = buf;
  140.     g->buffer_end   = buf + buf_size;
  141. }
  142.  
  143. static av_always_inline void bytestream2_init_writer(PutByteContext *p,
  144.                                                      uint8_t *buf,
  145.                                                      int buf_size)
  146. {
  147.     av_assert0(buf_size >= 0);
  148.     p->buffer       = buf;
  149.     p->buffer_start = buf;
  150.     p->buffer_end   = buf + buf_size;
  151.     p->eof          = 0;
  152. }
  153.  
  154. static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
  155. {
  156.     return g->buffer_end - g->buffer;
  157. }
  158.  
  159. static av_always_inline unsigned int bytestream2_get_bytes_left_p(PutByteContext *p)
  160. {
  161.     return p->buffer_end - p->buffer;
  162. }
  163.  
  164. static av_always_inline void bytestream2_skip(GetByteContext *g,
  165.                                               unsigned int size)
  166. {
  167.     g->buffer += FFMIN(g->buffer_end - g->buffer, size);
  168. }
  169.  
  170. static av_always_inline void bytestream2_skipu(GetByteContext *g,
  171.                                                unsigned int size)
  172. {
  173.     g->buffer += size;
  174. }
  175.  
  176. static av_always_inline void bytestream2_skip_p(PutByteContext *p,
  177.                                                 unsigned int size)
  178. {
  179.     int size2;
  180.     if (p->eof)
  181.         return;
  182.     size2 = FFMIN(p->buffer_end - p->buffer, size);
  183.     if (size2 != size)
  184.         p->eof = 1;
  185.     p->buffer += size2;
  186. }
  187.  
  188. static av_always_inline int bytestream2_tell(GetByteContext *g)
  189. {
  190.     return (int)(g->buffer - g->buffer_start);
  191. }
  192.  
  193. static av_always_inline int bytestream2_tell_p(PutByteContext *p)
  194. {
  195.     return (int)(p->buffer - p->buffer_start);
  196. }
  197.  
  198. static av_always_inline int bytestream2_size(GetByteContext *g)
  199. {
  200.     return (int)(g->buffer_end - g->buffer_start);
  201. }
  202.  
  203. static av_always_inline int bytestream2_size_p(PutByteContext *p)
  204. {
  205.     return (int)(p->buffer_end - p->buffer_start);
  206. }
  207.  
  208. static av_always_inline int bytestream2_seek(GetByteContext *g,
  209.                                              int offset,
  210.                                              int whence)
  211. {
  212.     switch (whence) {
  213.     case SEEK_CUR:
  214.         offset     = av_clip(offset, -(g->buffer - g->buffer_start),
  215.                              g->buffer_end - g->buffer);
  216.         g->buffer += offset;
  217.         break;
  218.     case SEEK_END:
  219.         offset    = av_clip(offset, -(g->buffer_end - g->buffer_start), 0);
  220.         g->buffer = g->buffer_end + offset;
  221.         break;
  222.     case SEEK_SET:
  223.         offset    = av_clip(offset, 0, g->buffer_end - g->buffer_start);
  224.         g->buffer = g->buffer_start + offset;
  225.         break;
  226.     default:
  227.         return AVERROR(EINVAL);
  228.     }
  229.     return bytestream2_tell(g);
  230. }
  231.  
  232. static av_always_inline int bytestream2_seek_p(PutByteContext *p,
  233.                                                int offset,
  234.                                                int whence)
  235. {
  236.     p->eof = 0;
  237.     switch (whence) {
  238.     case SEEK_CUR:
  239.         if (p->buffer_end - p->buffer < offset)
  240.             p->eof = 1;
  241.         offset     = av_clip(offset, -(p->buffer - p->buffer_start),
  242.                              p->buffer_end - p->buffer);
  243.         p->buffer += offset;
  244.         break;
  245.     case SEEK_END:
  246.         if (offset > 0)
  247.             p->eof = 1;
  248.         offset    = av_clip(offset, -(p->buffer_end - p->buffer_start), 0);
  249.         p->buffer = p->buffer_end + offset;
  250.         break;
  251.     case SEEK_SET:
  252.         if (p->buffer_end - p->buffer_start < offset)
  253.             p->eof = 1;
  254.         offset    = av_clip(offset, 0, p->buffer_end - p->buffer_start);
  255.         p->buffer = p->buffer_start + offset;
  256.         break;
  257.     default:
  258.         return AVERROR(EINVAL);
  259.     }
  260.     return bytestream2_tell_p(p);
  261. }
  262.  
  263. static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
  264.                                                             uint8_t *dst,
  265.                                                             unsigned int size)
  266. {
  267.     int size2 = FFMIN(g->buffer_end - g->buffer, size);
  268.     memcpy(dst, g->buffer, size2);
  269.     g->buffer += size2;
  270.     return size2;
  271. }
  272.  
  273. static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g,
  274.                                                              uint8_t *dst,
  275.                                                              unsigned int size)
  276. {
  277.     memcpy(dst, g->buffer, size);
  278.     g->buffer += size;
  279.     return size;
  280. }
  281.  
  282. static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
  283.                                                             const uint8_t *src,
  284.                                                             unsigned int size)
  285. {
  286.     int size2;
  287.     if (p->eof)
  288.         return 0;
  289.     size2 = FFMIN(p->buffer_end - p->buffer, size);
  290.     if (size2 != size)
  291.         p->eof = 1;
  292.     memcpy(p->buffer, src, size2);
  293.     p->buffer += size2;
  294.     return size2;
  295. }
  296.  
  297. static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p,
  298.                                                              const uint8_t *src,
  299.                                                              unsigned int size)
  300. {
  301.     memcpy(p->buffer, src, size);
  302.     p->buffer += size;
  303.     return size;
  304. }
  305.  
  306. static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
  307.                                                     const uint8_t c,
  308.                                                     unsigned int size)
  309. {
  310.     int size2;
  311.     if (p->eof)
  312.         return;
  313.     size2 = FFMIN(p->buffer_end - p->buffer, size);
  314.     if (size2 != size)
  315.         p->eof = 1;
  316.     memset(p->buffer, c, size2);
  317.     p->buffer += size2;
  318. }
  319.  
  320. static av_always_inline void bytestream2_set_bufferu(PutByteContext *p,
  321.                                                      const uint8_t c,
  322.                                                      unsigned int size)
  323. {
  324.     memset(p->buffer, c, size);
  325.     p->buffer += size;
  326. }
  327.  
  328. static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
  329. {
  330.     return p->eof;
  331. }
  332.  
  333. static av_always_inline unsigned int bytestream2_copy_bufferu(PutByteContext *p,
  334.                                                               GetByteContext *g,
  335.                                                               unsigned int size)
  336. {
  337.     memcpy(p->buffer, g->buffer, size);
  338.     p->buffer += size;
  339.     g->buffer += size;
  340.     return size;
  341. }
  342.  
  343. static av_always_inline unsigned int bytestream2_copy_buffer(PutByteContext *p,
  344.                                                              GetByteContext *g,
  345.                                                              unsigned int size)
  346. {
  347.     int size2;
  348.  
  349.     if (p->eof)
  350.         return 0;
  351.     size  = FFMIN(g->buffer_end - g->buffer, size);
  352.     size2 = FFMIN(p->buffer_end - p->buffer, size);
  353.     if (size2 != size)
  354.         p->eof = 1;
  355.  
  356.     return bytestream2_copy_bufferu(p, g, size2);
  357. }
  358.  
  359. static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b,
  360.                                                            uint8_t *dst,
  361.                                                            unsigned int size)
  362. {
  363.     memcpy(dst, *b, size);
  364.     (*b) += size;
  365.     return size;
  366. }
  367.  
  368. static av_always_inline void bytestream_put_buffer(uint8_t **b,
  369.                                                    const uint8_t *src,
  370.                                                    unsigned int size)
  371. {
  372.     memcpy(*b, src, size);
  373.     (*b) += size;
  374. }
  375.  
  376. #endif /* AVCODEC_BYTESTREAM_H */
  377.