Esempio n. 1
0
        public static void stbtt_GetGlyphBitmapBox(stbtt_fontinfo font, int glyph, float scale_x, float scale_y, ref int x0, ref int y0, ref int x1, ref int y1)
        {
            var px0 = new FakePtr <int>(1)
            {
                Value = x0
            };

            var px1 = new FakePtr <int>(1)
            {
                Value = x1
            };

            var py0 = new FakePtr <int>(1)
            {
                Value = y0
            };

            var py1 = new FakePtr <int>(1)
            {
                Value = y1
            };

            stbtt_GetGlyphBitmapBox(font, glyph, scale_x, scale_y, px0, py0, px1, py1);

            x0 = px0.Value;
            x1 = px1.Value;
            y0 = py0.Value;
            y1 = py1.Value;
        }
Esempio n. 2
0
        private int stbi__expand_png_palette(byte[] palette, int len, int pal_img_n)
        {
            uint i           = 0;
            var  pixel_count = (uint)(img_x * img_y);
            var  orig        = _out_;

            _out_ = new byte[pixel_count * pal_img_n];
            var p = new FakePtr <byte>(_out_);

            if (pal_img_n == 3)
            {
                for (i = (uint)0; i < pixel_count; ++i)
                {
                    var n = orig[i] * 4;
                    p[0] = palette[n];
                    p[1] = palette[n + 1];
                    p[2] = palette[n + 2];
                    p   += 3;
                }
            }
            else
            {
                for (i = (uint)0; i < pixel_count; ++i)
                {
                    var n = orig[i] * 4;
                    p[0] = palette[n];
                    p[1] = palette[n + 1];
                    p[2] = palette[n + 2];
                    p[3] = palette[n + 3];
                    p   += 4;
                }
            }

            return(1);
        }
Esempio n. 3
0
        public static int stbtt_GetGlyphBox(stbtt_fontinfo info, int glyph_index, ref int x0, ref int y0, ref int x1, ref int y1)
        {
            var px0 = new FakePtr <int>(1)
            {
                Value = x0
            };

            var px1 = new FakePtr <int>(1)
            {
                Value = x1
            };

            var py0 = new FakePtr <int>(1)
            {
                Value = y0
            };

            var py1 = new FakePtr <int>(1)
            {
                Value = y1
            };

            var result = stbtt_GetGlyphBox(info, glyph_index, px0, py0, px1, py1);

            x0 = px0.Value;
            x1 = px1.Value;
            y0 = py0.Value;
            y1 = py1.Value;

            return(result);
        }
Esempio n. 4
0
        private int stbi__compute_transparency(byte[] tc, int out_n)
        {
            uint i           = 0;
            var  pixel_count = (uint)(img_x * img_y);
            var  p           = new FakePtr <byte>(_out_);

            if (out_n == 2)
            {
                for (i = (uint)0; i < pixel_count; ++i)
                {
                    p[1] = (byte)(p[0] == tc[0] ? 0 : 255);
                    p   += 2;
                }
            }
            else
            {
                for (i = (uint)0; i < pixel_count; ++i)
                {
                    if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
                    {
                        p[3] = 0;
                    }
                    p += 4;
                }
            }

            return(1);
        }
Esempio n. 5
0
        private static void BlurCols(FakePtr <byte> dst, int w, int h, int dstStride, int alpha)
        {
            var x = 0;
            var y = 0;

            for (y = 0; y < h; y++)
            {
                var z = 0;
                for (x = 1; x < w; x++)
                {
                    z     += (alpha * ((dst[x] << 7) - z)) >> 16;
                    dst[x] = (byte)(z >> 7);
                }

                dst[w - 1] = 0;
                z          = 0;
                for (x = w - 2; x >= 0; x--)
                {
                    z     += (alpha * ((dst[x] << 7) - z)) >> 16;
                    dst[x] = (byte)(z >> 7);
                }

                dst[0] = 0;
                dst   += dstStride;
            }
        }
