예제 #1
0
        public virtual Bitmap view()
        {
            if (isDirty)
            {
                clean();
            }
            if (state != null && (state.type == DataBlob.Type.Image || state.bmp != null))
            {
                return(state.bmp);
            }
            if (state != null && state.type == DataBlob.Type.Channels && state.channels != null)
            {
                Size s = Subsample.deduceCbCrSize(state);

                Bitmap     bmp     = new Bitmap(state.channelWidth, state.channelHeight, PixelFormat.Format24bppRgb);
                BitmapData bmpData = bmp.LockBits(
                    new Rectangle(0, 0, bmp.Width, bmp.Height),
                    System.Drawing.Imaging.ImageLockMode.ReadWrite,
                    bmp.PixelFormat);

                IntPtr ptr = bmpData.Scan0;
                //copy bytes
                int    nBytes    = Math.Abs(bmpData.Stride) * bmp.Height;
                byte[] rgbValues = new byte[nBytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, nBytes);


                //order: B,G,R,  B,G,R,  ...
                int channelIndex   = 0;
                int counter        = 0;
                int channelIndexRB = 0;
                for (int y = 0; y < state.imageHeight; y++)
                {
                    channelIndex   = y * state.channelWidth;
                    channelIndexRB = y * s.Width;
                    counter        = y * bmpData.Stride;

                    for (int x = 0; x < state.imageWidth; x++)
                    {
                        rgbValues[counter + 2] = state.channels[0][channelIndex];
                        if (y < s.Height && x < s.Width)
                        {
                            rgbValues[counter + 1] = state.channels[1][channelIndexRB];
                            rgbValues[counter + 0] = state.channels[2][channelIndexRB];
                            channelIndexRB++;
                        }
                        counter += 3;
                        channelIndex++;
                    }
                }
                System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, nBytes);

                bmp.UnlockBits(bmpData);
                state.bmp = bmp;
                return(bmp);
            }

            //Debug.Write("View missing in " + properties["name"].getString() + "\n");
            return(null);
        }
예제 #2
0
        private void reassemble(byte[][] past, byte[][] diff, byte[][] vectors)
        {
            Chunker c = new Chunker(chunkSize, state.channelWidth, state.channelHeight, state.channelWidth, 1);
            int     pixelTL;

            for (int i = 0; i < c.getNumChunks(); i++)
            {
                pixelTL = c.chunkIndexToPixelIndex(i);

                //update channels to be difference.
                restoreChunk(state.channels[0], past[0], diff[0], vectors[0][i], pixelTL, state.channelWidth);
            }

            //Do the second two channels
            Size smaller = Subsample.deduceCbCrSize(state);

            c = new Chunker(chunkSize, smaller.Width, smaller.Height, smaller.Width, 1);
            for (int i = 0; i < c.getNumChunks(); i++)
            {
                pixelTL = c.chunkIndexToPixelIndex(i);

                restoreChunk(state.channels[1], past[1], diff[1], vectors[1][i], pixelTL, smaller.Width);
                restoreChunk(state.channels[2], past[2], diff[2], vectors[2][i], pixelTL, smaller.Width);
            }
        }
