예제 #1
0
 public static void TransformPlanar(Image src, Image dst, Codec.TransformationQuality quality)
 {
     //Source is planar RGB
     //1x4 image
     //                   RRRR
     //                   GGGG
     //                   BBBB
 }
예제 #2
0
 public static void TransformSemiPlanar(Image src, Image dst, Codec.TransformationQuality quality)
 {
     //Source is semi planar RGB????
     //1x4 image
     //                   RRRR
     //                   GBGB
     //                   GBGB
 }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        /// <param name="quality"></param>
        /// <param name="shouldDispose"></param>
        public AudioTransformation(AudioBuffer source, AudioBuffer dest, Codec.TransformationQuality quality = Codec.TransformationQuality.Unspecified, bool shouldDispose = true)
            : this(quality, shouldDispose)
        {
            if (Common.IDisposedExtensions.IsNullOrDisposed(source))
            {
                throw new System.ArgumentNullException("source");
            }
            m_Source = source;

            if (Common.IDisposedExtensions.IsNullOrDisposed(dest))
            {
                throw new System.ArgumentNullException("dest");
            }
            m_Dest = dest;
        }
예제 #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="quality"></param>
 /// <param name="shouldDispose"></param>
 protected AudioTransformation(Codec.TransformationQuality quality = Codec.TransformationQuality.Unspecified, bool shouldDispose = true)
     : base(Codec.MediaType.Audio, quality, shouldDispose)
 {
 }