Esempio n. 6
0
        private static void BlurRows(FakePtr <byte> dst, int w, int h, int dstStride, int alpha)
        {
            var x = 0;
            var y = 0;

            for (x = 0; x < w; x++)
            {
                var z = 0;
                for (y = dstStride; y < h * dstStride; y += dstStride)
                {
                    z     += (alpha * ((dst[y] << 7) - z)) >> 16;
                    dst[y] = (byte)(z >> 7);
                }

                dst[(h - 1) * dstStride] = 0;
                z = 0;
                for (y = (h - 2) * dstStride; y >= 0; y -= dstStride)
                {
                    z     += (alpha * ((dst[y] << 7) - z)) >> 16;
                    dst[y] = (byte)(z >> 7);
                }

                dst[0] = 0;
                dst++;
            }
        }
Esempio n. 7
0
        public void stbtt__dict_get_ints(int key, out uint _out_)
        {
            var temp = new FakePtr <uint>(new uint[1]);

            stbtt__dict_get_ints(key, 1, temp);

            _out_ = temp[0];
        }
Esempio n. 8
0
 static bool stbtt_tag(FakePtr <byte> p, string str)
 {
     return(stbtt_tag4(p,
                       (byte)(str.Length >= 1 ? str[0] : 0),
                       (byte)(str.Length >= 2 ? str[1] : 0),
                       (byte)(str.Length >= 3 ? str[2] : 0),
                       (byte)(str.Length >= 4 ? str[3] : 0)));
 }
Esempio n. 9
0
 private int stbi__do_zlib(byte[] obuf, int olen, int exp, int parse_header)
 {
     zout_start   = obuf;
     zout         = new FakePtr <byte>(obuf);
     zout_end     = new FakePtr <byte>(obuf, olen);
     z_expandable = exp;
     return(stbi__parse_zlib(parse_header));
 }
Esempio n. 10
0
        public void stbtt__rasterize(stbtt__point[] pts, int[] wcount, int windings,
                                     float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert)
        {
            var y_scale_inv = invert != 0 ? -scale_y : scale_y;
            var n           = 0;
            var i           = 0;
            var j           = 0;
            var k           = 0;
            var m           = 0;
            var vsubsample  = 1;

            n = 0;
            for (i = 0; i < windings; ++i)
            {
                n += wcount[i];
            }
            var e = new stbtt__edge[n + 1];

            for (i = 0; i < e.Length; ++i)
            {
                e[i] = new stbtt__edge();
            }
            n = 0;
            m = 0;
            for (i = 0; i < windings; ++i)
            {
                var p = new FakePtr <stbtt__point>(pts, m);
                m += wcount[i];
                j  = wcount[i] - 1;
                for (k = 0; k < wcount[i]; j = k++)
                {
                    var a = k;
                    var b = j;
                    if (p[j].y == p[k].y)
                    {
                        continue;
                    }
                    e[n].invert = 0;
                    if (invert != 0 && p[j].y > p[k].y || invert == 0 && p[j].y < p[k].y)
                    {
                        e[n].invert = 1;
                        a           = j;
                        b           = k;
                    }

                    e[n].x0 = p[a].x * scale_x + shift_x;
                    e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
                    e[n].x1 = p[b].x * scale_x + shift_x;
                    e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
                    ++n;
                }
            }

            var ptr = new FakePtr <stbtt__edge>(e);

            stbtt__sort_edges(ptr, n);
            stbtt__rasterize_sorted_edges(ptr, n, vsubsample, off_x, off_y);
        }
Esempio n. 11
0
        public void stbtt__dict_get_ints(int key, int outcount, FakePtr <uint> _out_)
        {
            var i        = 0;
            var operands = stbtt__dict_get(key);

            for (i = 0; i < outcount && operands.cursor < operands.size; i++)
            {
                _out_[i] = operands.stbtt__cff_int();
            }
        }
Esempio n. 12
0
        public static FakePtr <T> CreateWithSize(int size)
        {
            var result = new FakePtr <T>(new T[size]);

            for (int i = 0; i < size; ++i)
            {
                result[i] = new T();
            }

            return(result);
        }
