]> git.sesse.net Git - narabu/blobdiff - qdc.cpp
Prepare for more flexible slices.
[narabu] / qdc.cpp
diff --git a/qdc.cpp b/qdc.cpp
index 951915225f8784ff1ede25c8978db48ea6395a2a..556a8a5d541315a54d6bddf332cdd746a5c1769a 100644 (file)
--- a/qdc.cpp
+++ b/qdc.cpp
 
 #define WIDTH 1280
 #define HEIGHT 720
+#define WIDTH_BLOCKS (WIDTH/8)
+#define WIDTH_BLOCKS_CHROMA (WIDTH/16)
+#define HEIGHT_BLOCKS (HEIGHT/8)
+#define NUM_BLOCKS (WIDTH_BLOCKS * HEIGHT_BLOCKS)
+#define NUM_BLOCKS_CHROMA (WIDTH_BLOCKS_CHROMA * HEIGHT_BLOCKS)
 #define NUM_SYMS 256
 #define ESCAPE_LIMIT (NUM_SYMS - 1)
 
@@ -212,7 +217,7 @@ public:
                        printf("%d: cumfreqs=%d freqs=%d prob_bits=%d\n", i, s.cum_freqs[i], s.freqs[i], prob_bits + 1);
                        RansEncSymbolInit(&esyms[i], s.cum_freqs[i], s.freqs[i], prob_bits + 1);
                }
-               sign_bias = s.cum_freqs[256];
+               sign_bias = s.cum_freqs[NUM_SYMS];
        }
 
        void clear()
@@ -270,7 +275,7 @@ public:
                        RansEncPut(&rans, &ptr, k, 1, prob_bits);
                        k = ESCAPE_LIMIT;
                }
-               RansEncPutSymbol(&rans, &ptr, &esyms[(k - 1) & 255]);
+               RansEncPutSymbol(&rans, &ptr, &esyms[(k - 1) & (NUM_SYMS - 1)]);
                if (signed_k < 0) {
                        rans += sign_bias;
                }
@@ -404,7 +409,7 @@ void find_optimal_stream_assignment(int base)
        double inv_sum[64];
        for (unsigned i = 0; i < 64; ++i) {
                double s = 0.0;
-               for (unsigned k = 0; k < 256; ++k) {
+               for (unsigned k = 0; k < NUM_SYMS; ++k) {
                        s += stats[i + base].freqs[k] + 0.5;
                }
                inv_sum[i] = 1.0 / s;
@@ -413,7 +418,7 @@ void find_optimal_stream_assignment(int base)
        for (unsigned i = 0; i < 64; ++i) {
                for (unsigned j = 0; j < 64; ++j) {
                        double d = 0.0;
-                       for (unsigned k = 0; k < 256; ++k) {
+                       for (unsigned k = 0; k < NUM_SYMS; ++k) {
                                double p1 = (stats[i + base].freqs[k] + 0.5) * inv_sum[i];
                                double p2 = (stats[j + base].freqs[k] + 0.5) * inv_sum[j];
 
@@ -720,6 +725,12 @@ int main(int argc, char **argv)
                        coeff_y[yb * WIDTH + xb] -= coeff_y[yb * WIDTH + (xb + 8)];
                }
        }
+       for (unsigned yb = 0; yb < HEIGHT; yb += 8) {
+               for (unsigned xb = 0; xb < WIDTH/2 - 8; xb += 8) {
+                       coeff_cb[yb * WIDTH/2 + xb] -= coeff_cb[yb * WIDTH/2 + (xb + 8)];
+                       coeff_cr[yb * WIDTH/2 + xb] -= coeff_cr[yb * WIDTH/2 + (xb + 8)];
+               }
+       }
 
        FILE *fp = fopen("reconstructed.pgm", "wb");
        fprintf(fp, "P5\n%d %d\n255\n", WIDTH, HEIGHT);
@@ -771,7 +782,7 @@ int main(int argc, char **argv)
                                                k = ESCAPE_LIMIT;
                                                extra_bits += 12;  // escape this one
                                        }
-                                       ++s_luma.freqs[(k - 1) & 255];
+                                       ++s_luma.freqs[(k - 1) & (NUM_SYMS - 1)];
                                }
                        }
                        // Chroma
@@ -787,8 +798,8 @@ int main(int argc, char **argv)
                                                k_cr = ESCAPE_LIMIT;
                                                extra_bits += 12;  // escape this one
                                        }
-                                       ++s_chroma.freqs[(k_cb - 1) & 255];
-                                       ++s_chroma.freqs[(k_cr - 1) & 255];
+                                       ++s_chroma.freqs[(k_cb - 1) & (NUM_SYMS - 1)];
+                                       ++s_chroma.freqs[(k_cr - 1) & (NUM_SYMS - 1)];
                                }
                        }
                }
@@ -803,10 +814,10 @@ int main(int argc, char **argv)
 #endif
 
        for (unsigned i = 0; i < 64; ++i) {
-               stats[i].freqs[255] /= 2;  // zero, has no sign bits (yes, this is trickery)
+               stats[i].freqs[NUM_SYMS - 1] /= 2;  // zero, has no sign bits (yes, this is trickery)
                stats[i].normalize_freqs(prob_scale);
-               stats[i].cum_freqs[256] += stats[i].freqs[255];
-               stats[i].freqs[255] *= 2;
+               stats[i].cum_freqs[NUM_SYMS] += stats[i].freqs[NUM_SYMS - 1];
+               stats[i].freqs[NUM_SYMS - 1] *= 2;
        }
 
        FILE *codedfp = fopen("coded.dat", "wb");
