gosu 2.0.0.pre6 → 2.0.0.pre8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dependencies/SDL/include/SDL.h +1 -1
- data/dependencies/SDL/include/SDL_assert.h +3 -1
- data/dependencies/SDL/include/SDL_atomic.h +2 -2
- data/dependencies/SDL/include/SDL_audio.h +1 -1
- data/dependencies/SDL/include/SDL_bits.h +1 -1
- data/dependencies/SDL/include/SDL_blendmode.h +3 -3
- data/dependencies/SDL/include/SDL_clipboard.h +1 -1
- data/dependencies/SDL/include/SDL_config.h +1 -1
- data/dependencies/SDL/include/SDL_cpuinfo.h +1 -1
- data/dependencies/SDL/include/SDL_egl.h +1 -1
- data/dependencies/SDL/include/SDL_endian.h +1 -1
- data/dependencies/SDL/include/SDL_error.h +1 -1
- data/dependencies/SDL/include/SDL_events.h +4 -11
- data/dependencies/SDL/include/SDL_filesystem.h +3 -3
- data/dependencies/SDL/include/SDL_gamecontroller.h +27 -5
- data/dependencies/SDL/include/SDL_gesture.h +1 -1
- data/dependencies/SDL/include/SDL_guid.h +1 -1
- data/dependencies/SDL/include/SDL_haptic.h +1 -1
- data/dependencies/SDL/include/SDL_hidapi.h +1 -1
- data/dependencies/SDL/include/SDL_hints.h +268 -1
- data/dependencies/SDL/include/SDL_joystick.h +1 -1
- data/dependencies/SDL/include/SDL_keyboard.h +5 -3
- data/dependencies/SDL/include/SDL_keycode.h +1 -1
- data/dependencies/SDL/include/SDL_loadso.h +1 -1
- data/dependencies/SDL/include/SDL_locale.h +1 -1
- data/dependencies/SDL/include/SDL_log.h +3 -3
- data/dependencies/SDL/include/SDL_main.h +1 -1
- data/dependencies/SDL/include/SDL_messagebox.h +1 -1
- data/dependencies/SDL/include/SDL_metal.h +1 -1
- data/dependencies/SDL/include/SDL_misc.h +1 -1
- data/dependencies/SDL/include/SDL_mouse.h +1 -1
- data/dependencies/SDL/include/SDL_mutex.h +1 -1
- data/dependencies/SDL/include/SDL_name.h +1 -1
- data/dependencies/SDL/include/SDL_opengl.h +1 -1
- data/dependencies/SDL/include/SDL_opengles.h +1 -1
- data/dependencies/SDL/include/SDL_opengles2.h +1 -1
- data/dependencies/SDL/include/SDL_pixels.h +20 -2
- data/dependencies/SDL/include/SDL_platform.h +7 -1
- data/dependencies/SDL/include/SDL_power.h +1 -1
- data/dependencies/SDL/include/SDL_quit.h +1 -1
- data/dependencies/SDL/include/SDL_rect.h +1 -1
- data/dependencies/SDL/include/SDL_render.h +3 -3
- data/dependencies/SDL/include/SDL_revision.h +2 -2
- data/dependencies/SDL/include/SDL_rwops.h +1 -1
- data/dependencies/SDL/include/SDL_scancode.h +1 -1
- data/dependencies/SDL/include/SDL_sensor.h +1 -1
- data/dependencies/SDL/include/SDL_shape.h +1 -1
- data/dependencies/SDL/include/SDL_stdinc.h +18 -12
- data/dependencies/SDL/include/SDL_surface.h +1 -1
- data/dependencies/SDL/include/SDL_system.h +17 -2
- data/dependencies/SDL/include/SDL_syswm.h +1 -1
- data/dependencies/SDL/include/SDL_test.h +1 -1
- data/dependencies/SDL/include/SDL_test_assert.h +1 -1
- data/dependencies/SDL/include/SDL_test_common.h +1 -1
- data/dependencies/SDL/include/SDL_test_compare.h +1 -1
- data/dependencies/SDL/include/SDL_test_crc32.h +1 -1
- data/dependencies/SDL/include/SDL_test_font.h +1 -1
- data/dependencies/SDL/include/SDL_test_fuzzer.h +1 -1
- data/dependencies/SDL/include/SDL_test_harness.h +1 -1
- data/dependencies/SDL/include/SDL_test_images.h +1 -1
- data/dependencies/SDL/include/SDL_test_log.h +1 -1
- data/dependencies/SDL/include/SDL_test_md5.h +1 -1
- data/dependencies/SDL/include/SDL_test_memory.h +1 -1
- data/dependencies/SDL/include/SDL_test_random.h +1 -1
- data/dependencies/SDL/include/SDL_thread.h +1 -1
- data/dependencies/SDL/include/SDL_timer.h +1 -1
- data/dependencies/SDL/include/SDL_touch.h +1 -1
- data/dependencies/SDL/include/SDL_types.h +1 -1
- data/dependencies/SDL/include/SDL_version.h +3 -3
- data/dependencies/SDL/include/SDL_video.h +8 -2
- data/dependencies/SDL/include/begin_code.h +3 -1
- data/dependencies/SDL/include/close_code.h +1 -1
- data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
- data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
- data/dependencies/SDL_sound/SDL_sound_vorbis.c +6 -3
- data/dependencies/SDL_sound/dr_flac.h +9 -5
- data/dependencies/SDL_sound/dr_mp3.h +14 -3
- data/dependencies/SDL_sound/stb_vorbis.h +66 -20
- data/dependencies/stb/stb_image.h +173 -175
- data/ext/gosu-ffi/gosu-ffi.def +1 -0
- data/ffi/Gosu_FFI_internal.h +2 -2
- data/ffi/Gosu_Image.cpp +26 -14
- data/ffi/Gosu_Image.h +8 -2
- data/include/Gosu/Image.hpp +1 -1
- data/lib/SDL2.dll +0 -0
- data/lib/gosu/ffi.rb +2 -1
- data/lib/gosu/image.rb +33 -20
- data/lib64/SDL2.dll +0 -0
- data/src/BinPacker.cpp +1 -1
- data/src/ClipRectStack.cpp +38 -0
- data/src/ClipRectStack.hpp +17 -83
- data/src/DrawOp.hpp +0 -5
- data/src/DrawOpQueue.hpp +24 -30
- data/src/GosuGLView.cpp +1 -7
- data/src/Graphics.cpp +8 -5
- data/src/GraphicsImpl.hpp +0 -23
- data/src/RenderState.hpp +25 -38
- metadata +6 -5
@@ -1,4 +1,4 @@
|
|
1
|
-
/* stb_image - v2.
|
1
|
+
/* stb_image - v2.29 - public domain image loader - http://nothings.org/stb
|
2
2
|
no warranty implied; use at your own risk
|
3
3
|
|
4
4
|
Do this:
|
@@ -48,6 +48,7 @@ LICENSE
|
|
48
48
|
|
49
49
|
RECENT REVISION HISTORY:
|
50
50
|
|
51
|
+
2.29 (2023-05-xx) optimizations
|
51
52
|
2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
|
52
53
|
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
|
53
54
|
2.26 (2020-07-13) many minor fixes
|
@@ -1072,8 +1073,8 @@ static int stbi__addints_valid(int a, int b)
|
|
1072
1073
|
return a <= INT_MAX - b;
|
1073
1074
|
}
|
1074
1075
|
|
1075
|
-
// returns 1 if the product of two
|
1076
|
-
static int stbi__mul2shorts_valid(
|
1076
|
+
// returns 1 if the product of two ints fits in a signed short, 0 on overflow.
|
1077
|
+
static int stbi__mul2shorts_valid(int a, int b)
|
1077
1078
|
{
|
1078
1079
|
if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
|
1079
1080
|
if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid
|
@@ -3384,13 +3385,13 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
|
|
3384
3385
|
return 1;
|
3385
3386
|
}
|
3386
3387
|
|
3387
|
-
static
|
3388
|
+
static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
|
3388
3389
|
{
|
3389
3390
|
// some JPEGs have junk at end, skip over it but if we find what looks
|
3390
3391
|
// like a valid marker, resume there
|
3391
3392
|
while (!stbi__at_eof(j->s)) {
|
3392
|
-
|
3393
|
-
while (x ==
|
3393
|
+
stbi_uc x = stbi__get8(j->s);
|
3394
|
+
while (x == 0xff) { // might be a marker
|
3394
3395
|
if (stbi__at_eof(j->s)) return STBI__MARKER_none;
|
3395
3396
|
x = stbi__get8(j->s);
|
3396
3397
|
if (x != 0x00 && x != 0xff) {
|
@@ -4176,6 +4177,7 @@ typedef struct
|
|
4176
4177
|
{
|
4177
4178
|
stbi_uc *zbuffer, *zbuffer_end;
|
4178
4179
|
int num_bits;
|
4180
|
+
int hit_zeof_once;
|
4179
4181
|
stbi__uint32 code_buffer;
|
4180
4182
|
|
4181
4183
|
char *zout;
|
@@ -4242,9 +4244,20 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
|
4242
4244
|
int b,s;
|
4243
4245
|
if (a->num_bits < 16) {
|
4244
4246
|
if (stbi__zeof(a)) {
|
4245
|
-
|
4247
|
+
if (!a->hit_zeof_once) {
|
4248
|
+
// This is the first time we hit eof, insert 16 extra padding btis
|
4249
|
+
// to allow us to keep going; if we actually consume any of them
|
4250
|
+
// though, that is invalid data. This is caught later.
|
4251
|
+
a->hit_zeof_once = 1;
|
4252
|
+
a->num_bits += 16; // add 16 implicit zero bits
|
4253
|
+
} else {
|
4254
|
+
// We already inserted our extra 16 padding bits and are again
|
4255
|
+
// out, this stream is actually prematurely terminated.
|
4256
|
+
return -1;
|
4257
|
+
}
|
4258
|
+
} else {
|
4259
|
+
stbi__fill_bits(a);
|
4246
4260
|
}
|
4247
|
-
stbi__fill_bits(a);
|
4248
4261
|
}
|
4249
4262
|
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
4250
4263
|
if (b) {
|
@@ -4309,6 +4322,13 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
|
|
4309
4322
|
int len,dist;
|
4310
4323
|
if (z == 256) {
|
4311
4324
|
a->zout = zout;
|
4325
|
+
if (a->hit_zeof_once && a->num_bits < 16) {
|
4326
|
+
// The first time we hit zeof, we inserted 16 extra zero bits into our bit
|
4327
|
+
// buffer so the decoder can just do its speculative decoding. But if we
|
4328
|
+
// actually consumed any of those bits (which is the case when num_bits < 16),
|
4329
|
+
// the stream actually read past the end so it is malformed.
|
4330
|
+
return stbi__err("unexpected end","Corrupt PNG");
|
4331
|
+
}
|
4312
4332
|
return 1;
|
4313
4333
|
}
|
4314
4334
|
if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data
|
@@ -4320,7 +4340,7 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
|
|
4320
4340
|
dist = stbi__zdist_base[z];
|
4321
4341
|
if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
|
4322
4342
|
if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
|
4323
|
-
if (
|
4343
|
+
if (len > a->zout_end - zout) {
|
4324
4344
|
if (!stbi__zexpand(a, zout, len)) return 0;
|
4325
4345
|
zout = a->zout;
|
4326
4346
|
}
|
@@ -4464,6 +4484,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
|
|
4464
4484
|
if (!stbi__parse_zlib_header(a)) return 0;
|
4465
4485
|
a->num_bits = 0;
|
4466
4486
|
a->code_buffer = 0;
|
4487
|
+
a->hit_zeof_once = 0;
|
4467
4488
|
do {
|
4468
4489
|
final = stbi__zreceive(a,1);
|
4469
4490
|
type = stbi__zreceive(a,2);
|
@@ -4619,9 +4640,8 @@ enum {
|
|
4619
4640
|
STBI__F_up=2,
|
4620
4641
|
STBI__F_avg=3,
|
4621
4642
|
STBI__F_paeth=4,
|
4622
|
-
// synthetic
|
4623
|
-
STBI__F_avg_first
|
4624
|
-
STBI__F_paeth_first
|
4643
|
+
// synthetic filter used for first scanline to avoid needing a dummy row of 0s
|
4644
|
+
STBI__F_avg_first
|
4625
4645
|
};
|
4626
4646
|
|
4627
4647
|
static stbi_uc first_row_filter[5] =
|
@@ -4630,29 +4650,56 @@ static stbi_uc first_row_filter[5] =
|
|
4630
4650
|
STBI__F_sub,
|
4631
4651
|
STBI__F_none,
|
4632
4652
|
STBI__F_avg_first,
|
4633
|
-
|
4653
|
+
STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub
|
4634
4654
|
};
|
4635
4655
|
|
4636
4656
|
static int stbi__paeth(int a, int b, int c)
|
4637
4657
|
{
|
4638
|
-
|
4639
|
-
|
4640
|
-
|
4641
|
-
int
|
4642
|
-
|
4643
|
-
|
4644
|
-
|
4658
|
+
// This formulation looks very different from the reference in the PNG spec, but is
|
4659
|
+
// actually equivalent and has favorable data dependencies and admits straightforward
|
4660
|
+
// generation of branch-free code, which helps performance significantly.
|
4661
|
+
int thresh = c*3 - (a + b);
|
4662
|
+
int lo = a < b ? a : b;
|
4663
|
+
int hi = a < b ? b : a;
|
4664
|
+
int t0 = (hi <= thresh) ? lo : c;
|
4665
|
+
int t1 = (thresh <= lo) ? hi : t0;
|
4666
|
+
return t1;
|
4645
4667
|
}
|
4646
4668
|
|
4647
4669
|
static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
|
4648
4670
|
|
4671
|
+
// adds an extra all-255 alpha channel
|
4672
|
+
// dest == src is legal
|
4673
|
+
// img_n must be 1 or 3
|
4674
|
+
static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n)
|
4675
|
+
{
|
4676
|
+
int i;
|
4677
|
+
// must process data backwards since we allow dest==src
|
4678
|
+
if (img_n == 1) {
|
4679
|
+
for (i=x-1; i >= 0; --i) {
|
4680
|
+
dest[i*2+1] = 255;
|
4681
|
+
dest[i*2+0] = src[i];
|
4682
|
+
}
|
4683
|
+
} else {
|
4684
|
+
STBI_ASSERT(img_n == 3);
|
4685
|
+
for (i=x-1; i >= 0; --i) {
|
4686
|
+
dest[i*4+3] = 255;
|
4687
|
+
dest[i*4+2] = src[i*3+2];
|
4688
|
+
dest[i*4+1] = src[i*3+1];
|
4689
|
+
dest[i*4+0] = src[i*3+0];
|
4690
|
+
}
|
4691
|
+
}
|
4692
|
+
}
|
4693
|
+
|
4649
4694
|
// create the png data from post-deflated data
|
4650
4695
|
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
|
4651
4696
|
{
|
4652
|
-
int bytes = (depth == 16? 2 : 1);
|
4697
|
+
int bytes = (depth == 16 ? 2 : 1);
|
4653
4698
|
stbi__context *s = a->s;
|
4654
4699
|
stbi__uint32 i,j,stride = x*out_n*bytes;
|
4655
4700
|
stbi__uint32 img_len, img_width_bytes;
|
4701
|
+
stbi_uc *filter_buf;
|
4702
|
+
int all_ok = 1;
|
4656
4703
|
int k;
|
4657
4704
|
int img_n = s->img_n; // copy it into a local for later
|
4658
4705
|
|
@@ -4664,8 +4711,11 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4664
4711
|
a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
|
4665
4712
|
if (!a->out) return stbi__err("outofmem", "Out of memory");
|
4666
4713
|
|
4714
|
+
// note: error exits here don't need to clean up a->out individually,
|
4715
|
+
// stbi__do_png always does on error.
|
4667
4716
|
if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
|
4668
4717
|
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
|
4718
|
+
if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG");
|
4669
4719
|
img_len = (img_width_bytes + 1) * y;
|
4670
4720
|
|
4671
4721
|
// we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
|
@@ -4673,189 +4723,137 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4673
4723
|
// so just check for raw_len < img_len always.
|
4674
4724
|
if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
|
4675
4725
|
|
4726
|
+
// Allocate two scan lines worth of filter workspace buffer.
|
4727
|
+
filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0);
|
4728
|
+
if (!filter_buf) return stbi__err("outofmem", "Out of memory");
|
4729
|
+
|
4730
|
+
// Filtering for low-bit-depth images
|
4731
|
+
if (depth < 8) {
|
4732
|
+
filter_bytes = 1;
|
4733
|
+
width = img_width_bytes;
|
4734
|
+
}
|
4735
|
+
|
4676
4736
|
for (j=0; j < y; ++j) {
|
4677
|
-
|
4678
|
-
stbi_uc *
|
4737
|
+
// cur/prior filter buffers alternate
|
4738
|
+
stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes;
|
4739
|
+
stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes;
|
4740
|
+
stbi_uc *dest = a->out + stride*j;
|
4741
|
+
int nk = width * filter_bytes;
|
4679
4742
|
int filter = *raw++;
|
4680
4743
|
|
4681
|
-
|
4682
|
-
|
4683
|
-
|
4684
|
-
|
4685
|
-
if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG");
|
4686
|
-
cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
|
4687
|
-
filter_bytes = 1;
|
4688
|
-
width = img_width_bytes;
|
4744
|
+
// check filter type
|
4745
|
+
if (filter > 4) {
|
4746
|
+
all_ok = stbi__err("invalid filter","Corrupt PNG");
|
4747
|
+
break;
|
4689
4748
|
}
|
4690
|
-
prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
|
4691
4749
|
|
4692
4750
|
// if first row, use special filter that doesn't sample previous row
|
4693
4751
|
if (j == 0) filter = first_row_filter[filter];
|
4694
4752
|
|
4695
|
-
//
|
4696
|
-
|
4697
|
-
|
4698
|
-
|
4699
|
-
|
4700
|
-
|
4701
|
-
|
4702
|
-
|
4703
|
-
|
4704
|
-
|
4705
|
-
|
4706
|
-
|
4707
|
-
|
4708
|
-
|
4709
|
-
|
4710
|
-
|
4711
|
-
|
4712
|
-
|
4713
|
-
|
4714
|
-
|
4715
|
-
|
4716
|
-
|
4717
|
-
cur[
|
4718
|
-
|
4719
|
-
|
4720
|
-
|
4721
|
-
|
4722
|
-
|
4723
|
-
|
4724
|
-
|
4725
|
-
|
4753
|
+
// perform actual filtering
|
4754
|
+
switch (filter) {
|
4755
|
+
case STBI__F_none:
|
4756
|
+
memcpy(cur, raw, nk);
|
4757
|
+
break;
|
4758
|
+
case STBI__F_sub:
|
4759
|
+
memcpy(cur, raw, filter_bytes);
|
4760
|
+
for (k = filter_bytes; k < nk; ++k)
|
4761
|
+
cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]);
|
4762
|
+
break;
|
4763
|
+
case STBI__F_up:
|
4764
|
+
for (k = 0; k < nk; ++k)
|
4765
|
+
cur[k] = STBI__BYTECAST(raw[k] + prior[k]);
|
4766
|
+
break;
|
4767
|
+
case STBI__F_avg:
|
4768
|
+
for (k = 0; k < filter_bytes; ++k)
|
4769
|
+
cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1));
|
4770
|
+
for (k = filter_bytes; k < nk; ++k)
|
4771
|
+
cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1));
|
4772
|
+
break;
|
4773
|
+
case STBI__F_paeth:
|
4774
|
+
for (k = 0; k < filter_bytes; ++k)
|
4775
|
+
cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0)
|
4776
|
+
for (k = filter_bytes; k < nk; ++k)
|
4777
|
+
cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes]));
|
4778
|
+
break;
|
4779
|
+
case STBI__F_avg_first:
|
4780
|
+
memcpy(cur, raw, filter_bytes);
|
4781
|
+
for (k = filter_bytes; k < nk; ++k)
|
4782
|
+
cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1));
|
4783
|
+
break;
|
4726
4784
|
}
|
4727
4785
|
|
4728
|
-
|
4729
|
-
if (depth < 8 || img_n == out_n) {
|
4730
|
-
int nk = (width - 1)*filter_bytes;
|
4731
|
-
#define STBI__CASE(f) \
|
4732
|
-
case f: \
|
4733
|
-
for (k=0; k < nk; ++k)
|
4734
|
-
switch (filter) {
|
4735
|
-
// "none" filter turns into a memcpy here; make that explicit.
|
4736
|
-
case STBI__F_none: memcpy(cur, raw, nk); break;
|
4737
|
-
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break;
|
4738
|
-
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
4739
|
-
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break;
|
4740
|
-
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break;
|
4741
|
-
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break;
|
4742
|
-
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break;
|
4743
|
-
}
|
4744
|
-
#undef STBI__CASE
|
4745
|
-
raw += nk;
|
4746
|
-
} else {
|
4747
|
-
STBI_ASSERT(img_n+1 == out_n);
|
4748
|
-
#define STBI__CASE(f) \
|
4749
|
-
case f: \
|
4750
|
-
for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
|
4751
|
-
for (k=0; k < filter_bytes; ++k)
|
4752
|
-
switch (filter) {
|
4753
|
-
STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break;
|
4754
|
-
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break;
|
4755
|
-
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
4756
|
-
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break;
|
4757
|
-
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break;
|
4758
|
-
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break;
|
4759
|
-
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break;
|
4760
|
-
}
|
4761
|
-
#undef STBI__CASE
|
4762
|
-
|
4763
|
-
// the loop above sets the high byte of the pixels' alpha, but for
|
4764
|
-
// 16 bit png files we also need the low byte set. we'll do that here.
|
4765
|
-
if (depth == 16) {
|
4766
|
-
cur = a->out + stride*j; // start at the beginning of the row again
|
4767
|
-
for (i=0; i < x; ++i,cur+=output_bytes) {
|
4768
|
-
cur[filter_bytes+1] = 255;
|
4769
|
-
}
|
4770
|
-
}
|
4771
|
-
}
|
4772
|
-
}
|
4786
|
+
raw += nk;
|
4773
4787
|
|
4774
|
-
|
4775
|
-
|
4776
|
-
// intefere with filtering but will still be in the cache.
|
4777
|
-
if (depth < 8) {
|
4778
|
-
for (j=0; j < y; ++j) {
|
4779
|
-
stbi_uc *cur = a->out + stride*j;
|
4780
|
-
stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes;
|
4781
|
-
// unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
|
4782
|
-
// png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
|
4788
|
+
// expand decoded bits in cur to dest, also adding an extra alpha channel if desired
|
4789
|
+
if (depth < 8) {
|
4783
4790
|
stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
|
4791
|
+
stbi_uc *in = cur;
|
4792
|
+
stbi_uc *out = dest;
|
4793
|
+
stbi_uc inb = 0;
|
4794
|
+
stbi__uint32 nsmp = x*img_n;
|
4784
4795
|
|
4785
|
-
//
|
4786
|
-
// we can allocate enough data that this never writes out of memory, but it
|
4787
|
-
// could also overwrite the next scanline. can it overwrite non-empty data
|
4788
|
-
// on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel.
|
4789
|
-
// so we need to explicitly clamp the final ones
|
4790
|
-
|
4796
|
+
// expand bits to bytes first
|
4791
4797
|
if (depth == 4) {
|
4792
|
-
for (
|
4793
|
-
|
4794
|
-
*
|
4798
|
+
for (i=0; i < nsmp; ++i) {
|
4799
|
+
if ((i & 1) == 0) inb = *in++;
|
4800
|
+
*out++ = scale * (inb >> 4);
|
4801
|
+
inb <<= 4;
|
4795
4802
|
}
|
4796
|
-
if (k > 0) *cur++ = scale * ((*in >> 4) );
|
4797
4803
|
} else if (depth == 2) {
|
4798
|
-
for (
|
4799
|
-
|
4800
|
-
*
|
4801
|
-
|
4802
|
-
*cur++ = scale * ((*in ) & 0x03);
|
4804
|
+
for (i=0; i < nsmp; ++i) {
|
4805
|
+
if ((i & 3) == 0) inb = *in++;
|
4806
|
+
*out++ = scale * (inb >> 6);
|
4807
|
+
inb <<= 2;
|
4803
4808
|
}
|
4804
|
-
|
4805
|
-
|
4806
|
-
|
4807
|
-
|
4808
|
-
|
4809
|
-
|
4810
|
-
*cur++ = scale * ((*in >> 6) & 0x01);
|
4811
|
-
*cur++ = scale * ((*in >> 5) & 0x01);
|
4812
|
-
*cur++ = scale * ((*in >> 4) & 0x01);
|
4813
|
-
*cur++ = scale * ((*in >> 3) & 0x01);
|
4814
|
-
*cur++ = scale * ((*in >> 2) & 0x01);
|
4815
|
-
*cur++ = scale * ((*in >> 1) & 0x01);
|
4816
|
-
*cur++ = scale * ((*in ) & 0x01);
|
4809
|
+
} else {
|
4810
|
+
STBI_ASSERT(depth == 1);
|
4811
|
+
for (i=0; i < nsmp; ++i) {
|
4812
|
+
if ((i & 7) == 0) inb = *in++;
|
4813
|
+
*out++ = scale * (inb >> 7);
|
4814
|
+
inb <<= 1;
|
4817
4815
|
}
|
4818
|
-
if (k > 0) *cur++ = scale * ((*in >> 7) );
|
4819
|
-
if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01);
|
4820
|
-
if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01);
|
4821
|
-
if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01);
|
4822
|
-
if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01);
|
4823
|
-
if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01);
|
4824
|
-
if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01);
|
4825
4816
|
}
|
4826
|
-
|
4827
|
-
|
4828
|
-
|
4829
|
-
|
4817
|
+
|
4818
|
+
// insert alpha=255 values if desired
|
4819
|
+
if (img_n != out_n)
|
4820
|
+
stbi__create_png_alpha_expand8(dest, dest, x, img_n);
|
4821
|
+
} else if (depth == 8) {
|
4822
|
+
if (img_n == out_n)
|
4823
|
+
memcpy(dest, cur, x*img_n);
|
4824
|
+
else
|
4825
|
+
stbi__create_png_alpha_expand8(dest, cur, x, img_n);
|
4826
|
+
} else if (depth == 16) {
|
4827
|
+
// convert the image data from big-endian to platform-native
|
4828
|
+
stbi__uint16 *dest16 = (stbi__uint16*)dest;
|
4829
|
+
stbi__uint32 nsmp = x*img_n;
|
4830
|
+
|
4831
|
+
if (img_n == out_n) {
|
4832
|
+
for (i = 0; i < nsmp; ++i, ++dest16, cur += 2)
|
4833
|
+
*dest16 = (cur[0] << 8) | cur[1];
|
4834
|
+
} else {
|
4835
|
+
STBI_ASSERT(img_n+1 == out_n);
|
4830
4836
|
if (img_n == 1) {
|
4831
|
-
for (
|
4832
|
-
|
4833
|
-
|
4837
|
+
for (i = 0; i < x; ++i, dest16 += 2, cur += 2) {
|
4838
|
+
dest16[0] = (cur[0] << 8) | cur[1];
|
4839
|
+
dest16[1] = 0xffff;
|
4834
4840
|
}
|
4835
4841
|
} else {
|
4836
4842
|
STBI_ASSERT(img_n == 3);
|
4837
|
-
for (
|
4838
|
-
|
4839
|
-
cur[
|
4840
|
-
cur[
|
4841
|
-
|
4843
|
+
for (i = 0; i < x; ++i, dest16 += 4, cur += 6) {
|
4844
|
+
dest16[0] = (cur[0] << 8) | cur[1];
|
4845
|
+
dest16[1] = (cur[2] << 8) | cur[3];
|
4846
|
+
dest16[2] = (cur[4] << 8) | cur[5];
|
4847
|
+
dest16[3] = 0xffff;
|
4842
4848
|
}
|
4843
4849
|
}
|
4844
4850
|
}
|
4845
4851
|
}
|
4846
|
-
} else if (depth == 16) {
|
4847
|
-
// force the image data from big-endian to platform-native.
|
4848
|
-
// this is done in a separate pass due to the decoding relying
|
4849
|
-
// on the data being untouched, but could probably be done
|
4850
|
-
// per-line during decode if care is taken.
|
4851
|
-
stbi_uc *cur = a->out;
|
4852
|
-
stbi__uint16 *cur16 = (stbi__uint16*)cur;
|
4853
|
-
|
4854
|
-
for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
|
4855
|
-
*cur16 = (cur[0] << 8) | cur[1];
|
4856
|
-
}
|
4857
4852
|
}
|
4858
4853
|
|
4854
|
+
STBI_FREE(filter_buf);
|
4855
|
+
if (!all_ok) return 0;
|
4856
|
+
|
4859
4857
|
return 1;
|
4860
4858
|
}
|
4861
4859
|
|
data/ext/gosu-ffi/gosu-ffi.def
CHANGED
data/ffi/Gosu_FFI_internal.h
CHANGED
@@ -26,7 +26,7 @@ auto Gosu_translate_exceptions(Functor functor)
|
|
26
26
|
}
|
27
27
|
}
|
28
28
|
|
29
|
-
// C-compatible wrapper structs for Gosu classes
|
29
|
+
// C-compatible wrapper structs for Gosu classes. (No inheritance because of missing virtual dtors.)
|
30
30
|
|
31
31
|
struct Gosu_Channel
|
32
32
|
{
|
@@ -48,7 +48,7 @@ struct Gosu_Sample
|
|
48
48
|
Gosu::Sample sample;
|
49
49
|
};
|
50
50
|
|
51
|
-
// Use inheritance where composition is not feasible
|
51
|
+
// Use inheritance where composition is not feasible (because we want to compare pointers).
|
52
52
|
|
53
53
|
struct Gosu_Song : Gosu::Song
|
54
54
|
{
|
data/ffi/Gosu_Image.cpp
CHANGED
@@ -2,9 +2,18 @@
|
|
2
2
|
#include <cstring> // for std::memcpy
|
3
3
|
|
4
4
|
GOSU_FFI_API Gosu_Image* Gosu_Image_create(const char* filename, unsigned image_flags)
|
5
|
+
{
|
6
|
+
return Gosu_translate_exceptions([=] { //
|
7
|
+
return new Gosu_Image { Gosu::Image(filename, image_flags) };
|
8
|
+
});
|
9
|
+
}
|
10
|
+
|
11
|
+
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_rect(const char* filename, //
|
12
|
+
int x, int y, int width, int height,
|
13
|
+
unsigned image_flags)
|
5
14
|
{
|
6
15
|
return Gosu_translate_exceptions([=] {
|
7
|
-
return new Gosu_Image{Gosu::Image
|
16
|
+
return new Gosu_Image { Gosu::Image(filename, { x, y, width, height }, image_flags) };
|
8
17
|
});
|
9
18
|
}
|
10
19
|
|
@@ -32,32 +41,35 @@ GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_text(const char* text, const cha
|
|
32
41
|
});
|
33
42
|
}
|
34
43
|
|
35
|
-
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_blob(void* blob,
|
36
|
-
int rows,
|
44
|
+
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_blob(void* blob, size_t byte_count, //
|
45
|
+
int columns, int rows, //
|
46
|
+
int x, int y, int width, int height,
|
47
|
+
unsigned image_flags)
|
37
48
|
{
|
38
49
|
return Gosu_translate_exceptions([=] {
|
39
|
-
|
40
|
-
Gosu::Bitmap bitmap
|
50
|
+
const int pixels = columns * rows * 4;
|
51
|
+
Gosu::Bitmap bitmap;
|
41
52
|
|
42
|
-
if (byte_count ==
|
53
|
+
if (byte_count == pixels) {
|
43
54
|
// 32 bit per pixel, assume R8G8B8A8
|
44
|
-
|
55
|
+
bitmap = Gosu::Bitmap(columns, rows, Gosu::Buffer(blob, byte_count, nullptr));
|
45
56
|
}
|
46
|
-
else if (byte_count ==
|
47
|
-
|
57
|
+
else if (byte_count == pixels * 4UL * sizeof(float)) {
|
58
|
+
bitmap.resize(columns, rows);
|
59
|
+
// 128 bit per channel, assume float/float/float/float RGBA - for Texplay compatibility.
|
48
60
|
const float* in = static_cast<const float*>(blob);
|
49
61
|
Gosu::Color::Channel* out = reinterpret_cast<Gosu::Color::Channel*>(bitmap.data());
|
50
|
-
for (std::size_t i = 0; i <
|
62
|
+
for (std::size_t i = 0; i < pixels; ++i) {
|
51
63
|
out[i] = static_cast<Gosu::Color::Channel>(in[i] * 255);
|
52
64
|
}
|
53
65
|
}
|
54
66
|
else {
|
55
|
-
throw std::invalid_argument
|
56
|
-
"for image of size " + std::to_string(columns) + "x"
|
57
|
-
std::to_string(rows)
|
67
|
+
throw std::invalid_argument("Invalid byte_count " + std::to_string(byte_count)
|
68
|
+
+ " for image of size " + std::to_string(columns) + "x"
|
69
|
+
+ std::to_string(rows));
|
58
70
|
}
|
59
71
|
|
60
|
-
return new Gosu_Image{Gosu::Image
|
72
|
+
return new Gosu_Image { Gosu::Image(bitmap, { x, y, width, height }, image_flags) };
|
61
73
|
});
|
62
74
|
}
|
63
75
|
|
data/ffi/Gosu_Image.h
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include "Gosu_FFI.h"
|
4
|
+
#include <stddef.h> // for size_t
|
4
5
|
#include <stdint.h>
|
5
6
|
|
6
7
|
typedef struct Gosu_Image Gosu_Image;
|
@@ -13,8 +14,13 @@ typedef struct Gosu_GLTexInfo
|
|
13
14
|
|
14
15
|
// Constructor
|
15
16
|
GOSU_FFI_API Gosu_Image* Gosu_Image_create(const char* filename, unsigned image_flags);
|
16
|
-
GOSU_FFI_API Gosu_Image*
|
17
|
-
|
17
|
+
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_rect(const char* filename, //
|
18
|
+
int x, int y, int width, int height,
|
19
|
+
unsigned image_flags);
|
20
|
+
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_blob(void* blob, size_t byte_count, //
|
21
|
+
int columns, int rows, //
|
22
|
+
int x, int y, int width, int height,
|
23
|
+
unsigned image_flags);
|
18
24
|
GOSU_FFI_API Gosu_Image* Gosu_Image_create_from_markup(const char* markup, const char* font,
|
19
25
|
double font_height, int width,
|
20
26
|
double spacing, unsigned align,
|
data/include/Gosu/Image.hpp
CHANGED
@@ -24,7 +24,7 @@ namespace Gosu
|
|
24
24
|
/// For more flexibility, use the corresponding constructor that uses a Bitmap object.
|
25
25
|
explicit Image(const std::string& filename, unsigned image_flags = IF_SMOOTH);
|
26
26
|
|
27
|
-
|
27
|
+
/// Loads a portion of the the image at the given filename..
|
28
28
|
///
|
29
29
|
/// A color key of #ff00ff is automatically applied to BMP image files.
|
30
30
|
/// For more flexibility, use the corresponding constructor that uses a Bitmap object.
|
data/lib/SDL2.dll
CHANGED
Binary file
|
data/lib/gosu/ffi.rb
CHANGED
@@ -134,11 +134,12 @@ module GosuFFI
|
|
134
134
|
attach_function :Gosu_Font_set_image, [:pointer, :string, :uint32, :pointer], :void
|
135
135
|
|
136
136
|
attach_function :Gosu_Image_create, [:string, :uint32], :pointer
|
137
|
+
attach_function :Gosu_Image_create_from_rect, [:string, :int, :int, :int, :int, :uint32], :pointer
|
137
138
|
attach_function :Gosu_Image_destroy, [:pointer], :void
|
138
139
|
|
139
140
|
attach_function :Gosu_Image_create_from_markup, [:string, :string, :double, :int, :double, :uint32, :uint32, :uint32], :pointer
|
140
141
|
attach_function :Gosu_Image_create_from_text, [:string, :string, :double, :int, :double, :uint32, :uint32, :uint32], :pointer
|
141
|
-
attach_function :Gosu_Image_create_from_blob, [:pointer, :
|
142
|
+
attach_function :Gosu_Image_create_from_blob, [:pointer, :size_t, :int, :int, :int, :int, :int, :int, :uint32], :pointer
|
142
143
|
attach_function :Gosu_Image_create_from_subimage, [:pointer, :int, :int, :int, :int], :pointer
|
143
144
|
attach_function :Gosu_Image_create_from_tiles, [:string, :int, :int, :_callback_with_image, :pointer, :uint32], :void
|
144
145
|
attach_function :Gosu_Image_create_tiles_from_image, [:pointer, :int, :int, :_callback_with_image, :pointer, :uint32], :void
|