Пример #1
0
 public void SkipBytes(int bytes)
 {
     int blocks = (bytes / BufSize) * BufSize;
     input.ReadBytes(blocks);
     for (int i = blocks; i < bytes; i++)
         GetBits(8);
 }
Пример #2
0
 /* This will attempt to parse makernotes and return it as an IFD */
 //makernote should be self contained
 Makernote ParseMakerNote(ImageBinaryReader reader, Tag tag, Endianness parentEndian)
 {
     //read twice the makernote lenght, should be enough
     reader.BaseStream.Position = tag.dataOffset + RelativeOffset;
     byte[] data = reader.ReadBytes((int)Math.Min(tag.dataCount * 3, reader.BaseStream.Length));
     return(ParseMakerNote(data, parentEndian, (int)tag.dataOffset));
 }
Пример #3
0
        public static void Decode10BitRaw(ImageBinaryReader input, Point2D size, Point2D offset, Image <ushort> rawImage)
        {
            int off   = (int)(size.width * 10) / 8;
            var pumps = new byte[size.height][];

            //read the data
            for (int i = 0; i < size.height; i++)
            {
                pumps[i] = input.ReadBytes(off);
            }

            Parallel.For(0, size.height, i =>
            {
                long pos    = (i + offset.height) * rawImage.fullSize.dim.width + offset.width;
                var data    = pumps[i];
                var bytePos = 0;
                for (uint x = 0; x < size.width;)
                {
                    rawImage.fullSize.rawView[pos + x++] = (ushort)((data[bytePos++] << 2) + (data[bytePos] >> 6));
                    rawImage.fullSize.rawView[pos + x++] = (ushort)(((data[bytePos++] & 63) << 4) + (data[bytePos] >> 4));
                    rawImage.fullSize.rawView[pos + x++] = (ushort)(((data[bytePos++] & 15) << 6) + (data[bytePos] >> 2));
                    rawImage.fullSize.rawView[pos + x++] = (ushort)(((data[bytePos++] & 3) << 8) + data[bytePos++]);
                }
                pumps[i] = null;
            });
        }
Пример #4
0
 internal PanaBitpump(ImageBinaryReader _input, uint load)
 {
     var temp = _input.ReadBytes((int)_input.RemainingSize);
     Array.Resize(ref temp, temp.Length + 32);
     input = new ImageBinaryReader(temp);
     vbits = 0;
     load_flags = (int)load;
 }
Пример #5
0
        public static void Decode8BitRaw(ImageBinaryReader input, Point2D size, Point2D offset, Image <ushort> rawImage)
        {
            var temp = input.ReadBytes((int)size.Area);

            Parallel.For(0, size.height, y =>
            {
                var skip = (y + offset.height) * rawImage.fullSize.UncroppedDim.width + offset.width;
                for (int x = 0; x < size.width; x++)
                {
                    rawImage.fullSize.rawView[skip + x] = temp[skip + x];
                }
            });
        }
Пример #6
0
        public Tag(ImageBinaryReader fileStream, int baseOffset)
        {
            parent_offset = baseOffset;
            TagId         = (TagType)fileStream.ReadUInt16();
            dataType      = (TiffDataType)fileStream.ReadUInt16();
            if (TagId == TagType.FUJI_RAW_IFD)
            {
                if (dataType == TiffDataType.OFFSET) // FUJI - correct type
                {
                    dataType = TiffDataType.LONG;
                }
            }

            dataCount  = fileStream.ReadUInt32();
            dataOffset = 0;
            if (((dataCount * dataType.GetTypeSize() > 4)))
            {
                dataOffset = fileStream.ReadUInt32();
            }
            else
            {
                GetData(fileStream);
                int k = (int)dataCount * dataType.GetTypeSize();
                if (k < 4)
                {
                    fileStream.ReadBytes(4 - k);
                }
            }

            /*            if (dataOffset < fileStream.BaseStream.Length && dataOffset > 1)
             * {
             *  long firstPosition = fileStream.Position;
             *  fileStream.Position = dataOffset + parent_offset;
             *  GetData(fileStream);
             *  fileStream.BaseStream.Position = firstPosition;
             * ¨*/
        }
