Avoid double zero-checking block after zero blocks
authorMathis Rosenhauer <rosenhauer@dkrz.de>
Wed, 5 Dec 2012 14:21:56 +0000 (15:21 +0100)
committerThomas Jahns <jahns@dkrz.de>
Tue, 19 Feb 2013 10:33:02 +0000 (11:33 +0100)
src/encode.c
src/encode.h

index a937a7b..5f75eae 100644 (file)
@@ -425,6 +425,31 @@ static int assess_se_option(uint64_t limit, struct aec_stream *strm)
     return len;
 }
 
+static void init_output(struct aec_stream *strm)
+{
+    /**
+       Direct output to next_out if next_out can hold a Coded Data
+       Set, use internal buffer otherwise.
+    */
+
+    struct internal_state *state = strm->state;
+
+    if (strm->avail_out > state->cds_len) {
+        if (!state->direct_out) {
+            state->direct_out = 1;
+            *strm->next_out = *state->cds;
+            state->cds = strm->next_out;
+        }
+    } else {
+        if (state->zero_blocks == 0 || state->direct_out) {
+            /* copy leftover from last block */
+            *state->cds_buf = *state->cds;
+            state->cds = state->cds_buf;
+        }
+        state->direct_out = 0;
+    }
+}
+
 /*
  *
  * FSM functions
@@ -596,10 +621,9 @@ static int m_check_zero_block(struct aec_stream *strm)
         if (state->zero_blocks) {
             /* The current block isn't zero but we have to emit a
              * previous zero block first. The current block will be
-             * handled later.
+             * flagged and handled later.
              */
-            state->block -= strm->block_size;
-            state->blocks_avail++;
+            state->block_nonzero = 1;
             state->mode = m_encode_zero;
             return M_CONTINUE;
         }
@@ -682,19 +706,12 @@ static int m_get_block(struct aec_stream *strm)
 
     struct internal_state *state = strm->state;
 
-    if (strm->avail_out > state->cds_len) {
-        if (!state->direct_out) {
-            state->direct_out = 1;
-            *strm->next_out = *state->cds;
-            state->cds = strm->next_out;
-        }
-    } else {
-        if (state->zero_blocks == 0 || state->direct_out) {
-            /* copy leftover from last block */
-            *state->cds_buf = *state->cds;
-            state->cds = state->cds_buf;
-        }
-        state->direct_out = 0;
+    init_output(strm);
+
+    if (state->block_nonzero) {
+        state->block_nonzero = 0;
+        state->mode = m_select_code_option;
+        return M_CONTINUE;
     }
 
     if (state->blocks_avail == 0) {
index 9c0a1af..8bcf6db 100644 (file)
@@ -95,6 +95,8 @@ struct internal_state {
     int zero_ref;           /* current zero block has a reference sample */
     int64_t zero_ref_sample;/* reference sample of zero block */
     int zero_blocks;        /* number of contiguous zero blocks */
+    int block_nonzero;      /* 1 if this is the first non-zero block
+                             * after one or more zero blocks */
     int k;                  /* splitting position */
     int kmax;               /* maximum number for k depending on id_len */
     int flush;              /* flush option copied from argument */