Esempio n. 13
0
        private void stbi__tga_read_rgb16(FakePtr <byte> _out_)
        {
            var px          = (ushort)stbi__get16le();
            var fiveBitMask = (ushort)31;
            var r           = (px >> 10) & fiveBitMask;
            var g           = (px >> 5) & fiveBitMask;
            var b           = px & fiveBitMask;

            _out_[0] = (byte)(r * 255 / 31);
            _out_[1] = (byte)(g * 255 / 31);
            _out_[2] = (byte)(b * 255 / 31);
        }
Esempio n. 14
0
        private void stbi__de_iphone()
        {
            uint i           = 0;
            var  pixel_count = (uint)(img_x * img_y);
            var  p           = new FakePtr <byte>(_out_);

            if (img_out_n == 3)
            {
                for (i = (uint)0; i < pixel_count; ++i)
                {
                    var t = p[0];
                    p[0] = p[2];
                    p[2] = t;
                    p   += 3;
                }
            }
            else
            {
                if (stbi__unpremultiply_on_load != 0)
                {
                    for (i = (uint)0; i < pixel_count; ++i)
                    {
                        var a = p[3];
                        var t = p[0];
                        if (a != 0)
                        {
                            var half = (byte)(a / 2);
                            p[0] = (byte)((p[2] * 255 + half) / a);
                            p[1] = (byte)((p[1] * 255 + half) / a);
                            p[2] = (byte)((t * 255 + half) / a);
                        }
                        else
                        {
                            p[0] = p[2];
                            p[2] = t;
                        }

                        p += 4;
                    }
                }
                else
                {
                    for (i = (uint)0; i < pixel_count; ++i)
                    {
                        var t = p[0];
                        p[0] = p[2];
                        p[2] = t;
                        p   += 4;
                    }
                }
            }
        }
Esempio n. 15
0
        private int stbi__psd_decode_rle(FakePtr <byte> p, int pixelCount)
        {
            var count = 0;
            var nleft = 0;
            var len   = 0;

            count = 0;
            while ((nleft = pixelCount - count) > 0)
            {
                len = stbi__get8();
                if (len == 128)
                {
                }
                else if (len < 128)
                {
                    len++;
                    if (len > nleft)
                    {
                        return(0);
                    }
                    count += len;
                    while (len != 0)
                    {
                        p.Value = stbi__get8();
                        p      += 4;
                        len--;
                    }
                }
                else if (len > 128)
                {
                    byte val = 0;
                    len = 257 - len;
                    if (len > nleft)
                    {
                        return(0);
                    }
                    val    = stbi__get8();
                    count += len;
                    while (len != 0)
                    {
                        p.Value = val;
                        p      += 4;
                        len--;
                    }
                }
            }

            return(1);
        }
        public int stbtt_PackFontRange(byte[] fontdata, int font_index, float font_size,
                                       int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar[] chardata_for_range)
        {
            var range = new stbtt_pack_range();

            range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range;
            range.array_of_unicode_codepoints      = null;
            range.num_chars          = num_chars_in_range;
            range.chardata_for_range = chardata_for_range;
            range.font_size          = font_size;

            var ranges = new FakePtr <stbtt_pack_range>(range);

            return(stbtt_PackFontRanges(fontdata, font_index, ranges, 1));
        }
Esempio n. 17
0
        private int stbi__parse_uncompressed_block()
        {
            var header = new byte[4];
            var len    = 0;
            var nlen   = 0;
            var k      = 0;

            if ((num_bits & 7) != 0)
            {
                stbi__zreceive(num_bits & 7);
            }
            k = 0;
            while (num_bits > 0)
            {
                header[k++]   = (byte)(code_buffer & 255);
                code_buffer >>= 8;
                num_bits     -= 8;
            }

            while (k < 4)
            {
                header[k++] = stbi__zget8();
            }
            len  = header[1] * 256 + header[0];
            nlen = header[3] * 256 + header[2];
            if (nlen != (len ^ 0xffff))
            {
                Decoder.stbi__err("zlib corrupt");
            }
            if (zbuffer.Offset + len > zbuffer_end.Offset)
            {
                Decoder.stbi__err("read past buffer");
            }
            if (zout.Offset + len > zout_end.Offset)
            {
                if (stbi__zexpand(zout, len) == 0)
                {
                    return(0);
                }
            }
            for (var i = 0; i < len; i++)
            {
                zout[i] = zbuffer[i];
            }
            zbuffer += len;
            zout    += len;
            return(1);
        }
