code wiki / (root) / nx_jpeg_zigzag.nx

nx_jpeg_zigzag.nx source

↩ module page · 62 lines · 2645 B

1// nx_jpeg_zigzag.nx -- inverse zig-zag scan order for JPEG 8x8 blocks. 2// Per ITU-T Rec. T.81 Fig. A.6 / table H.1. 3// 4// JPEG stores DCT coefficients in zig-zag order to cluster non-zero 5// coefficients near the start of the stream (improves run-length 6// coding efficiency). Decoding pipeline needs the inverse: 7// 8// natural_block[un_zigzag[k]] = zigzag_block[k] 9// 10// for k in 0..63. This file ships the 64-entry inverse-zigzag table 11// AND a primitive that applies it to an 8x8 i64 coefficient block. 12// 13// The zig-zag scan visits 8x8 block positions in this order 14// (T.81 Fig. A.6): 15// 16// 0 1 5 6 14 15 27 28 17// 2 4 7 13 16 26 29 42 18// 3 8 12 17 25 30 41 43 19// 9 11 18 24 31 40 44 53 20// 10 19 23 32 39 45 52 54 21// 20 22 33 38 46 51 55 60 22// 21 34 37 47 50 56 59 61 23// 35 36 48 49 57 58 62 63 24// 25// nx_safety_envelope: 26// intended_use: "8x8 DCT-block un-zigzag for JPEG decode." 27// sil_target: SIL1 28// evidence: [t81_figure_a6_canonical_basis, 29// fixed_64_entry_table_bit_exact_reproducible] 30// verdict: NOT_YET_EVALUATED 31 32import "nx_syscalls.nx" 33 34// Initialise a caller-supplied 64-entry i64 buffer with the inverse 35// zigzag table: un_zigzag[k] = natural-order position of the k-th 36// zigzag-order coefficient. 37func nx_jpeg_zigzag_inverse_table(out: *i64) -> i64 { 38 out[ 0]= 0; out[ 1]= 1; out[ 2]= 8; out[ 3]=16; out[ 4]= 9; out[ 5]= 2; out[ 6]= 3; out[ 7]=10 39 out[ 8]=17; out[ 9]=24; out[10]=32; out[11]=25; out[12]=18; out[13]=11; out[14]= 4; out[15]= 5 40 out[16]=12; out[17]=19; out[18]=26; out[19]=33; out[20]=40; out[21]=48; out[22]=41; out[23]=34 41 out[24]=27; out[25]=20; out[26]=13; out[27]= 6; out[28]= 7; out[29]=14; out[30]=21; out[31]=28 42 out[32]=35; out[33]=42; out[34]=49; out[35]=56; out[36]=57; out[37]=50; out[38]=43; out[39]=36 43 out[40]=29; out[41]=22; out[42]=15; out[43]=23; out[44]=30; out[45]=37; out[46]=44; out[47]=51 44 out[48]=58; out[49]=59; out[50]=52; out[51]=45; out[52]=38; out[53]=31; out[54]=39; out[55]=46 45 out[56]=53; out[57]=60; out[58]=61; out[59]=54; out[60]=47; out[61]=55; out[62]=62; out[63]=63 46 return 0 47} 48 49// Apply inverse zig-zag to a 64-entry coefficient array. 50// src[k] = zigzag-order coefficient k 51// dst[natural_pos] = src[k] where natural_pos = un_zigzag[k] 52// `dst` must NOT alias `src` (caller responsibility). 53func nx_jpeg_un_zigzag(src: *i64, dst: *i64) -> i64 { 54 let table: *i64 = sys_mmap(64 * 8) as *i64 55 nx_jpeg_zigzag_inverse_table(table) 56 var k: i64 = 0 57 while k < 64 { 58 dst[table[k]] = src[k] 59 k = k + 1 60 } 61 return 0 62}