Example #1
0
        /// <summary>Reads the GIF Color Table as 256 integer values</summary>
        /// <param name="numberOfColors">The number of colors to read</param>
        /// <returns>The GIF color table</returns>
        protected int[] ReadColorTable(int numberOfColors)
        {
            int nbytes = 3 * numberOfColors;

            int[]  tab = null;
            byte[] c   = new byte[nbytes];
            int    n   = 0;

            try
            {
                n = inStream.Read(c, 0, c.Length);
            }
            catch (IOException)
            {
            }
            if (n < nbytes)
            {
                status = DecoderStatus.FormatError;
            }
            else
            {
                tab = new int[256];                 // max size to avoid bounds checks
                int i = 0;
                int j = 0;
                while (i < numberOfColors)
                {
                    byte r = (byte)(c[j++] & 0xff);
                    byte g = (byte)(c[j++] & 0xff);
                    byte b = (byte)(c[j++] & 0xff);
                    tab[i++] = BitConverter.ToInt32(new[] { r, g, b, byte.MaxValue }, 0);
                }
            }
            return(tab);
        }
Example #2
0
        /// <summary>Reads the next variable length input block</summary>
        /// <returns>The remaining input bytes stored in the buffer</returns>
        protected int ReadBlock()
        {
            blockSize = Read();
            int n = 0;

            if (blockSize > 0)
            {
                try
                {
                    while (n < blockSize)
                    {
                        int count = inStream.Read(block, n, blockSize - n);
                        if (count == -1)
                        {
                            break;
                        }
                        n += count;
                    }
                }
                catch (IOException)
                {
                }

                if (n < blockSize)
                {
                    status = DecoderStatus.FormatError;
                }
            }
            return(n);
        }
Example #3
0
        public static void DecompressAlpha(AvifItemData alphaImage,
                                           DecodeInfo decodeInfo,
                                           Surface fullSurface)
        {
            if (alphaImage is null)
            {
                ExceptionUtil.ThrowArgumentNullException(nameof(alphaImage));
            }

            if (decodeInfo is null)
            {
                ExceptionUtil.ThrowArgumentNullException(nameof(decodeInfo));
            }

            if (fullSurface is null)
            {
                ExceptionUtil.ThrowArgumentNullException(nameof(fullSurface));
            }

            DecoderStatus status = DecoderStatus.Ok;

            unsafe
            {
                alphaImage.UseBufferPointer((ptr, length) =>
                {
                    BitmapData bitmapData = new BitmapData
                    {
                        scan0  = fullSurface.Scan0.Pointer,
                        width  = (uint)fullSurface.Width,
                        height = (uint)fullSurface.Height,
                        stride = (uint)fullSurface.Stride
                    };

                    UIntPtr alphaImageSize = new UIntPtr(length);

                    if (IntPtr.Size == 8)
                    {
                        status = AvifNative_64.DecompressAlphaImage(ptr,
                                                                    alphaImageSize,
                                                                    decodeInfo,
                                                                    ref bitmapData);
                    }
                    else
                    {
                        status = AvifNative_86.DecompressAlphaImage(ptr,
                                                                    alphaImageSize,
                                                                    decodeInfo,
                                                                    ref bitmapData);
                    }
                });
            }

            if (status != DecoderStatus.Ok)
            {
                HandleError(status);
            }
        }
Example #4
0
 /// <summary>Initializes or reinitalizes the reader</summary>
 protected void Init()
 {
     status           = DecoderStatus.OK;
     frameCount       = 0;
     frames           = new List <int[]>();
     delays           = new List <int>();
     globalColorTable = null;
     localColorTable  = null;
 }
Example #5
0
 /// <summary>Reads a GIF file from the specified source</summary>
 /// <param name="name">The source file / URL</param>
 /// <returns>The status code</returns>
 public DecoderStatus Read(string name)
 {
     status = DecoderStatus.OK;
     try
     {
         status = Read(new FileInfo(name).OpenRead());
     }
     catch (IOException)
     {
         status = DecoderStatus.OpenError;
     }
     return(status);
 }