Esempio n. 18
0
        static uint stbtt__find_table(FakePtr <byte> data, int fontstart, string tag)
        {
            int num_tables = ttUSHORT(data + fontstart + 4);
            int tabledir   = fontstart + 12;
            int i;

            for (i = 0; i < num_tables; ++i)
            {
                int loc = tabledir + 16 * i;
                if (stbtt_tag(data + loc + 0, tag))
                {
                    return(ttULONG(data + loc + 8));
                }
            }
            return(0);
        }
        public int stbtt_PackFontRangesGatherRects(FontInfo info,
                                                   FakePtr <stbtt_pack_range> ranges, int num_ranges, stbrp_rect[] rects)
        {
            var i = 0;
            var j = 0;
            var k = 0;
            var missing_glyph_added = 0;

            k = 0;
            for (i = 0; i < num_ranges; ++i)
            {
                var fh    = ranges[i].font_size;
                var scale = fh > 0 ? info.stbtt_ScaleForPixelHeight(fh) : info.stbtt_ScaleForMappingEmToPixels(-fh);
                ranges[i].h_oversample = (byte)this.h_oversample;
                ranges[i].v_oversample = (byte)this.v_oversample;
                for (j = 0; j < ranges[i].num_chars; ++j)
                {
                    var x0        = 0;
                    var y0        = 0;
                    var x1        = 0;
                    var y1        = 0;
                    var codepoint = ranges[i].array_of_unicode_codepoints == null
                                                ? ranges[i].first_unicode_codepoint_in_range + j
                                                : ranges[i].array_of_unicode_codepoints[j];
                    var glyph = info.stbtt_FindGlyphIndex(codepoint);
                    if (glyph == 0 && (this.skip_missing != 0 || missing_glyph_added != 0))
                    {
                        rects[k].w = rects[k].h = 0;
                    }
                    else
                    {
                        info.stbtt_GetGlyphBitmapBoxSubpixel(glyph, scale * this.h_oversample, scale * this.v_oversample,
                                                             0, 0, ref x0, ref y0, ref x1, ref y1);
                        rects[k].w = (int)(x1 - x0 + this.padding + this.h_oversample - 1);
                        rects[k].h = (int)(y1 - y0 + this.padding + this.v_oversample - 1);
                        if (glyph == 0)
                        {
                            missing_glyph_added = 1;
                        }
                    }

                    ++k;
                }
            }

            return(k);
        }
Esempio n. 20
0
        public static uint stbtt__find_table(FakePtr <byte> data, uint fontstart, string tag)
        {
            int num_tables = ttUSHORT(data + fontstart + 4);
            var tabledir   = fontstart + 12;
            int i;

            for (i = 0; (i) < num_tables; ++i)
            {
                var loc = (int)(tabledir + 16 * i);
                if (((data)[loc] == (tag[0])) && ((data)[loc + 1] == tag[1]) &&
                    ((data)[loc + 2] == tag[2]) && ((data)[loc + 3] == (tag[3])))
                {
                    return(ttULONG(data + loc + 8));
                }
            }
            return(0);
        }
Esempio n. 21
0
        private void Blur(byte[] dst, int w, int h, int dstStride, int blur)
        {
            var   alpha = 0;
            float sigma = 0;

            if (blur < 1)
            {
                return;
            }
            sigma = blur * 0.57735f;
            alpha = (int)((1 << 16) * (1.0f - Math.Exp(-2.3f / (sigma + 1.0f))));
            var ptr = new FakePtr <byte>(dst);

            BlurRows(ptr, w, h, dstStride, alpha);
            BlurCols(ptr, w, h, dstStride, alpha);
            BlurRows(ptr, w, h, dstStride, alpha);
            BlurCols(ptr, w, h, dstStride, alpha);
        }
        public int stbtt_PackBegin(byte[] pixels, int pw, int ph, int stride_in_bytes, int padding)
        {
            var context = new stbrp_context(pw - padding, ph - padding);

            this.width           = pw;
            this.height          = ph;
            this.pixels          = new FakePtr <byte>(pixels);
            this.pack_info       = context;
            this.padding         = padding;
            this.stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
            this.h_oversample    = 1;
            this.v_oversample    = 1;
            this.skip_missing    = 0;
            if (pixels != null)
            {
                Array.Clear(pixels, 0, pw * ph);
            }
            return(1);
        }
