Download code

Jump to: navigation, search

Back to BMP_decoder_(C)

Download for Windows: single file, zip

Download for UNIX: single file, zip, tar.gz, tar.bz2

build.log

1 /tmp/litprog1283788/bmp_decode.c: In function 'read_s32':
2 /tmp/litprog1283788/bmp_decode.c:106:9: warning: left shift count >= width of type [enabled by default]


bmp_decode.c

  1 /* The authors of this work have released all rights to it and placed it
  2 in the public domain under the Creative Commons CC0 1.0 waiver
  3 (http://creativecommons.org/publicdomain/zero/1.0/).
  4 
  5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  6 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  7 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  8 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  9 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 10 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 11 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 12 
 13 Retrieved from: http://en.literateprograms.org/BMP_decoder_(C)?oldid=15641
 14 */
 15 
 16 #include <stdio.h>
 17 #include <stdlib.h>
 18 /* Reads up to size bytes into the buffer, returning number of bytes read */
 19 typedef int (*read_func)(void* buffer, int size);
 20 enum color_component {
 21     BLUE,
 22     GREEN,
 23     RED
 24 };
 25 
 26 #define PALETTE_ENTRY_SIZE   4
 27 #define MAX_PALETTE_SIZE     256
 28 
 29 typedef unsigned char palette[MAX_PALETTE_SIZE][PALETTE_ENTRY_SIZE];
 30 typedef unsigned char raw_pixels[][3];
 31 
 32 #define HEADER_SIZE (2 + 6*4 + 2*2 + 6*4)
 33 
 34 enum compression_values {
 35     UNCOMPRESSED = 0,
 36 
 37 };
 38 struct bmp_file_header { 
 39     unsigned short   type; 
 40     unsigned long    size; 
 41     unsigned long    reserved; 
 42     unsigned long    bitmap_offset;
 43     unsigned long    header_size; 
 44     signed   long    width; 
 45     signed   long    height; 
 46     unsigned short   planes; 
 47     unsigned short   bits_per_pixel; 
 48     unsigned long    compression; 
 49     unsigned long    bitmap_size;
 50     signed   long    horizontal_resolution;
 51     signed   long    vertical_resolution;
 52     unsigned long    num_colors; 
 53     unsigned long    num_important_colors; 
 54 }; 
 55 
 56 void fix_endian_func(void* data, int size) {
 57     int endian_test = 1;
 58     unsigned char* endian_test_bytes = (unsigned char *)&endian_test;
 59     if (endian_test_bytes[0] == '\0') {
 60         unsigned char* cdata = data;
 61         int i;
 62         for (i=0; i<size/2; i++) {
 63             unsigned char temp = cdata[i];
 64             cdata[i] = cdata[size-1 - i];
 65             cdata[size-1 - i] = temp;
 66         }
 67     }
 68 }
 69 
 70 #define fix_endian(x)  (fix_endian_func(&(x), sizeof(x)))
 71 unsigned char read_u8(read_func read) {
 72     unsigned char result;
 73     if (read(&result, 1) < 1) {
 74         printf("Unexpected end of file");
 75         exit(-1);
 76     }
 77     return result;
 78 }
 79 unsigned short read_u16(read_func read) {
 80     unsigned short result = 0;
 81     if (read(&result, 2) < 2) {
 82         printf("Unexpected end of file");
 83         exit(-1);
 84     }
 85     fix_endian(result);
 86     return result;
 87 }
 88 
 89 unsigned long read_u32(read_func read) {
 90     unsigned long result = 0;
 91     if (read(&result, 4) < 4) {
 92         printf("Unexpected end of file");
 93         exit(-1);
 94     }
 95     fix_endian(result);
 96     return result;
 97 }
 98 signed long read_s32(read_func read) {
 99     unsigned long result = 0;
100     if (read(&result, 4) < 4) {
101         printf("Unexpected end of file");
102         exit(-1);
103     }
104     fix_endian(result);
105     if ((result >> 31) & 1) { /* If it's negative... */
106         result |= ((unsigned long)(-1)) << 32;
107     }
108     return (long)result;
109 }
110 void read_bitmap_header(read_func in, struct bmp_file_header* header) {
111     header->type                  = read_u16(in);
112     header->size                  = read_u32(in);
113     header->reserved              = read_u32(in);
114     header->bitmap_offset         = read_u32(in);
115     header->header_size           = read_u32(in);
116     header->width                 = read_s32(in);
117     header->height                = read_s32(in);
118     header->planes                = read_u16(in);
119     header->bits_per_pixel        = read_u16(in); 
120     header->compression           = read_u32(in);
121     header->bitmap_size           = read_u32(in);
122     header->horizontal_resolution = read_s32(in);
123     header->vertical_resolution   = read_u32(in);
124     header->num_colors            = read_u32(in);
125     header->num_important_colors  = read_u32(in);
126 }
127 int read_palette(read_func in, struct bmp_file_header* header, palette palette) {
128     int palette_size = header->bitmap_offset - HEADER_SIZE;
129     if (in(&palette[0][0], palette_size) < palette_size) {
130         printf("Unexpected end of file");
131         exit(-1);
132     }
133     return palette_size/PALETTE_ENTRY_SIZE;
134 }


hijacker
hijacker
hijacker
hijacker