Example #6
0
        /// <summary>Reads a single byte from the input stream</summary>
        protected int Read()
        {
            int curByte = 0;

            try
            {
                curByte = inStream.ReadByte();
            }
            catch (IOException)
            {
                status = DecoderStatus.FormatError;
            }
            return(curByte);
        }
Example #7
0
        private static void HandleError(DecoderStatus status)
        {
            switch (status)
            {
            case DecoderStatus.Ok:
                break;

            case DecoderStatus.NullParameter:
                throw new FormatException("A required decoder parameter was null.");

            case DecoderStatus.OutOfMemory:
                throw new OutOfMemoryException();

            case DecoderStatus.CodecInitFailed:
                throw new FormatException("Unable to initialize AV1 decoder.");

            case DecoderStatus.DecodeFailed:
                throw new FormatException("The AV1 decode failed.");

            case DecoderStatus.AlphaSizeMismatch:
                throw new FormatException("The alpha image does not match the expected size.");

            case DecoderStatus.ColorSizeMismatch:
                throw new FormatException("The color image does not match the expected size.");

            case DecoderStatus.TileNclxProfileMismatch:
                throw new FormatException("The color image tiles must use an identical color profile.");

            case DecoderStatus.UnsupportedBitDepth:
                throw new FormatException("The image has an unsupported bit depth.");

            case DecoderStatus.UnknownYUVFormat:
                throw new FormatException("The YUV format is not supported by the decoder.");

            case DecoderStatus.TileFormatMismatch:
                throw new FormatException("The color image tiles must use the same YUV format and bit depth.");

            default:
                throw new FormatException("An unknown error occurred when decoding the image.");
            }
        }
Example #8
0
        /// <summary>Reads the GIF header</summary>
        protected void ReadHeader()
        {
            string id = "";

            for (int i = 0; i < 6; i++)
            {
                id += (char)Read();
            }
            if (!id.StartsWith("GIF"))
            {
                status = DecoderStatus.FormatError;
                return;
            }

            ReadLSD();
            if (golbalColorTableFlag && !Error)
            {
                globalColorTable = ReadColorTable(golbalColorTableSize);
                bgColor          = globalColorTable[bgIndex];
            }
        }
Example #9
0
 /// <summary>Reads a GIF file from the specified stream</summary>
 /// <param name="inputStream">The source stream</param>
 /// <returns>The status code</returns>
 public DecoderStatus Read(Stream inputStream)
 {
     Init();
     if (inputStream != null)
     {
         this.inStream = inputStream;
         ReadHeader();
         if (!Error)
         {
             ReadContents();
             if (frameCount < 0)
             {
                 status = DecoderStatus.FormatError;
             }
         }
         inputStream.Close();
     }
     else
     {
         status = DecoderStatus.OpenError;
     }
     return(status);
 }
Example #10
0
        /// <summary>Reads the next frame image</summary>
        protected void ReadNextFrame()
        {
            imagePosition = ReadVector2();
            imageSize     = ReadVector2();
            int packed = Read();

            lctFlag   = (packed & 0x80) != 0;           // 1 - local color table flag
            interlace = (packed & 0x40) != 0;           // 2 - interlace flag
            // 3 - sort flag
            // 4-5 - reserved
            int localColorTableSize = 2 << (packed & 7);             // 6-8 - local color table size

            if (lctFlag)
            {
                localColorTable = ReadColorTable(localColorTableSize);                 // read table
            }
            else
            {
                if (bgIndex == transIndex)
                {
                    bgColor = 0;
                }
            }
            int save = 0;

            if (transparency)
            {
                save = activeColorTable[transIndex];
                activeColorTable[transIndex] = 0;                 // set transparent color if specified
            }

            if (activeColorTable == null)
            {
                status = DecoderStatus.FormatError;                 // no color table defined
            }

            if (Error)
            {
                return;
            }

            DecodeImageData();             // decode pixel data
            Skip();

            if (Error)
            {
                return;
            }

            frameCount++;
            // create new image to receive frame data
            bitmap = new int[width * height];
            image  = bitmap;
            SetPixels();             // transfer pixel data to image

            frames.Add(bitmap);      // add image to frame list
            delays.Add(delay);

            if (transparency)
            {
                activeColorTable[transIndex] = save;
            }
            ResetFrame();
        }