Пример #7
0
        void DecodeARW2(ImageBinaryReader input, long w, long h, int bpp)
        {
            input.Position = 0;
            if (bpp == 8)
            {
                // Since ARW2 compressed images have predictable offsets, we decode them threaded
                BitPumpPlain bits = new BitPumpPlain(reader);
                //todo add parralel (parrallel.For not working because onlyone bits so not thread safe;
                //set one bits pump per row (may be slower)
                for (uint y = 0; y < rawImage.fullSize.dim.height; y++)
                {
                    // Realign
                    bits.Offset = (int)(rawImage.fullSize.dim.width * 8 * y) >> 3;
                    uint random = bits.PeekBits(24);

                    // Process 32 pixels (16x2) per loop.
                    for (uint x = 0; x < rawImage.fullSize.dim.width - 30;)
                    {
                        int _max  = (int)bits.GetBits(11);
                        int _min  = (int)bits.GetBits(11);
                        int _imax = (int)bits.GetBits(4);
                        int _imin = (int)bits.GetBits(4);
                        int sh;
                        for (sh = 0; sh < 4 && 0x80 << sh <= _max - _min; sh++)
                        {
                            ;
                        }
                        for (int i = 0; i < 16; i++)
                        {
                            int p;
                            if (i == _imax)
                            {
                                p = _max;
                            }
                            else if (i == _imin)
                            {
                                p = _min;
                            }
                            else
                            {
                                p = (int)(bits.GetBits(7) << sh) + _min;
                                if (p > 0x7ff)
                                {
                                    p = 0x7ff;
                                }
                            }
                            rawImage.SetWithLookUp((ushort)(p << 1), rawImage.fullSize.rawView, (int)((y * rawImage.fullSize.dim.width) + x + i * 2), ref random);
                        }
                        x += (x & 1) != 0 ? (uint)31 : 1;  // Skip to next 32 pixels
                    }
                }
            }
            else if (bpp == 12)
            {
                byte[] inputTempArray = input.ReadBytes((int)input.BaseStream.Length);

                if (input.RemainingSize < (w * 3 / 2))
                {
                    throw new RawDecoderException("Sony Decoder: Image data section too small, file probably truncated");
                }

                if (input.RemainingSize < (w * h * 3 / 2))
                {
                    h = input.RemainingSize / (w * 3 / 2) - 1;
                }
                int i = 0;
                for (uint y = 0; y < h; y++)
                {
                    for (uint x = 0; x < w; x += 2)
                    {
                        uint g1 = inputTempArray[i++];
                        uint g2 = inputTempArray[i++];
                        rawImage.fullSize.rawView[y * rawImage.fullSize.dim.width + x] = (ushort)(g1 | ((g2 & 0xf) << 8));
                        uint g3 = inputTempArray[i++];
                        rawImage.fullSize.rawView[y * rawImage.fullSize.dim.width + x + 1] = (ushort)((g2 >> 4) | (g3 << 4));
                    }
                }
            }
            else
            {
                throw new RawDecoderException("Unsupported bit depth");
            }
        }
