symbian-qemu-0.9.1-12/qemu-symbian-svp/gui_png.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * GUI PNG files processing
       
     3  *
       
     4  * Copyright (c) 2009 CodeSourcery
       
     5  *
       
     6  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     7  * of this software and associated documentation files (the "Software"), to deal
       
     8  * in the Software without restriction, including without limitation the rights
       
     9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
    10  * copies of the Software, and to permit persons to whom the Software is
       
    11  * furnished to do so, subject to the following conditions:
       
    12  *
       
    13  * The above copyright notice and this permission notice shall be included in
       
    14  * all copies or substantial portions of the Software.
       
    15  *
       
    16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
       
    19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    22  * THE SOFTWARE.
       
    23  */
       
    24 
       
    25 #include "png.h"
       
    26 #include "qemu-common.h"
       
    27 #include "gui_common.h"
       
    28 #include "gui_png.h"
       
    29 
       
    30 /*
       
    31 int x, y;
       
    32 
       
    33 int width, height;
       
    34 png_byte color_type;
       
    35 png_byte bit_depth;
       
    36 */
       
    37 
       
    38 typedef struct
       
    39 {
       
    40     int width;
       
    41     int height;
       
    42     void* image4c; /* in 4 channels */
       
    43 } png_image_data_t;
       
    44 
       
    45 static void abort_(const char * s, ...)
       
    46 {
       
    47 	va_list args;
       
    48 	va_start(args, s);
       
    49 	vfprintf(stderr, s, args);
       
    50 	fprintf(stderr, "\n");
       
    51 	va_end(args);
       
    52 	abort();
       
    53 }
       
    54 
       
    55 #if 0
       
    56 static void read_png_file_low(const char* file_name, png_image_data_t *png_image_data)
       
    57 {
       
    58     png_structp png_ptr;
       
    59     int number_of_passes;
       
    60 	char header[8];	// 8 is the maximum size that can be checked
       
    61     int y;
       
    62 
       
    63 	/* open file and test for it being a png */
       
    64 	FILE *fp = fopen(file_name, "rb");
       
    65 	if (!fp)
       
    66 		abort_("[read_png_file] File %s could not be opened for reading", file_name);
       
    67 	fread(header, 1, 8, fp);
       
    68 	if (png_sig_cmp(header, 0, 8))
       
    69 		abort_("[read_png_file] File %s is not recognized as a PNG file", file_name);
       
    70 
       
    71 
       
    72 	/* initialize stuff */
       
    73 	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
       
    74 	
       
    75 	if (!png_ptr)
       
    76 		abort_("[read_png_file] png_create_read_struct failed");
       
    77 
       
    78 	png_image_data->info_ptr = png_create_info_struct(png_ptr);
       
    79 	if (!png_image_data->info_ptr)
       
    80 		abort_("[read_png_file] png_create_info_struct failed");
       
    81 
       
    82 	if (setjmp(png_jmpbuf(png_ptr)))
       
    83 		abort_("[read_png_file] Error during init_io");
       
    84 	png_init_io(png_ptr, fp);
       
    85 
       
    86 	png_set_sig_bytes(png_ptr, 8); /* 8 == sig_read ? */
       
    87 
       
    88 	png_read_info(png_ptr, png_image_data->info_ptr);
       
    89 
       
    90     /* set transformations */
       
    91 /*
       
    92 	if ((png_image_data->info_ptr->color_type & PNG_COLOR_TYPE_RGB) == 0)
       
    93         transforms |= PNG_TRANSFORM_BGR;
       
    94 */
       
    95    if (png_get_valid(png_ptr, png_image_data->info_ptr, PNG_INFO_sBIT))
       
    96    {
       
    97       png_color_8p sig_bit;
       
    98 
       
    99       png_get_sBIT(png_ptr, png_image_data->info_ptr, &sig_bit);
       
   100       printf("sig_bit: %d\n", sig_bit);
       
   101       png_set_shift(png_ptr, sig_bit);
       
   102    }
       
   103 
       
   104     /* TODO DFG: is this needed? */
       
   105 	number_of_passes = png_set_interlace_handling(png_ptr);
       
   106 	png_read_update_info(png_ptr, png_image_data->info_ptr);
       
   107 
       
   108 
       
   109 
       
   110 
       
   111 
       
   112 	/* read file */
       
   113 	if (setjmp(png_jmpbuf(png_ptr)))
       
   114 		abort_("[read_png_file] Error during read_image");
       
   115 
       
   116 #if 1
       
   117 	png_image_data->row_pointers = (png_bytep*) qemu_malloc(sizeof(png_bytep) * png_image_data->info_ptr->height);
       
   118 	for (y=0; y < png_image_data->info_ptr->height; y++)
       
   119 		png_image_data->row_pointers[y] = (png_byte*) qemu_malloc(png_image_data->info_ptr->rowbytes);
       
   120 
       
   121 	png_read_image(png_ptr, png_image_data->row_pointers);
       
   122 #endif
       
   123     /* DFG TODO: Cleanup */
       
   124 
       
   125 /*    png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); */
       
   126 
       
   127     fclose(fp);
       
   128 }
       
   129 #endif
       
   130 
       
   131 static void read_png_file(const char* file_name, png_image_data_t *png_image_data, int max_width, int max_height)
       
   132 {
       
   133     png_structp png_ptr;
       
   134     png_infop info_ptr;
       
   135     png_bytep *row_pointers;
       
   136 	char header[8];	// 8 is the maximum size that can be checked
       
   137     int y;
       
   138     char* dest;
       
   139 
       
   140 	/* open file and test for it being a png */
       
   141 	FILE *fp = fopen(file_name, "rb");
       
   142 	if (!fp)
       
   143 		abort_("[read_png_file] File %s could not be opened for reading", file_name);
       
   144 	fread(header, 1, 8, fp);
       
   145 	if (png_sig_cmp(header, 0, 8))
       
   146 		abort_("[read_png_file] File %s is not recognized as a PNG file", file_name);
       
   147 
       
   148 
       
   149 	/* initialize stuff */
       
   150 	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
       
   151 	
       
   152 	if (!png_ptr)
       
   153 		abort_("[read_png_file] png_create_read_struct failed");
       
   154 
       
   155     if (max_width > 0 && max_height > 0)
       
   156         png_set_user_limits(png_ptr, max_width, max_height);
       
   157 
       
   158 	info_ptr = png_create_info_struct(png_ptr);
       
   159 
       
   160 	if (setjmp(png_jmpbuf(png_ptr)))
       
   161 		abort_("[read_png_file] Error during init_io");
       
   162 	png_init_io(png_ptr, fp);
       
   163 
       
   164 	if (setjmp(png_jmpbuf(png_ptr)))
       
   165 		abort_("[read_png_file] Error during init_io");
       
   166    png_set_sig_bytes(png_ptr, sizeof(header));
       
   167 
       
   168 	if (setjmp(png_jmpbuf(png_ptr)))
       
   169 		abort_("[read_png_file] Error during init_io");
       
   170    png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_ALPHA, png_voidp_NULL);
       
   171 
       
   172 	if (setjmp(png_jmpbuf(png_ptr)))
       
   173 		abort_("[read_png_file] Error during init_io");
       
   174 
       
   175     row_pointers = png_get_rows(png_ptr, info_ptr);
       
   176 
       
   177     png_image_data->height = png_get_image_height(png_ptr, info_ptr);
       
   178     png_image_data->width = png_get_image_width(png_ptr, info_ptr);
       
   179 
       
   180     png_image_data->image4c = (void*)qemu_malloc(png_image_data->width * png_image_data->height * 4);
       
   181 
       
   182     dest = (char*)png_image_data->image4c;
       
   183 
       
   184     /* transform this from 3 channels to a (fake for now) 4 channels */
       
   185 	for (y=0; y < png_image_data->height; y++) {
       
   186         char* src = row_pointers[y];
       
   187         int x;
       
   188         for (x = 0; x < png_image_data->width; x++) {
       
   189             *dest = *src; dest++, src++;
       
   190             *dest = *src; dest++, src++;
       
   191             *dest = *src; dest++, src++;
       
   192             *dest = 0; dest++; /* alpha channel ignored */ 
       
   193         }
       
   194     }
       
   195 
       
   196     png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
       
   197 
       
   198     fclose(fp);
       
   199 }
       
   200 
       
   201 
       
   202 
       
   203 void gui_load_image_png(const char *filename, gui_image_t *image_data)
       
   204 {
       
   205     const int area_height = GET_GUI_AREA_HEIGHT(&image_data->area);
       
   206     const int area_width  = GET_GUI_AREA_WIDTH(&image_data->area);
       
   207     png_image_data_t png_image_data;
       
   208 
       
   209     read_png_file(filename, &png_image_data, area_width, area_height);
       
   210 
       
   211     /* see if area has to be resized, because of any of these reasons:
       
   212         a) the image is smaller than the area
       
   213         b) the area is 0 (auto size for the background)
       
   214     */
       
   215     if (area_height > png_image_data.height || area_height <= 0)
       
   216         SET_GUI_AREA_HEIGHT(&image_data->area, png_image_data.height);
       
   217     if (area_width > png_image_data.width || area_width <= 0)
       
   218         SET_GUI_AREA_WIDTH(&image_data->area, png_image_data.width);
       
   219 
       
   220     image_data->image = png_image_data.image4c;
       
   221 }
       
   222