gosu 0.10.6 → 0.10.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,7 +6,7 @@
6
6
 
7
7
  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
8
8
  {
9
- self.window = (UIWindow *)windowInstance().UIWindow();
9
+ self.window = (__bridge UIWindow *)windowInstance().UIWindow();
10
10
  [self.window makeKeyAndVisible];
11
11
 
12
12
  return YES;
@@ -74,8 +74,6 @@ namespace Gosu
74
74
  - (void)dealloc
75
75
  {
76
76
  [EAGLContext setCurrentContext:nil];
77
- [_context release];
78
- [super dealloc];
79
77
  }
80
78
 
81
79
  - (void)redrawGL:(void (^)())code
@@ -42,7 +42,7 @@ static void handleAudioInterruption(void *unused, UInt32 inInterruptionState)
42
42
 
43
43
  - (void)loadView
44
44
  {
45
- self.view = [[[GosuGLView alloc] initWithFrame:[UIScreen mainScreen].bounds] autorelease];
45
+ self.view = [[GosuGLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
46
46
  }
47
47
 
48
48
  - (BOOL)prefersStatusBarHidden
@@ -95,8 +95,6 @@ static void handleAudioInterruption(void *unused, UInt32 inInterruptionState)
95
95
  - (void)dealloc
96
96
  {
97
97
  [[NSNotificationCenter defaultCenter] removeObserver:self];
98
-
99
- [super dealloc];
100
98
  }
101
99
 
102
100
  - (void)applicationDidBecomeActive:(NSNotification *)notification
@@ -128,7 +126,6 @@ static void handleAudioInterruption(void *unused, UInt32 inInterruptionState)
128
126
  - (void)applicationDidEnterBackground:(NSNotification *)notification
129
127
  {
130
128
  [_timerOrDisplayLink invalidate];
131
- [_timerOrDisplayLink release];
132
129
  _timerOrDisplayLink = nil;
133
130
  }
134
131
 
@@ -154,14 +151,14 @@ static void handleAudioInterruption(void *unused, UInt32 inInterruptionState)
154
151
  NSTimeInterval interval = self.gosuWindowReference.updateInterval() / 1000.0;
155
152
  NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(updateAndDraw:) userInfo:nil repeats:YES];
156
153
 
157
- _timerOrDisplayLink = [timer retain];
154
+ _timerOrDisplayLink = timer;
158
155
  }
159
156
  else {
160
157
  CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateAndDraw:)];
161
158
  displayLink.frameInterval = 60 / targetFPS;
162
159
  [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
163
160
 
164
- _timerOrDisplayLink = [displayLink retain];
161
+ _timerOrDisplayLink = displayLink;
165
162
  }
166
163
  }
167
164
 
@@ -193,22 +190,22 @@ static void handleAudioInterruption(void *unused, UInt32 inInterruptionState)
193
190
 
194
191
  - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
195
192
  {
196
- self.gosuWindowReference.input().feedTouchEvent(0, touches);
193
+ self.gosuWindowReference.input().feedTouchEvent(0, (__bridge void *)touches);
197
194
  }
198
195
 
199
196
  - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
200
197
  {
201
- self.gosuWindowReference.input().feedTouchEvent(1, touches);
198
+ self.gosuWindowReference.input().feedTouchEvent(1, (__bridge void *)touches);
202
199
  }
203
200
 
204
201
  - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
205
202
  {
206
- self.gosuWindowReference.input().feedTouchEvent(2, touches);
203
+ self.gosuWindowReference.input().feedTouchEvent(2, (__bridge void *)touches);
207
204
  }
208
205
 
209
206
  - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
210
207
  {
211
- self.gosuWindowReference.input().feedTouchEvent(3, touches);
208
+ self.gosuWindowReference.input().feedTouchEvent(3, (__bridge void *)touches);
212
209
  }
213
210
 
214
211
  @end
@@ -9,38 +9,44 @@ using namespace std;
9
9
  #ifdef GOSU_IS_IPHONE // (but could also be used for OS X)
10
10
  wstring Gosu::utf8ToWstring(const string& s)
11
11
  {
12
- if (s.empty())
12
+ if (s.empty()) {
13
13
  return wstring();
14
+ }
14
15
 
15
- ObjCRef<NSString> str([[NSString alloc] initWithUTF8String:s.c_str()]);
16
+ NSString *str = [NSString stringWithUTF8String:s.c_str()];
16
17
  vector<wchar_t> buffer(s.size());
17
18
  NSUInteger usedBufferCount;
18
- if (![str.obj() getBytes:&buffer[0]
19
- maxLength:buffer.size() * sizeof(wchar_t)
20
- usedLength:&usedBufferCount
21
- encoding:NSUTF32LittleEndianStringEncoding
22
- options:0
23
- range:NSMakeRange(0, [str.obj() length])
24
- remainingRange:NULL])
19
+ if (![str getBytes:&buffer[0]
20
+ maxLength:buffer.size() * sizeof(wchar_t)
21
+ usedLength:&usedBufferCount
22
+ encoding:NSUTF32LittleEndianStringEncoding
23
+ options:0
24
+ range:NSMakeRange(0, str.length)
25
+ remainingRange:NULL]) {
25
26
  throw std::runtime_error("String " + s + " could not be converted to Unicode");
27
+ }
26
28
  return wstring(&buffer[0], &buffer[0] + usedBufferCount / sizeof(wchar_t));
27
29
  }
30
+
28
31
  string Gosu::wstringToUTF8(const std::wstring& ws)
29
32
  {
30
- if (ws.empty())
33
+ if (ws.empty()) {
31
34
  return string();
35
+ }
32
36
 
33
- ObjCRef<NSString> str([[NSString alloc] initWithBytes: ws.data()
34
- length: ws.size() * sizeof(wchar_t)
35
- encoding:NSUTF32LittleEndianStringEncoding]);
36
- ObjCRef<NSAutoreleasePool> pool([[NSAutoreleasePool alloc] init]);
37
- const char* utf8 = [str.obj() UTF8String];
38
- return utf8 ? utf8 : string();
37
+ @autoreleasepool {
38
+ NSString *str = [[NSString alloc] initWithBytes:ws.data()
39
+ length:ws.size() * sizeof(wchar_t)
40
+ encoding:NSUTF32LittleEndianStringEncoding];
41
+ return str.UTF8String ?: string();
42
+ }
39
43
  }
44
+
40
45
  wstring Gosu::widen(const string& s)
41
46
  {
42
47
  return utf8ToWstring(s);
43
48
  }
49
+
44
50
  string Gosu::narrow(const std::wstring& ws)
45
51
  {
46
52
  return wstringToUTF8(ws);
@@ -49,7 +55,8 @@ string Gosu::narrow(const std::wstring& ws)
49
55
 
50
56
  string Gosu::language()
51
57
  {
52
- ObjCRef<NSAutoreleasePool> pool([NSAutoreleasePool new]);
53
- NSString* language = [[NSLocale preferredLanguages] objectAtIndex:0];
54
- return [language UTF8String];
58
+ @autoreleasepool {
59
+ NSString *language = [[NSLocale preferredLanguages] firstObject];
60
+ return [language UTF8String] ?: "en";
61
+ }
55
62
  }
@@ -17,16 +17,26 @@ namespace Gosu
17
17
  static CGFloat width = MAX(screenSize.width, screenSize.height);
18
18
  return width;
19
19
  }
20
+
21
+ unsigned availableWidth()
22
+ {
23
+ return screenWidth();
24
+ }
25
+
26
+ unsigned availableHeight()
27
+ {
28
+ return screenHeight();
29
+ }
20
30
  }
21
31
 
22
32
  class Gosu::Audio {};
23
33
 
24
34
  struct Gosu::Window::Impl