예제 #3
0
        private void setupBlobs(DataBlob metadata)
        {
            C1      = new DataBlob();
            C2      = new DataBlob();
            C3      = new DataBlob();
            V2      = new DataBlob();
            V3      = new DataBlob();
            C1.type = C2.type = C3.type = DataBlob.Type.Channels;
            V2.type = V3.type = DataBlob.Type.Vectors;

            //import metadata onto channels
            C1.imageWidth      = C2.imageWidth = C3.imageWidth = metadata.imageWidth;
            C1.imageHeight     = C2.imageHeight = C3.imageHeight = metadata.imageHeight;
            C1.channelWidth    = C2.channelWidth = C3.channelWidth = metadata.channelWidth;
            C1.channelHeight   = C2.channelHeight = C3.channelHeight = metadata.channelHeight;
            C1.quantizeQuality = C2.quantizeQuality = C3.quantizeQuality = metadata.quantizeQuality;
            C1.samplingMode    = C2.samplingMode = C3.samplingMode = metadata.samplingMode;

            Chunker c = new Chunker(8, metadata.channelWidth, metadata.channelHeight, metadata.channelWidth, 1);

            V2.imageWidth      = V3.imageWidth = metadata.imageWidth;
            V2.imageHeight     = V3.imageHeight = metadata.imageHeight;
            V2.channelWidth    = V3.channelWidth = c.getChunksWide();
            V2.channelHeight   = V3.channelHeight = c.getChunksHigh();
            V2.quantizeQuality = V3.quantizeQuality = metadata.quantizeQuality;
            V2.samplingMode    = V3.samplingMode = metadata.samplingMode;

            //Allocate space for incoming data
            C1.channels = new byte[3][];
            C2.channels = new byte[3][];
            C3.channels = new byte[3][];
            V2.channels = new byte[3][];
            V3.channels = new byte[3][];

            int  cMajor    = C1.channelWidth * C1.channelHeight;
            Size sizeMinor = Subsample.getPaddedCbCrSize(new Size(C1.channelWidth, C1.channelHeight), C1.samplingMode);
            int  cMinor    = sizeMinor.Width * sizeMinor.Height;

            C1.channels[0] = new byte[cMajor];
            C2.channels[0] = new byte[cMajor];
            C3.channels[0] = new byte[cMajor];
            C1.channels[1] = new byte[cMinor];
            C2.channels[1] = new byte[cMinor];
            C3.channels[1] = new byte[cMinor];
            C1.channels[2] = new byte[cMinor];
            C2.channels[2] = new byte[cMinor];
            C3.channels[2] = new byte[cMinor];
            cMajor         = V2.channelWidth * V2.channelHeight;
            sizeMinor      = Subsample.getCbCrSize(new Size(V2.channelWidth, V2.channelHeight), V2.samplingMode);
            cMinor         = sizeMinor.Width * sizeMinor.Height;
            V2.channels[0] = new byte[cMajor];
            V3.channels[0] = new byte[cMajor];
            V2.channels[1] = new byte[cMinor];
            V3.channels[1] = new byte[cMinor];
            V2.channels[2] = new byte[cMinor];
            V3.channels[2] = new byte[cMinor];
        }
예제 #4
0
        private void readChannels(BinaryReader reader, DataBlob ch)
        {
            Chunker c = new Chunker(8, ch.channelWidth, ch.channelHeight, ch.channelWidth, 1);

            readChannel(reader, ch.channels[0], c);
            Size s = Subsample.deduceCbCrSize(ch);

            c = new Chunker(8, s.Width, s.Height, s.Width, 1);
            readChannel(reader, ch.channels[1], c);
            readChannel(reader, ch.channels[2], c);
        }
예제 #5
0
        protected static void writeChannels(BinaryWriter writer, DataBlob ch)
        {
            Chunker c = new Chunker(8, ch.channelWidth, ch.channelHeight, ch.channelWidth, 1);

            writeChannel(writer, ch.channels[0], c);
            Size s = Subsample.deduceCbCrSize(ch);

            c = new Chunker(8, s.Width, s.Height, s.Width, 1);
            writeChannel(writer, ch.channels[1], c);
            writeChannel(writer, ch.channels[2], c);
        }
예제 #6
0
        private void calcMoVec(byte[][] chOld, byte[][] chNew)
        {
            //for each channel
            //chunk state.channels into 8x8 blocks
            //compare each block with blocks surrounding them in the arg channels
            //over x = [-7,7] (range 15 values)
            //and  y = [-7,7] (range 15 values)


            //Do the first channel
            Chunker c = new Chunker(chunkSize, state.channelWidth, state.channelHeight, state.channelWidth, 1);
            int     pixelTL;
            byte    offset;

            //need to set vState.channelWidth and vState.channelHeight correctly, I think....
            vState.channels[0]   = new byte[c.getNumChunks()];
            vState.channelWidth  = c.getChunksWide();
            vState.channelHeight = c.getChunksHigh();

            for (int i = 0; i < c.getNumChunks(); i++)
            {
                pixelTL = c.chunkIndexToPixelIndex(i);
                //find best match given search area
                offset = findOffsetVector(chNew[0], chOld[0], pixelTL, state.channelWidth);
                //save best match vector
                vState.channels[0][i] = offset;
                //update channels to be difference.
                if (i == 20)
                {
                    i = 20;
                }
                setDiff(state.channels[0], chNew[0], chOld[0], pixelTL, offset, state.channelWidth);
            }

            //Do the second two channels
            Size smaller = Subsample.deduceCbCrSize(state);

            c = new Chunker(chunkSize, smaller.Width, smaller.Height, smaller.Width, 1);
            vState.channels[1] = new byte[c.getNumChunks()];
            vState.channels[2] = new byte[c.getNumChunks()];
            for (int i = 0; i < c.getNumChunks(); i++)
            {
                pixelTL = c.chunkIndexToPixelIndex(i);
                offset  = findOffsetVector(chNew[1], chOld[1], pixelTL, smaller.Width);
                vState.channels[1][i] = offset;
                setDiff(state.channels[1], chNew[1], chOld[1], pixelTL, offset, smaller.Width);
                //offset = findOffsetVector(state.channels[2], channels[2], pixelTL, state.channelWidth);
                //Just use the same vectors for channel 3 as channel 2. Probably okay.
                vState.channels[2][i] = offset;
                setDiff(state.channels[2], chNew[2], chOld[2], pixelTL, offset, smaller.Width);
            }
        }
