소스 검색

modifications to vertical flip API:
more consistent name,
refactor stbi_load_main to preserve old code,
support float HDR path,
minor bugfix

Sean Barrett 10 년 전
부모
커밋
040df963c8
1개의 변경된 파일66개의 추가작업 그리고 38개의 파일을 삭제
  1. 66 38
      stb_image.h

+ 66 - 38
stb_image.h

@@ -181,7 +181,7 @@
     James "moose2000" Brown (iPhone PNG)         Roy Eltham
     James "moose2000" Brown (iPhone PNG)         Roy Eltham
     Ben "Disch" Wenger (io callbacks)            Luke Graham
     Ben "Disch" Wenger (io callbacks)            Luke Graham
     Omar Cornut (1/2/4-bit PNG)                  Thomas Ruf
     Omar Cornut (1/2/4-bit PNG)                  Thomas Ruf
-                                                 John Bartholomew
+    Nicolas Guillemot (vertical flip)            John Bartholomew
                                                  Ken Hamada
                                                  Ken Hamada
  Optimizations & bugfixes                        Cort Stratton
  Optimizations & bugfixes                        Cort Stratton
     Fabian "ryg" Giesen                          Blazej Dariusz Roszkowski
     Fabian "ryg" Giesen                          Blazej Dariusz Roszkowski
@@ -489,8 +489,8 @@ STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultipl
 // or just pass them through "as-is"
 // or just pass them through "as-is"
 STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
 STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
 
 
-// flip the image vertically. useful for opengl image loading.
-STBIDEF void stbi_vertically_flip_on_load(int flag_true_if_should_flip);
+// flip the image vertically, so the first pixel in the output array is the bottom left
+STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
 
 
 // ZLIB client - used by PNG, available for other purposes
 // ZLIB client - used by PNG, available for other purposes
 
 
@@ -891,66 +891,68 @@ static stbi_uc *stbi__hdr_to_ldr(float   *data, int x, int y, int comp);
 
 
 static int stbi__vertically_flip_on_load = 0;
 static int stbi__vertically_flip_on_load = 0;
 
 
-STBIDEF void stbi_vertically_flip_on_load(int flag_true_if_should_flip)
+STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
 {
 {
     stbi__vertically_flip_on_load = flag_true_if_should_flip;
     stbi__vertically_flip_on_load = flag_true_if_should_flip;
 }
 }
 
 
-static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
 {
 {
-   unsigned char *result = NULL;
-
-   if (0); // get the test chain started
    #ifndef STBI_NO_JPEG
    #ifndef STBI_NO_JPEG
-   else if (stbi__jpeg_test(s)) result = stbi__jpeg_load(s,x,y,comp,req_comp);
+   if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp);
    #endif
    #endif
    #ifndef STBI_NO_PNG
    #ifndef STBI_NO_PNG
-   else if (stbi__png_test(s))  result = stbi__png_load(s,x,y,comp,req_comp);
+   if (stbi__png_test(s))  return stbi__png_load(s,x,y,comp,req_comp);
    #endif
    #endif
    #ifndef STBI_NO_BMP
    #ifndef STBI_NO_BMP
-   else if (stbi__bmp_test(s))  result = stbi__bmp_load(s,x,y,comp,req_comp);
+   if (stbi__bmp_test(s))  return stbi__bmp_load(s,x,y,comp,req_comp);
    #endif
    #endif
    #ifndef STBI_NO_GIF
    #ifndef STBI_NO_GIF
-   else if (stbi__gif_test(s))  result = stbi__gif_load(s,x,y,comp,req_comp);
+   if (stbi__gif_test(s))  return stbi__gif_load(s,x,y,comp,req_comp);
    #endif
    #endif
    #ifndef STBI_NO_PSD
    #ifndef STBI_NO_PSD
-   else if (stbi__psd_test(s))  result = stbi__psd_load(s,x,y,comp,req_comp);
+   if (stbi__psd_test(s))  return stbi__psd_load(s,x,y,comp,req_comp);
    #endif
    #endif
    #ifndef STBI_NO_PIC
    #ifndef STBI_NO_PIC
-   else if (stbi__pic_test(s))  result = stbi__pic_load(s,x,y,comp,req_comp);
+   if (stbi__pic_test(s))  return stbi__pic_load(s,x,y,comp,req_comp);
    #endif
    #endif
    #ifndef STBI_NO_PNM
    #ifndef STBI_NO_PNM
-   else if (stbi__pnm_test(s))  result = stbi__pnm_load(s,x,y,comp,req_comp);
+   if (stbi__pnm_test(s))  return stbi__pnm_load(s,x,y,comp,req_comp);
    #endif
    #endif
 
 
    #ifndef STBI_NO_HDR
    #ifndef STBI_NO_HDR
-   else if (stbi__hdr_test(s)) {
+   if (stbi__hdr_test(s)) {
       float *hdr = stbi__hdr_load(s, x,y,comp,req_comp);
       float *hdr = stbi__hdr_load(s, x,y,comp,req_comp);
-      result = stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
+      return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
    }
    }
    #endif
    #endif
 
 
    #ifndef STBI_NO_TGA
    #ifndef STBI_NO_TGA
    // test tga last because it's a crappy test!
    // test tga last because it's a crappy test!
-   else if (stbi__tga_test(s))
-      result = stbi__tga_load(s,x,y,comp,req_comp);
+   if (stbi__tga_test(s))
+      return stbi__tga_load(s,x,y,comp,req_comp);
    #endif
    #endif
 
 
-   else
-      return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
+   return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
+}
+
+static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+{
+   unsigned char *result = stbi__load_main(s, x, y, comp, req_comp);
 
 
-   // post-processing
-   if (stbi__vertically_flip_on_load) {
+   if (stbi__vertically_flip_on_load && result != NULL) {
+      int w = *x, h = *y;
       int depth = req_comp ? req_comp : *comp;
       int depth = req_comp ? req_comp : *comp;
       int row,col,z;
       int row,col,z;
       stbi_uc temp;
       stbi_uc temp;
 
 
-      for (row = 0; row < *y / 2; row++) {
-         for (col = 0; col < *x; col++) {
+      // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once
+      for (row = 0; row < (h>>1); row++) {
+         for (col = 0; col < w; col++) {
             for (z = 0; z < depth; z++) {
             for (z = 0; z < depth; z++) {
-               temp = result[(row * (*x) + col) * depth + z];
-               result[(row * (*x) + col) * depth + z] = result[((*y - row - 1) * (*x) + col) * depth + z];
-               result[((*y - row - 1) * (*x) + col) * depth + z] = temp;
+               temp = result[(row * w + col) * depth + z];
+               result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z];
+               result[((h - row - 1) * w + col) * depth + z] = temp;
             }
             }
          }
          }
       }
       }
@@ -959,6 +961,28 @@ static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp
    return result;
    return result;
 }
 }
 
 
