コード例 #1
0
        private YCbCrImage ycbcrImage; // YCrCb

        #endregion Fields

        #region Constructors

        public JpegDecoderCore()
        {
            huff = new Huffman[maxTc + 1, maxTh + 1];
            quant = new Block[maxTq + 1];
            tmp = new byte[2*Block.blockSize];
            comp = new Component[maxComponents];
            progCoeffs = new Block[maxComponents][];
            bits = new BitsClass();
            bytes = new BytesClass();
            for (int i = 0; i < maxTc + 1; i++){
                for (int j = 0; j < maxTh + 1; j++){
                    huff[i, j] = new Huffman();
                }
            }
            for (int i = 0; i < quant.Length; i++){
                quant[i] = new Block();
            }
            for (int i = 0; i < comp.Length; i++){
                comp[i] = new Component();
            }
        }
コード例 #2
0
 private void ProcessSos(int n)
 {
     if (nComp == 0){
         throw new Exception("missing SOF marker");
     }
     if (n < 6 || 4 + (2*nComp) < n || n%2 != 0){
         throw new Exception("SOS has wrong length");
     }
     ReadFull(tmp, 0, n);
     byte lnComp = tmp[0];
     if (n != 4 + (2*lnComp)){
         throw new Exception("SOS length inconsistent with number of components");
     }
     Scan[] scan = new Scan[maxComponents];
     int totalHv = 0;
     for (int i = 0; i < lnComp; i++){
         int cs = tmp[1 + (2*i)];
         int compIndex = -1;
         for (int j = 0; j < nComp; j++){
             Component compv = comp[j];
             if (cs == compv.c){
                 compIndex = j;
             }
         }
         if (compIndex < 0){
             throw new Exception("Unknown component selector");
         }
         scan[i].compIndex = (byte) compIndex;
         for (int j = 0; j < i; j++){
             if (scan[i].compIndex == scan[j].compIndex){
                 throw new Exception("Repeated component selector");
             }
         }
         totalHv += comp[compIndex].h*comp[compIndex].v;
         scan[i].td = (byte) (tmp[2 + (2*i)] >> 4);
         if (scan[i].td > maxTh){
             throw new Exception("bad Td value");
         }
         scan[i].ta = (byte) (tmp[2 + (2*i)] & 0x0f);
         if (scan[i].ta > maxTh){
             throw new Exception("bad Ta value");
         }
     }
     if (nComp > 1 && totalHv > 10){
         throw new Exception("Total sampling factors too large.");
     }
     int zigStart = 0;
     int zigEnd = Block.blockSize - 1;
     int ah = 0;
     int al = 0;
     if (progressive){
         zigStart = tmp[1 + (2*lnComp)];
         zigEnd = tmp[2 + (2*lnComp)];
         ah = tmp[3 + (2*lnComp)] >> 4;
         al = tmp[3 + (2*lnComp)] & 0x0f;
         if ((zigStart == 0 && zigEnd != 0) || zigStart > zigEnd || Block.blockSize <= zigEnd){
             throw new Exception("Bad spectral selection bounds");
         }
         if (zigStart != 0 && lnComp != 1){
             throw new Exception("Progressive AC coefficients for more than one component");
         }
         if (ah != 0 && ah != al + 1){
             throw new Exception("Bad successive approximation values");
         }
     }
     int h0 = comp[0].h;
     int v0 = comp[0].v;
     int mxx = (width + (8*h0) - 1)/(8*h0);
     int myy = (height + (8*v0) - 1)/(8*v0);
     if (grayImage == null && ycbcrImage == null){
         MakeImg(mxx, myy);
     }
     if (progressive){
         for (int i = 0; i < lnComp; i++){
             int compIndex = scan[i].compIndex;
             if (progCoeffs[compIndex] == null){
                 progCoeffs[compIndex] = new Block[mxx*myy*comp[compIndex].h*comp[compIndex].v];
                 for (int j = 0; j < progCoeffs[compIndex].Length; j++){
                     progCoeffs[compIndex][j] = new Block();
                 }
             }
         }
     }
     bits = new BitsClass();
     int mcu = 0;
     byte expectedRst = JpegConstants.Markers.RST0;
     Block b = new Block();
     int[] dc = new int[maxComponents];
     int blockCount = 0;
     for (int my = 0; my < myy; my++){
         for (int mx = 0; mx < mxx; mx++){
             for (int i = 0; i < lnComp; i++){
                 int compIndex = scan[i].compIndex;
                 int hi = comp[compIndex].h;
                 int vi = comp[compIndex].v;
                 Block qt = quant[comp[compIndex].tq];
                 for (int j = 0; j < hi*vi; j++){
                     int bx;
                     int by;
                     if (lnComp != 1){
                         bx = hi*mx + j%hi;
                         by = vi*my + j/hi;
                     } else{
                         int q = mxx*hi;
                         bx = blockCount%q;
                         by = blockCount/q;
                         blockCount++;
                         if (bx*8 >= width || by*8 >= height){
                             continue;
                         }
                     }
                     b = progressive ? progCoeffs[compIndex][@by*mxx*hi + bx] : new Block();
                     if (ah != 0){
                         Refine(b, huff[acTable, scan[i].ta], zigStart, zigEnd, 1 << al);
                     } else{
                         int zig = zigStart;
                         if (zig == 0){
                             zig++;
                             byte value = DecodeHuffman(huff[dcTable, scan[i].td]);
                             if (value > 16){
                                 throw new Exception("Excessive DC component");
                             }
                             int dcDelta = ReceiveExtend(value);
                             dc[compIndex] += dcDelta;
                             b[0] = dc[compIndex] << al;
                         }
                         if (zig <= zigEnd && eobRun > 0){
                             eobRun--;
                         } else{
                             var huffv = huff[acTable, scan[i].ta];
                             for (; zig <= zigEnd; zig++){
                                 byte value = DecodeHuffman(huffv);
                                 byte val0 = (byte) (value >> 4);
                                 byte val1 = (byte) (value & 0x0f);
                                 if (val1 != 0){
                                     zig += val0;
                                     if (zig > zigEnd){
                                         break;
                                     }
                                     int ac = ReceiveExtend(val1);
                                     b[unzig[zig]] = ac << al;
                                 } else{
                                     if (val0 != 0x0f){
                                         eobRun = (ushort) (1 << val0);
                                         if (val0 != 0){
                                             eobRun |= (ushort) DecodeBits(val0);
                                         }
                                         eobRun--;
                                         break;
                                     }
                                     zig += 0x0f;
                                 }
                             }
                         }
                     }
                     if (progressive){
                         if (zigEnd != Block.blockSize - 1 || al != 0){
                             progCoeffs[compIndex][by*mxx*hi + bx] = b;
                             continue;
                         }
                     }
                     for (int zig = 0; zig < Block.blockSize; zig++){
                         b[unzig[zig]] *= qt[zig];
                     }
                     IDCT.Transform(b);
                     byte[] dst;
                     int offset;
                     int stride;
                     if (nComp == 1){
                         dst = grayImage.pixels;
                         stride = grayImage.stride;
                         offset = grayImage.offset + 8*(by*grayImage.stride + bx);
                     } else{
                         switch (compIndex){
                             case 0:
                                 dst = ycbcrImage.pix_y;
                                 stride = ycbcrImage.y_stride;
                                 offset = ycbcrImage.y_offset + 8*(by*ycbcrImage.y_stride + bx);
                                 break;
                             case 1:
                                 dst = ycbcrImage.pix_cb;
                                 stride = ycbcrImage.c_stride;
                                 offset = ycbcrImage.c_offset + 8*(by*ycbcrImage.c_stride + bx);
                                 break;
                             case 2:
                                 dst = ycbcrImage.pix_cr;
                                 stride = ycbcrImage.c_stride;
                                 offset = ycbcrImage.c_offset + 8*(by*ycbcrImage.c_stride + bx);
                                 break;
                             case 3:
                                 throw new Exception("Too many components");
                             default:
                                 throw new Exception("Too many components");
                         }
                     }
                     for (int y = 0; y < 8; y++){
                         int y8 = y*8;
                         int yStride = y*stride;
                         for (int x = 0; x < 8; x++){
                             int c = b[y8 + x];
                             if (c < -128){
                                 c = 0;
                             } else if (c > 127){
                                 c = 255;
                             } else{
                                 c += 128;
                             }
                             dst[yStride + x + offset] = (byte) c;
                         }
                     }
                 } // for j
             } // for i
             mcu++;
             if (ri > 0 && mcu%ri == 0 && mcu < mxx*myy){
                 ReadFull(tmp, 0, 2);
                 if (tmp[0] != 0xff || tmp[1] != expectedRst){
                     throw new Exception("Bad RST marker");
                 }
                 expectedRst++;
                 if (expectedRst == JpegConstants.Markers.RST7 + 1){
                     expectedRst = JpegConstants.Markers.RST0;
                 }
                 bits = new BitsClass();
                 dc = new int[maxComponents];
                 eobRun = 0;
             }
         } // for mx
     } // for my
 }