Beispiel #1
0
        public static void *stbi__gif_load(StbiContext s, int *x, int *y, int *comp, int reqComp,
                                           StbiResultInfo *ri)
        {
            byte *u = null;
            var   g = new StbiGif();

            u = stbi__gif_load_next(s, g, comp, reqComp, null);
            if (u != null)
            {
                *x = g.W;
                *y = g.H;
                if (reqComp != 0 && reqComp != 4)
                {
                    u = stbi__convert_format(u, 4, reqComp, (uint)g.W, (uint)g.H);
                }
            }
            else if (g.Out != null)
            {
                CRuntime.Free(g.Out);
            }

            CRuntime.Free(g.History);
            CRuntime.Free(g.Background);
            return(u);
        }
        public static IMemoryHolder Load(BinReader s, ReadState ri)
        {
            var info = new PsdInfo();

            if (!ParseHeader(s, ri, ref info))
            {
                return(null);
            }

            if (AreValidMad3Sizes(4, ri.Width, ri.Height, 0) == 0)
            {
                s.Error(ErrorCode.TooLarge);
                return(null);
            }

            byte *_out_ = (byte *)MAllocMad3((4 * ri.OutDepth + 7) / 8, ri.Width, ri.Height, 0);

            if (_out_ == null)
            {
                s.Error(ErrorCode.OutOfMemory);
                return(null);
            }

            int pixelCount = ri.Width * ri.Height;

            if (info.compression != 0)
            {
                s.Skip(ri.Height * info.channelCount * 2);

                for (int channel = 0; channel < 4; channel++)
                {
                    byte *dst;
                    dst = _out_ + channel;
                    if (channel >= info.channelCount)
                    {
                        for (int i = 0; i < pixelCount; i++, dst += 4)
                        {
                            *dst = (byte)(channel == 3 ? 255 : 0);
                        }
                    }
                    else
                    {
                        if (!DecodeRLE(s, dst, pixelCount))
                        {
                            CRuntime.Free(_out_);
                            throw new StbImageReadException(ErrorCode.Corrupt);
                        }
                    }
                }
            }
            else
            {
                for (int channel = 0; channel < 4; channel++)
                {
                    if (channel >= info.channelCount)
                    {
                        if (ri.Depth == 16)
                        {
                            ushort *q   = ((ushort *)_out_) + channel;
                            ushort  val = (ushort)(channel == 3 ? 65535 : 0);
                            for (int i = 0; i < pixelCount; i++, q += 4)
                            {
                                *q = val;
                            }
                        }
                        else
                        {
                            byte *p   = _out_ + channel;
                            byte  val = (byte)(channel == 3 ? 255 : 0);
                            for (int i = 0; i < pixelCount; i++, p += 4)
                            {
                                *p = val;
                            }
                        }
                    }
                    else
                    {
                        if (ri.OutDepth == 16)
                        {
                            ushort *q = ((ushort *)_out_) + channel;
                            for (int i = 0; i < pixelCount; i++, q += 4)
                            {
                                *q = (ushort)s.ReadInt16BE();
                            }
                        }
                        else
                        {
                            byte *p = _out_ + channel;
                            if (ri.OutDepth == 16)
                            {
                                for (int i = 0; i < pixelCount; i++, p += 4)
                                {
                                    *p = (byte)(s.ReadInt16BE() >> 8);
                                }
                            }
                            else
                            {
                                for (int i = 0; i < pixelCount; i++, p += 4)
                                {
                                    *p = s.ReadByte();
                                }
                            }
                        }
                    }
                }
            }

            if (info.channelCount >= 4)
            {
                if (ri.OutDepth == 16)
                {
                    for (int i = 0; i < pixelCount; ++i)
                    {
                        ushort *pixel = (ushort *)_out_ + 4 * i;
                        if ((pixel[3] != 0) && (pixel[3] != 65535))
                        {
                            float a     = pixel[3] / 65535.0f;
                            float ra    = 1f / a;
                            float inv_a = 65535.0f * (1 - ra);
                            pixel[0] = (ushort)(pixel[0] * ra + inv_a);
                            pixel[1] = (ushort)(pixel[1] * ra + inv_a);
                            pixel[2] = (ushort)(pixel[2] * ra + inv_a);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < pixelCount; ++i)
                    {
                        byte *pixel = _out_ + 4 * i;
                        if ((pixel[3] != 0) && (pixel[3] != 255))
                        {
                            float a     = pixel[3] / 255f;
                            float ra    = 1f / a;
                            float inv_a = 255f * (1 - ra);
                            pixel[0] = (byte)(pixel[0] * ra + inv_a);
                            pixel[1] = (byte)(pixel[1] * ra + inv_a);
                            pixel[2] = (byte)(pixel[2] * ra + inv_a);
                        }
                    }
                }
            }

            IMemoryHolder result = new HGlobalMemoryHolder(
                _out_, (ri.Width * ri.Height * ri.OutComponents * ri.OutDepth + 7) / 8);

            var errorCode = ConvertFormat(result, ri, out var convertedResult);

            if (errorCode != ErrorCode.Ok)
            {
                return(null);
            }
            return(convertedResult);
        }
Beispiel #3
0
        public static void *stbi__tga_load(StbiContext s, int *x, int *y, int *comp, int reqComp,
                                           StbiResultInfo *ri)
        {
            var   tga_offset         = (int)stbi__get8(s);
            var   tga_indexed        = (int)stbi__get8(s);
            var   tga_image_type     = (int)stbi__get8(s);
            var   tga_is_rle         = 0;
            var   tga_palette_start  = stbi__get16le(s);
            var   tga_palette_len    = stbi__get16le(s);
            var   tga_palette_bits   = (int)stbi__get8(s);
            var   tga_x_origin       = stbi__get16le(s);
            var   tga_y_origin       = stbi__get16le(s);
            var   tga_width          = stbi__get16le(s);
            var   tga_height         = stbi__get16le(s);
            var   tga_bits_per_pixel = (int)stbi__get8(s);
            var   tga_comp           = 0;
            var   tga_rgb16          = 0;
            var   tga_inverted       = (int)stbi__get8(s);
            byte *tga_data;
            byte *tga_palette = null;
            var   i           = 0;
            var   j           = 0;
            var   raw_data    = stackalloc byte[4];

            raw_data[0] = 0;

            var rle_count       = 0;
            var rle_repeating   = 0;
            var read_next_pixel = 1;

            if (tga_image_type >= 8)
            {
                tga_image_type -= 8;
                tga_is_rle      = 1;
            }

            tga_inverted = 1 - ((tga_inverted >> 5) & 1);
            if (tga_indexed != 0)
            {
                tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
            }
            else
            {
                tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, tga_image_type == 3 ? 1 : 0, &tga_rgb16);
            }
            if (tga_comp == 0)
            {
                return((byte *)(ulong)(stbi__err("bad format") != 0 ? (byte *)null : null));
            }
            *x = tga_width;
            *y = tga_height;
            if (comp != null)
            {
                *comp = tga_comp;
            }
            if (stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0) == 0)
            {
                return((byte *)(ulong)(stbi__err("too large") != 0 ? (byte *)null : null));
            }
            tga_data = (byte *)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
            if (tga_data == null)
            {
                return((byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null));
            }
            stbi__skip(s, tga_offset);
            if (tga_indexed == 0 && tga_is_rle == 0 && tga_rgb16 == 0)
            {
                for (i = 0; i < tga_height; ++i)
                {
                    var row     = tga_inverted != 0 ? tga_height - i - 1 : i;
                    var tga_row = tga_data + row * tga_width * tga_comp;
                    stbi__getn(s, tga_row, tga_width * tga_comp);
                }
            }
            else
            {
                if (tga_indexed != 0)
                {
                    stbi__skip(s, tga_palette_start);
                    tga_palette = (byte *)stbi__malloc_mad2(tga_palette_len, tga_comp, 0);
                    if (tga_palette == null)
                    {
                        CRuntime.Free(tga_data);
                        return((byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null));
                    }

                    if (tga_rgb16 != 0)
                    {
                        var pal_entry = tga_palette;
                        for (i = 0; i < tga_palette_len; ++i)
                        {
                            stbi__tga_read_rgb16(s, pal_entry);
                            pal_entry += tga_comp;
                        }
                    }
                    else if (stbi__getn(s, tga_palette, tga_palette_len * tga_comp) == 0)
                    {
                        CRuntime.Free(tga_data);
                        CRuntime.Free(tga_palette);
                        return((byte *)(ulong)(stbi__err("bad palette") != 0 ? (byte *)null : null));
                    }
                }

                for (i = 0; i < tga_width * tga_height; ++i)
                {
                    if (tga_is_rle != 0)
                    {
                        if (rle_count == 0)
                        {
                            var rle_cmd = (int)stbi__get8(s);
                            rle_count       = 1 + (rle_cmd & 127);
                            rle_repeating   = rle_cmd >> 7;
                            read_next_pixel = 1;
                        }
                        else if (rle_repeating == 0)
                        {
                            read_next_pixel = 1;
                        }
                    }
                    else
                    {
                        read_next_pixel = 1;
                    }

                    if (read_next_pixel != 0)
                    {
                        if (tga_indexed != 0)
                        {
                            var pal_idx = tga_bits_per_pixel == 8 ? stbi__get8(s) : stbi__get16le(s);
                            if (pal_idx >= tga_palette_len)
                            {
                                pal_idx = 0;
                            }
                            pal_idx *= tga_comp;
                            for (j = 0; j < tga_comp; ++j)
                            {
                                raw_data[j] = tga_palette[pal_idx + j];
                            }
                        }
                        else if (tga_rgb16 != 0)
                        {
                            stbi__tga_read_rgb16(s, raw_data);
                        }
                        else
                        {
                            for (j = 0; j < tga_comp; ++j)
                            {
                                raw_data[j] = stbi__get8(s);
                            }
                        }

                        read_next_pixel = 0;
                    }

                    for (j = 0; j < tga_comp; ++j)
                    {
                        tga_data[i * tga_comp + j] = raw_data[j];
                    }
                    --rle_count;
                }

                if (tga_inverted != 0)
                {
                    for (j = 0; j * 2 < tga_height; ++j)
                    {
                        var index1 = j * tga_width * tga_comp;
                        var index2 = (tga_height - 1 - j) * tga_width * tga_comp;
                        for (i = tga_width * tga_comp; i > 0; --i)
                        {
                            var temp = tga_data[index1];
                            tga_data[index1] = tga_data[index2];
                            tga_data[index2] = temp;
                            ++index1;
                            ++index2;
                        }
                    }
                }

                if (tga_palette != null)
                {
                    CRuntime.Free(tga_palette);
                }
            }

            if (tga_comp >= 3 && tga_rgb16 == 0)
            {
                var tga_pixel = tga_data;
                for (i = 0; i < tga_width * tga_height; ++i)
                {
                    var temp = tga_pixel[0];
                    tga_pixel[0] = tga_pixel[2];
                    tga_pixel[2] = temp;
                    tga_pixel   += tga_comp;
                }
            }

            if (reqComp != 0 && reqComp != tga_comp)
            {
                tga_data = stbi__convert_format(tga_data, tga_comp, reqComp, (uint)tga_width, (uint)tga_height);
            }
            tga_palette_start = tga_palette_len = tga_palette_bits = tga_x_origin = tga_y_origin = 0;
            return(tga_data);
        }
