| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "vpx_ports/mem.h" | 11 #include "vpx_ports/mem.h" |
| 12 #include "vpx_mem/vpx_mem.h" | 12 #include "vpx_mem/vpx_mem.h" |
| 13 | 13 |
| 14 #include "vp9/decoder/vp9_dboolhuff.h" | 14 #include "vp9/decoder/vp9_dboolhuff.h" |
| 15 | 15 |
| 16 // This is meant to be a large, positive constant that can still be efficiently | 16 // This is meant to be a large, positive constant that can still be efficiently |
| 17 // loaded as an immediate (on platforms like ARM, for example). | 17 // loaded as an immediate (on platforms like ARM, for example). |
| 18 // Even relatively modest values like 100 would work fine. | 18 // Even relatively modest values like 100 would work fine. |
| 19 #define VP9_LOTS_OF_BITS 0x40000000 | 19 #define LOTS_OF_BITS 0x40000000 |
| 20 | 20 |
| 21 | 21 |
| 22 int vp9_reader_init(vp9_reader *r, const uint8_t *buffer, size_t size) { | 22 int vp9_reader_init(vp9_reader *r, const uint8_t *buffer, size_t size) { |
| 23 int marker_bit; | 23 int marker_bit; |
| 24 | 24 |
| 25 r->buffer_end = buffer + size; | 25 r->buffer_end = buffer + size; |
| 26 r->buffer = buffer; | 26 r->buffer = buffer; |
| 27 r->value = 0; | 27 r->value = 0; |
| 28 r->count = -8; | 28 r->count = -8; |
| 29 r->range = 255; | 29 r->range = 255; |
| 30 | 30 |
| 31 if (size && !buffer) | 31 if (size && !buffer) |
| 32 return 1; | 32 return 1; |
| 33 | 33 |
| 34 vp9_reader_fill(r); | 34 vp9_reader_fill(r); |
| 35 marker_bit = vp9_read_bit(r); | 35 marker_bit = vp9_read_bit(r); |
| 36 return marker_bit != 0; | 36 return marker_bit != 0; |
| 37 } | 37 } |
| 38 | 38 |
| 39 void vp9_reader_fill(vp9_reader *r) { | 39 void vp9_reader_fill(vp9_reader *r) { |
| 40 const uint8_t *const buffer_end = r->buffer_end; | 40 const uint8_t *const buffer_end = r->buffer_end; |
| 41 const uint8_t *buffer = r->buffer; | 41 const uint8_t *buffer = r->buffer; |
| 42 VP9_BD_VALUE value = r->value; | 42 VP9_BD_VALUE value = r->value; |
| 43 int count = r->count; | 43 int count = r->count; |
| 44 int shift = VP9_BD_VALUE_SIZE - 8 - (count + 8); | 44 int shift = BD_VALUE_SIZE - 8 - (count + 8); |
| 45 int loop_end = 0; | 45 int loop_end = 0; |
| 46 const int bits_left = (int)((buffer_end - buffer)*CHAR_BIT); | 46 const int bits_left = (int)((buffer_end - buffer)*CHAR_BIT); |
| 47 const int x = shift + CHAR_BIT - bits_left; | 47 const int x = shift + CHAR_BIT - bits_left; |
| 48 | 48 |
| 49 if (x >= 0) { | 49 if (x >= 0) { |
| 50 count += VP9_LOTS_OF_BITS; | 50 count += LOTS_OF_BITS; |
| 51 loop_end = x; | 51 loop_end = x; |
| 52 } | 52 } |
| 53 | 53 |
| 54 if (x < 0 || bits_left) { | 54 if (x < 0 || bits_left) { |
| 55 while (shift >= loop_end) { | 55 while (shift >= loop_end) { |
| 56 count += CHAR_BIT; | 56 count += CHAR_BIT; |
| 57 value |= (VP9_BD_VALUE)*buffer++ << shift; | 57 value |= (VP9_BD_VALUE)*buffer++ << shift; |
| 58 shift -= CHAR_BIT; | 58 shift -= CHAR_BIT; |
| 59 } | 59 } |
| 60 } | 60 } |
| 61 | 61 |
| 62 r->buffer = buffer; | 62 r->buffer = buffer; |
| 63 r->value = value; | 63 r->value = value; |
| 64 r->count = count; | 64 r->count = count; |
| 65 } | 65 } |
| 66 | 66 |
| 67 const uint8_t *vp9_reader_find_end(vp9_reader *r) { | 67 const uint8_t *vp9_reader_find_end(vp9_reader *r) { |
| 68 // Find the end of the coded buffer | 68 // Find the end of the coded buffer |
| 69 while (r->count > CHAR_BIT && r->count < VP9_BD_VALUE_SIZE) { | 69 while (r->count > CHAR_BIT && r->count < BD_VALUE_SIZE) { |
| 70 r->count -= CHAR_BIT; | 70 r->count -= CHAR_BIT; |
| 71 r->buffer--; | 71 r->buffer--; |
| 72 } | 72 } |
| 73 return r->buffer; | 73 return r->buffer; |
| 74 } | 74 } |
| 75 | 75 |
| 76 int vp9_reader_has_error(vp9_reader *r) { | 76 int vp9_reader_has_error(vp9_reader *r) { |
| 77 // Check if we have reached the end of the buffer. | 77 // Check if we have reached the end of the buffer. |
| 78 // | 78 // |
| 79 // Variable 'count' stores the number of bits in the 'value' buffer, minus | 79 // Variable 'count' stores the number of bits in the 'value' buffer, minus |
| 80 // 8. The top byte is part of the algorithm, and the remainder is buffered | 80 // 8. The top byte is part of the algorithm, and the remainder is buffered |
| 81 // to be shifted into it. So if count == 8, the top 16 bits of 'value' are | 81 // to be shifted into it. So if count == 8, the top 16 bits of 'value' are |
| 82 // occupied, 8 for the algorithm and 8 in the buffer. | 82 // occupied, 8 for the algorithm and 8 in the buffer. |
| 83 // | 83 // |
| 84 // When reading a byte from the user's buffer, count is filled with 8 and | 84 // When reading a byte from the user's buffer, count is filled with 8 and |
| 85 // one byte is filled into the value buffer. When we reach the end of the | 85 // one byte is filled into the value buffer. When we reach the end of the |
| 86 // data, count is additionally filled with VP9_LOTS_OF_BITS. So when | 86 // data, count is additionally filled with LOTS_OF_BITS. So when |
| 87 // count == VP9_LOTS_OF_BITS - 1, the user's data has been exhausted. | 87 // count == LOTS_OF_BITS - 1, the user's data has been exhausted. |
| 88 // | 88 // |
| 89 // 1 if we have tried to decode bits after the end of stream was encountered. | 89 // 1 if we have tried to decode bits after the end of stream was encountered. |
| 90 // 0 No error. | 90 // 0 No error. |
| 91 return r->count > VP9_BD_VALUE_SIZE && r->count < VP9_LOTS_OF_BITS; | 91 return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; |
| 92 } | 92 } |
| OLD | NEW |