Пример #8
0
        public void DecodeSlice()
        {
            //first read data for each slice
            for (int i = 0; i < slices.Count; i++)
            {
                file.BaseStream.Position = slices[i].byteOffset;
                slices[i].data           = file.ReadBytes((int)slices[i].byteCount);
            }
            Parallel.For(0, slices.Count, (i) =>
            {
                DngSliceElement e = slices[i];
                LJPEGPlain l      = new LJPEGPlain(e.data, raw, e.mUseBigtable, FixLjpeg)
                {
                    offX = e.offX,
                    offY = e.offY
                };
                l.StartDecoder(0, e.byteCount);
                l.input.Dispose();
            });

            /* Lossy DNG
             *
             * // Each slice is a JPEG image
             * struct jpeg_decompress_struct dinfo;
             * struct jpeg_error_mgr jerr;
             * while (!t.slices.empty()) {
             * DngSliceEleqment e = t.slices.front();
             * t.slices.pop();
             * byte* complete_buffer = null;
             * JSAMPARRAY buffer = (JSAMPARRAY)malloc(sizeof(JSAMPROW));
             *
             * try {
             * jpeg_create_decompress(&dinfo);
             * dinfo.err = jpeg_std_error(&jerr);
             * jerr.error_exit = my_error_throw;
             * JPEG_MEMSRC(&dinfo, (unsigned char*)mFile.getData(e.byteOffset, e.byteCount), e.byteCount);
             *
             * if (JPEG_HEADER_OK != jpeg_read_header(&dinfo, true))
             * ThrowRDE("DngDecoderSlices: Unable to read JPEG header");
             *
             * jpeg_start_decompress(&dinfo);
             * if (dinfo.output_components != (int) mRaw.getCpp())
             * ThrowRDE("DngDecoderSlices: Component count doesn't match");
             * int row_stride = dinfo.output_width * dinfo.output_components;
             * int pic_size = dinfo.output_height * row_stride;
             * complete_buffer = (byte8*) _aligned_malloc(pic_size, 16);
             * while (dinfo.output_scanline<dinfo.output_height) {
             * buffer[0] = (JSAMPROW) (&complete_buffer[dinfo.output_scanline * row_stride]);
             * if (0 == jpeg_read_scanlines(&dinfo, buffer, 1))
             * ThrowRDE("DngDecoderSlices: JPEG Error while decompressing image.");
             * }
             * jpeg_finish_decompress(&dinfo);
             *
             * // Now the image is decoded, and we copy the image data
             * int copy_w = Math.Math.Min(((mraw.raw.dim.x - e.offX, dinfo.output_width);
             * int copy_h = Math.Math.Min(((mraw.raw.dim.y - e.offY, dinfo.output_height);
             * for (int y = 0; y<copy_h; y++) {
             * byte[] src = &complete_buffer[row_stride * y];
             * UInt16* dst = (UInt16*)mRaw.getData(e.offX, y + e.offY);
             * for (int x = 0; x<copy_w; x++) {
             * for (int c=0; c<dinfo.output_components; c++)
             * dst++ = (* src++);
             * }
             * }
             * } catch (RawDecoderException &err) {
             * mRaw.setError(err.what());
             * } catch (IOException &err) {
             * mRaw.setError(err.what());
             * }
             * free(buffer);
             * if (complete_buffer)
             * _aligned_free(complete_buffer);
             * jpeg_destroy_decompress(&dinfo);
             * }
             * }*/
        }
Пример #9
0
        public void Decompress(ImageBinaryReader metadata, uint offset, uint size)
        {
            metadata.Position = 0;
            byte v0         = metadata.ReadByte();
            byte v1         = metadata.ReadByte();
            int  huffSelect = 0;
            uint split      = 0;
            var  pUp1       = new int[2];
            var  pUp2       = new int[2];

            huff[0].UseBigTable = true;

            if (v0 == 73 || v1 == 88)
            {
                metadata.ReadBytes(2110);
            }

            if (v0 == 70)
            {
                huffSelect = 2;
            }
            if (raw.fullSize.ColorDepth == 14)
            {
                huffSelect += 3;
            }

            pUp1[0] = metadata.ReadInt16();
            pUp1[1] = metadata.ReadInt16();
            pUp2[0] = metadata.ReadInt16();
            pUp2[1] = metadata.ReadInt16();

            int max = 1 << raw.fullSize.ColorDepth & 0x7fff;
            int step = 0, csize = metadata.ReadUInt16();

            if (csize > 1)
            {
                step = max / (csize - 1);
            }
            if (v0 == 68 && v1 == 32 && step > 0)
            {
                for (int i = 0; i < csize; i++)
                {
                    curve[i * step] = metadata.ReadUInt16();
                }
                for (int i = 0; i < max; i++)
                {
                    curve[i] = (ushort)((curve[i - i % step] * (step - i % step) + curve[i - i % step + step] * (i % step)) / step);
                }
                metadata.Position = (562);
                split             = metadata.ReadUInt16();
            }
            else if (v0 != 70 && csize <= 0x4001)
            {
                for (int i = 0; i < csize; i++)
                {
                    curve[i] = metadata.ReadUInt16();
                }
                max = csize;
            }
            huff[0].Create(huffSelect);

            raw.whitePoint = curve[max - 1];
            raw.black      = curve[0];
            raw.table      = new TableLookUp(curve, max, true);

            huff[0].bitPump = new BitPumpMSB(input, offset, size);
            int  pLeft1 = 0, pLeft2 = 0;
            uint random = huff[0].bitPump.PeekBits(24);

            for (int y = 0; y < raw.fullSize.dim.height; y++)
            {
                if (split != 0 && (y == split))
                {
                    huff[0].Create(huffSelect + 1);
                }
                pUp1[y & 1] += huff[0].Decode();
                pUp2[y & 1] += huff[0].Decode();
                pLeft1       = pUp1[y & 1];
                pLeft2       = pUp2[y & 1];
                long dest = y * raw.fullSize.dim.width;
                raw.SetWithLookUp((ushort)pLeft1, raw.fullSize.rawView, dest++, ref random);
                raw.SetWithLookUp((ushort)pLeft2, raw.fullSize.rawView, dest++, ref random);
                for (int x = 1; x < raw.fullSize.dim.width / 2; x++)
                {
                    pLeft1 += huff[0].Decode();
                    pLeft2 += huff[0].Decode();
                    raw.SetWithLookUp((ushort)pLeft1, raw.fullSize.rawView, dest++, ref random);
                    raw.SetWithLookUp((ushort)pLeft2, raw.fullSize.rawView, dest++, ref random);
                }
            }
            raw.table = null;
        }