25
35
  {
26
- ObjCRef<::UIWindow> window;
27
- ObjCRef<GosuViewController> controller;
28
- std::auto_ptr<Graphics> graphics;
29
- std::auto_ptr<Input> input;
36
+ ::UIWindow *window;
37
+ GosuViewController *controller;
38
+ std::unique_ptr<Graphics> graphics;
39
+ std::unique_ptr<Input> input;
30
40
  double interval;
31
41
  std::wstring caption;
32
42
  };
@@ -35,18 +45,18 @@ Gosu::Window::Window(unsigned width, unsigned height,
35
45
  bool fullscreen, double updateInterval)
36
46
  : pimpl(new Impl)
37
47
  {
38
- pimpl->window.reset([[::UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]);
39
- pimpl->controller.reset([[GosuViewController alloc] init]);
40
- pimpl->controller.obj().gosuWindow = this;
41
- pimpl->window.obj().rootViewController = pimpl->controller.obj();
48
+ pimpl->window = [[::UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
49
+ pimpl->controller = [GosuViewController new];
50
+ pimpl->controller.gosuWindow = this;
51
+ pimpl->window.rootViewController = pimpl->controller;
42
52
 
43
53
  // It is important to load the view before creating the Graphics instance.
44
- [pimpl->controller.obj() loadView];
54
+ [pimpl->controller loadView];
45
55
 
46
56
  pimpl->graphics.reset(new Graphics(screenHeight(), screenWidth(), false));
47
57
  pimpl->graphics->setResolution(width, height);
48
58
 
49
- pimpl->input.reset(new Input(pimpl->controller.obj().view, updateInterval));
59
+ pimpl->input.reset(new Input((__bridge void *)pimpl->controller.view, updateInterval));
50
60
  pimpl->input->setMouseFactors(1.0 * width / screenHeight(), 1.0 * height / screenWidth());
51
61
 
52
62
  using namespace std::tr1::placeholders;
@@ -123,7 +133,7 @@ void Gosu::Window::close()
123
133
  throw std::logic_error("Cannot close windows manually on iOS");
124
134
  }
125
135
 
126
- void* Gosu::Window::UIWindow() const
136
+ void *Gosu::Window::UIWindow() const
127
137
  {
128
- return pimpl->window.get();
138
+ return (__bridge void *)pimpl->window;
129
139
  }
@@ -1,4 +1,4 @@
1
- /* stb_image - v2.08 - public domain image loader - http://nothings.org/stb_image.h
1
+ /* stb_image - v2.12 - public domain image loader - http://nothings.org/stb_image.h
2
2
  no warranty implied; use at your own risk
3
3
 
4
4
  Do this:
@@ -146,6 +146,13 @@
146
146
 
147
147
 
148
148
  Latest revision history:
149
+ 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
150
+ 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
151
+ RGB-format JPEG; remove white matting in PSD;
152
+ allocate large structures on the stack;
153
+ correct channel count for PNG & BMP
154
+ 2.10 (2016-01-22) avoid warning introduced in 2.09
155
+ 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
149
156
  2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
150
157
  2.07 (2015-09-13) partial animated GIF support
151
158
  limited 16-bit PSD support
@@ -165,60 +172,47 @@
165
172
  STBI_MALLOC,STBI_REALLOC,STBI_FREE
166
173
  STBI_NO_*, STBI_ONLY_*
167
174
  GIF bugfix
168
- 1.48 (2014-12-14) fix incorrectly-named assert()
169
- 1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted)
170
- optimize PNG
171
- fix bug in interlaced PNG with user-specified channel count
172
175
 
173
176
  See end of file for full revision history.
174
177
 
175
178
 
176
179
  ============================ Contributors =========================
177
180
 
178
- Image formats Bug fixes & warning fixes
179
- Sean Barrett (jpeg, png, bmp) Marc LeBlanc
180
- Nicolas Schulz (hdr, psd) Christpher Lloyd
181
- Jonathan Dummer (tga) Dave Moore
182
- Jean-Marc Lienher (gif) Won Chun
183
- Tom Seddon (pic) the Horde3D community
184
- Thatcher Ulrich (psd) Janez Zemva
185
- Ken Miller (pgm, ppm) Jonathan Blow
186
- urraka@github (animated gif) Laurent Gomila
187
- Aruelien Pocheville
188
- Ryamond Barbiero
189
- David Woo
190
- Extensions, features Martin Golini
191
- Jetro Lauha (stbi_info) Roy Eltham
192
- Martin "SpartanJ" Golini (stbi_info) Luke Graham
193
- James "moose2000" Brown (iPhone PNG) Thomas Ruf
194
- Ben "Disch" Wenger (io callbacks) John Bartholomew
195
- Omar Cornut (1/2/4-bit PNG) Ken Hamada
196
- Nicolas Guillemot (vertical flip) Cort Stratton
197
- Richard Mitton (16-bit PSD) Blazej Dariusz Roszkowski
198
- Thibault Reuille
199
- Paul Du Bois
200
- Guillaume George
201
- Jerry Jansson
202
- Hayaki Saito
203
- Johan Duparc
204
- Ronny Chevalier
205
- Optimizations & bugfixes Michal Cichon
206
- Fabian "ryg" Giesen Tero Hanninen
207
- Arseny Kapoulkine Sergio Gonzalez
208
- Cass Everitt
209
- Engin Manap
210
- If your name should be here but Martins Mozeiko
211
- isn't, let Sean know. Joseph Thomson
212
- Phil Jordan
213
- Nathan Reed
214
- Michaelangel007@github
215
- Nick Verigakis
181
+ Image formats Extensions, features
182
+ Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info)
183
+ Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info)
184
+ Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG)
185
+ Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks)
186
+ Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG)
187
+ Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip)
188
+ Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
189
+ urraka@github (animated gif) Junggon Kim (PNM comments)
190
+ Daniel Gibson (16-bit TGA)
191
+
192
+ Optimizations & bugfixes
193
+ Fabian "ryg" Giesen
194
+ Arseny Kapoulkine
195
+
196
+ Bug & warning fixes
197
+ Marc LeBlanc David Woo Guillaume George Martins Mozeiko
198
+ Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson
199
+ Dave Moore Roy Eltham Hayaki Saito Phil Jordan
200
+ Won Chun Luke Graham Johan Duparc Nathan Reed
201
+ the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis
202
+ Janez Zemva John Bartholomew Michal Cichon svdijk@github
203
+ Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson
204
+ Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github
205
+ Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan
206
+ Ryamond Barbiero Paul Du Bois Engin Manap snagar@github
207
+ Michaelangel007@github Oriol Ferrer Mesia socks-the-fox
208
+ Blazej Dariusz Roszkowski
209
+
216
210
 
217
211
  LICENSE
218
212
 
219
- This software is in the public domain. Where that dedication is not
220
- recognized, you are granted a perpetual, irrevocable license to copy,
221
- distribute, and modify this file as you see fit.
213
+ This software is dual-licensed to the public domain and under the following
214
+ license: you are granted a perpetual, irrevocable license to copy, modify,
215
+ publish, and distribute this file as you see fit.
222
216
 
223
217
  */
224
218
 
@@ -461,12 +455,12 @@ STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y,
461
455
  #ifndef STBI_NO_HDR
462
456
  STBIDEF void stbi_hdr_to_ldr_gamma(float gamma);
463
457
  STBIDEF void stbi_hdr_to_ldr_scale(float scale);
464
- #endif
458
+ #endif // STBI_NO_HDR
465
459
 
466
460
  #ifndef STBI_NO_LINEAR
467
461
  STBIDEF void stbi_ldr_to_hdr_gamma(float gamma);
468
462
  STBIDEF void stbi_ldr_to_hdr_scale(float scale);
469
- #endif // STBI_NO_HDR
463
+ #endif // STBI_NO_LINEAR
470
464
 
471
465
  // stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
472
466
  STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
@@ -630,18 +624,22 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
630
624
  #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
631
625
  #endif
632
626
 
633
- #if defined(STBI_MALLOC) && defined(STBI_FREE) && defined(STBI_REALLOC)
627
+ #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
634
628
  // ok
635
- #elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC)
629
+ #elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED)
636
630
  // ok
637
631
  #else
638
- #error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC."
632
+ #error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)."
639
633
  #endif
640
634
 
641
635
  #ifndef STBI_MALLOC
642
- #define STBI_MALLOC(sz) malloc(sz)
643
- #define STBI_REALLOC(p,sz) realloc(p,sz)
644
- #define STBI_FREE(p) free(p)
636
+ #define STBI_MALLOC(sz) malloc(sz)
637
+ #define STBI_REALLOC(p,newsz) realloc(p,newsz)
638
+ #define STBI_FREE(p) free(p)
639
+ #endif
640
+
641
+ #ifndef STBI_REALLOC_SIZED
642
+ #define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
645
643
  #endif
646
644
 
647
645
  // x86/x64 detection
@@ -675,7 +673,7 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
675
673
  #define STBI_NO_SIMD
676
674
  #endif
677
675
 
678
- #if !defined(STBI_NO_SIMD) && defined(STBI__X86_TARGET)
676
+ #if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET))
679
677
  #define STBI_SSE2
680
678
  #include <emmintrin.h>
681
679
 
@@ -1186,14 +1184,15 @@ STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void
1186
1184
  #endif
1187
1185
  }
1188
1186
 
1189
- static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
1187
+ #ifndef STBI_NO_LINEAR
1190
1188
  static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f;
1191
1189
 
1192
- #ifndef STBI_NO_LINEAR
1193
1190
  STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; }
1194
1191
  STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
1195
1192
  #endif
1196
1193
 
1194
+ static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
1195
+
1197
1196
  STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; }