예제 #7
0
        private void padChannels()
        {
            //pad the size
            Size ySize     = new Size(state.channelWidth, state.channelHeight);
            Size brOldSize = Subsample.deduceCbCrSize(state);
            Size brNewSize = Subsample.getPaddedCbCrSize(ySize, state.samplingMode);

            if (ySize.Width % 8 != 0)
            {
                ySize.Width += 8 - (ySize.Width % 8);
            }
            if (ySize.Height % 8 != 0)
            {
                ySize.Height += 8 - (ySize.Height % 8);
            }

            //create padded container
            byte[][] newChannels = new byte[3][];
            newChannels[0] = new byte[ySize.Width * ySize.Height];
            newChannels[1] = new byte[brNewSize.Width * brNewSize.Height];
            newChannels[2] = new byte[newChannels[1].Length];

            //copy array into larger container
            for (int y = 0; y < state.channelHeight; y++)
            {
                Array.Copy(state.channels[0], y * state.channelWidth, newChannels[0], y * ySize.Width, state.channelWidth);
            }
            for (int y = 0; y < brOldSize.Height; y++)
            {
                Array.Copy(state.channels[1], y * brOldSize.Width, newChannels[1], y * brNewSize.Width, brOldSize.Width);
                Array.Copy(state.channels[2], y * brOldSize.Width, newChannels[2], y * brNewSize.Width, brOldSize.Width);
                for (int x = brOldSize.Width; x < brNewSize.Width; x++)
                {
                    newChannels[1][y * brNewSize.Width + x] = 127;
                    newChannels[2][y * brNewSize.Width + x] = 127;
                }
            }

            //update state
            state.channelWidth  = ySize.Width;
            state.channelHeight = ySize.Height;
            state.channels      = newChannels;
        }
예제 #8
0
파일: DCT.cs 프로젝트: JoePelz/NodeShop
        protected override void clean()
        {
            base.clean();
            if (state == null || state.channels == null)
            {
                return;
            }

            if (!isInverse)
            {
                state.quantizeQuality = properties["quality"].nValue;
            }
            generateQTables(state.quantizeQuality);

            padChannels();
            Chunker c = new Chunker(chunkSize, state.channelWidth, state.channelHeight, state.channelWidth, 1);

            byte[] data = new byte[chunkSize * chunkSize];
            for (int i = 0; i < c.getNumChunks(); i++)
            {
                c.getBlock(state.channels[0], data, i);
                data = isInverse ? doIDCT(data, quantizationY) : doDCT(data, quantizationY);
                c.setBlock(state.channels[0], data, i);
            }

            Size tempS = Subsample.getPaddedCbCrSize(new Size(state.channelWidth, state.channelHeight), state.samplingMode);

            c = new Chunker(chunkSize, tempS.Width, tempS.Height, tempS.Width, 1);
            for (int i = 0; i < c.getNumChunks(); i++)
            {
                c.getBlock(state.channels[1], data, i);
                data = isInverse ? doIDCT(data, quantizationC) : doDCT(data, quantizationC);
                c.setBlock(state.channels[1], data, i);
                c.getBlock(state.channels[2], data, i);
                data = isInverse ? doIDCT(data, quantizationC) : doDCT(data, quantizationC);
                c.setBlock(state.channels[2], data, i);
            }
        }
