/* * -- http://android-fb2png.googlecode.com/svn/trunk/img_process.c -- * * Copyright 2011, Kyan He * * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "img_process.h" #include "log.h" int rgb565_to_rgb888(const char* src, char* dst, size_t pixel) { struct rgb565 *from; struct rgb888 *to; from = (struct rgb565 *) src; to = (struct rgb888 *) dst; size_t i = 0; /* traverse pixel of the row */ while(i++ < pixel) { to->r = from->r; to->g = from->g; to->b = from->b; /* scale */ to->r <<= 3; to->g <<= 2; to->b <<= 3; to++; from++; } return 0; } int argb8888_to_rgb888(const char* src, char* dst, size_t pixel) { size_t i; struct argb8888 *from; struct rgb888 *to; from = (struct argb8888 *) src; to = (struct rgb888 *) dst; i = 0; /* traverse pixel of the row */ while(i++ < pixel) { to->r = from->r; to->g = from->g; to->b = from->b; to++; from++; } return 0; } int abgr8888_to_rgb888(const char* src, char* dst, size_t pixel) { size_t i; struct abgr8888 *from; struct rgb888 *to; from = (struct abgr8888 *) src; to = (struct rgb888 *) dst; i = 0; /* traverse pixel of the row */ while(i++ < pixel) { to->r = from->r; to->g = from->g; to->b = from->b; to++; from++; } return 0; } int bgra8888_to_rgb888(const char* src, char* dst, size_t pixel) { size_t i; struct bgra8888 *from; struct rgb888 *to; from = (struct bgra8888 *) src; to = (struct rgb888 *) dst; i = 0; /* traverse pixel of the row */ while(i++ < pixel) { to->r = from->r; to->g = from->g; to->b = from->b; to++; from++; } return 0; } int rgba8888_to_rgb888(const char* src, char* dst, size_t pixel) { size_t i; struct rgba8888 *from; struct rgb888 *to; from = (struct rgba8888 *) src; to = (struct rgb888 *) dst; i = 0; /* traverse pixel of the row */ while(i++ < pixel) { to->r = from->r; to->g = from->g; to->b = from->b; to++; from++; } return 0; } static void stdio_write_func (png_structp png, png_bytep data, png_size_t size) { FILE *fp; size_t ret; fp = png_get_io_ptr (png); while (size) { ret = fwrite (data, 1, size, fp); size -= ret; data += ret; if (size && ferror (fp)) E("write: %m\n"); } } static void png_simple_output_flush_fn (__attribute__((unused)) png_structp png_ptr) { } static void png_simple_error_callback (__attribute__((unused)) png_structp png, png_const_charp error_msg) { E("png error: %s\n", error_msg); } static void png_simple_warning_callback (__attribute__((unused)) png_structp png, png_const_charp error_msg) { fprintf(stderr, "png warning: %s\n", error_msg); } /* save rgb888 to png format in fp */ int save_png(const char* path, const char* data, int width, int height) { FILE *fp; png_byte **volatile rows; png_struct *png; png_info *info; fp = fopen(path, "w"); if (!fp) { int errsv = errno; E("Cannot open file %s for writing.\n", path); return errsv; } rows = malloc(height * sizeof rows[0]); if (!rows) goto oops; int i; for (i = 0; i < height; i++) rows[i] = (png_byte *) data + i * width * 3 /*fb.stride*/; png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, png_simple_error_callback, png_simple_warning_callback); if (!png) { E("png_create_write_struct failed\n"); goto oops; } info = png_create_info_struct (png); if (!info) { E("png_create_info_struct failed\n"); png_destroy_write_struct (&png, NULL); goto oops; } png_set_write_fn (png, fp, stdio_write_func, png_simple_output_flush_fn); png_set_IHDR (png, info, width, height, #define DEPTH 8 DEPTH, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_color_16 white; white.gray = (1 << DEPTH) - 1; white.red = white.blue = white.green = white.gray; png_set_bKGD (png, info, &white); png_write_info (png, info); png_write_image (png, rows); png_write_end (png, info); png_destroy_write_struct (&png, &info); fclose(fp); free (rows); return 0; oops: fclose(fp); free (rows); return -1; }