예제 #5
0
        public static void TransformPacked(Image src, Image dst, Codec.TransformationQuality quality)
        {
            //Source is packed RGB in any possible format
            //For example a 1x4 image assuming 8 bpp

            //RGB
            //                   RGBR
            //                   GBRG
            //                   BRGB

            //ARGB
            //                   ARGB
            //                   ARGB
            //                   ARGB
            //                   ARGB

            //BGRA
            //                   BGRA
            //                   BGRA
            //                   BGRA
            //                   BGRA

            //Some other format... with or without equal bit sizes for the alpha or other components.
            //Not the alpha component may have less bits than the others
            //                   BRAG
            //                   BRAG
            //                   BRAG
            //                   BRAG

            //Another hypothetical format..
            //                   GRAB
            //                   GRAB
            //                   GRAB
            //                   GRAB

            //Scope references to the data
            Common.MemorySegment source = src.Data, dest = dst.Data;

            //Create cache of 3 8 bit RGB values * 4 pixels
            //byte[] cache = new byte[12];

            //Setup variables
            int offChr = 0, offLuma = 0, offSrc = 0, strideSrc = src.Width * src.ImageFormat.Length, strideDst = dst.Width, dstComponentOffset = dst.MediaFormat.Length;

            //Could probably handle packed or semi planar YUV by making a small offset change
            if (dst.ImageFormat.DataLayout == Codec.DataLayout.Packed || dst.ImageFormat.DataLayout == Codec.DataLayout.SemiPlanar)
            {
                strideDst = dst.MediaFormat.Length;

                dstComponentOffset = 1;
            }

            //Should also have a way to write the components of dst

            //Keeps the offset in bits of the current byte
            //int bitOffset = 0;

            //1 pixel images...
            //Should actualy use width or height and check after each operation

            //Should definitely use PlaneHeight of the source to determine if Upsamlping is needed?
            //E.g. 4:1:1 RGB to 4:2:0 YUV
            //Although I am not sure how you would have 4:1:1 rgb, it would just be different size R, B and G Components...

            int halfHeight = src.Height >> 1, halfWidth = src.Width >> 1;

            //Do in parallel
            Parallel.For(0, halfHeight, (i) =>
            {
                Parallel.For(0, halfWidth, (j) =>
                {
                    //Use local variables based on i and j.

                    //Create cache of 3 8 bit RGB values * 4 pixels
                    byte[] cache = new byte[12];

                    int currentLuma = i * j, currentChroma = src.Height + halfHeight + j,
                    currentSrc      = i + j * src.ImageFormat.Length,
                    currentBsrc     = i + j * src.ImageFormat.Size % Common.Binary.BitsPerByte;

                    //Read and convert component
                    ReadAndConvertRGBComponentsToYUV(src, ref currentSrc, ref currentBsrc, cache, 0);

                    //if (++j >= src.Width) break;

                    //Write Luma
                    dest[currentLuma] = cache[0];

                    //Read and convert component
                    ReadAndConvertRGBComponentsToYUV(src, ref currentSrc, ref currentBsrc, cache, 3);

                    //Write Luma and move offset
                    dest[currentLuma++ + strideDst] = cache[3];

                    //Read and convert component
                    ReadAndConvertRGBComponentsToYUV(src, ref currentSrc, ref currentBsrc, cache, 6);

                    //Write Luma
                    dest[currentLuma] = cache[6];

                    //Read and convert component
                    ReadAndConvertRGBComponentsToYUV(src, ref currentSrc, ref currentBsrc, cache, 9);

                    //Write Luma and move offset
                    dest[currentLuma++ + strideDst] = cache[9];

                    //If dest is not sub sampled then just write the components...

                    //Otherwise this will need to ensure its taking the correct amount of components for the dest SubSampling.

                    //Also needs to write in the correct plane, this assumes YUV, needs to actually write in the correct order.

                    //Needs Common.Binary.WriteBinaryInteger

                    //Determine how to write the Chroma data depending on the SubSampling.
                    switch (dst.ImageFormat.Widths[1])
                    {
                    //No plane data
                    case -1: break;

                    case 0:     //No sub sampling in plane 1, components map 1 : 1
                        {
                            //Needs to be written to the correct offset, this assumes YUV

                            //Cb
                            dest[currentChroma++] = cache[1];

                            dest[currentChroma + dstComponentOffset] = cache[4];

                            //Cr
                            dest[currentChroma++] = cache[7];

                            dest[currentChroma + dstComponentOffset] = cache[10];

                            break;
                        }

                    case 1:     //Half samples in plane 1, components map 1 : 2
                        {
                            //Write averaged Chroma Major
                            dest[currentChroma] = AverageCb(cache, quality);

                            //Write averaged Chroma Minor
                            dest[currentChroma + dstComponentOffset] = AverageCr(cache, quality);

                            //Move the Chroma offset
                            ++offChr;

                            break;
                        }

                    case 2:     //Quarter samples in plane 1, components map 4 : 1
                        {
                            byte average = (byte)(AverageCb(cache, quality) + AverageCr(cache, quality));

                            if (average > 0)
                            {
                                average >>= 1;
                            }

                            //Write averaged Chroma value
                            dest[currentChroma++] = average;

                            //Move the Chroma offset
                            ++currentChroma;

                            break;
                        }
                    }
                });
            });

            ////Loop half height
            //for (int i = 0, ie = src.Height >> 1; i < ie; ++i)
            //{

            //    //Loop for half width
            //    for (int j = 0, je = src.Width >> 1; j < je; ++j)
            //    {
            //        //Read and convert component
            //        ReadAndConvertRGBComponentsToYUV(src, ref offSrc, ref bitOffset, cache, 0);

            //        //if (++j >= src.Width) break;

            //        //Write Luma
            //        dest[offLuma] = cache[0];

            //        //Read and convert component
            //        ReadAndConvertRGBComponentsToYUV(src, ref offSrc, ref bitOffset, cache, 3);

            //        //Write Luma and move offset
            //        dest[offLuma++ + strideDst] = cache[3];

            //        //Read and convert component
            //        ReadAndConvertRGBComponentsToYUV(src, ref offSrc, ref bitOffset, cache, 6);

            //        //Write Luma
            //        dest[offLuma] = cache[6];

            //        //Read and convert component
            //        ReadAndConvertRGBComponentsToYUV(src, ref offSrc, ref bitOffset, cache, 9);

            //        //Write Luma and move offset
            //        dest[offLuma++ + strideDst] = cache[9];

            //        //If dest is not sub sampled then just write the components...

            //        //Otherwise this will need to ensure its taking the correct amount of components for the dest SubSampling.

            //        //Also needs to write in the correct plane, this assumes YUV, needs to actually write in the correct order.

            //        //Needs Common.Binary.WriteBinaryInteger

            //        //Determine how to write the Chroma data depending on the SubSampling.
            //        switch (dst.ImageFormat.Widths[1])
            //        {
            //            //No plane data
            //            case -1: break;
            //            case 0: //No sub sampling in plane 1, components map 1 : 1
            //                {
            //                    //Needs to be written to the correct offset, this assumes YUV

            //                    //Cb
            //                    dest[offChr++] = cache[1];

            //                    dest[offChr + dstComponentOffset] = cache[4];

            //                    //Cr
            //                    dest[offChr++] = cache[7];

            //                    dest[offChr + dstComponentOffset] = cache[10];

            //                    break;
            //                }
            //            case 1: //Half samples in plane 1, components map 1 : 2
            //                {
            //                    //Write averaged Chroma Major
            //                    dest[offChr] = AverageCb(cache, quality);

            //                    //Write averaged Chroma Minor
            //                    dest[offChr + dstComponentOffset] = AverageCr(cache, quality);

            //                    //Move the Chroma offset
            //                    ++offChr;

            //                    break;
            //                }
            //            case 2: //Quarter samples in plane 1, components map 4 : 1
            //                {
            //                    byte average = (byte)(AverageCb(cache, quality) + AverageCr(cache, quality));

            //                    if (average > 0) average >>= 1;

            //                    //Write averaged Chroma value
            //                    dest[offChr++] = average;

            //                    //Move the Chroma offset
            //                    ++offChr;

            //                    break;
            //                }
            //        }


            //    }

            //    //should only be done when dst.ImageFormat is Planar!!!

            //    //Move the Luma offset
            //    offLuma += strideDst;
            //}

            //cache = null;

            source = dest = null;
        }