1198
1197
  STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; }
1199
1198
 
@@ -1508,6 +1507,7 @@ typedef struct
1508
1507
  int succ_high;
1509
1508
  int succ_low;
1510
1509
  int eob_run;
1510
+ int rgb;
1511
1511
 
1512
1512
  int scan_n, order[4];
1513
1513
  int restart_interval, todo;
@@ -2719,11 +2719,17 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
2719
2719
 
2720
2720
  if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG");
2721
2721
 
2722
+ z->rgb = 0;
2722
2723
  for (i=0; i < s->img_n; ++i) {
2724
+ static unsigned char rgb[3] = { 'R', 'G', 'B' };
2723
2725
  z->img_comp[i].id = stbi__get8(s);
2724
2726
  if (z->img_comp[i].id != i+1) // JFIF requires
2725
- if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files!
2726
- return stbi__err("bad component ID","Corrupt JPEG");
2727
+ if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files!
2728
+ // somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format)
2729
+ if (z->img_comp[i].id != rgb[i])
2730
+ return stbi__err("bad component ID","Corrupt JPEG");
2731
+ ++z->rgb;
2732
+ }
2727
2733
  q = stbi__get8(s);
2728
2734
  z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
2729
2735
  z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
@@ -3385,7 +3391,17 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
3385
3391
  if (n >= 3) {
3386
3392
  stbi_uc *y = coutput[0];
3387
3393
  if (z->s->img_n == 3) {
3388
- z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
3394
+ if (z->rgb == 3) {
3395
+ for (i=0; i < z->s->img_x; ++i) {
3396
+ out[0] = y[i];
3397
+ out[1] = coutput[1][i];
3398
+ out[2] = coutput[2][i];
3399
+ out[3] = 255;
3400
+ out += n;
3401
+ }
3402
+ } else {
3403
+ z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
3404
+ }
3389
3405
  } else
3390
3406
  for (i=0; i < z->s->img_x; ++i) {
3391
3407
  out[0] = out[1] = out[2] = y[i];
@@ -3410,10 +3426,13 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
3410
3426
 
3411
3427
  static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
3412
3428
  {
3413
- stbi__jpeg j;
3414
- j.s = s;
3415
- stbi__setup_jpeg(&j);
3416
- return load_jpeg_image(&j, x,y,comp,req_comp);
3429
+ unsigned char* result;
3430
+ stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
3431
+ j->s = s;
3432
+ stbi__setup_jpeg(j);
3433
+ result = load_jpeg_image(j, x,y,comp,req_comp);
3434
+ STBI_FREE(j);
3435
+ return result;
3417
3436
  }
3418
3437
 
3419
3438
  static int stbi__jpeg_test(stbi__context *s)
@@ -3441,9 +3460,12 @@ static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
3441
3460
 
3442
3461
  static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
3443
3462
  {
3444
- stbi__jpeg j;
3445
- j.s = s;
3446
- return stbi__jpeg_info_raw(&j, x, y, comp);
3463
+ int result;
3464
+ stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
3465
+ j->s = s;
3466
+ result = stbi__jpeg_info_raw(j, x, y, comp);
3467
+ STBI_FREE(j);
3468
+ return result;
3447
3469
  }
3448
3470
  #endif
3449
3471
 
@@ -3616,14 +3638,15 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
3616
3638
  static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
3617
3639
  {
3618
3640
  char *q;
3619
- int cur, limit;
3641
+ int cur, limit, old_limit;
3620
3642
  z->zout = zout;
3621
3643
  if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
3622
3644
  cur = (int) (z->zout - z->zout_start);
3623
- limit = (int) (z->zout_end - z->zout_start);
3645
+ limit = old_limit = (int) (z->zout_end - z->zout_start);
3624
3646
  while (cur + n > limit)
3625
3647
  limit *= 2;
3626
- q = (char *) STBI_REALLOC(z->zout_start, limit);
3648
+ q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
3649
+ STBI_NOTUSED(old_limit);
3627
3650
  if (q == NULL) return stbi__err("outofmem", "Out of memory");
3628
3651
  z->zout_start = q;
3629
3652
  z->zout = q + cur;
@@ -3733,7 +3756,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
3733
3756
  return 1;
3734
3757
  }
3735
3758
 
3736
- static int stbi__parse_uncomperssed_block(stbi__zbuf *a)
3759
+ static int stbi__parse_uncompressed_block(stbi__zbuf *a)
3737
3760
  {
3738
3761
  stbi_uc header[4];
3739
3762
  int len,nlen,k;
@@ -3799,7 +3822,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
3799
3822
  final = stbi__zreceive(a,1);
3800
3823
  type = stbi__zreceive(a,2);
3801
3824
  if (type == 0) {
3802
- if (!stbi__parse_uncomperssed_block(a)) return 0;
3825
+ if (!stbi__parse_uncompressed_block(a)) return 0;
3803
3826
  } else if (type == 3) {
3804
3827
  return 0;
3805
3828
  } else {
@@ -3941,6 +3964,7 @@ typedef struct
3941
3964
  {
3942
3965
  stbi__context *s;
3943
3966
  stbi_uc *idata, *expanded, *out;
3967
+ int depth;
3944
3968
  } stbi__png;
3945
3969
 
3946
3970
 
@@ -3980,14 +4004,19 @@ static stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x0
3980
4004
  // create the png data from post-deflated data
3981
4005
  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)
3982
4006
  {
4007
+ int bytes = (depth == 16? 2 : 1);
3983
4008
  stbi__context *s = a->s;
3984
- stbi__uint32 i,j,stride = x*out_n;
4009
+ stbi__uint32 i,j,stride = x*out_n*bytes;
3985
4010
  stbi__uint32 img_len, img_width_bytes;
3986
4011
  int k;
3987
4012
  int img_n = s->img_n; // copy it into a local for later
3988
4013
 
4014
+ int output_bytes = out_n*bytes;
4015
+ int filter_bytes = img_n*bytes;
4016
+ int width = x;
4017
+
3989
4018
  STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
3990
- a->out = (stbi_uc *) stbi__malloc(x * y * out_n); // extra bytes to write off the end into
4019
+ a->out = (stbi_uc *) stbi__malloc(x * y * output_bytes); // extra bytes to write off the end into
3991
4020
  if (!a->out) return stbi__err("outofmem", "Out of memory");
3992
4021
 
3993
4022
  img_width_bytes = (((img_n * x * depth) + 7) >> 3);
@@ -4002,8 +4031,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
4002
4031
  stbi_uc *cur = a->out + stride*j;
4003
4032
  stbi_uc *prior = cur - stride;
4004
4033
  int filter = *raw++;
4005
- int filter_bytes = img_n;
4006
- int width = x;
4034
+
4007
4035
  if (filter > 4)
4008
4036
  return stbi__err("invalid filter","Corrupt PNG");
4009
4037
 
@@ -4036,6 +4064,14 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
4036
4064
  raw += img_n;
4037
4065
  cur += out_n;
4038
4066
  prior += out_n;
4067
+ } else if (depth == 16) {
4068
+ if (img_n != out_n) {
4069
+ cur[filter_bytes] = 255; // first pixel top byte
4070
+ cur[filter_bytes+1] = 255; // first pixel bottom byte
4071
+ }
4072
+ raw += filter_bytes;
4073
+ cur += output_bytes;
4074
+ prior += output_bytes;
4039
4075
  } else {
4040
4076
  raw += 1;
4041
4077
  cur += 1;
@@ -4044,7 +4080,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
4044
4080
 
4045
4081
  // this is a little gross, so that we don't switch per-pixel or per-component
4046
4082
  if (depth < 8 || img_n == out_n) {
4047
- int nk = (width - 1)*img_n;
4083
+ int nk = (width - 1)*filter_bytes;
4048
4084
  #define CASE(f) \
4049
4085
  case f: \
4050
4086
  for (k=0; k < nk; ++k)
@@ -4064,18 +4100,27 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
4064
4100
  STBI_ASSERT(img_n+1 == out_n);
4065
4101
  #define CASE(f) \
4066
4102
  case f: \
4067
- for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \
4068
- for (k=0; k < img_n; ++k)
4103
+ for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
4104
+ for (k=0; k < filter_bytes; ++k)
4069
4105
  switch (filter) {
4070
4106
  CASE(STBI__F_none) cur[k] = raw[k]; break;
4071
- CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-out_n]); break;
4107
+ CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); break;
4072
4108
  CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
4073
- CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-out_n])>>1)); break;
4074
- CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],prior[k],prior[k-out_n])); break;
4075
- CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-out_n] >> 1)); break;
4076
- CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],0,0)); break;
4109
+ CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); break;
4110
+ CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); break;
4111
+ CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); break;
4112
+ CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break;
4077
4113
  }