Пример #10
0
        /* This is probably the slowest decoder of them all.
         * I cannot see any way to effectively speed up the prediction
         * phase, which is by far the slowest part of this algorithm.
         * Also there is no way to multithread this code, since prediction
         * is based on the output of all previous pixel (bar the first four)
         */
        private void DecodeCompressed(ImageBinaryReader s, uint width, uint height)
        {
            int  nbits;
            long left0, nw0, left1, nw1;
            long sign, low, high;

            long[] acarry0 = new long[3], acarry1 = new long[3];
            long   pred, diff;

            //uint pitch = rawImage.pitch;

            /* Build a table to quickly look up "high" value */
            byte[] bittable = new byte[4096];
            for (int i = 0; i < 4096; i++)
            {
                int b = i;
                for (high = 0; high < 12; high++)
                {
                    if (((b >> (11 - (int)high)) & 1) != 0)
                    {
                        break;
                    }
                }
                bittable[i] = (byte)Math.Min(12, high);
            }
            left0 = nw0 = left1 = nw1 = 0;
            s.ReadBytes(7);
            BitPumpMSB bits = new BitPumpMSB(s);

            for (int y = 0; y < height; y++)
            {
                var pos = y * rawImage.fullSize.UncroppedDim.width;
                acarry0 = new long[3];
                acarry1 = new long[3];
                bool y_border = y < 2;
                bool border   = true;
                for (int x = 0; x < width; x++)
                {
                    bits.Fill();
                    int i = 0;
                    if (acarry0[2] < 3)
                    {
                        i = 2;
                    }

                    for (nbits = 2 + i; acarry0[0] >> (nbits + i) != 0; nbits++)
                    {
                        ;
                    }

                    uint b = bits.PeekBits(15);
                    sign = (b >> 14) * -1;
                    low  = (b >> 12) & 3;
                    high = bittable[b & 4095];

                    // Skip bytes used above or read bits
                    if (high == 12)
                    {
                        bits.SkipBits(15);
                        high = bits.GetBits(16 - nbits) >> 1;
                    }
                    else
                    {
                        bits.SkipBits((int)high + 1 + 3);
                    }

                    acarry0[0] = (high << nbits) | bits.GetBits(nbits);
                    diff       = (acarry0[0] ^ sign) + acarry0[1];
                    acarry0[1] = (diff * 3 + acarry0[1]) >> 5;
                    acarry0[2] = acarry0[0] > 16 ? 0 : acarry0[2] + 1;

                    if (border)
                    {
                        if (y_border && x < 2)
                        {
                            pred = 0;
                        }
                        else if (y_border)
                        {
                            pred = left0;
                        }
                        else
                        {
                            pred = nw0 = rawImage.fullSize.rawView[pos - rawImage.fullSize.UncroppedDim.width + x];
                        }
                        rawImage.fullSize.rawView[pos + x] = (ushort)(pred + ((diff << 2) | low));
                        // Set predictor
                        left0 = rawImage.fullSize.rawView[pos + x];
                    }
                    else
                    {
                        // Have local variables for values used several tiles
                        // (having a "UInt16 *dst_up" that caches dest[-pitch+((int)x)] is actually slower, probably stack spill or aliasing)
                        int  up          = rawImage.fullSize.rawView[pos - rawImage.fullSize.UncroppedDim.width + x];
                        long leftMinusNw = left0 - nw0;
                        long upMinusNw   = up - nw0;
                        // Check if sign is different, and one is not zero
                        if (leftMinusNw * upMinusNw < 0)
                        {
                            if (Other_abs(leftMinusNw) > 32 || Other_abs(upMinusNw) > 32)
                            {
                                pred = left0 + upMinusNw;
                            }
                            else
                            {
                                pred = (left0 + up) >> 1;
                            }
                        }
                        else
                        {
                            pred = Other_abs(leftMinusNw) > Other_abs(upMinusNw) ? left0 : up;
                        }

                        rawImage.fullSize.rawView[pos + x] = (ushort)(pred + ((diff << 2) | low));
                        // Set predictors
                        left0 = rawImage.fullSize.rawView[pos + x];
                        nw0   = up;
                    }

                    // ODD PIXELS
                    x += 1;
                    bits.Fill();
                    i = 0;
                    if (acarry1[2] < 3)
                    {
                        i = 2;
                    }

                    for (nbits = 2 + i; acarry1[0] >> (nbits + i) != 0; nbits++)
                    {
                        ;
                    }
                    b    = bits.PeekBits(15);
                    sign = (b >> 14) * -1;
                    low  = (b >> 12) & 3;
                    high = bittable[b & 4095];

                    // Skip bytes used above or read bits
                    if (high == 12)
                    {
                        bits.SkipBits(15);
                        high = bits.GetBits(16 - nbits) >> 1;
                    }
                    else
                    {
                        bits.SkipBits((int)high + 1 + 3);
                    }

                    acarry1[0] = (high << nbits) | bits.GetBits(nbits);
                    diff       = (acarry1[0] ^ sign) + acarry1[1];
                    acarry1[1] = (diff * 3 + acarry1[1]) >> 5;
                    acarry1[2] = acarry1[0] > 16 ? 0 : acarry1[2] + 1;

                    if (border)
                    {
                        if (y_border && x < 2)
                        {
                            pred = 0;
                        }
                        else if (y_border)
                        {
                            pred = left1;
                        }
                        else
                        {
                            pred = nw1 = rawImage.fullSize.rawView[pos - rawImage.fullSize.UncroppedDim.width + x];
                        }
                        rawImage.fullSize.rawView[pos + x] = (ushort)(left1 = pred + ((diff << 2) | low));
                    }
                    else
                    {
                        int  up          = rawImage.fullSize.rawView[pos - rawImage.fullSize.UncroppedDim.width + x];
                        long leftminusNw = left1 - nw1;
                        long upminusNw   = up - nw1;

                        // Check if sign is different, and one is not zero
                        if (leftminusNw * upminusNw < 0)
                        {
                            if (Other_abs(leftminusNw) > 32 || Other_abs(upminusNw) > 32)
                            {
                                pred = left1 + upminusNw;
                            }
                            else
                            {
                                pred = (left1 + up) >> 1;
                            }
                        }
                        else
                        {
                            pred = Other_abs(leftminusNw) > Other_abs(upminusNw) ? left1 : up;
                        }

                        rawImage.fullSize.rawView[pos + x] = (ushort)(left1 = pred + ((diff << 2) | low));
                        nw1 = up;
                    }
                    border = y_border;
                }
            }
        }
