Пример #1
0
        public static ChunkyDataPTBN CreateFromTGA(int version, string name, byte[] tgaData)
        {
            //check image type code
            if (tgaData[2] != 0x03)
            {
                bool worked = false;

                if (tgaData[1] == 0x01 && tgaData[2] == 0x01)
                {
                    tgaData = ImageConverter.ColourMapToGreyscale(tgaData);
                    worked  = true;
                }


                if (!worked)
                {
                    ImageConverter.MapEncStruct format = ImageConverter.getMapEncStruct(tgaData[2]);
                    throw new InvalidFileException("_banner.tga must be an unencoded unmapped monochrome Targa image.\r\n" +
                                                   "  Image type: " + format.formatType + "\r\n" +
                                                   "  Image encoded: " + ((format.isEncoded)?"yes":"no") + "\r\n" +
                                                   "  Colour mapped: " + ((format.isMapped)?"yes":"no"));
                }
            }

            //check colour depth
            if (tgaData[16] != 0x08)
            {
                throw new InvalidFileException("_banner.tga must be an 8-bit Targa image. Image was " + tgaData[16] + "-bit.");
            }

            float pos_x      = float.MinValue;
            float pos_y      = float.MinValue;
            int   width      = (int)tgaData[12] + (((int)tgaData[13]) << 8);
            int   height     = (int)tgaData[14] + (((int)tgaData[15]) << 8);
            int   currPos    = 0;
            int   size_x_int = (int)size_x;

            for (currPos = 18; currPos < tgaData.Length; currPos += size_x_int)
            {
                //try to find out badge;
                if (tgaData[currPos] == byte.MaxValue)
                {
                    pos_y = (float)((currPos - 18) / width);
                    pos_x = (float)(currPos - 18 - (pos_y * height));
                    break;
                }
            }

            if (pos_y != float.MinValue)
            {
                int maxPossibleEnd = currPos + width;
                int extra          = 0;

                while (currPos < maxPossibleEnd && tgaData[currPos] == byte.MaxValue)
                {
                    currPos++;
                    extra++;
                }

                //check where the left hand side should start
                if (pos_x > 0 && (tgaData[currPos - size_x_int] != byte.MaxValue || tgaData[currPos - size_x_int - 1] != byte.MinValue))
                {
                    throw new InvalidFileException("Banner is positioned beyond the edge of the texture");
                }
                else
                {
                    pos_x = pos_x + extra - size_x;
                }

                //and check for the top - not all of the block, just assume a left and bottom side are OK
                int aboveTop = currPos - size_x_int + (width * (int)size_y);
                for (int i = currPos - size_x_int; i <= aboveTop && i < tgaData.Length; i += width)
                {
                    if (tgaData[i] != byte.MaxValue && i != aboveTop)
                    {
                        throw new InvalidFileException("Banner area is too small. Banner must be 64px by 96px");
                    }
                }

                //if we got here, it's all OK

                byte[] data = new byte[16];

                BitConverter.GetBytes(pos_x).CopyTo(data, 0);
                BitConverter.GetBytes(pos_y).CopyTo(data, 4);
                BitConverter.GetBytes((float)size_x).CopyTo(data, 8);
                BitConverter.GetBytes((float)size_y).CopyTo(data, 12);

                return(new ChunkyDataPTBN(version, name, data));
            }
            else
            {
                return(null);
            }
        }
Пример #2
0
        public static ChunkyDataPTLD CreateFromTGA(PTLD_Layers layer_in, int version, string name, byte[] tgaData)
        {
            //check image type code
            if (tgaData[2] != 0x03)
            {
                bool worked = false;

                if (tgaData[1] == 0x01 && tgaData[2] == 0x01)
                {
                    tgaData = ImageConverter.ColourMapToGreyscale(tgaData);
                    worked  = true;
                }


                if (!worked)
                {
                    ImageConverter.MapEncStruct format = ImageConverter.getMapEncStruct(tgaData[2]);
                    throw new InvalidFileException("_" + layer_in.ToString() + ".tga must be an unencoded unmapped monochrome Targa image.\r\n" +
                                                   "  Image type: " + format.formatType + "\r\n" +
                                                   "  Image encoded: " + ((format.isEncoded)?"yes":"no") + "\r\n" +
                                                   "  Colour mapped: " + ((format.isMapped)?"yes":"no"));
                }
            }

            //check colour depth
            if (tgaData[16] != 0x08)
            {
                throw new InvalidFileException("_" + layer_in.ToString() + ".tga must be an 8-bit Targa image. Image was " + tgaData[16] + "-bit.");
            }

            int width  = tgaData[12] + (tgaData[13] << 8);
            int height = tgaData[14] + (tgaData[15] << 8);

            byte[] data = new byte[width * height + 8];         //only take the correct number of bytes so that we don't include comments

            int layerDataLength = data.Length - 8;
            int layer           = (int)layer_in;

            data[0] = (byte)(layer);
            data[1] = (byte)(layer >> 8);
            data[2] = (byte)(layer >> 16);
            data[3] = (byte)(layer >> 24);
            data[4] = (byte)layerDataLength;
            data[5] = (byte)(layerDataLength >> 8);
            data[6] = (byte)(layerDataLength >> 16);
            data[7] = (byte)(layerDataLength >> 24);

            int  offset   = 10 + tgaData[0];   //should be 18, but we're starting at i=8 so remove 8 here as well
            bool nonBlack = false;             //boolean to check whether they actually included any data in the layer

            for (int i = 8; i < data.Length; i++)
            {
                data[i] = tgaData[i + offset];              //take in to account any possible image ID

                if (data[i] > 5)
                {
                    nonBlack = true;
                }
            }

            //make sure we always return a dirt layer, even if they made it all black (all teamcolourable)
            if (nonBlack || layer_in == PTLD_Layers.Dirt)
            {
                return(new ChunkyDataPTLD(version, name, data));
            }
            else
            {
                return(null);
            }
        }