public override void LoadRaw()
        {
            ushort[,] vpred = new ushort[2, 2];
            ushort[] hpred = new ushort[2];
            ushort   csize;
            int      step  = 0;
            int      huff  = 0;
            int      split = 0;
            int      row;

            RawStream ifp = state.ifp;

            ifp.Seek(state.meta_offset, SeekOrigin.Begin);
            ushort ver0 = (ushort)ifp.ReadByte();
            ushort ver1 = (ushort)ifp.ReadByte();

            if (ver0 == 0x49 || ver1 == 0x58)
            {
                ifp.Seek(2110, SeekOrigin.Current);
            }

            if (ver0 == 0x46)
            {
                huff = 2;
            }
            if (state.tiff_bps == 14)
            {
                huff += 3;
            }

            vpred[0, 0] = ifp.get2();
            vpred[0, 1] = ifp.get2();
            vpred[1, 0] = ifp.get2();
            vpred[1, 1] = ifp.get2();

            int max = 1 << state.tiff_bps & 0x7fff;

            if ((csize = ifp.get2()) > 1)
            {
                step = max / (csize - 1);
            }
            if (ver0 == 0x44 && ver1 == 0x20 && step > 0)
            {
                int i;
                for (i = 0; i < csize; i++)
                {
                    state.curve[i * step] = ifp.get2();
                }

                for (i = 0; i < max; i++)
                {
                    state.curve[i] = (ushort)((state.curve[i - i % step] * (step - i % step) + state.curve[i - i % step + step] * (i % step)) / step);
                }

                ifp.Seek(state.meta_offset + 562, SeekOrigin.Begin);
                split = ifp.get2();
            }
            else if (ver0 != 0x46 && csize <= 0x4001)
            {
                max = csize;
                ifp.ReadShorts(state.curve, max);
            }

            int         tempIdx = 0;
            HuffmanTree htree   = new HuffmanTree(nikon_tree[huff], ref tempIdx);

            ifp.Seek(state.data_offset, SeekOrigin.Begin);
            ifp.ResetBits();

            for (row = 0; row < state.height; row++)
            {
                if (split != 0 && row == split)
                {
                    tempIdx = 0;
                    htree   = new HuffmanTree(nikon_tree[huff], ref tempIdx);
                }

                for (int col = 0; col < state.raw_width; col++)
                {
                    int leaf = htree.ReadNextSymbolLength(ifp);
                    int len  = leaf & 15;
                    int shl  = leaf >> 4;
                    int diff = (((int)ifp.GetBits(len - shl) << 1) + 1) << shl >> 1;
                    if ((diff & (1 << (len - 1))) == 0)
                    {
                        diff -= (1 << len) - (shl == 0 ? 1 : 0);
                    }

                    if (col < 2)
                    {
                        vpred[row & 1, col] = (ushort)(vpred[row & 1, col] + diff);
                        hpred[col]          = vpred[row & 1, col];
                    }
                    else
                    {
                        hpred[col & 1] = (ushort)(hpred[col & 1] + diff);
                    }

                    if (hpred[col & 1] >= max)
                    {
                        throw new Exception("derror()");
                    }

                    if ((uint)(col - state.left_margin) < state.width)
                    {
                        state.BAYER_set(row, col - state.left_margin, state.curve[hpred[col & 1] & 0x3fff]);
                    }
                }
            }
        }
Beispiel #2
0
        public JHead(DcRawState state, RawStream s, bool info_only, uint dng_version)
        {
            byte[] data = new byte[0x10000];

            restart = int.MaxValue;

            s.Read(data, 0, 2);

            if (data[1] != 0xd8)
            {
                // Error state (I think)
                throw new Exception("unexpected value in jpeg header");
                //return 0;
            }

            int tag;
            int len;

            do
            {
                s.Read(data, 0, 2 * 2);
                tag = data[0] << 8 | data[1];
                len = (data[2] << 8 | data[3]) - 2;
                if (tag <= 0xff00)
                {
                    // Non error
                    return;
                }

                s.Read(data, 0, len);
                switch (tag)
                {
                case 0xffc0:        // SOF0 - Start of Frame 0 - Baseline DCT
                case 0xffc3:        // SOF3 - Start of Frame 3 - Lossless (sequential)
                    if (tag == 0xffc3)
                    {
                        sraw = ((((data[7] >> 4) * (data[7] & 15) - 1) & 3) == 0) ? false : true;
                    }
                    bits = data[0];
                    high = data[1] << 8 | data[2];
                    wide = data[3] << 8 | data[4];
                    clrs = data[5] - (sraw ? 1 : 0);
                    if (len == 9 && dng_version == 0)
                    {
                        s.ReadByte();
                    }
                    break;

                case 0xffc4:        // DHT - Define Huffman Table
                    if (info_only)
                    {
                        break;
                    }

                    for (int dpi = 0; dpi < len && data[dpi] < 4;)
                    {
                        int idx = data[dpi];
                        dpi++;
                        huff[idx] = new HuffmanTree(data, ref dpi);
                    }
                    break;

                case 0xffda:        // SOS - Start of Scan
                    psv   = data[1 + data[0] * 2];
                    bits -= data[3 + data[0] * 2] & 15;
                    break;

                case 0xffdd:        // DRI - Define Restart Interval
                    restart = data[0] << 8 | data[1];
                    break;

                // <-- end of dcraw.c ported code (for this switch statement) -->

                // thumbnail image
                // for more unhandled tags, see: http://www.impulseadventure.com/photo/jpeg-decoder.html
                case 0xffd8:        // SOI - Start of Image
                case 0xffd9:        // EOI - End of Image
                case 0xffdb:        // DQT - Define Quantization Table
                    break;

                default:
                    Console.WriteLine("Unhandled jpeg tag: {0}", tag);
                    break;
                }
            } while (tag != 0xffda);

            if (info_only)
            {
                // No error
                //return 1;
                return;
            }

            if (sraw)
            {
                huff[3] = huff[2] = huff[1];
                huff[1] = huff[0];
            }

            row = new ushort[wide * clrs * 2];

            /*
             * for (int iii = 0; iii < huff.Length; iii++)
             * {
             *  Console.WriteLine("huff[{0}]", iii);
             *  Decode.DumpTable(huff[iii], 0);
             * }
             */

            //row = (ushort*) calloc(wide * clrs, 4);
            //merror(jh->row, "ljpeg_start()");
            // TODO: why do we need error handling here?
            s.ZeroAfterFF = true;
        }