4078
4114
  #undef CASE
4115
+
4116
+ // the loop above sets the high byte of the pixels' alpha, but for
4117
+ // 16 bit png files we also need the low byte set. we'll do that here.
4118
+ if (depth == 16) {
4119
+ cur = a->out + stride*j; // start at the beginning of the row again
4120
+ for (i=0; i < x; ++i,cur+=output_bytes) {
4121
+ cur[filter_bytes+1] = 255;
4122
+ }
4123
+ }
4079
4124
  }
4080
4125
  }
4081
4126
 
@@ -4151,6 +4196,17 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
4151
4196
  }
4152
4197
  }
4153
4198
  }
4199
+ } else if (depth == 16) {
4200
+ // force the image data from big-endian to platform-native.
4201
+ // this is done in a separate pass due to the decoding relying
4202
+ // on the data being untouched, but could probably be done
4203
+ // per-line during decode if care is taken.
4204
+ stbi_uc *cur = a->out;
4205
+ stbi__uint16 *cur16 = (stbi__uint16*)cur;
4206
+
4207
+ for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
4208
+ *cur16 = (cur[0] << 8) | cur[1];
4209
+ }
4154
4210
  }
4155
4211
 
4156
4212
  return 1;
@@ -4223,6 +4279,31 @@ static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
4223
4279
  return 1;
4224
4280
  }
4225
4281
 
4282
+ static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n)
4283
+ {
4284
+ stbi__context *s = z->s;
4285
+ stbi__uint32 i, pixel_count = s->img_x * s->img_y;
4286
+ stbi__uint16 *p = (stbi__uint16*) z->out;
4287
+
4288
+ // compute color-based transparency, assuming we've
4289
+ // already got 65535 as the alpha value in the output
4290
+ STBI_ASSERT(out_n == 2 || out_n == 4);
4291
+
4292
+ if (out_n == 2) {
4293
+ for (i = 0; i < pixel_count; ++i) {
4294
+ p[1] = (p[0] == tc[0] ? 0 : 65535);
4295
+ p += 2;
4296
+ }
4297
+ } else {
4298
+ for (i = 0; i < pixel_count; ++i) {
4299
+ if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
4300
+ p[3] = 0;
4301
+ p += 4;
4302
+ }
4303
+ }
4304
+ return 1;
4305
+ }
4306
+
4226
4307
  static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n)
4227
4308
  {
4228
4309
  stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
@@ -4260,6 +4341,26 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
4260
4341
  return 1;
4261
4342
  }
4262
4343
 
4344
+ static int stbi__reduce_png(stbi__png *p)
4345
+ {
4346
+ int i;
4347
+ int img_len = p->s->img_x * p->s->img_y * p->s->img_out_n;
4348
+ stbi_uc *reduced;
4349
+ stbi__uint16 *orig = (stbi__uint16*)p->out;
4350
+
4351
+ if (p->depth != 16) return 1; // don't need to do anything if not 16-bit data
4352
+
4353
+ reduced = (stbi_uc *)stbi__malloc(img_len);
4354
+ if (p == NULL) return stbi__err("outofmem", "Out of memory");
4355
+
4356
+ for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is a decent approx of 16->8 bit scaling
4357
+
4358
+ p->out = reduced;
4359
+ STBI_FREE(orig);
4360
+
4361
+ return 1;
4362
+ }
4363
+
4263
4364
  static int stbi__unpremultiply_on_load = 0;
4264
4365
  static int stbi__de_iphone_flag = 0;
4265
4366
 
@@ -4321,8 +4422,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
4321
4422
  {
4322
4423
  stbi_uc palette[1024], pal_img_n=0;
4323
4424
  stbi_uc has_trans=0, tc[3];
4425
+ stbi__uint16 tc16[3];
4324
4426
  stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
4325
- int first=1,k,interlace=0, color=0, depth=0, is_iphone=0;
4427
+ int first=1,k,interlace=0, color=0, is_iphone=0;
4326
4428
  stbi__context *s = z->s;
4327
4429
 
4328
4430
  z->expanded = NULL;
@@ -4347,8 +4449,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
4347
4449
  if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
4348
4450
  s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
4349
4451
  s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
4350
- depth = stbi__get8(s); if (depth != 1 && depth != 2 && depth != 4 && depth != 8) return stbi__err("1/2/4/8-bit only","PNG not supported: 1/2/4/8-bit only");
4452
+ z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
4351
4453
  color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
4454
+ if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
4352
4455
  if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
4353
4456
  comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
4354
4457
  filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG");
@@ -4396,8 +4499,11 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
4396
4499
  if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
4397
4500
  if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
4398
4501
  has_trans = 1;
4399
- for (k=0; k < s->img_n; ++k)
4400
- tc[k] = (stbi_uc) (stbi__get16be(s) & 255) * stbi__depth_scale_table[depth]; // non 8-bit images will be larger
4502
+ if (z->depth == 16) {
4503
+ for (k = 0; k < s->img_n; ++k) tc16[k] = stbi__get16be(s); // copy the values as-is
4504
+ } else {
4505
+ for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
4506
+ }
4401
4507
  }
4402
4508
  break;
4403
4509
  }
@@ -4408,11 +4514,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
4408
4514
  if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
4409
4515
  if ((int)(ioff + c.length) < (int)ioff) return 0;
