Beispiel #1
0
        public void Decode12BitRawBE(TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            if (w < 2)
            {
                throw new IOException("Are you mad? 1 pixel wide raw images are no fun");
            }

            UInt32 pitch = mRaw.pitch;

            if (input.getRemainSize() < ((w * 12 / 8) * h))
            {
                if ((UInt32)input.getRemainSize() > (w * 12 / 8))
                {
                    h = (uint)(input.getRemainSize() / (w * 12 / 8) - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
                }
            }
            for (UInt32 y = 0; y < h; y++)
            {
                for (UInt32 x = 0; x < w; x += 2)
                {
                    UInt32 g1 = input.ReadByte();
                    UInt32 g2 = input.ReadByte();
                    mRaw.rawData[y * pitch + x] = (ushort)((g1 << 4) | (g2 >> 4));
                    UInt32 g3 = input.ReadByte();
                    mRaw.rawData[y * pitch + x + 1] = (ushort)(((g2 & 0x0f) << 8) | g3);
                }
            }
        }
Beispiel #2
0
        public void Decode12BitRawUnpacked(TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            UInt32 pitch = mRaw.pitch;

            if (input.getRemainSize() < w * h * 2)
            {
                if ((UInt32)input.getRemainSize() > w * 2)
                {
                    h = (uint)(input.getRemainSize() / (w * 2) - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
                }
            }
            for (UInt32 y = 0; y < h; y++)
            {
                for (UInt32 x = 0; x < w; x += 1)
                {
                    UInt32 g1 = input.ReadByte();
                    UInt32 g2 = input.ReadByte();
                    mRaw.rawData[y * pitch + x] = (ushort)(((g2 << 8) | g1) >> 4);
                }
            }
        }
Beispiel #3
0
        public void Decode12BitRawBEInterlaced(TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            if (w < 2)
            {
                throw new IOException("Are you mad? 1 pixel wide raw images are no fun");
            }

            UInt32 pitch = mRaw.pitch;

            if (input.getRemainSize() < ((w * 12 / 8) * h))
            {
                if ((UInt32)input.getRemainSize() > (w * 12 / 8))
                {
                    h = (uint)(input.getRemainSize() / (w * 12 / 8) - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
                }
            }

            UInt32 half = (h + 1) >> 1;
            UInt32 y    = 0;

            for (UInt32 row = 0; row < h; row++)
            {
                y = row % half * 2 + row / half;
                if (y == 1)
                {
                    // The second field starts at a 2048 byte aligment
                    UInt32 offset = ((half * w * 3 / 2 >> 11) + 1) << 11;
                    if (offset > input.getRemainSize())
                    {
                        throw new IOException("Decode12BitSplitRaw: Trying to jump to invalid offset " + offset);
                    }
                    input.Position = offset;
                }
                for (UInt32 x = 0; x < w; x += 2)
                {
                    UInt32 g1 = input.ReadByte();
                    UInt32 g2 = input.ReadByte();
                    mRaw.rawData[y * pitch + x] = (ushort)((g1 << 4) | (g2 >> 4));
                    UInt32 g3 = input.ReadByte();
                    mRaw.rawData[y * pitch + x + 1] = (ushort)(((g2 & 0x0f) << 8) | g3);
                }
            }
        }
 /*** Used for entropy encoded sections, for now only Nikon Coolpix ***/
 public BitPumpMSB32(ref TIFFBinaryReader s)
 {
     s.Read(buffer, (int)s.Position, (int)s.BaseStream.Length);
     size         = (uint)(s.getRemainSize() + sizeof(UInt32));
     MIN_GET_BITS = (BITS_PER_LONG_LONG - 33);
     init();
 }
Beispiel #5
0
        public void Decode12BitRawBEWithControl(ref TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            if (w < 2)
            {
                throw new IOException("Are you mad? 1 pixel wide raw images are no fun");
            }

            UInt32 pitch = mRaw.pitch;

            // Calulate expected bytes per line.
            UInt32 perline = (w * 12 / 8);

            // Add skips every 10 pixels
            perline += ((w + 2) / 10);

            // If file is too short, only decode as many lines as we have
            if (input.getRemainSize() < (perline * h))
            {
                if ((UInt32)input.getRemainSize() > perline)
                {
                    h = (uint)(input.getRemainSize() / perline - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("Decode12BitRawBEWithControl: Not enough data to decode a single line. Image file truncated.");
                }
            }

            UInt32 x;

            for (UInt32 y = 0; y < h; y++)
            {
                for (x = 0; x < w; x += 2)
                {
                    UInt32 g1 = input.ReadByte();
                    UInt32 g2 = input.ReadByte();
                    mRaw.rawData[(y * pitch) + x] = (ushort)((g1 << 4) | (g2 >> 4));
                    UInt32 g3 = input.ReadByte();
                    mRaw.rawData[(y * pitch) + x + 1] = (ushort)(((g2 & 0x0f) << 8) | g3);
                    if ((x % 10) == 8)
                    {
                        input.Position++;
                    }
                }
            }
        }
Beispiel #6
0
        public void Decode8BitRaw(ref TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            ushort[] data  = mRaw.rawData;
            UInt32   pitch = mRaw.pitch;

            if (input.getRemainSize() < w * h)
            {
                if ((UInt32)input.getRemainSize() > w)
                {
                    h = (uint)(input.getRemainSize() / w - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("Decode8BitRaw: Not enough data to decode a single line. Image file truncated.");
                }
            }

            UInt32 random = 0;

            for (UInt32 y = 0; y < h; y++)
            {
                for (UInt32 x = 0; x < w; x += 1)
                {
                    if (uncorrectedRawValues)
                    {
                        mRaw.rawData[(y * pitch) + x] = input.ReadByte();
                    }
                    else
                    {
                        mRaw.setWithLookUp(input.ReadByte(), ref mRaw.rawData, x, ref random);
                        input.Position++;
                    }
                }
            }
        }
Beispiel #7
0
        /* Attempt to decode the image */

        /* A RawDecoderException will be thrown if the image cannot be decoded
         * public void readUncompressedRaw(ref TIFFBinaryReader input, iPoint2D size, iPoint2D offset, int inputPitch, int bitPerPixel, BitOrder order)
         * {
         *  UInt32 outPitch = mRaw.pitch;
         *  uint w = (uint)size.x;
         *  uint h = (uint)size.y;
         *  UInt32 cpp = mRaw.cpp;
         *  UInt64 ox = (ulong)offset.x;
         *  UInt64 oy = (ulong)offset.y;
         *  if (this.mRaw.rawData == null)
         *  {
         *      mRaw.rawData = new ushort[w * h * cpp];
         *  }
         *  if (input.getRemainSize() < (inputPitch * (int)h))
         *  {
         *      if (input.getRemainSize() > inputPitch)
         *      {
         *          h = (uint)(input.getRemainSize() / inputPitch - 1);
         *          mRaw.errors.Add("Image truncated (file is too short)");
         *      }
         *      else
         *          throw new IOException("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
         *  }
         *  if (bitPerPixel > 16)
         *      throw new RawDecoderException("readUncompressedRaw: Unsupported bit depth");
         *
         *  UInt32 skipBits = (uint)(inputPitch - (int)w * cpp * bitPerPixel / 8);  // Skip per line
         *  if (oy > (ulong)mRaw.dim.y)
         *      throw new RawDecoderException("readUncompressedRaw: Invalid y offset");
         *  if (ox + (ulong)size.x > (ulong)mRaw.dim.x)
         *      throw new RawDecoderException("readUncompressedRaw: Invalid x offset");
         *
         *  UInt64 y = oy;
         *  h = (uint)Math.Min(h + (uint)oy, mRaw.dim.y);
         *  /*
         *  if (mRaw.getDataType() == RawImageType.TYPE_FLOAT32)
         *  {
         *      if (bitPerPixel != 32)
         *          throw new RawDecoderException("readUncompressedRaw: Only 32 bit float point supported");
         *      BitBlt(&data[offset.x * sizeof(float) * cpp + y * outPitch], outPitch,
         *          input.getData(), inputPitch, w * mRaw.bpp, h - y);
         *      return;
         *  }
         *
         *  if (BitOrder.Jpeg == order)
         *  {
         *      BitPumpMSB bits = new BitPumpMSB(ref input);
         *      w *= cpp;
         *      for (; y < h; y++)
         *      {
         *          bits.checkPos();
         *          for (UInt32 x = 0; x < w; x++)
         *          {
         *              UInt32 b = bits.getBits((uint)bitPerPixel);
         *              mRaw.rawData[(((int)(offset.x * sizeof(UInt16) * cpp) + (int)y * (int)outPitch)) + x] = (ushort)b;
         *          }
         *          bits.skipBits(skipBits);
         *      }
         *  }
         *  else if (BitOrder.Jpeg16 == order)
         *  {
         *      BitPumpMSB16 bits = new BitPumpMSB16(input);
         *      w *= cpp;
         *      for (; y < h; y++)
         *      {
         *          bits.checkPos();
         *          for (UInt32 x = 0; x < w; x++)
         *          {
         *              UInt32 b = bits.getBits((uint)bitPerPixel);
         *              mRaw.rawData[(offset.x * sizeof(ushort) * (int)cpp + (int)y * (int)outPitch) + x] = (ushort)b;
         *          }
         *          bits.skipBits(skipBits);
         *      }
         *  }
         *  else if (BitOrder.Jpeg32 == order)
         *  {
         *      BitPumpMSB32 bits = new BitPumpMSB32(input);
         *      w *= cpp;
         *      for (; y < h; y++)
         *      {
         *          bits.checkPos();
         *          for (UInt32 x = 0; x < w; x++)
         *          {
         *              UInt32 b = bits.getBits((uint)bitPerPixel);
         *              mRaw.rawData[(offset.x * sizeof(ushort) * (int)cpp + (int)y * (int)outPitch) + x] = (ushort)b;
         *          }
         *          bits.skipBits(skipBits);
         *      }
         *  }
         *  else
         *  {
         *      if (bitPerPixel == 16)
         *      {
         *          Decode16BitRawUnpacked(input, w, h);
         *          return;
         *      }
         *      if (bitPerPixel == 12 && (int)w == inputPitch * 8 / 12)
         *      {
         *          Decode12BitRaw(input, w, h);
         *          return;
         *      }
         *      BitPumpPlain bits = new BitPumpPlain(input);
         *      w *= cpp;
         *      for (; y < h; y++)
         *      {
         *          bits.checkPos();
         *          for (UInt32 x = 0; x < w; x++)
         *          {
         *              UInt32 b = bits.getBits((uint)bitPerPixel);
         *              mRaw.rawData[(offset.x * sizeof(ushort) + (int)y * (int)outPitch) + x] = (ushort)b;
         *          }
         *          bits.skipBits(skipBits);
         *      }
         *  }
         * }
         */

        public unsafe void readUncompressedRaw(ref TIFFBinaryReader input, iPoint2D size, iPoint2D offset, int inputPitch, int bitPerPixel, BitOrder order)
        {
            fixed(ushort *d = mRaw.rawData)
            {
                byte *data     = (byte *)d;
                uint  outPitch = mRaw.pitch;
                int   w        = size.x;
                int   h        = size.y;
                uint  cpp      = mRaw.cpp;
                int   ox       = offset.x;
                int   oy       = offset.y;

                if (input.getRemainSize() < (inputPitch * h))
                {
                    if ((int)input.getRemainSize() > inputPitch)
                    {
                        h = input.getRemainSize() / inputPitch - 1;
                        mRaw.errors.Add("Image truncated (file is too short)");
                    }
                    else
                    {
                        throw new IOException("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
                    }
                }
                if (bitPerPixel > 16)
                {
                    throw new RawDecoderException("readUncompressedRaw: Unsupported bit depth");
                }

                uint skipBits = (uint)(inputPitch - w * cpp * bitPerPixel / 8);  // Skip per line

                if (oy > mRaw.dim.y)
                {
                    throw new RawDecoderException("readUncompressedRaw: Invalid y offset");
                }
                if (ox + size.x > mRaw.dim.x)
                {
                    throw new RawDecoderException("readUncompressedRaw: Invalid x offset");
                }

                int y = oy;

                h = (int)Math.Min(h + oy, (uint)mRaw.dim.y);

                /*if (mRaw.getDataType() == TYPE_FLOAT32)
                 * {
                 *  if (bitPerPixel != 32)
                 *      throw new RawDecoderException("readUncompressedRaw: Only 32 bit float point supported");
                 *  BitBlt(&data[offset.x * sizeof(float) * cpp + y * outPitch], outPitch,
                 *      input.getData(), inputPitch, w * mRaw.bpp, h - y);
                 *  return;
                 * }*/

                if (BitOrder.Jpeg == order)
                {
                    BitPumpMSB bits = new BitPumpMSB(ref input);
                    w *= (int)cpp;
                    for (; y < h; y++)
                    {
                        bits.checkPos();
                        for (uint x = 0; x < w; x++)
                        {
                            uint b = bits.getBits((uint)bitPerPixel);
                            mRaw.rawData[x + (offset.x * cpp + y * mRaw.dim.x * cpp)] = (ushort)b;
                        }
                        bits.skipBits(skipBits);
                    }
                }
                else if (BitOrder.Jpeg16 == order)
                {
                    BitPumpMSB16 bits = new BitPumpMSB16(ref input);
                    w *= (int)cpp;
                    for (; y < h; y++)
                    {
                        UInt16 *dest = (UInt16 *)&data[offset.x * sizeof(UInt16) * cpp + y * outPitch];
                        bits.checkPos();
                        for (uint x = 0; x < w; x++)
                        {
                            uint b = bits.getBits((uint)bitPerPixel);
                            dest[x] = (ushort)b;
                        }
                        bits.skipBits(skipBits);
                    }
                }
                else if (BitOrder.Jpeg32 == order)
                {
                    BitPumpMSB32 bits = new BitPumpMSB32(ref input);
                    w *= (int)cpp;
                    for (; y < h; y++)
                    {
                        UInt16 *dest = (UInt16 *)&data[offset.x * sizeof(UInt16) * cpp + y * outPitch];
                        bits.checkPos();
                        for (uint x = 0; x < w; x++)
                        {
                            uint b = bits.getBits((uint)bitPerPixel);
                            dest[x] = (ushort)b;
                        }
                        bits.skipBits(skipBits);
                    }
                }
                else
                {
                    if (bitPerPixel == 16 && Common.getHostEndianness() == Endianness.little)
                    {
                        Decode16BitRawUnpacked(input, (uint)w, (uint)h);
                        return;
                    }
                    if (bitPerPixel == 12 && (int)w == inputPitch * 8 / 12 && Common.getHostEndianness() == Endianness.little)
                    {
                        Decode12BitRaw(input, (uint)w, (uint)h);
                        return;
                    }
                    BitPumpPlain bits = new BitPumpPlain(ref input);
                    w *= (int)cpp;
                    for (; y < h; y++)
                    {
                        UInt16 *dest = (UInt16 *)&data[offset.x * sizeof(UInt16) + y * outPitch];
                        bits.checkPos();
                        for (uint x = 0; x < w; x++)
                        {
                            uint b = bits.getBits((uint)bitPerPixel);
                            dest[x] = (ushort)b;
                        }
                        bits.skipBits(skipBits);
                    }
                }
            }
        }
Beispiel #8
0
        int MIN_GET_BITS;// = (BITS_PER_LONG - 7);  /* max value for long getBuffer */

        public BitPumpPlain(ref TIFFBinaryReader s)
        {
            MIN_GET_BITS = (BITS_PER_LONG - 7);
            s.Read(buffer, (int)s.Position, (int)s.BaseStream.Length);
            size = (uint)(8 * s.getRemainSize());
        }