Beispiel #4
0
        public static void *stbi__load_gif_main(StbiContext s, int **delays, int *x, int *y, int *z, int *comp,
                                                int reqComp)
        {
            if (stbi__gif_test(s) != 0)
            {
                var   layers   = 0;
                byte *u        = null;
                byte *out_     = null;
                byte *two_back = null;
                var   g        = new StbiGif();
                var   stride   = 0;
                if (delays != null)
                {
                    *delays = null;
                }
                do
                {
                    u = stbi__gif_load_next(s, g, comp, reqComp, two_back);
                    if (u != null)
                    {
                        *x = g.W;
                        *y = g.H;
                        ++layers;
                        stride = g.W * g.H * 4;
                        if (out_ != null)
                        {
                            out_ = (byte *)CRuntime.Realloc(out_, (ulong)(layers * stride));
                            if (delays != null)
                            {
                                *delays = (int *)CRuntime.Realloc(*delays, (ulong)(sizeof(int) * layers));
                            }
                        }
                        else
                        {
                            out_ = (byte *)stbi__malloc((ulong)(layers * stride));
                            if (delays != null)
                            {
                                *delays = (int *)stbi__malloc((ulong)(layers * sizeof(int)));
                            }
                        }

                        CRuntime.Memcpy(out_ + (layers - 1) * stride, u, (ulong)stride);
                        if (layers >= 2)
                        {
                            two_back = out_ - 2 * stride;
                        }
                        if (delays != null)
                        {
                            (*delays)[layers - 1U] = g.Delay;
                        }
                    }
                } while (u != null);

                CRuntime.Free(g.Out);
                CRuntime.Free(g.History);
                CRuntime.Free(g.Background);
                if (reqComp != 0 && reqComp != 4)
                {
                    out_ = stbi__convert_format(out_, 4, reqComp, (uint)(layers * g.W), (uint)g.H);
                }
                *z = layers;
                return(out_);
            }

            return((byte *)(ulong)(stbi__err("not GIF") != 0 ? (byte *)null : null));
        }