4410
4516
  if (ioff + c.length > idata_limit) {
4517
+ stbi__uint32 idata_limit_old = idata_limit;
4411
4518
  stbi_uc *p;
4412
4519
  if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
4413
4520
  while (ioff + c.length > idata_limit)
4414
4521
  idata_limit *= 2;
4415
- p = (stbi_uc *) STBI_REALLOC(z->idata, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
4522
+ STBI_NOTUSED(idata_limit_old);
4523
+ p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
4416
4524
  z->idata = p;
4417
4525
  }
4418
4526
  if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG");
@@ -4426,7 +4534,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
4426
4534
  if (scan != STBI__SCAN_load) return 1;
4427
4535
  if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
4428
4536
  // initial guess for decoded data size to avoid unnecessary reallocs
4429
- bpl = (s->img_x * depth + 7) / 8; // bytes per line, per component
4537
+ bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component
4430
4538
  raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */;
4431
4539
  z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone);
4432
4540
  if (z->expanded == NULL) return 0; // zlib should set error
@@ -4435,9 +4543,14 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
4435
4543
  s->img_out_n = s->img_n+1;
4436
4544
  else
4437
4545
  s->img_out_n = s->img_n;
4438
- if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, depth, color, interlace)) return 0;
4439
- if (has_trans)
4440
- if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
4546
+ if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0;
4547
+ if (has_trans) {
4548
+ if (z->depth == 16) {
4549
+ if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0;
4550
+ } else {
4551
+ if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
4552
+ }
4553
+ }
4441
4554
  if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
4442
4555
  stbi__de_iphone(z);
4443
4556
  if (pal_img_n) {
@@ -4479,6 +4592,11 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
4479
4592
  unsigned char *result=NULL;
4480
4593
  if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
4481
4594
  if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
4595
+ if (p->depth == 16) {
4596
+ if (!stbi__reduce_png(p)) {
4597
+ return result;
4598
+ }
4599
+ }
4482
4600
  result = p->out;
4483
4601
  p->out = NULL;
4484
4602
  if (req_comp && req_comp != p->s->img_out_n) {
@@ -4488,7 +4606,7 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
4488
4606
  }
4489
4607
  *x = p->s->img_x;
4490
4608
  *y = p->s->img_y;
4491
- if (n) *n = p->s->img_out_n;
4609
+ if (n) *n = p->s->img_n;
4492
4610
  }
4493
4611
  STBI_FREE(p->out); p->out = NULL;
4494
4612
  STBI_FREE(p->expanded); p->expanded = NULL;
@@ -4598,19 +4716,23 @@ static int stbi__shiftsigned(int v, int shift, int bits)
4598
4716
  return result;
4599
4717
  }
4600
4718
 
4601
- static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
4719
+ typedef struct
4602
4720
  {
4603
- stbi_uc *out;
4604
- unsigned int mr=0,mg=0,mb=0,ma=0, all_a=255;
4605
- stbi_uc pal[256][4];
4606
- int psize=0,i,j,compress=0,width;
4607
- int bpp, flip_vertically, pad, target, offset, hsz;
4721
+ int bpp, offset, hsz;
4722
+ unsigned int mr,mg,mb,ma, all_a;
4723
+ } stbi__bmp_data;
4724
+
4725
+ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
4726
+ {
4727
+ int hsz;
4608
4728
  if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP");
4609
4729
  stbi__get32le(s); // discard filesize
4610
4730
  stbi__get16le(s); // discard reserved
4611
4731
  stbi__get16le(s); // discard reserved
4612
- offset = stbi__get32le(s);
4613
- hsz = stbi__get32le(s);
4732
+ info->offset = stbi__get32le(s);
4733
+ info->hsz = hsz = stbi__get32le(s);
4734
+ info->mr = info->mg = info->mb = info->ma = 0;
4735
+
4614
4736
  if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
4615
4737
  if (hsz == 12) {
4616
4738
  s->img_x = stbi__get16le(s);
@@ -4620,15 +4742,10 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
4620
4742
  s->img_y = stbi__get32le(s);
4621
4743
  }
4622
4744
  if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP");
4623
- bpp = stbi__get16le(s);
4624
- if (bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit");
4625
- flip_vertically = ((int) s->img_y) > 0;
4626
- s->img_y = abs((int) s->img_y);
4627
- if (hsz == 12) {
4628
- if (bpp < 24)
4629
- psize = (offset - 14 - 24) / 3;
4630
- } else {
4631
- compress = stbi__get32le(s);
4745
+ info->bpp = stbi__get16le(s);
4746
+ if (info->bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit");
4747
+ if (hsz != 12) {
4748
+ int compress = stbi__get32le(s);
4632
4749
  if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
4633
4750
  stbi__get32le(s); // discard sizeof
4634
4751
  stbi__get32le(s); // discard hres
@@ -4642,26 +4759,25 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
4642
4759
  stbi__get32le(s);
4643
4760
  stbi__get32le(s);
4644
4761
  }
4645
- if (bpp == 16 || bpp == 32) {
4646
- mr = mg = mb = 0;
4762
+ if (info->bpp == 16 || info->bpp == 32) {
4647
4763
  if (compress == 0) {
4648
- if (bpp == 32) {
4649
- mr = 0xffu << 16;
4650
- mg = 0xffu << 8;
4651
- mb = 0xffu << 0;
4652
- ma = 0xffu << 24;
4653
- all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
4764
+ if (info->bpp == 32) {
4765
+ info->mr = 0xffu << 16;
4766
+ info->mg = 0xffu << 8;
4767
+ info->mb = 0xffu << 0;
4768
+ info->ma = 0xffu << 24;
4769
+ info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
4654
4770
  } else {
4655
- mr = 31u << 10;
4656
- mg = 31u << 5;
4657
- mb = 31u << 0;
4771
+ info->mr = 31u << 10;
4772
+ info->mg = 31u << 5;
4773
+ info->mb = 31u << 0;
4658
4774
  }
4659
4775
  } else if (compress == 3) {
4660
- mr = stbi__get32le(s);
4661
- mg = stbi__get32le(s);
4662
- mb = stbi__get32le(s);
4776
+ info->mr = stbi__get32le(s);
4777
+ info->mg = stbi__get32le(s);
4778
+ info->mb = stbi__get32le(s);
4663
4779
  // not documented, but generated by photoshop and handled by mspaint
4664
- if (mr == mg && mg == mb) {
4780
+ if (info->mr == info->mg && info->mg == info->mb) {
4665
4781
  // ?!?!?
4666
4782
  return stbi__errpuc("bad BMP", "bad BMP");
4667
4783
  }
@@ -4669,11 +4785,13 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
4669
4785
  return stbi__errpuc("bad BMP", "bad BMP");
4670
4786
  }
4671
4787
  } else {
4672
- STBI_ASSERT(hsz == 108 || hsz == 124);
4673
- mr = stbi__get32le(s);
4674
- mg = stbi__get32le(s);
4675
- mb = stbi__get32le(s);
4676
- ma = stbi__get32le(s);
4788
+ int i;
4789
+ if (hsz != 108 && hsz != 124)
4790
+ return stbi__errpuc("bad BMP", "bad BMP");
4791
+ info->mr = stbi__get32le(s);
4792
+ info->mg = stbi__get32le(s);
4793
+ info->mb = stbi__get32le(s);
4794
+ info->ma = stbi__get32le(s);
4677
4795
  stbi__get32le(s); // discard color space
4678
4796
  for (i=0; i < 12; ++i)
4679
4797
  stbi__get32le(s); // discard color space parameters
@@ -4684,35 +4802,68 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
4684
4802
  stbi__get32le(s); // discard reserved
4685
4803
  }
4686
4804
  }
4687
- if (bpp < 16)
4688
- psize = (offset - 14 - hsz) >> 2;
4689
4805
  }
4806
+ return (void *) 1;
4807
+ }
4808
+
4809
+
4810
+ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
4811
+ {
4812
+ stbi_uc *out;
4813
+ unsigned int mr=0,mg=0,mb=0,ma=0, all_a;
4814
+ stbi_uc pal[256][4];
4815
+ int psize=0,i,j,width;
4816
+ int flip_vertically, pad, target;
4817
+ stbi__bmp_data info;
4818
+
4819
+ info.all_a = 255;
4820
+ if (stbi__bmp_parse_header(s, &info) == NULL)
4821
+ return NULL; // error code already set
4822
+
4823
+ flip_vertically = ((int) s->img_y) > 0;
4824
+ s->img_y = abs((int) s->img_y);
4825
+
4826
+ mr = info.mr;
4827
+ mg = info.mg;
4828
+ mb = info.mb;
4829
+ ma = info.ma;
4830
+ all_a = info.all_a;
4831
+
4832
+ if (info.hsz == 12) {
4833
+ if (info.bpp < 24)
4834
+ psize = (info.offset - 14 - 24) / 3;
4835
+ } else {
4836
+ if (info.bpp < 16)
4837
+ psize = (info.offset - 14 - info.hsz) >> 2;
4838
+ }
4839
+
4690
4840
  s->img_n = ma ? 4 : 3;
4691
4841
  if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
4692
4842
  target = req_comp;
4693
4843
  else
4694
4844
  target = s->img_n; // if they want monochrome, we'll post-convert
4845
+
4695
4846
  out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y);
4696
4847
  if (!out) return stbi__errpuc("outofmem", "Out of memory");
4697
- if (bpp < 16) {
4848
+ if (info.bpp < 16) {
4698
4849
  int z=0;
4699
4850
  if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); }
4700
4851
  for (i=0; i < psize; ++i) {
4701
4852
  pal[i][2] = stbi__get8(s);
4702
4853
  pal[i][1] = stbi__get8(s);
4703
4854
  pal[i][0] = stbi__get8(s);
4704
- if (hsz != 12) stbi__get8(s);
4855
+ if (info.hsz != 12) stbi__get8(s);
4705
4856
  pal[i][3] = 255;
4706
4857
  }
4707
- stbi__skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4));
4708
- if (bpp == 4) width = (s->img_x + 1) >> 1;
4709
- else if (bpp == 8) width = s->img_x;
4858
+ stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
4859
+ if (info.bpp == 4) width = (s->img_x + 1) >> 1;
4860
+ else if (info.bpp == 8) width = s->img_x;
4710
4861
  else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); }