Esempio n. 23
0
        public void RenderGlyph(GraphicsDevice device, FontGlyph glyph)
        {
            var pad = glyph.Pad;

            // Render glyph to byte buffer
            var buffer = new byte[glyph.Bounds.Width * glyph.Bounds.Height];

            Array.Clear(buffer, 0, buffer.Length);

            var            g   = glyph.Index;
            FakePtr <byte> dst = new FakePtr <byte>(buffer, pad + pad * glyph.Bounds.Width);

            glyph.Font.RenderGlyphBitmap(dst,
                                         glyph.Bounds.Width - pad * 2,
                                         glyph.Bounds.Height - pad * 2,
                                         glyph.Bounds.Width,
                                         g);

            if (glyph.Blur > 0)
            {
                Blur(buffer, glyph.Bounds.Width, glyph.Bounds.Height, glyph.Bounds.Width, glyph.Blur);
            }

            // Byte buffer to RGBA
            var colorBuffer = new Color[glyph.Bounds.Width * glyph.Bounds.Height];

            for (var i = 0; i < colorBuffer.Length; ++i)
            {
                var c = buffer[i];
                colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = 255;
                colorBuffer[i].A = c;
            }

            // Write to texture
            if (Texture == null)
            {
                Texture = new Texture2D(device, Width, Height);
            }

            Texture.SetData(0, glyph.Bounds, colorBuffer, 0, colorBuffer.Length);
        }
        public int stbtt_PackFontRanges(byte[] fontdata, int font_index,
                                        FakePtr <stbtt_pack_range> ranges, int num_ranges)
        {
            var info         = new FontInfo();
            var i            = 0;
            var j            = 0;
            var n            = 0;
            var return_value = 1;

            stbrp_rect[] rects;
            for (i = 0; i < num_ranges; ++i)
            {
                for (j = 0; j < ranges[i].num_chars; ++j)
                {
                    ranges[i].chardata_for_range[j].x0     = ranges[i].chardata_for_range[j].y0 =
                        ranges[i].chardata_for_range[j].x1 = ranges[i].chardata_for_range[j].y1 = 0;
                }
            }
            n = 0;
            for (i = 0; i < num_ranges; ++i)
            {
                n += ranges[i].num_chars;
            }
            rects = new stbrp_rect[n];
            for (i = 0; i < rects.Length; ++i)
            {
                rects[i] = new stbrp_rect();
            }
            if (rects == null)
            {
                return(0);
            }
            info.stbtt_InitFont(fontdata, Common.stbtt_GetFontOffsetForIndex(fontdata, font_index));
            n = stbtt_PackFontRangesGatherRects(info, ranges, num_ranges, rects);
            stbtt_PackFontRangesPackRects(rects, n);
            return_value = stbtt_PackFontRangesRenderIntoRects(info, ranges, num_ranges, rects);
            return(return_value);
        }
Esempio n. 25
0
        private void stbi__out_gif_code(ushort code)
        {
            var idx = 0;

            if (codes[code].prefix >= 0)
            {
                stbi__out_gif_code((ushort)codes[code].prefix);
            }
            if (cur_y >= max_y)
            {
                return;
            }
            idx = cur_x + cur_y;
            history[idx / 4] = 1;
            var c = new FakePtr <byte>(color_table, codes[code].suffix * 4);

            if (c[3] > 128)
            {
                var p = new FakePtr <byte>(_out_, idx);
                p[0] = c[2];
                p[1] = c[1];
                p[2] = c[0];
                p[3] = c[3];
            }

            cur_x += 4;
            if (cur_x >= max_x)
            {
                cur_x  = start_x;
                cur_y += step;
                while (cur_y >= max_y && parse > 0)
                {
                    step  = (1 << parse) * line_size;
                    cur_y = start_y + (step >> 1);
                    --parse;
                }
            }
        }