Example #11
0
        /// <summary>Reads the contents of the file</summary>
        protected void ReadContents()
        {
            // read GIF file content blocks
            bool done = false;

            while (!(done || Error))
            {
                ControlCode code = ReadControlCode();
                switch (code)
                {
                case ControlCode.ImageSeparator:
                    ReadNextFrame();
                    break;

                case ControlCode.ExtensionBlock:
                    code = ReadControlCode();
                    switch (code)
                    {
                    case ControlCode.GraphicsExtension:
                        ReadGraphicControlExt();
                        break;

                    case ControlCode.ApplicationExtension:
                        ReadBlock();
                        string app = "";
                        for (int i = 0; i < 11; i++)
                        {
                            app += (char)block[i];
                        }

                        if (app.Equals("NETSCAPE2.0") || app.Equals("ANIMEXTS1.0"))
                        {
                            ReadNetscapeExt();
                        }
                        else
                        {
                            Skip();                                             // don't care
                        }
                        break;

                    case ControlCode.TextOverlay:
                        Skip();
                        break;

                    default:
                        Skip();
                        break;
                    }
                    break;

                case ControlCode.Terminator:
                    done = true;
                    break;

                case ControlCode.BadByte:
                    break;

                default:
                    status = DecoderStatus.FormatError;
                    break;
                }
            }
        }
Example #12
0
 /// <summary>
 /// resets decoder
 /// </summary>
 public void ResetDecoder()
 {
     m_decoder_status = DecoderStatus.NoPacket;
 }
Example #13
0
        /// <summary>
        /// Decodes SLIP encoded block
        /// </summary>
        /// <param name="in_source_buffer"></param>
        /// <param name="in_source_pos"></param>
        /// <param name="in_source_length"></param>
        /// <param name="in_destination_buffer"></param>
        /// <param name="inout_destination_pos"></param>
        /// <returns></returns>
        public bool DecodeBlock(byte[] in_source_buffer, ref int in_source_pos, int in_source_length, byte[] in_destination_buffer, ref int inout_destination_pos)
        {
            byte data;
            int  destination_length = in_destination_buffer.Length;

            while (in_source_pos < in_source_length && inout_destination_pos < destination_length)
            {
                // get data
                data = in_source_buffer[in_source_pos++];

                switch (m_decoder_status)
                {
                case DecoderStatus.NoPacket:
                    if (data == SLIP_END)
                    {
                        m_decoder_status = DecoderStatus.Packet;
                    }
                    break;

                case DecoderStatus.Packet:
                    if (data == SLIP_ESC)
                    {
                        // escaped data
                        m_decoder_status = DecoderStatus.Escaped;
                    }
                    else
                    {
                        if (data == SLIP_END)
                        {
                            // drop zero length packets
                            if (inout_destination_pos != 0)
                            {
                                // packet end found
                                m_decoder_status = DecoderStatus.NoPacket;

                                return(true);
                            }
                        }
                        else
                        {
                            // store if not escaped
                            in_destination_buffer[inout_destination_pos++] = data;
                        }
                    }
                    break;

                case DecoderStatus.Escaped:
                    // process escaped data
                    switch (data)
                    {
                    case SLIP_ESC_END:
                        data             = SLIP_END;
                        m_decoder_status = DecoderStatus.Packet;
                        break;

                    case SLIP_ESC_ESC:
                        data             = SLIP_ESC;
                        m_decoder_status = DecoderStatus.Packet;
                        break;
                    }

                    // store data
                    in_destination_buffer[inout_destination_pos++] = data;
                    break;
                }
            }

            return(false);
        }