4711
4862
  pad = (-width)&3;
4712
4863
  for (j=0; j < (int) s->img_y; ++j) {
4713
4864
  for (i=0; i < (int) s->img_x; i += 2) {
4714
4865
  int v=stbi__get8(s),v2=0;
4715
- if (bpp == 4) {
4866
+ if (info.bpp == 4) {
4716
4867
  v2 = v & 15;
4717
4868
  v >>= 4;
4718
4869
  }
@@ -4721,7 +4872,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
4721
4872
  out[z++] = pal[v][2];
4722
4873
  if (target == 4) out[z++] = 255;
4723
4874
  if (i+1 == (int) s->img_x) break;
4724
- v = (bpp == 8) ? stbi__get8(s) : v2;
4875
+ v = (info.bpp == 8) ? stbi__get8(s) : v2;
4725
4876
  out[z++] = pal[v][0];
4726
4877
  out[z++] = pal[v][1];
4727
4878
  out[z++] = pal[v][2];
@@ -4733,14 +4884,14 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
4733
4884
  int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
4734
4885
  int z = 0;
4735
4886
  int easy=0;
4736
- stbi__skip(s, offset - 14 - hsz);
4737
- if (bpp == 24) width = 3 * s->img_x;
4738
- else if (bpp == 16) width = 2*s->img_x;
4887
+ stbi__skip(s, info.offset - 14 - info.hsz);
4888
+ if (info.bpp == 24) width = 3 * s->img_x;
4889
+ else if (info.bpp == 16) width = 2*s->img_x;
4739
4890
  else /* bpp = 32 and pad = 0 */ width=0;
4740
4891
  pad = (-width) & 3;
4741
- if (bpp == 24) {
4892
+ if (info.bpp == 24) {
4742
4893
  easy = 1;
4743
- } else if (bpp == 32) {
4894
+ } else if (info.bpp == 32) {
4744
4895
  if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
4745
4896
  easy = 2;
4746
4897
  }
@@ -4765,6 +4916,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
4765
4916
  if (target == 4) out[z++] = a;
4766
4917
  }
4767
4918
  } else {
4919
+ int bpp = info.bpp;
4768
4920
  for (i=0; i < (int) s->img_x; ++i) {
4769
4921
  stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
4770
4922
  int a;
@@ -4811,20 +4963,55 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
4811
4963
  // Targa Truevision - TGA
4812
4964
  // by Jonathan Dummer
4813
4965
  #ifndef STBI_NO_TGA
4966
+ // returns STBI_rgb or whatever, 0 on error
4967
+ static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
4968
+ {
4969
+ // only RGB or RGBA (incl. 16bit) or grey allowed
4970
+ if(is_rgb16) *is_rgb16 = 0;
4971
+ switch(bits_per_pixel) {
4972
+ case 8: return STBI_grey;
4973
+ case 16: if(is_grey) return STBI_grey_alpha;
4974
+ // else: fall-through
4975
+ case 15: if(is_rgb16) *is_rgb16 = 1;
4976
+ return STBI_rgb;
4977
+ case 24: // fall-through
4978
+ case 32: return bits_per_pixel/8;
4979
+ default: return 0;
4980
+ }
4981
+ }
4982
+
4814
4983
  static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
4815
4984
  {
4816
- int tga_w, tga_h, tga_comp;
4817
- int sz;
4985
+ int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
4986
+ int sz, tga_colormap_type;
4818
4987
  stbi__get8(s); // discard Offset
4819
- sz = stbi__get8(s); // color type
4820
- if( sz > 1 ) {
4988
+ tga_colormap_type = stbi__get8(s); // colormap type
4989
+ if( tga_colormap_type > 1 ) {
4821
4990
  stbi__rewind(s);
4822
4991
  return 0; // only RGB or indexed allowed
4823
4992
  }
4824
- sz = stbi__get8(s); // image type
4825
- // only RGB or grey allowed, +/- RLE
4826
- if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0;
4827
- stbi__skip(s,9);
4993
+ tga_image_type = stbi__get8(s); // image type
4994
+ if ( tga_colormap_type == 1 ) { // colormapped (paletted) image
4995
+ if (tga_image_type != 1 && tga_image_type != 9) {
4996
+ stbi__rewind(s);
4997
+ return 0;
4998
+ }
4999
+ stbi__skip(s,4); // skip index of first colormap entry and number of entries
5000
+ sz = stbi__get8(s); // check bits per palette color entry
5001
+ if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) {
5002
+ stbi__rewind(s);
5003
+ return 0;
5004
+ }
5005
+ stbi__skip(s,4); // skip image x and y origin
5006
+ tga_colormap_bpp = sz;
5007
+ } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE
5008
+ if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) {
5009
+ stbi__rewind(s);
5010
+ return 0; // only RGB or grey allowed, +/- RLE
5011
+ }
5012
+ stbi__skip(s,9); // skip colormap specification and image x/y origin
5013
+ tga_colormap_bpp = 0;
5014
+ }
4828
5015
  tga_w = stbi__get16le(s);
4829
5016
  if( tga_w < 1 ) {
4830
5017
  stbi__rewind(s);
@@ -4835,44 +5022,80 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
4835
5022
  stbi__rewind(s);
4836
5023
  return 0; // test height
4837
5024
  }
4838
- sz = stbi__get8(s); // bits per pixel
4839
- // only RGB or RGBA or grey allowed
4840
- if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) {
4841
- stbi__rewind(s);
4842
- return 0;
5025
+ tga_bits_per_pixel = stbi__get8(s); // bits per pixel
5026
+ stbi__get8(s); // ignore alpha bits
5027
+ if (tga_colormap_bpp != 0) {
5028
+ if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) {
5029
+ // when using a colormap, tga_bits_per_pixel is the size of the indexes
5030
+ // I don't think anything but 8 or 16bit indexes makes sense
5031
+ stbi__rewind(s);
5032
+ return 0;
5033
+ }
5034
+ tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL);
5035
+ } else {
5036
+ tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL);
5037
+ }
5038
+ if(!tga_comp) {
5039
+ stbi__rewind(s);
5040
+ return 0;
4843
5041
  }