+static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
+{
+   if (stbi__vertically_flip_on_load && result != NULL) {
+      int w = *x, h = *y;
+      int depth = req_comp ? req_comp : *comp;
+      int row,col,z;
+      float temp;
+
+      // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once
+      for (row = 0; row < (h>>1); row++) {
+         for (col = 0; col < w; col++) {
+            for (z = 0; z < depth; z++) {
+               temp = result[(row * w + col) * depth + z];
+               result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z];
+               result[((h - row - 1) * w + col) * depth + z] = temp;
+            }
+         }
+      }
+   }
+}
+
+
 #ifndef STBI_NO_STDIO
 #ifndef STBI_NO_STDIO
 
 
 static FILE *stbi__fopen(char const *filename, char const *mode)
 static FILE *stbi__fopen(char const *filename, char const *mode)
@@ -989,7 +1013,7 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
    unsigned char *result;
    unsigned char *result;
    stbi__context s;
    stbi__context s;
    stbi__start_file(&s,f);
    stbi__start_file(&s,f);
-   result = stbi_load_main(&s,x,y,comp,req_comp);
+   result = stbi__load_flip(&s,x,y,comp,req_comp);
    if (result) {
    if (result) {
       // need to 'unget' all the characters in the IO buffer
       // need to 'unget' all the characters in the IO buffer
       fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
       fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
@@ -1002,25 +1026,29 @@ STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, i
 {
 {
    stbi__context s;
    stbi__context s;
    stbi__start_mem(&s,buffer,len);
    stbi__start_mem(&s,buffer,len);
-   return stbi_load_main(&s,x,y,comp,req_comp);
+   return stbi__load_flip(&s,x,y,comp,req_comp);
 }
 }
 
 
 STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
 STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
 {
 {
    stbi__context s;
    stbi__context s;
    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
-   return stbi_load_main(&s,x,y,comp,req_comp);
+   return stbi__load_flip(&s,x,y,comp,req_comp);
 }
 }
 
 
 #ifndef STBI_NO_LINEAR
 #ifndef STBI_NO_LINEAR
-static float *stbi_loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
 {
 {
    unsigned char *data;
    unsigned char *data;
    #ifndef STBI_NO_HDR
    #ifndef STBI_NO_HDR
-   if (stbi__hdr_test(s))
-      return stbi__hdr_load(s,x,y,comp,req_comp);
+   if (stbi__hdr_test(s)) {
+      float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp);
+      if (hdr_data)
+         stbi__float_postprocess(hdr_data,x,y,comp,req_comp);
+      return hdr_data;
+   }
    #endif
    #endif
-   data = stbi_load_main(s, x, y, comp, req_comp);
+   data = stbi__load_flip(s, x, y, comp, req_comp);
    if (data)
    if (data)
       return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
       return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
    return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
    return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
@@ -1030,14 +1058,14 @@ STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, in
 {
 {
    stbi__context s;
    stbi__context s;
    stbi__start_mem(&s,buffer,len);
    stbi__start_mem(&s,buffer,len);
-   return stbi_loadf_main(&s,x,y,comp,req_comp);
+   return stbi__loadf_main(&s,x,y,comp,req_comp);
 }
 }
 
 
 STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
 STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
 {
 {
    stbi__context s;
    stbi__context s;
    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
-   return stbi_loadf_main(&s,x,y,comp,req_comp);
+   return stbi__loadf_main(&s,x,y,comp,req_comp);
 }
 }
 
 
 #ifndef STBI_NO_STDIO
 #ifndef STBI_NO_STDIO
@@ -1055,7 +1083,7 @@ STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_
 {
 {
    stbi__context s;
    stbi__context s;
    stbi__start_file(&s,f);
    stbi__start_file(&s,f);
-   return stbi_loadf_main(&s,x,y,comp,req_comp);
+   return stbi__loadf_main(&s,x,y,comp,req_comp);
 }
 }
 #endif // !STBI_NO_STDIO
 #endif // !STBI_NO_STDIO