Esempio n. 26
0
        public static void stbi__vertical_flip(byte[] image, int w, int h, int bytes_per_pixel)
        {
            int row           = 0;
            int bytes_per_row = w * bytes_per_pixel;

            byte[] temp = new byte[2048];
            for (row = (int)(0); (row) < (h >> 1); row++)
            {
                FakePtr <byte> row0       = new FakePtr <byte>(image, (int)(row * bytes_per_row));
                FakePtr <byte> row1       = new FakePtr <byte>(image, (int)((h - row - 1) * bytes_per_row));
                int            bytes_left = bytes_per_row;
                while ((bytes_left) != 0)
                {
                    int bytes_copy = (((bytes_left) < (2048)) ? bytes_left : 2048);
                    temp.memcpy(row0, bytes_copy);
                    row0.memcpy(row1, bytes_copy);
                    row1.memcpy(temp, bytes_copy);
                    row0       += bytes_copy;
                    row1       += bytes_copy;
                    bytes_left -= bytes_copy;
                }
            }
        }
Esempio n. 27
0
        private int stbi__zexpand(FakePtr <byte> zout, int n)
        {
            var cur       = 0;
            var limit     = 0;
            var old_limit = 0;

            this.zout = zout;
            if (z_expandable == 0)
            {
                Decoder.stbi__err("output buffer limit");
            }
            cur   = this.zout.Offset;
            limit = old_limit = zout_end.Offset;
            while (cur + n > limit)
            {
                limit *= 2;
            }

            Array.Resize(ref zout_start, limit);
            this.zout = new FakePtr <byte>(zout_start, cur);
            zout_end  = new FakePtr <byte>(zout_start, limit);
            return(1);
        }
Esempio n. 28
0
        static int stbtt_InitFont(ref stbtt_fontinfo info, FakePtr <byte> data2, int fontstart)
        {
            FakePtr <byte> data = (FakePtr <byte>)data2;
            uint           i;

            info.data      = data;
            info.fontstart = fontstart;

            info.name = stbtt__find_table(data, fontstart, "name"); // required
            if (info.name == 0)
            {
                return(0);
            }

            var format          = ttUSHORT(data + info.name);
            var nameRecordCount = ttUSHORT(data + info.name + 2);
            var stringOffset    = ttUSHORT(data + info.name + 4);
            var offset          = info.name + stringOffset;
            var nameRecords     = new stbtt_name_record[nameRecordCount];

            for (i = 0; i < nameRecordCount; ++i)
            {
                uint name_record = info.name + 6 + 12 * i;
                var  nr          = nameRecords[i];
                nr.platformId         = ttUSHORT(data + name_record);
                nr.platformSpecificId = ttUSHORT(data + name_record + 2);
                nr.languageId         = ttUSHORT(data + name_record + 4);
                nr.nameId             = ttUSHORT(data + name_record + 6);
                nr.length             = ttUSHORT(data + name_record + 8);
                nr.offset             = ttUSHORT(data + name_record + 10) + offset;
                nameRecords[i]        = nr;
            }

            info.nameRecords = nameRecords;

            return(1);
        }