4844
- tga_comp = sz;
4845
5042
  if (x) *x = tga_w;
4846
5043
  if (y) *y = tga_h;
4847
- if (comp) *comp = tga_comp / 8;
5044
+ if (comp) *comp = tga_comp;
4848
5045
  return 1; // seems to have passed everything
4849
5046
  }
4850
5047
 
4851
5048
  static int stbi__tga_test(stbi__context *s)
4852
5049
  {
4853
- int res;
4854
- int sz;
5050
+ int res = 0;
5051
+ int sz, tga_color_type;
4855
5052
  stbi__get8(s); // discard Offset
4856
- sz = stbi__get8(s); // color type
4857
- if ( sz > 1 ) return 0; // only RGB or indexed allowed
5053
+ tga_color_type = stbi__get8(s); // color type
5054
+ if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed
4858
5055
  sz = stbi__get8(s); // image type
4859
- if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE
4860
- stbi__get16be(s); // discard palette start
4861
- stbi__get16be(s); // discard palette length
4862
- stbi__get8(s); // discard bits per palette color entry
4863
- stbi__get16be(s); // discard x origin
4864
- stbi__get16be(s); // discard y origin
4865
- if ( stbi__get16be(s) < 1 ) return 0; // test width
4866
- if ( stbi__get16be(s) < 1 ) return 0; // test height
5056
+ if ( tga_color_type == 1 ) { // colormapped (paletted) image
5057
+ if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9
5058
+ stbi__skip(s,4); // skip index of first colormap entry and number of entries
5059
+ sz = stbi__get8(s); // check bits per palette color entry
5060
+ if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
5061
+ stbi__skip(s,4); // skip image x and y origin
5062
+ } else { // "normal" image w/o colormap
5063
+ if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE
5064
+ stbi__skip(s,9); // skip colormap specification and image x/y origin
5065
+ }
5066
+ if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width
5067
+ if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height
4867
5068
  sz = stbi__get8(s); // bits per pixel
4868
- if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) )
4869
- res = 0;
4870
- else
4871
- res = 1;
5069
+ if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index
5070
+ if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
5071
+
5072
+ res = 1; // if we got this far, everything's good and we can return 1 instead of 0
5073
+
5074
+ errorEnd:
4872
5075
  stbi__rewind(s);
4873
5076
  return res;
4874
5077
  }
4875
5078
 
5079
+ // read 16bit value and convert to 24bit RGB
5080
+ void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
5081
+ {
5082
+ stbi__uint16 px = stbi__get16le(s);
5083
+ stbi__uint16 fiveBitMask = 31;
5084
+ // we have 3 channels with 5bits each
5085
+ int r = (px >> 10) & fiveBitMask;
5086
+ int g = (px >> 5) & fiveBitMask;
5087
+ int b = px & fiveBitMask;
5088
+ // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
5089
+ out[0] = (r * 255)/31;
5090
+ out[1] = (g * 255)/31;
5091
+ out[2] = (b * 255)/31;
5092
+
5093
+ // some people claim that the most significant bit might be used for alpha
5094
+ // (possibly if an alpha-bit is set in the "image descriptor byte")
5095
+ // but that only made 16bit test images completely translucent..
5096
+ // so let's treat all 15 and 16bit TGAs as RGB with no alpha.
5097
+ }
5098
+
4876
5099
  static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
4877
5100
  {
4878
5101
  // read in the TGA header stuff
@@ -4888,8 +5111,9 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
4888
5111
  int tga_width = stbi__get16le(s);
4889
5112
  int tga_height = stbi__get16le(s);
4890
5113
  int tga_bits_per_pixel = stbi__get8(s);
4891
- int tga_comp = tga_bits_per_pixel / 8;
5114
+ int tga_comp, tga_rgb16=0;
4892
5115
  int tga_inverted = stbi__get8(s);
5116
+ // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?)
4893
5117
  // image data
4894
5118
  unsigned char *tga_data;
4895
5119
  unsigned char *tga_palette = NULL;
@@ -4905,25 +5129,14 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
4905
5129
  tga_image_type -= 8;
4906
5130
  tga_is_RLE = 1;
4907
5131
  }
4908
- /* int tga_alpha_bits = tga_inverted & 15; */
4909
5132
  tga_inverted = 1 - ((tga_inverted >> 5) & 1);
4910
5133
 
4911
- // error check
4912
- if ( //(tga_indexed) ||
4913
- (tga_width < 1) || (tga_height < 1) ||
4914
- (tga_image_type < 1) || (tga_image_type > 3) ||
4915
- ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) &&
4916
- (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32))
4917
- )
4918
- {
4919
- return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA
4920
- }
4921
-
4922
5134
  // If I'm paletted, then I'll use the number of bits from the palette
4923
- if ( tga_indexed )
4924
- {
4925
- tga_comp = tga_palette_bits / 8;
4926
- }
5135
+ if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
5136
+ else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16);
5137
+
5138
+ if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency
5139
+ return stbi__errpuc("bad format", "Can't find out TGA pixelformat");
4927
5140
 
4928
5141
  // tga info
4929
5142
  *x = tga_width;
@@ -4936,7 +5149,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
4936
5149
  // skip to the data's starting position (offset usually = 0)
4937
5150
  stbi__skip(s, tga_offset );
4938
5151
 
4939
- if ( !tga_indexed && !tga_is_RLE) {
5152
+ if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) {
4940
5153
  for (i=0; i < tga_height; ++i) {
4941
5154
  int row = tga_inverted ? tga_height -i - 1 : i;
4942
5155
  stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
@@ -4949,15 +5162,22 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
4949
5162
  // any data to skip? (offset usually = 0)
4950
5163
  stbi__skip(s, tga_palette_start );
4951
5164
  // load the palette
4952
- tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_palette_bits / 8 );
5165
+ tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp );
4953
5166
  if (!tga_palette) {
4954
5167
  STBI_FREE(tga_data);
4955
5168
  return stbi__errpuc("outofmem", "Out of memory");
4956
5169
  }
4957
- if (!stbi__getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) {
4958
- STBI_FREE(tga_data);
4959
- STBI_FREE(tga_palette);
4960
- return stbi__errpuc("bad palette", "Corrupt TGA");
5170
+ if (tga_rgb16) {
5171
+ stbi_uc *pal_entry = tga_palette;
5172
+ STBI_ASSERT(tga_comp == STBI_rgb);
5173
+ for (i=0; i < tga_palette_len; ++i) {
5174
+ stbi__tga_read_rgb16(s, pal_entry);
5175
+ pal_entry += tga_comp;
5176
+ }
5177
+ } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) {
5178
+ STBI_FREE(tga_data);
5179
+ STBI_FREE(tga_palette);
5180
+ return stbi__errpuc("bad palette", "Corrupt TGA");
4961
5181
  }
4962
5182
  }
4963
5183
  // load the data
@@ -4987,23 +5207,22 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
4987
5207
  // load however much data we did have
4988
5208
  if ( tga_indexed )
