aboutsummaryrefslogtreecommitdiffstats
path: root/lib/xz/xz_dec_bcj.c
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2011-10-27 15:01:19 -0700
committerColin Cross <ccross@android.com>2011-10-27 15:01:19 -0700
commit2bb3e310159b65c88caf0c67a20ed257568be267 (patch)
treee4ad01c06a9e27939781c5dd9d0cb92e6fcd54d5 /lib/xz/xz_dec_bcj.c
parent2f53cb72c1574d3880d9e88e254b756565fe2f6d (diff)
parent97596c34030ed28657ccafddb67e17a03890b90a (diff)
downloadkernel_samsung_tuna-2bb3e310159b65c88caf0c67a20ed257568be267.zip
kernel_samsung_tuna-2bb3e310159b65c88caf0c67a20ed257568be267.tar.gz
kernel_samsung_tuna-2bb3e310159b65c88caf0c67a20ed257568be267.tar.bz2
Merge commit 'v3.0.8' into android-3.0
Diffstat (limited to 'lib/xz/xz_dec_bcj.c')
-rw-r--r--lib/xz/xz_dec_bcj.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/xz/xz_dec_bcj.c b/lib/xz/xz_dec_bcj.c
index e51e255..a768e6d 100644
--- a/lib/xz/xz_dec_bcj.c
+++ b/lib/xz/xz_dec_bcj.c
@@ -441,8 +441,12 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
* next filter in the chain. Apply the BCJ filter on the new data
* in the output buffer. If everything cannot be filtered, copy it
* to temp and rewind the output buffer position accordingly.
+ *
+ * This needs to be always run when temp.size == 0 to handle a special
+ * case where the output buffer is full and the next filter has no
+ * more output coming but hasn't returned XZ_STREAM_END yet.
*/
- if (s->temp.size < b->out_size - b->out_pos) {
+ if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) {
out_start = b->out_pos;
memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
b->out_pos += s->temp.size;
@@ -465,16 +469,25 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
s->temp.size = b->out_pos - out_start;
b->out_pos -= s->temp.size;
memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
+
+ /*
+ * If there wasn't enough input to the next filter to fill
+ * the output buffer with unfiltered data, there's no point
+ * to try decoding more data to temp.
+ */
+ if (b->out_pos + s->temp.size < b->out_size)
+ return XZ_OK;
}
/*
- * If we have unfiltered data in temp, try to fill by decoding more
- * data from the next filter. Apply the BCJ filter on temp. Then we
- * hopefully can fill the actual output buffer by copying filtered
- * data from temp. A mix of filtered and unfiltered data may be left
- * in temp; it will be taken care on the next call to this function.
+ * We have unfiltered data in temp. If the output buffer isn't full
+ * yet, try to fill the temp buffer by decoding more data from the
+ * next filter. Apply the BCJ filter on temp. Then we hopefully can
+ * fill the actual output buffer by copying filtered data from temp.
+ * A mix of filtered and unfiltered data may be left in temp; it will
+ * be taken care on the next call to this function.
*/
- if (s->temp.size > 0) {
+ if (b->out_pos < b->out_size) {
/* Make b->out{,_pos,_size} temporarily point to s->temp. */
s->out = b->out;
s->out_pos = b->out_pos;