Abstract:
A method and a decoding or coding device for calculating at least one of run and level representations of respective quantized transform coefficients representing pixel values in a block of a video picture inserted in a coefficient array is disclosed. The method and the decoding or coding device are adjusted to generate a bitmask of the quantized transform coefficients, respectively perform a look up of the 8 least significant bits and the 8 most significant bits of the bitmask in a look up table, patch the looked up lower part and upper part bytemap values and insert the bytes of the first bytemap array from index position 8 minus the number of non-zeros in the 8 least significant bits of the bitmask.

Description:
CROSS-REFERENCE TO RELATED APPLICATION 
       [0001]    This application is related to and claims priority to U.S. Provisional Patent Application No. 61/746,703, filed Dec. 28, 2012, entitled SIMULTANEOUS AND LOOPLESS VECTOR CALCULATION OF ALL RUN-LEVEL PAIRS IN VIDEO COMPRESSION, and is related to and claims priority to Norwegian Patent Application No. 20121570, the entirety of both of which are incorporated herein by reference. 
     
    
     FIELD OF THE INVENTION 
       [0002]    The present disclosure relates to an implementation of entropy coding/decoding of transform coefficient data of video compression systems in computer devices or systems. 
       BACKGROUND OF THE INVENTION 
       [0003]    Transmission of moving pictures in real time is employed in several applications such as, but not limited to, video conferencing, net meetings, television (TV) broadcasting, and video telephony. Representing moving pictures requires bulk information as digital video typically is described by representing each pixel in a picture with 8 bits, which is equal to 1 byte. Such uncompressed video data results in large bit volumes, and cannot be transferred over conventional communication networks and transmission lines in real time due to limited bandwidth. 
         [0004]    Thus, enabling real time video transmission requires a large extent of data compression. Data compression may, however, compromise the picture quality. Therefore, great efforts have been made to develop compression techniques allowing real time transmission of high quality video over bandwidth limited data connections. In video compression systems, the main goal is to represent the video information with as little capacity as possible. Capacity is defined with bits, either as a constant value or as bits/time unit. In both cases, the goal is to reduce the number of bits. A conventional video coding method is described in the Moving Picture Experts Group (MPEG) and H.26 standards. The video data undergoes four main processes before transmission (i.e., the prediction process, the transformation process, the quantization process, and the entropy coding). 
         [0005]    The prediction process reduces the amount of bits required for each picture in a video sequence to be transferred. The process takes advantage of the similarity of parts of the sequence with other parts of the sequence. Since the predictor part is known to both encoder and decoder, only the difference has to be transferred. This difference typically requires much less capacity for its representation. The prediction is mainly based on vectors representing movements. The prediction process is conventionally performed on square block sizes (e.g., 16×16 pixels). Note that in some cases, predictions of pixels based on adjacent pixels in the same picture, rather than pixels of preceding pictures, are used. This is referred to as intra prediction (not to be confused with inter prediction). The residual represented as a block of data (e.g., 4×4 pixels) still contains internal correlation. A conventional method which takes advantage of this and performs a two-dimensional block transform. In H.263, an 8×8 Discrete Cosine Transform (DCT) is used, whereas in H.264, a 4×4 integer-type transform is used. This transforms 4×4 pixels into 4×4 transform coefficients which can usually be represented by fewer0 bits than the pixel representation. Transform of a 4×4 array of pixels with internal correlation may result in a 4×4 block of transform coefficients with much fewer nonzero values than the original 4×4 pixel block. 
         [0006]    Direct representation of the transform coefficients is too costly for many applications. A quantization process is carried out for a further reduction of the data representation. Hence, the transform coefficients undergo quantization. One way of quantization is to divide parameter values by a number, which results in a smaller number that may be represented by fewer bits. This quantization process results in the reconstructed video sequence being somewhat different from the uncompressed sequence. This phenomenon is referred to as “lossy coding.” The outcome from the quantization part is referred to as quantized transform coefficients. 
         [0007]    Entropy coding is a special form of lossless data compression. Entropy coding involves arranging the image components in a “zigzag” order employing a run-length encoding (RLE) algorithm that groups similar frequencies together, inserting length coding zeros, and then using Huffman coding on what is left. 
         [0008]    In H.264 encoding, the DCT coefficients for a block are reordered in order to group together non-zero coefficients in an array, enabling efficient representation of the remaining zero-valued coefficients.  FIG. 1  shows the zigzag reordering path (i.e., scan order). The pattern of the order of the zigzag scan is configured according to the probability of non-zero coefficients in each positions. Due to the characteristics of the preceding DCT, the probability of non-zero coefficients in a block decreases in the downward right diagonal direction of a DCT block. When reordering the coefficients in a zigzag pattern, as illustrated in  FIG. 1 , the non-zero coefficients generally tend to concentrate in the first positions of the array. 
         [0009]    The output of the reordering process includes a one-dimensional array that contains one or more clusters of non-zero coefficients near the start, followed by strings of zero coefficients. Due to the large number of zero values, the array is further represented as a series of (run, level) pairs, where “run” indicates the number of zeros preceding a non-zero coefficient, and “level” indicates the magnitude of the non-zero coefficient. As an example, the input array 7, −3, 0, 0, 0, 0, 3, −1, 2, −1, 0, 0, 0, 1, 0, 1 will have the following corresponding run-level values: (0,7), (0,−3), (4,3), (0,−1), (0,2), (0,−1), (3,1) (1,1). When transforming the zigzag array to run-level values, it is computationally expensive to loop over all coefficients and check whether they are non-zero. 
         [0010]    Video encoding for HD formats increases the demands for memory and data processing, and requires efficient and high bandwidth memory organizations coupled with compute intensive capabilities. Due to these multiple demands, a flexible parallel processing approach must be found to meet the demands in a cost effective manner. 
         [0011]    Video codecs are typically installed on customized hardware in video endpoints with DSP based processors. However, it has recently become more common to install video codecs in general purpose processors with a SIMD processor environment. 
         [0012]    Therefore, there is a need for a time and processor efficient run/level or CAVLC (Context Aware Variable Length Coding) method taking advantage of the nature of the general purpose processors in a SIMD processor environment with no loops and without compromising with data quality. 
       SUMMARY OF THE INVENTION 
       [0013]    The embodiments herein discloses a method in a video coding or decoding process performed in a computer device for calculating run and/or level representations of respective quantized transform coefficients representing pixel values in a block of a video picture inserted in a coefficient array, comprising the steps of generating a bitmask array inserting “1” in corresponding positions of nonzero coefficients in the coefficient array and “0” in corresponding positions of zero coefficients in the coefficient array, respectively performing a look up of the 8 least significant bits and the 8 most significant bits of the bitmask in a look up table mapping all possible 8 bits bitmap values to corresponding lower part and upper part bytemap values, patching the looked up lower part and upper part bytemap values in a first bytemap array, and inserting the bytes of the first bytemap array from index position 8 minus the number of non-zeros in the 8 least significant bits of the bitmask in a second bytemap array. 
         [0014]    In some embodiments, the method also comprises a step of determining the level representation by reading consecutive bytes from the coefficient arrays being indexed by values of the second bytemap array. 
         [0015]    In some embodiments, the method also comprises the steps of creating a copy of the second bytemap array in a third bytemap array, adding +1 to each value of the third bytemap array, shifting the values of the third bytemap array to the right and subtracting the third bytemap array from the second bytemap array, resulting in values corresponding to the run representation. 
         [0016]    In some embodiments, the entries in the look up table are of 8 bytes size, the lower part values are right aligned, the upper part values are left aligned, and bytes not occupied by the lower part and upper part values are stuffed with −1&#39;s. 
         [0017]    In some embodiments, steps in the method are executed by SIMD instructions. 
         [0018]    The embodiments herein also discloses a coding or decoding device adjusted to calculate run and/or level representations of respective quantized transform coefficients representing pixel values in a block of a video picture inserted in a coefficient array, comprising means for generating a bitmask array inserting “1” in corresponding positions of nonzero coefficients in the coefficient array and “0” in corresponding positions of zero coefficients in the coefficient array, means for respectively performing a look up of the 8 least significant bits and the 8 most significant bits of the bitmask in a look up table mapping all possible 8 bits bitmap values to corresponding lower part and upper part bytemap values, means for patching the looked up 8 bytes lower part and upper part bytemap values in a first bytemap array, and means for inserting the bytes of the first bytemap array from index position 8 minus the number of non-zeros in the 8 least significant bits of the bitmask in a second bytemap array. 
         [0019]    In some embodiments, the coding or decoding device also comprises means for determining the level representation by reading consecutive bytes from the coefficient arrays being indexed by values of the second bytemap array. 
         [0020]    In some embodiments, the coding or decoding device also comprises means for creating a copy of the second bytemap array in a third bytemap array, means for adding +1 to each value of the third bytemap array, means for shifting the values of the third bytemap array to the right, means for subtracting the third bytemap array from the second bytemap array, resulting in values corresponding to the run representation. 
         [0021]    In some embodiments of the coding or decoding device, the entries in the look up table are of 8 bytes size, the lower part values are right aligned, the upper part values are left aligned, and bytes not occupied by the lower part and upper part values are stuffed with −1&#39;s. 
         [0022]    In some embodiments of the coding or decoding device, the means are implemented by SIMD instructions. 
     
    
     
       BRIEF DESCRIPTION OF THE DRAWINGS 
         [0023]      FIG. 1  shows a zigzag pattern indicating the coefficient order of a coefficient array within a block; 
           [0024]      FIG. 2  shows a flow chart illustrating how the run-level code is calculated in a conventional implementation; 
           [0025]      FIG. 3  is a flow chart illustrating the main steps of an embodiment according to the present invention; and 
           [0026]      FIG. 4A-4F  is a table disclosing a look-up table being used in one embodiment according to the present invention. 
       
    
    
     DETAILED DESCRIPTION OF THE INVENTION 
       [0027]      FIG. 2  is a flow chart illustrating how the run-level code, according to Moving Picture Experts Group (MPEG-4) and H.264, is calculated in a conventional implementation. After quantizing the transform coefficients (Quant C)  201  in a block, the Run variable and the position index (I) are set to zero  203 . Then, the quantized coefficients are reordered  205  to a one-dimensional array according to the aforementioned zigzag pattern  100  shown in  FIG. 1 . The process then enters into a loop for parsing the array to determine the run-level values. First, it is checked whether—the number of positions in the array is exceeded (i.e., I&gt;16) 207. If not, it is then checked whether current position in the array contains a zero  209 . If so, both the Run variable and the position index (I) are incremented, at steps  217  and  219 , and the process proceeds to the start of the loop. If the current position contains a non-zero value, the current Run variable and the value of the current position are stored as the Run-Level value, at steps  211  and  213 . The Run variable is then reset  215 , before both the Run variable and the position index (I) are incremented, at steps  217  and  219 , and the process proceeds to the start of the loop. The process ends whenever the position index (I) exceeds the maximum size of the array, which, in the example illustrated in  FIG. 2 , is 16. 
         [0028]    As can be seen from the conventional implementation illustrated in  FIG. 2 , the process always has to run through the run-level encoding loop as many times as there are positions in the array (i.e., 16 times in the example of  FIG. 2 ). This becomes very inefficient as most coefficients in C are zero, and it is computationally expensive to loop over all coefficients and check whether they are non-zero. 
         [0029]    According to embodiments disclosed herein, a simple and computationally cheap method where all nonzero coefficients quickly are determined simultaneously using table lookup and SIMD (Single Instructions, Multiple Data). 
         [0030]    In the following discussion, the same example of sequence of coefficients of a 4×4 block that has been quantized and reordered according to the standard as the one used in the above background section will be used, inserted in the following one dimensional coefficient array: 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
               
             
             
               
                 coefficients 
                 7 
                 −3 
                 0 
                 0 
                 0 
                 0 
                 3 
                 −1 
                 2 
                 −1 
                 0 
                 0 
                 0 
                 1 
                 0 
                 1 
               
               
                   
               
             
          
         
       
     
         [0031]    As already indicated, it is required to calculate level and run, where “level” simply are the nonzero coefficients stored sequentially, and “run” are the distance between two subsequent coefficients according to their original location 
         [0032]    The result to be achieved is therefore as follows: 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
                   
               
             
             
               
                   
                 level 
                 7 
                 −3 
                 3 
                 −1 
                 2 
                 −1 
                 1 
                 1 
               
               
                   
                 run 
                 0 
                 0 
                 4 
                 0 
                 0 
                 0 
                 3 
                 1 
               
               
                   
                   
               
             
          
         
       
     
         [0033]    In order to achieve this result, a so-called bit mask is generated where “1” denotes a nonzero coefficient and “0” denotes a coefficient that is zero. 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
               
             
             
               
                 coefficients 
                 7 
                 −3 
                 0 
                 0 
                 0 
                 0 
                 3 
                 −1 
                 2 
                 −1 
                 0 
                 0 
                 0 
                 1 
                 0 
                 1 
               
               
                 bitmask 
                 1 
                 1 
                 0 
                 0 
                 0 
                 0 
                 1 
                 1 
                 1 
                 1 
                 0 
                 0 
                 0 
                 1 
                 0 
                 1 
               
               
                   
               
             
          
         
       
     
         [0034]    Note that in the bit mask above, the leftmost bit is the least significant bit, and is therefore indexed 0. This will implicitly be taken into account in the further description, e.g. when referring to “lower” and “upper”. 
         [0035]    As run and level normally are calculated manually in an inefficient loop that iterates over the coefficients sequentially the inventor instead proposes, based on the bitmask, to generate a compact so-called bytemap that denotes the position of the nonzero coefficients, as follows: 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
             
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
               
               
                 Index 
                 0 
                 1 
                 2 
                 3 
                 4 
                 5 
                 6 
                 7 
                 8 
                 9 
                 10 
                 11 
                 12 
                 13 
                 14 
                 15 
               
               
                   
               
             
             
               
                   
               
             
          
           
               
                 coefficients 
                 7 
                 −3 
                 0 
                 0 
                 0 
                 0 
                 3 
                 −1 
                 2 
                 −1 
                 0 
                 0 
                 0 
                 1 
                 0 
                 1 
               
               
                 Bytemap 
                 0 
                 1 
                 6 
                 7 
                 8 
                 9 
                 13 
                 15 
               
               
                   
               
             
          
         
       
     
         [0036]    As can be seen, the byte map specifies the respective bit positions of the non-zero coefficients in the sequence of coefficients. 
         [0037]    Apparently, there is one unique bytemap for each possible bitmask pattern. The inventor therefore further proposes to map bytemaps to corresponding bitmasks in a lookup table. However, since one table would be too large for practical purposes as it would contain 256 elements of 16 bytes, altogether 1 MB, two tables are used where one table represents a lower part of the bytemap, and another table represents an upper part, each with 256 elements of 8 bytes, altogether only 4 KB. The mapping of the bytemap and bitmask of the example above will be as follows: 
         [0000]    Upper part:
 