Example #14
0
        public static void DecompressColor(AvifItemData colorImage,
                                           CICPColorData?colorConversionInfo,
                                           DecodeInfo decodeInfo,
                                           Surface fullSurface)
        {
            if (colorImage is null)
            {
                ExceptionUtil.ThrowArgumentNullException(nameof(colorImage));
            }

            if (decodeInfo is null)
            {
                ExceptionUtil.ThrowArgumentNullException(nameof(decodeInfo));
            }

            if (fullSurface is null)
            {
                ExceptionUtil.ThrowArgumentNullException(nameof(fullSurface));
            }


            DecoderStatus status = DecoderStatus.Ok;

            unsafe
            {
                colorImage.UseBufferPointer((ptr, length) =>
                {
                    BitmapData bitmapData = new BitmapData
                    {
                        scan0  = fullSurface.Scan0.Pointer,
                        width  = (uint)fullSurface.Width,
                        height = (uint)fullSurface.Height,
                        stride = (uint)fullSurface.Stride
                    };
                    UIntPtr colorImageSize = new UIntPtr(length);

                    if (colorConversionInfo.HasValue)
                    {
                        CICPColorData colorData = colorConversionInfo.Value;

                        if (IntPtr.Size == 8)
                        {
                            status = AvifNative_64.DecompressColorImage(ptr,
                                                                        colorImageSize,
                                                                        ref colorData,
                                                                        decodeInfo,
                                                                        ref bitmapData);
                        }
                        else
                        {
                            status = AvifNative_86.DecompressColorImage(ptr,
                                                                        colorImageSize,
                                                                        ref colorData,
                                                                        decodeInfo,
                                                                        ref bitmapData);
                        }
                    }
                    else
                    {
                        if (IntPtr.Size == 8)
                        {
                            status = AvifNative_64.DecompressColorImage(ptr,
                                                                        colorImageSize,
                                                                        IntPtr.Zero,
                                                                        decodeInfo,
                                                                        ref bitmapData);
                        }
                        else
                        {
                            status = AvifNative_86.DecompressColorImage(ptr,
                                                                        colorImageSize,
                                                                        IntPtr.Zero,
                                                                        decodeInfo,
                                                                        ref bitmapData);
                        }
                    }
                });
            }

            if (status != DecoderStatus.Ok)
            {
                HandleError(status);
            }
        }
Example #15
0
	// This function is called when we want to flush the decoder state
	// (i.e. in case of invalid UTF-8 characters or interrupted sequences)
	internal unsafe static DecoderStatus InternalGetCharsFlush (
		char* chars, int charCount,
		DecoderFallbackBuffer fallbackBuffer,
		DecoderStatus s,
		int bytesProcessed, ref int charsProcessed,
		ref uint leftBytes, ref uint leftBits, ref uint procBytes)
	{
		// if there is nothing to flush, then exit silently
		if(procBytes == 0)
			return DecoderStatus.Ok;
		// now we build a 'bytesUnknown' array with the
		// stored bytes in 'procBytes'.
		int extra = 0;
		for (uint t = procBytes; t != 0; extra++)
			t = t >> 8;
		byte [] bytesUnknown = new byte [extra];
		for (int i = extra; i > 0; i--)
			bytesUnknown [i - 1] = (byte) ((procBytes >> (8 * (extra - i))) & 0xff);
		// partial reset: this condition avoids infinite loops
		if (s == DecoderStatus.InvalidSequence)
			leftBytes = 0;
		// call the fallback and cross fingers
		fallbackBuffer.Fallback (bytesUnknown, bytesProcessed - extra);
		if (chars != null) {
			while (fallbackBuffer.Remaining > 0) {
				if (charsProcessed >= charCount)
					return DecoderStatus.InsufficientSpace;
				chars [charsProcessed++] = fallbackBuffer.GetNextChar ();
			}
		} else
			charsProcessed += fallbackBuffer.Remaining;
		fallbackBuffer.Reset ();

		// recovery was succesful, flush decoder state
		leftBits = leftBytes = procBytes = 0;

		return DecoderStatus.Ok;
	}