Esempio n. 29
0
        private ImageResult InternalDecode(ColorComponents?requiredComponents, int bpc)
        {
            var pixelCount   = 0;
            var channelCount = 0;
            var compression  = 0;
            var channel      = 0;
            var i            = 0;
            var bitdepth     = 0;
            var w            = 0;
            var h            = 0;

            byte[] _out_;
            if (stbi__get32be() != 0x38425053)
            {
                stbi__err("not PSD");
            }
            if (stbi__get16be() != 1)
            {
                stbi__err("wrong version");
            }
            stbi__skip(6);
            channelCount = stbi__get16be();
            if (channelCount < 0 || channelCount > 16)
            {
                stbi__err("wrong channel count");
            }
            h        = (int)stbi__get32be();
            w        = (int)stbi__get32be();
            bitdepth = stbi__get16be();
            if (bitdepth != 8 && bitdepth != 16)
            {
                stbi__err("unsupported bit depth");
            }
            if (stbi__get16be() != 3)
            {
                stbi__err("wrong color format");
            }
            stbi__skip((int)stbi__get32be());
            stbi__skip((int)stbi__get32be());
            stbi__skip((int)stbi__get32be());
            compression = stbi__get16be();
            if (compression > 1)
            {
                stbi__err("bad compression");
            }

            var bits_per_channel = 8;

            if (compression == 0 && bitdepth == 16 && bpc == 16)
            {
                _out_            = new byte[8 * w * h];
                bits_per_channel = 16;
            }
            else
            {
                _out_ = new byte[4 * w * h];
            }

            pixelCount = w * h;

            var ptr = new FakePtr <byte>(_out_);

            if (compression != 0)
            {
                stbi__skip(h * channelCount * 2);
                for (channel = 0; channel < 4; channel++)
                {
                    FakePtr <byte> p;
                    p = ptr + channel;
                    if (channel >= channelCount)
                    {
                        for (i = 0; i < pixelCount; i++, p += 4)
                        {
                            p.Set((byte)(channel == 3 ? 255 : 0));
                        }
                    }
                    else
                    {
                        if (stbi__psd_decode_rle(p, pixelCount) == 0)
                        {
                            stbi__err("corrupt");
                        }
                    }
                }
            }
            else
            {
                for (channel = 0; channel < 4; channel++)
                {
                    if (channel >= channelCount)
                    {
                        if (bitdepth == 16 && bpc == 16)
                        {
                            throw new NotImplementedException();
                        }

                        /*							ushort* q = ((ushort*)(ptr)) + channel;
                         *                                                      ushort val = (ushort)((channel) == (3) ? 65535 : 0);
                         *                                                      for (i = (int)(0); (i) < (pixelCount); i++, q += 4)
                         *                                                      {
                         * q = (ushort)(val);
                         *                                                      }*/

                        var p   = ptr + channel;
                        var val = (byte)(channel == 3 ? 255 : 0);
                        for (i = 0; i < pixelCount; i++, p += 4)
                        {
                            p.Set(val);
                        }
                    }
                    else
                    {
                        if (bits_per_channel == 16)
                        {
                            throw new NotImplementedException();
                        }

                        /*							ushort* q = ((ushort*)(ptr)) + channel;
                         *                                                      for (i = (int)(0); (i) < (pixelCount); i++, q += 4)
                         *                                                      {
                         * q = ((ushort)(stbi__get16be()));
                         *                                                      }*/

                        var p = ptr + channel;
                        if (bitdepth == 16)
                        {
                            for (i = 0; i < pixelCount; i++, p += 4)
                            {
                                p.Set((byte)(stbi__get16be() >> 8));
                            }
                        }
                        else
                        {
                            for (i = 0; i < pixelCount; i++, p += 4)
                            {
                                p.Set(stbi__get8());
                            }
                        }
                    }
                }
            }

            if (channelCount >= 4)
            {
                if (bits_per_channel == 16)
                {
                    throw new NotImplementedException();
                }

                /*					for (i = (int)(0); (i) < (w * h); ++i)
                 *                                      {
                 *                                              ushort* pixel = (ushort*)(ptr) + 4 * i;
                 *                                              if ((pixel[3] != 0) && (pixel[3] != 65535))
                 *                                              {
                 *                                                      float a = (float)(pixel[3] / 65535.0f);
                 *                                                      float ra = (float)(1.0f / a);
                 *                                                      float inv_a = (float)(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));
                 *                                              }
                 *                                      }*/
                for (i = 0; i < w * h; ++i)
                {
                    var pixel = ptr + 4 * i;
                    if (pixel[3] != 0 && pixel[3] != 255)
                    {
                        var a     = pixel[3] / 255.0f;
                        var ra    = 1.0f / a;
                        var inv_a = 255.0f * (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);
                    }
                }
            }

            var req_comp = requiredComponents.ToReqComp();

            if (req_comp != 0 && req_comp != 4)
            {
                if (bits_per_channel == 16)
                {
                    _out_ = Conversion.stbi__convert_format16(_out_, 4, req_comp, (uint)w, (uint)h);
                }
                else
                {
                    _out_ = Conversion.stbi__convert_format(_out_, 4, req_comp, (uint)w, (uint)h);
                }
            }

            return(new ImageResult
            {
                Width = w,
                Height = h,
                SourceComponents = ColorComponents.RedGreenBlueAlpha,
                ColorComponents = requiredComponents != null
                                        ? requiredComponents.Value
                                        : ColorComponents.RedGreenBlueAlpha,
                BitsPerChannel = bits_per_channel,
                Data = _out_
            });
        }