@@ -842,21 +853,20 @@ int main(int argc, char **argv)
                        // need to reverse later
                        rans_encoder.clear();
                        size_t num_bytes = 0;
-                       for (unsigned yb = 0; yb < HEIGHT; yb += 8) {
-                               for (unsigned xb = 0; xb < WIDTH; xb += 8) {
-                                       int k = coeff_y[(yb + y) * WIDTH + (xb + x)];
-                                       //printf("encoding coeff %d xb,yb=%d,%d: %d\n", y*8+x, xb, yb, k);
-                                       rans_encoder.encode_coeff(k);
-                               }
-                               if (yb % 16 == 8) {
+                       for (unsigned block_idx = 0; block_idx < NUM_BLOCKS; ++block_idx) {
+                               unsigned yb = block_idx / WIDTH_BLOCKS;
+                               unsigned xb = block_idx % WIDTH_BLOCKS;
+
+                               int k = coeff_y[(yb * 8 + y) * WIDTH + (xb * 8 + x)];
+                               //printf("encoding coeff %d xb,yb=%d,%d: %d\n", y*8+x, xb, yb, k);
+                               rans_encoder.encode_coeff(k);
+
+                               if (block_idx % 320 == 319 || block_idx == NUM_BLOCKS - 1) {
                                        int l = rans_encoder.save_block(codedfp);
                                        num_bytes += l;
                                        lens.push_back(l);
                                }
                        }
-                       if (HEIGHT % 16 != 0) {
-                               num_bytes += rans_encoder.save_block(codedfp);
-                       }
                        tot_bytes += num_bytes;
                        printf("coeff %d Y': %ld bytes\n", y * 8 + x, num_bytes);
 
@@ -883,18 +893,18 @@ int main(int argc, char **argv)
 
                        rans_encoder.clear();
                        size_t num_bytes = 0;
-                       for (unsigned yb = 0; yb < HEIGHT; yb += 8) {
-                               for (unsigned xb = 0; xb < WIDTH/2; xb += 8) {
-                                       int k = coeff_cb[(yb + y) * WIDTH/2 + (xb + x)];
-                                       rans_encoder.encode_coeff(k);
-                               }
-                               if (yb % 16 == 8) {
+                       for (unsigned block_idx = 0; block_idx < NUM_BLOCKS_CHROMA; ++block_idx) {
+                               unsigned yb = block_idx / WIDTH_BLOCKS_CHROMA;
+                               unsigned xb = block_idx % WIDTH_BLOCKS_CHROMA;
+
+                               int k = coeff_cb[(yb * 8 + y) * WIDTH/2 + (xb * 8 + x)];
+                               //printf("encoding coeff %d xb,yb=%d,%d: %d\n", y*8+x, xb, yb, k);
+                               rans_encoder.encode_coeff(k);
+
+                               if (block_idx % 320 == 319 || block_idx == NUM_BLOCKS - 1) {
                                        num_bytes += rans_encoder.save_block(codedfp);
                                }
                        }
-                       if (HEIGHT % 16 != 0) {
-                               num_bytes += rans_encoder.save_block(codedfp);
-                       }
                        tot_bytes += num_bytes;
                        printf("coeff %d Cb: %ld bytes\n", y * 8 + x, num_bytes);
                }
@@ -908,18 +918,18 @@ int main(int argc, char **argv)
 
                        rans_encoder.clear();
                        size_t num_bytes = 0;
-                       for (unsigned yb = 0; yb < HEIGHT; yb += 8) {
-                               for (unsigned xb = 0; xb < WIDTH/2; xb += 8) {
-                                       int k = coeff_cr[(yb + y) * WIDTH/2 + (xb + x)];
-                                       rans_encoder.encode_coeff(k);
-                               }
-                               if (yb % 16 == 8) {
+                       for (unsigned block_idx = 0; block_idx < NUM_BLOCKS_CHROMA; ++block_idx) {
+                               unsigned yb = block_idx / WIDTH_BLOCKS_CHROMA;
+                               unsigned xb = block_idx % WIDTH_BLOCKS_CHROMA;
+
+                               int k = coeff_cr[(yb * 8 + y) * WIDTH/2 + (xb * 8 + x)];
+                               //printf("encoding coeff %d xb,yb=%d,%d: %d\n", y*8+x, xb, yb, k);
+                               rans_encoder.encode_coeff(k);
+
+                               if (block_idx % 320 == 319 || block_idx == NUM_BLOCKS - 1) {
                                        num_bytes += rans_encoder.save_block(codedfp);
                                }
                        }
-                       if (HEIGHT % 16 != 0) {
-                               num_bytes += rans_encoder.save_block(codedfp);
-                       }
                        tot_bytes += num_bytes;
                        printf("coeff %d Cr: %ld bytes\n", y * 8 + x, num_bytes);
                }