4989
5209
  {
4990
- // read in 1 byte, then perform the lookup
4991
- int pal_idx = stbi__get8(s);
4992
- if ( pal_idx >= tga_palette_len )
4993
- {
4994
- // invalid index
5210
+ // read in index, then perform the lookup
5211
+ int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
5212
+ if ( pal_idx >= tga_palette_len ) {
5213
+ // invalid index
4995
5214
  pal_idx = 0;
4996
5215
  }
4997
- pal_idx *= tga_bits_per_pixel / 8;
4998
- for (j = 0; j*8 < tga_bits_per_pixel; ++j)
4999
- {
5216
+ pal_idx *= tga_comp;
5217
+ for (j = 0; j < tga_comp; ++j) {
5000
5218
  raw_data[j] = tga_palette[pal_idx+j];
5001
5219
  }
5002
- } else
5003
- {
5220
+ } else if(tga_rgb16) {
5221
+ STBI_ASSERT(tga_comp == STBI_rgb);
5222
+ stbi__tga_read_rgb16(s, raw_data);
5223
+ } else {
5004
5224
  // read in the data raw
5005
- for (j = 0; j*8 < tga_bits_per_pixel; ++j)
5006
- {
5225
+ for (j = 0; j < tga_comp; ++j) {
5007
5226
  raw_data[j] = stbi__get8(s);
5008
5227
  }
5009
5228
  }
@@ -5042,8 +5261,8 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
5042
5261
  }
5043
5262
  }
5044
5263
 
5045
- // swap RGB
5046
- if (tga_comp >= 3)
5264
+ // swap RGB - if the source data was RGB16, it already is in the right order
5265
+ if (tga_comp >= 3 && !tga_rgb16)
5047
5266
  {
5048
5267
  unsigned char* tga_pixel = tga_data;
5049
5268
  for (i=0; i < tga_width * tga_height; ++i)
@@ -5235,6 +5454,21 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
5235
5454
  }
5236
5455
  }
5237
5456
 
5457
+ if (channelCount >= 4) {
5458
+ for (i=0; i < w*h; ++i) {
5459
+ unsigned char *pixel = out + 4*i;
5460
+ if (pixel[3] != 0 && pixel[3] != 255) {
5461
+ // remove weird white matte from PSD
5462
+ float a = pixel[3] / 255.0f;
5463
+ float ra = 1.0f / a;
5464
+ float inv_a = 255.0f * (1 - ra);
5465
+ pixel[0] = (unsigned char) (pixel[0]*ra + inv_a);
5466
+ pixel[1] = (unsigned char) (pixel[1]*ra + inv_a);
5467
+ pixel[2] = (unsigned char) (pixel[2]*ra + inv_a);
5468
+ }
5469
+ }
5470
+ }
5471
+
5238
5472
  if (req_comp && req_comp != 4) {
5239
5473
  out = stbi__convert_format(out, 4, req_comp, w, h);
5240
5474
  if (out == NULL) return out; // stbi__convert_format frees input on failure
@@ -5547,13 +5781,15 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
5547
5781
 
5548
5782
  static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
5549
5783
  {
5550
- stbi__gif g;
5551
- if (!stbi__gif_header(s, &g, comp, 1)) {
5784
+ stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
5785
+ if (!stbi__gif_header(s, g, comp, 1)) {
5786
+ STBI_FREE(g);
5552
5787
  stbi__rewind( s );
5553
5788
  return 0;
5554
5789
  }
5555
- if (x) *x = g.w;
5556
- if (y) *y = g.h;
5790
+ if (x) *x = g->w;
5791
+ if (y) *y = g->h;
5792
+ STBI_FREE(g);
5557
5793
  return 1;
5558
5794
  }
5559
5795
 
@@ -5806,20 +6042,20 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
5806
6042
  static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
5807
6043
  {
5808
6044
  stbi_uc *u = 0;
5809
- stbi__gif g;
5810
- memset(&g, 0, sizeof(g));
6045
+ stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
6046
+ memset(g, 0, sizeof(*g));
5811
6047
 
5812
- u = stbi__gif_load_next(s, &g, comp, req_comp);
6048
+ u = stbi__gif_load_next(s, g, comp, req_comp);
5813
6049
  if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
5814
6050
  if (u) {
5815
- *x = g.w;
5816
- *y = g.h;
6051
+ *x = g->w;
6052
+ *y = g->h;
5817
6053
  if (req_comp && req_comp != 4)
5818
- u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
6054
+ u = stbi__convert_format(u, 4, req_comp, g->w, g->h);
5819
6055
  }
5820
- else if (g.out)
5821
- STBI_FREE(g.out);
5822
-
6056
+ else if (g->out)
6057
+ STBI_FREE(g->out);
6058
+ STBI_FREE(g);
5823
6059
  return u;
5824
6060
  }
5825
6061
 
@@ -6017,7 +6253,7 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
6017
6253
  char *token;
6018
6254
  int valid = 0;
6019
6255
 
6020
- if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) {
6256
+ if (stbi__hdr_test(s) == 0) {
6021
6257
  stbi__rewind( s );
6022
6258
  return 0;
6023
6259
  }
@@ -6054,29 +6290,17 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
6054
6290
  #ifndef STBI_NO_BMP
6055
6291
  static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
6056
6292
  {
6057
- int hsz;
6058
- if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') {
6059
- stbi__rewind( s );
6060
- return 0;
6061
- }
6062
- stbi__skip(s,12);
6063
- hsz = stbi__get32le(s);
6064
- if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) {
6065
- stbi__rewind( s );
6066
- return 0;
6067
- }
6068
- if (hsz == 12) {
6069
- *x = stbi__get16le(s);
6070
- *y = stbi__get16le(s);
6071
- } else {
6072
- *x = stbi__get32le(s);
6073
- *y = stbi__get32le(s);
6074
- }
6075
- if (stbi__get16le(s) != 1) {
6076
- stbi__rewind( s );
6077
- return 0;
6078
- }
6079
- *comp = stbi__get16le(s) / 8;
6293
+ void *p;
6294
+ stbi__bmp_data info;
6295
+
6296
+ info.all_a = 255;
6297
+ p = stbi__bmp_parse_header(s, &info);
6298
+ stbi__rewind( s );
6299
+ if (p == NULL)
6300
+ return 0;
6301
+ *x = s->img_x;
6302
+ *y = s->img_y;
6303
+ *comp = info.ma ? 4 : 3;
6080
6304
  return 1;
6081
6305
  }
6082
6306
  #endif
@@ -6222,8 +6446,16 @@ static int stbi__pnm_isspace(char c)
6222
6446
 
6223
6447
  static void stbi__pnm_skip_whitespace(stbi__context *s, char *c)
6224
6448
  {
6225
- while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
6226
- *c = (char) stbi__get8(s);
6449
+ for (;;) {
6450
+ while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
6451
+ *c = (char) stbi__get8(s);
6452
+
6453
+ if (stbi__at_eof(s) || *c != '#')
6454
+ break;
6455
+
6456
+ while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' )
6457
+ *c = (char) stbi__get8(s);
6458
+ }
6227
6459
  }
6228
6460
 
6229
6461
  static int stbi__pnm_isdigit(char c)
@@ -6361,10 +6593,24 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
6361
6593
 
6362
6594
  /*
6363
6595
  revision history:
6596
+ 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
6597
+ 2.11 (2016-04-02) allocate large structures on the stack
6598
+ remove white matting for transparent PSD
6599
+ fix reported channel count for PNG & BMP
6600
+ re-enable SSE2 in non-gcc 64-bit
6601
+ support RGB-formatted JPEG
6602
+ read 16-bit PNGs (only as 8-bit)
6603
+ 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
6604
+ 2.09 (2016-01-16) allow comments in PNM files
6605
+ 16-bit-per-pixel TGA (not bit-per-component)
6606
+ info() for TGA could break due to .hdr handling
6607
+ info() for BMP to shares code instead of sloppy parse
6608
+ can use STBI_REALLOC_SIZED if allocator doesn't support realloc
6609
+ code cleanup
6364
6610
  2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
6365
6611
  2.07 (2015-09-13) fix compiler warnings
6366
6612
  partial animated GIF support
6367
- limited 16-bit PSD support
6613
+ limited 16-bpc PSD support
6368
6614
  #ifdef unused functions
6369
6615
  bug with < 92 byte PIC,PNM,HDR,TGA
6370
6616
  2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value