예제 #1
0
        private static int FindNearestPal(RGBQUAD inputPal, List <RGBQUAD> palList, Dictionary <RGBQUAD, int> additionalPalMap)
        {
            if (additionalPalMap.TryGetValue(inputPal, out var addPal))
            {
                return(addPal);
            }
            var ind = palList
                      .IndexOf(palList
                               .OrderBy(x =>
                                        Math.Sqrt(Math.Pow(x.rgbBlue - inputPal.rgbBlue, 2) + Math.Pow(x.rgbGreen - inputPal.rgbGreen, 2) + Math.Pow(x.rgbRed - inputPal.rgbRed, 2)))
                               .First());

            additionalPalMap[inputPal] = ind;
            return(ind);
        }
예제 #2
0
        private static void EncodeColorMapWithAlpha(byte[] decodedData, BITMAPINFOHEADER bmi, ProcessData processData, out byte[] encodedData, out byte[] alphaData, out RGBQUAD[] pal)
        {
            //must be padded to 4 bytes
            uint rgbStride = (uint)((bmi.biWidth * processData.Decoding.Bmi.biBitCount / 8 + 3) & ~3);

            alphaData   = new byte[processData.Decoding.Bmi.biBitCount == 8 ? bmi.biHeight * bmi.biWidth : processData.Decoding.AlphaBuff.Length];
            encodedData = new byte[processData.Decoding.Bmi.biBitCount == 8 ? bmi.biHeight * rgbStride : processData.Decoding.EncodedData.Length];
            var palList          = useExistingPal ? processData.Decoding?.PalArray.ToList() : new List <RGBQUAD>();
            var additionalPalMap = new Dictionary <RGBQUAD, int>();

            for (long y = 0; y < bmi.biHeight; y++)
            {
                uint alphaLineIndex = (uint)((bmi.biHeight - y - 1) * bmi.biWidth);
                uint rgbaLineIndex  = (uint)(y * bmi.biWidth * 4);
                long rgbLineIndex   = y * rgbStride;
                for (long x = 0; x < bmi.biWidth; x++)
                {
                    long blueIndex = rgbaLineIndex + x * 4 + 0;
                    if (processData.Decoding.Bmi.biBitCount == 8)
                    {
                        var newPal = new RGBQUAD
                        {
                            rgbBlue  = decodedData[blueIndex],
                            rgbGreen = decodedData[blueIndex + 1],
                            rgbRed   = decodedData[blueIndex + 2]
                        };
                        var palIndex = palList.IndexOf(newPal);
                        if (palIndex == -1)
                        {
                            palIndex = useExistingPal ? FindNearestPal(newPal, palList, additionalPalMap) : GetPal(newPal, palList, additionalPalMap);
                        }
                        encodedData[y * rgbStride + x] = (byte)palIndex;
                    }
                    else
                    {
                        encodedData[rgbLineIndex + x * 3]     = decodedData[blueIndex];
                        encodedData[rgbLineIndex + x * 3 + 1] = decodedData[blueIndex + 1];
                        encodedData[rgbLineIndex + x * 3 + 2] = decodedData[blueIndex + 2];
                    }
                    alphaData[alphaLineIndex + x] = decodedData[blueIndex + 3];
                }
            }
            if (palList.Count < 256)
            {
                palList.AddRange(Enumerable.Repeat(new RGBQUAD(), 256 - palList.Count));
            }
            pal = palList.ToArray();
        }