Dec: 8,9,13,15 Hex:08090d0f=&gt;Dec:163 Bin:10100011
 
Lower part:
 
       Dec: 0,1,6,7 Hex: 00010607=&gt;Dec:195 Bin:11000011 
       [0038]    Note that the binary numbers above are flipped compared with the illustrated bitmask, due to the fact that the least significant bit is indexed 0 (as earlier mentioned). 
         [0039]    The two tables are further merged together so that bytemaps of the lower and the upper part corresponding to the same lower and upper part bitmap value are aligned. Such a merged table is illustrated in  FIG. 4A-4F . Here, all possible hexadecimal representations of the upper and lower part of the bytemaps are placed side by side together with the corresponding decimal representation of the bitmap. Also note that the elements in the lower table are right aligned and the elements in the upper table are left aligned, the reason of which will be apparent in the later discussion. Also note that the redundant bytes are stuffed with the hexadecimal ff, which in the following also may be referred to as −1. 
         [0040]    In the above example, a look up of the lower 8-bits “11000011”=195 in the table returns, 
         [0000]                                                                        −1   −1   −1   −1   0   1   6   7                        
Stuff bytes are set to “−1” intentionally.
 
         [0041]    A look up of the upper 8-bits “11000101”=163 in the table returns, 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
             
           
               
                   
                   
               
             
             
               
                   
                 8 
                 9 
                 13 
                 15 
                 −1 
                 −1 
                 −1 
                 −1 
               
               
                   
                   
               
             
          
         
       
     
         [0042]    These two are then patched together resulting in, 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
               
             
             
               
                 −1 
                 −1 
                 −1 
                 −1 
                 0 
                 1 
                 6 
                 7 
                 8 
                 9 
                 13 
                 15 
                 −1 
                 −1 
                 −1 
                 −1 
               
               
                   
               
             
          
         
       
     
         [0043]    This 16 byte array is then stored in a 24 byte buffer in a manner that always ensures that element 8 happens to be the starting position of the bytemap. Thus, it is proposed to calculate the number of bits set (equal to 1) in the upper 8-bits part of the mask, e.g. using the SIMD instruction POPCNT and store the 16 byte vector at this offset. In the example, there are 4 bits set in the upper part of the mask, and the result becomes: 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
               
               
                 23 
                 22 
                 21 
                 20 
                 19 
                 18 
                 17 
                 16 
                 15 
                 14 
                 13 
                 12 
                 11 
                 10 
                 9 
                 8 
                 7 
                 6 
                 5 
                 4 
                 3 
                 2 
                 1 
                 0 
               
               
                   
               
             
             
               
                 C 
                 C 
                 C 
                 C 
                 −1 
                 −1 
                 −1 
                 −1 
                 0 
                 1 
                 6 
                 7 
                 8 
                 9 
                 13 
                 15 
                 −1 
                 −1 
                 −1 
                 −1 
                 C 
                 C 
                 C 
                 C 
               
               
                   
               
             
          
         
       
     
         [0044]    Here, C denotes uninitialized bytes. Then, the 16 bytes from position 8 is read as follows: 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
               
               
                 23 
                 22 
                 21 
                 20 
                 19 
                 18 
                 17 
                 16 
                 15 
                 14 
                 13 
                 12 
                 11 
                 10 
                 9 
                 8 
               
               
                   
               
             
             
               
                 C 
                 C 
                 C 
                 C 
                 −1 
                 −1 
                 −1 
                 −1 
                 0 
                 1 
                 6 
                 7 
                 8 
                 9 
                 13 
                 15 
               
               
                   
               
             
          
         
       
     
         [0045]    The level values are then obtained in a single step by e.g. calling the SIMD instruction PSHUFB, with the coefficients and the bytemap as the argument, giving the following result: 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
               
             
             
               
                 coefficients 
                 7 
                 −3 
                 0 
                 0 
                 0 
                 0 
                 3 
                 −1 
                 2 
                 −1 
                 0 
                 0 
                 0 
                 1 
                 0 
                 1 
               
               
                 bytemap 
                 C 
                 C 
                 C 
                 C 
                 −1 
                 −1 
                 −1 
                 −1 
                 0 
                 1 
                 6 
                 7 
                 8 
                 9 
                 13 
                 15 
               
               
                 PSHUFB 
                   
                   
                   
                   
                   
                   
                   
                   
                 7 
                 −3 
                 3 
                 −1 
                 2 
                 −1 
                 1 
                 1 
               
               
                   
               
             
          
         
       
     
         [0046]    Then, the run is calculated by subtracting the bytemap by the shifted bytemap +1 as follows. The reason stuff bytes are set to −1 is that the stuff values after shifting and adding +1 should be zero to obtain the correct run after subtraction. 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
               
             
             
               
                 bytemap 
                 C 
                 C 
                 C 
                 C 
                 −1 
                 −1 
                 −1 
                 −1 
                 0 
                 1 
                 6 
                 7 
                 8 
                 9 
                 13 
                 15 
               
               
                 PADDB 1 
                 C 
                 C 
                 C 
                 C 
                 C 
                   0 
                 0 
                 0 
                 1 
                 2 
                 7 
                 8 
                 9 
                 10 
                 14 
                 16 
               
               
                 PSLLDQ 1 
                 C 
                 C 
                 C 
                 C 
                 C 
                 C 
                 0 
                 0 
                 0 
                 1 
                 2 
                 7 
                 8 
                 9 
                 10 
                 14 
               
               
                 PSUBUSB 
                 C 
                 C 
                 C 
                 C 
                 C 
                 C 
                 0 
                 0 
                 0 
                 0 
                 4 
                 0 
                 0 
                 0 
                 3 
                 1 
               
               
                   
               
             
          
         
       
     
         [0047]    Finally, the number of nonzero bytes of the entire bitmask is calculated e.g. by using the SIMD instruction POPCNT. In this example, POPCNT returns 8 and the result, as desired, the final result becomes: 
         [0000]    
       
         
               
               
               
               
               
               
               
               
               
               
             
           
               
                   
                   
               
             
             
               
                   
                 level 
                 7 
                 −3 
                 3 
                 −1 
                 2 
                 −1 
                 1 
                 1 
               
               
                   
                 run 
                 0 
                 0 
                 4 
                 0 
                 0 
                 0 
                 3 
                 1 
               
               
                   
                   
               
             
          
         
       
     
         [0048]    The main elements of the embodiment discussed above is illustrated in the flow chart of  FIG. 3 . 
         [0049]    As already indicated, the embodiment described above may advantageously be implemented by SIMD instructions in a SIMD processor environment. In the following, the example above will be described by referring to a concrete executable SIMD instruction set. The functions used are commonly known functions for persons skilled in the art. The instruction set is highlighted in italics, and are merged with the explanation of the different parts of the instruction set. 
         [0000]    
       
         
               
               
             
               
               
             
           
               
                   
                   
               
             
             
               
                   
                 #include “magic.h” 
               
               
                   
                 #include &lt;stdio.h&gt; 
               
               
                   
                 #include &lt;nmmintrin.h&gt; 
               
               
                   
                 #define O _mm_setzero_si128( ) 
               
               
                   
                 #define v(x) *( —— m128i*)(x) 
               
               
                   
                 int main( ) 
               
             
          
           
               
                   
                 { 
               
               
                   
                 int i; 
               
               
                   
                 char buffer[24]; 
               
               
                   
                 char bytemap[16]; 
               
               
                   
                 char level[16]; 
               
               
                   
                 char run[16]; 
               
               
                   
                 char shiftmap[16]; 
               
               
                   
                   
               
             
          
         
       
     
         [0050]    The 16 coefficients in a 4×4 block are stored sequentially in a 16 byte array. In the example the coefficients are set to:
       char coeffs[16]={7,−3, 0, 0, 0, 0, 3,−1, 2,−1, 0, 0, 0, 1, 0, 1};
 
First, a bitmask that denotes which coefficients are not zero must be determined
   unsigned short bitmask=˜_mm_movemask_epi8(_mm_cmpeq_epi8(v(&amp;coeffs),O));       
 
         [0053]    Note that this bitmask would be expected to be:
       {1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1}
 
However, the bitmask would actually be the reverse of this, as the least significant bit corresponds to index zero:
   {1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1}       
 
         [0056]    This bitmask can actually be regarded as a number, and each such number uniquely describes which of the 16 coefficients that are nonzero. To avoid too many entries in the lookup table, this number is split into a lower and upper part in the following manner:
       unsigned char bitmask_lo=bitmask&amp;0xff;   unsigned char bitmask_hi=bitmask&gt;&gt;0x8;       
 
         [0059]    The result of this operation is 
         [0000]    lower mask {1, 1, 0, 0, 0, 0, 1, 1}
 
upper mask {1, 0, 1, 0, 0, 0, 1, 1}
 
These two numbers are 8-bits each, and 8-bits integers are in the range from 0 to 255. In the example, the two numbers are:
 
lower mask 195
 
upper mask 163
 
         [0060]    With these two numbers, a lookup in the bytemap table will identify the corresponding bytemaps. 
         [0061]    At location 195 on the left part of the bytemap table the hexadecimal number 0xffffffff00010607 can be found, and at location 163 on the right part of the bytemap table the hexadecimal number 0x08090d0fffffffff can be found. Hence,
       long long bytemap_lo=magic[bitmask_lo][0];
 
results in ff ff ff ff 00 01 06 07, and
   long long bytemap_hi=magic[bitmask_hi][1];
 
results in 08 09 0d 0f ff ff ff ff.
       
 
         [0064]    The numbers above are written in hexadecimal format, and if the corresponding decimal numbers are: 
         [0000]    lower bytemap {−1,−1,−1,−1, 0, 1, 6, 7}
 
upper bytemap {8, 9,13,15,−1,−1,−1,−1}
 
         [0065]    It is not a coincidence that the “unused” bytes are set to −1, as this may help us to achieve the correct run values later. The two bytemaps now need to be patched to obtain a single bytemap. 
         [0066]    The most naive way to do this, would lead to: 
         [0000]    bytemap {−1,−1,−1,−1, 0, 1, 6, 7, 8, 9,13,15,−1,−1,−1,−1} 
         [0067]    This, however, would not be so easy to use, as the bytes, from which run and level are to be calculated are stored in the middle of the array, at location 4 to 12. 
         [0068]    The “unused” bytes at each side of the table must therefore be eliminated. To do this, the bytemap must be shifted as a function of the number of nonzero bytes. In the following, X denotes the locations in the upper bytemap which is nonzero, and Y denotes the locations in the lower bytemap 
         [0000]    shift=0 {Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X, X, X, X, X}
 
shift=1 {Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X, X, X, X,−1}
 
shift=2 {Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X, X, X,−1,−1}
 
shift=3 {Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X, X,−1,−1,−1}
 
shift=4 {Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X,−1,−1,−1,−1}
 
shift=5 {Y, Y, Y, Y, Y, Y, Y, Y, X, X, X,−1,−1,−1,−1,−1}
 
shift=6 {Y, Y, Y, Y, Y, Y, Y, Y, X, X,−1,−1,−1,−1,−1,−1}
 
shift=7 {Y, Y, Y, Y, Y, Y, Y, Y, X,−1,−1,−1,−1,−1,−1,−1}
 
shift=8 {Y, Y, Y, Y, Y, Y, Y, Y,−1,−1,−1,−1,−1,−1,−1,−1}
 
         [0069]    Thus, if all the bytes in the upper bytemap are unused “4”, it will be necessary to shift the bytemap by 8, which would mean that the first byte in the resulting bytemap would be the first byte in the lower bytemap. In order to achieve this, the bytemap may simply be shifted with the number of bits set in the upper bitmask. One way to achieve this would be to first count the number of nonzero bits in the upper bitmask:
       int nonzero_hi=_mm_popcnt_u32(bitmask_hi);       
 
         [0071]    If the patched bytemap is stored in a buffer at the location which is equal to the number of bits set in the upper bitmask, the following will be obtained for all possible combinations: 
       Position: 23,22,21,20,19,18,17,16,15,14,13,12,11,10,9, 8, 7, 6, 5, 4, 3, 2, 1, 0 
       [0072]    nonzero_hi=8 {Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X, X, X, X, X, C, C, C, C, C, C, C, C}
 
nonzero_hi=7 {C, Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X, X, X, X,−1, C, C, C, C, C, C, C}
 
nonzero_hi=6 {C, C, Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X, X, X,−1,−1, C, C, C, C, C, C}
 
nonzero_hi=5 {C, C, C, Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X, X,−1,−1,−1, C, C, C, C, C}
 
nonzero_hi=4 {C, C, C, C, Y, Y, Y, Y, Y, Y, Y, Y, X, X, X, X,−1,−1,−1,−1, C, C, C, C}
 
nonzero_hi=3 {C, C, C, C, C, Y, Y, Y, Y, Y, Y, Y, Y, X, X, X,−1,−1,−1,−1,−1, C, C, C}
 
nonzero_hi=2 {C, C, C, C, C, C, Y, Y, Y, Y, Y, Y, Y, Y, X, X,−1,−1,−1,−1,−1,−1, C, C}
 
nonzero_hi=1 {C, C, C, C, C, C, C, Y, Y, Y, Y, Y, Y, Y, Y, X,−1,−1,−1,−1,−1,−1,−1, C}
 
nonzero_hi=0 {C, C, C, C, C, C, C, C, Y, Y, Y, Y, Y, Y, Y, Y,−1,−1,−1,−1,−1,−1,−1,−1}
 
where C denotes uninitialized bytes.
       v(&amp;buffer[nonzero_hi])=_mm_set_epi64x(bytemap_lo,bytemap_hi);       
 
         [0074]    Then the bytes from location 8 in this buffer are read obtaining, in the example case: 
         [0000]    {cc, cc, cc, cc, ff, ff, ff, ff, 00, 01, 06, 07, 08, 09, 0d, 0f} 
         [0075]    The nonzero bytemap written in decimal form then becomes 
         [0000]    {0, 1, 6, 7, 8, 9, 13, 15}
       v(&amp;bytemap)=v(&amp;buffer[8]);       
 
         [0077]    The level values may now be calculated by simply using a table lookup function on the coefficients with the last mentioned bytemap array as argument to obtain:
       {1, 1,−1, 2,−1, 3,−3, 7}   v(&amp;level)=_mm_shuffle_epi8(v(&amp;coeffs),v(&amp;bytemap));       
 
         [0080]    However, to calculate the run values, the bytemap must first be shift and add by 1 to obtain a “shiftmap” 
       Bytemap {C, C, C, C,−1,−1,−1,−1, 0, 1, 6, 7, 8, 9,13,15} 
       [0081]    shift right by 1 {C, C, C, C, C,−1,−1,−1,−1, 0, 1, 6, 7, 8, 9,13}
 
shiftmap=add 1 {C, C, C, C, C, 0, 0, 0, 0, 1, 2, 7, 8, 9,10,14}
       v(&amp;shiftmap)=_mm_srli_si128(_mm_add_epi8(v(&amp;bytemap),_mm_set1_epi8(1)),1);       
 
         [0083]    Then the run values will be obtained by subtracting the shiftmap from the bitmap: 
         [0000]    shiftmap—bytemap {C, C, C, C, C,−1,−1,−1, 0, 0, 4, 0, 0, 0, 3, 1}
       v(&amp;run)=_mm_subs_epu8(v(&amp;bytemap),v(&amp;shiftmap));       
 
         [0085]    Then both the run and level are obtained. To complete the instruction set, instructions for displaying run/level to a screen is disclosed below. 
         [0000]    
       
         
               
               
             
           
               
                   
                   
               
             
             
               
                   
                 int nonzero = _mm_popcnt_u32(bitmask); 
               
               
                   
                 for(i=0;i&lt;nonzero;i++) 
               
               
                   
                 { 
               
               
                   
                 printf(“%4d”, level[i]); 
               
               
                   
                 printf(“\n”); 
               
               
                   
                 for(i=0;i&lt;nonzero;i++) 
               
               
                   
                 { 
               
               
                   
                 printf(“%4d”, run[i]); 
               
               
                   
                 } 
               
               
                   
                 printf(“\n”); 
               
               
                   
                 return(0); 
               
               
                   
                 } 
               
               
                   
                   
               
             
          
         
       
     
         [0086]    The main advantage of the present invention is that run and level can be quickly determined using a simple table lookup and efficient vector instructions, as opposed to the various conventional methods that manually iterates over the coefficients one at a time. Treating the level values as signed bytes is an approximation, and a fallback method has to be implemented in the case in which two bytes is required to represent the level. While the fallback method is considerably slower, investigations have revealed that this represents a negligible overhead as the signed byte approximation is valid more than 99% of time.