예제 #9
0
        private void open(object sender, EventArgs e)
        {
            soil();
            clean();
            state          = new DataBlob();
            state.type     = DataBlob.Type.Channels;
            state.channels = new byte[3][];
            using (Stream stream = new FileStream(inPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                using (BinaryReader reader = new BinaryReader(stream, Encoding.Default)) {
                    state.imageWidth      = reader.ReadUInt16();
                    state.imageHeight     = reader.ReadUInt16();
                    state.channelWidth    = reader.ReadUInt16();
                    state.channelHeight   = reader.ReadUInt16();
                    state.quantizeQuality = reader.ReadByte();
                    state.samplingMode    = (DataBlob.Samples)reader.ReadByte();

                    state.channels[0] = new byte[state.channelWidth * state.channelHeight];

                    byte[] data = new byte[64];
                    byte   count, val;

                    //======================
                    //===== Y Channel ======
                    //======================
                    Chunker c       = new Chunker(8, state.channelWidth, state.channelHeight, state.channelWidth, 1);
                    var     indexer = Chunker.zigZag8Index();
                    for (int iChunk = 0; iChunk < c.getNumChunks(); iChunk++)
                    {
                        for (int iPixel = 0; iPixel < 64;)
                        {
                            val = reader.ReadByte();
                            if (val != rleToken)
                            {
                                data[iPixel++] = val;
                            }
                            else
                            {
                                count = reader.ReadByte();
                                val   = reader.ReadByte();
                                while (count > 0)
                                {
                                    data[iPixel++] = val;
                                    count--;
                                }
                            }
                        }
                        c.setZigZag8Block(state.channels[0], data, iChunk);
                    }

                    //===========================
                    //===== Cr, Cb Channels =====
                    //===========================
                    Size len = Subsample.getPaddedCbCrSize(new Size(state.channelWidth, state.channelHeight), state.samplingMode);
                    state.channels[1] = new byte[len.Width * len.Height];
                    state.channels[2] = new byte[state.channels[1].Length];
                    c = new Chunker(8, len.Width, len.Height, len.Width, 1);

                    indexer = Chunker.zigZag8Index();
                    for (int channel = 1; channel < state.channels.Length; channel++)
                    {
                        for (int iChunk = 0; iChunk < c.getNumChunks(); iChunk++)
                        {
                            for (int iPixel = 0; iPixel < 64;)
                            {
                                val = reader.ReadByte();
                                if (val != rleToken)
                                {
                                    data[iPixel++] = val;
                                }
                                else
                                {
                                    count = reader.ReadByte();
                                    val   = reader.ReadByte();
                                    while (count > 0)
                                    {
                                        data[iPixel++] = val;
                                        count--;
                                    }
                                }
                            }
                            c.setZigZag8Block(state.channels[channel], data, iChunk);
                        }
                    }
                }
            } //close file
        }
예제 #10
0
        public static Bitmap channelsToBitmap(DataBlob data)
        {
            if (data == null || data.channels == null)
            {
                return(null);
            }

            Bitmap bmp = new Bitmap(data.imageWidth, data.imageHeight, PixelFormat.Format24bppRgb);

            BitmapData bmpData = bmp.LockBits(
                new Rectangle(0, 0, bmp.Width, bmp.Height),
                ImageLockMode.ReadWrite,
                bmp.PixelFormat);

            IntPtr ptr = bmpData.Scan0;


            //copy bytes
            int nBytes = Math.Abs(bmpData.Stride) * bmp.Height;

            byte[] rgbValues = new byte[nBytes];

            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, nBytes);
            int pixel;
            int iY, iCrb;
            int channelYStride = data.channelWidth;
            //TODO: don't assume padded. :P
            int channelCRBStride = Subsample.getCbCrStride(data);

            for (int y = 0; y < data.imageHeight; y++)
            {
                pixel = y * bmpData.Stride;
                iY    = y * channelYStride;
                iCrb  = (data.samplingMode == DataBlob.Samples.s420 ? y / 2 : y) * channelCRBStride;
                for (int x = 0; x < data.imageWidth; x++)
                {
                    rgbValues[pixel + 2] = data.channels[0][iY];
                    rgbValues[pixel + 1] = data.channels[1][iCrb];
                    rgbValues[pixel]     = data.channels[2][iCrb];
                    pixel += 3;
                    iY++;

                    if (data.samplingMode == DataBlob.Samples.s420 || data.samplingMode == DataBlob.Samples.s422)
                    {
                        if (x % 2 == 1)
                        {
                            iCrb++;
                        }
                    }
                    else if (data.samplingMode == DataBlob.Samples.s444)
                    {
                        iCrb++;
                    }
                    else if (data.samplingMode == DataBlob.Samples.s411)
                    {
                        if (x % 4 == 3)
                        {
                            iCrb++;
                        }
                    }
                }
            }

            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, nBytes);

            bmp.UnlockBits(bmpData);

            return(bmp);
        }