Пример #11
0
        public void ParseSOS()
        {
            if (!frame.Initialized)
            {
                throw new RawDecoderException("Frame not yet initialized (SOF Marker not parsed)");
            }

            input.ReadInt16();
            uint soscps = input.ReadByte();

            if (frame.numComponents != soscps)
            {
                throw new RawDecoderException("Component number mismatch.");
            }

            for (int i = 0; i < frame.numComponents; i++)
            {
                uint cs    = input.ReadByte();
                uint count = 0;  // Find the correct component
                while (frame.ComponentInfo[count].componentId != cs)
                {
                    if (count >= frame.numComponents)
                    {
                        throw new RawDecoderException("Invalid Component Selector");
                    }
                    count++;
                }

                uint b1 = input.ReadByte();
                uint td = b1 >> 4;
                if (td > 3)
                {
                    throw new RawDecoderException("Invalid Huffman table selection");
                }
                if (!huff[td].Initialized)
                {
                    throw new RawDecoderException("Invalid Huffman table selection, not defined.");
                }

                if (count > 3)
                {
                    throw new RawDecoderException("Component count out of range");
                }

                frame.ComponentInfo[count].dcTblNo = td;
            }

            predictor = input.ReadByte();
            if (predictor > 7)
            {
                throw new RawDecoderException("Invalid predictor mode.");
            }

            input.ReadBytes(1); // Se + Ah Not used in LJPEG
            int b = input.ReadByte();

            Pt = b & 0xf;        // Point Transform

            bits = new BitPumpJPEG(input);
            for (int i = 0; i < huff.Length; i++)
            {
                huff[i].bitPump   = bits;
                huff[i].precision = frame.precision;
            }
            DecodeScan();
            input.Position = bits.Offset;
        }