Esempio n. 30
0
        private ImageResult InternalDecode(ColorComponents?requiredComponents)
        {
            var tga_offset         = (int)stbi__get8();
            var tga_indexed        = (int)stbi__get8();
            var tga_image_type     = (int)stbi__get8();
            var tga_is_RLE         = 0;
            var tga_palette_start  = stbi__get16le();
            var tga_palette_len    = stbi__get16le();
            var tga_palette_bits   = (int)stbi__get8();
            var tga_x_origin       = stbi__get16le();
            var tga_y_origin       = stbi__get16le();
            var tga_width          = stbi__get16le();
            var tga_height         = stbi__get16le();
            var tga_bits_per_pixel = (int)stbi__get8();
            var tga_comp           = 0;
            var tga_rgb16          = 0;
            var tga_inverted       = (int)stbi__get8();

            byte[] tga_data;
            byte[] tga_palette = null;
            var    i           = 0;
            var    j           = 0;
            var    raw_data    = new 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, out tga_rgb16);
            }
            else
            {
                tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, tga_image_type == 3 ? 1 : 0, out tga_rgb16);
            }
            if (tga_comp == 0)
            {
                stbi__err("bad format");
            }

            tga_data = new byte[tga_width * tga_height * tga_comp];
            stbi__skip(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;
                    stbi__getn(tga_data, row * tga_width * tga_comp, tga_width * tga_comp);
                }
            }
            else
            {
                if (tga_indexed != 0)
                {
                    stbi__skip(tga_palette_start);
                    tga_palette = new byte[tga_palette_len * tga_comp];
                    if (tga_rgb16 != 0)
                    {
                        var pal_entry = new FakePtr <byte>(tga_palette);
                        for (i = 0; i < tga_palette_len; ++i)
                        {
                            stbi__tga_read_rgb16(pal_entry);
                            pal_entry += tga_comp;
                        }
                    }
                    else if (!stbi__getn(tga_palette, 0, tga_palette_len * tga_comp))
                    {
                        stbi__err("bad palette");
                    }
                }

                for (i = 0; i < tga_width * tga_height; ++i)
                {
                    if (tga_is_RLE != 0)
                    {
                        if (RLE_count == 0)
                        {
                            var RLE_cmd = (int)stbi__get8();
                            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() : stbi__get16le();
                            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(new FakePtr <byte>(raw_data));
                        }
                        else
                        {
                            for (j = 0; j < tga_comp; ++j)
                            {
                                raw_data[j] = stbi__get8();
                            }
                        }

                        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_comp >= 3 && tga_rgb16 == 0)
            {
                var tga_pixel = new FakePtr <byte>(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;
                }
            }

            var req_comp = requiredComponents.ToReqComp();

            if (req_comp != 0 && req_comp != tga_comp)
            {
                tga_data = Conversion.stbi__convert_format(tga_data, tga_comp, req_comp, (uint)tga_width,
                                                           (uint)tga_height);
            }
            tga_palette_start = tga_palette_len = tga_palette_bits = tga_x_origin = tga_y_origin = 0;

            return(new ImageResult
            {
                Width = tga_width,
                Height = tga_height,
                SourceComponents = (ColorComponents)tga_comp,
                ColorComponents = requiredComponents != null ? requiredComponents.Value : (ColorComponents)tga_comp,
                BitsPerChannel = 8,
                Data = tga_data
            });
        }