From patchwork Thu Jul 21 12:36:38 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Barker X-Patchwork-Id: 2928 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 4F1ED23F4D for ; Thu, 21 Jul 2011 12:41:49 +0000 (UTC) Received: from mail-qy0-f180.google.com (mail-qy0-f180.google.com [209.85.216.180]) by fiordland.canonical.com (Postfix) with ESMTP id 07FF0A185A2 for ; Thu, 21 Jul 2011 12:41:48 +0000 (UTC) Received: by mail-qy0-f180.google.com with SMTP id 30so845420qyk.11 for ; Thu, 21 Jul 2011 05:41:48 -0700 (PDT) Received: by 10.229.25.212 with SMTP id a20mr173397qcc.148.1311252107310; Thu, 21 Jul 2011 05:41:47 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.217.78 with SMTP id hl14cs139461qcb; Thu, 21 Jul 2011 05:41:47 -0700 (PDT) Received: by 10.216.234.80 with SMTP id r58mr148841weq.109.1311251798765; Thu, 21 Jul 2011 05:36:38 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id t48si2395805weq.41.2011.07.21.05.36.38; Thu, 21 Jul 2011 05:36:38 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) client-ip=91.189.90.139; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) smtp.mail=bounces@canonical.com Received: from loganberry.canonical.com ([91.189.90.37]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QjsUY-0000D2-2W for ; Thu, 21 Jul 2011 12:36:38 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id 11EB62E84FB for ; Thu, 21 Jul 2011 12:36:38 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~glmark2-dev/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 109 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 109: Cleanup of PNG image loading code. Still wildly uncomfortable with libpng using Message-Id: <20110721123638.17019.15664.launchpad@loganberry.canonical.com> Date: Thu, 21 Jul 2011 12:36:38 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13475"; Instance="initZopeless config overlay" X-Launchpad-Hash: b0e3936fca3ef1c49bdef5bd4b21a53b456addfe ------------------------------------------------------------ revno: 109 committer: Jesse Barker timestamp: Thu 2011-07-14 10:23:51 -0700 message: Cleanup of PNG image loading code. Still wildly uncomfortable with libpng using setjmp/longjmp, but this gets rid of the goto's and makes the code more self-managing. modified: src/texture.cpp --- lp:glmark2 https://code.launchpad.net/~glmark2-dev/glmark2/trunk You are subscribed to branch lp:glmark2. To unsubscribe from this branch go to https://code.launchpad.net/~glmark2-dev/glmark2/trunk/+edit-subscription === modified file 'src/texture.cpp' --- src/texture.cpp 2011-06-30 13:33:37 +0000 +++ src/texture.cpp 2011-07-14 17:23:51 +0000 @@ -27,76 +27,118 @@ #include #include +class PNGState +{ +public: + PNGState() : + fp_(0), + png_(0), + info_(0), + rows_(0) {} + ~PNGState() + { + if (fp_) + { + fclose(fp_); + } + if (png_) + { + png_destroy_read_struct(&png_, &info_, 0); + } + } + bool gotData(const std::string& filename) + { + static const int png_transforms = PNG_TRANSFORM_STRIP_16 | + PNG_TRANSFORM_GRAY_TO_RGB | + PNG_TRANSFORM_PACKING | + PNG_TRANSFORM_EXPAND; + + Log::debug("Reading PNG file %s\n", filename.c_str()); + + fp_ = fopen(filename.c_str(), "rb"); + if (!fp_) { + Log::error("Cannot open file %s!\n", filename.c_str()); + return false; + } + + /* Set up all the libpng structs we need */ + png_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + if (!png_) { + Log::error("Couldn't create libpng read struct\n"); + return false; + } + + info_ = png_create_info_struct(png_); + if (!info_) { + Log::error("Couldn't create libpng info struct\n"); + return false; + } + + /* Set up libpng error handling */ + if (setjmp(png_jmpbuf(png_))) { + Log::error("libpng error while reading file %s\n", filename.c_str()); + return false; + } + + /* Read the image information and data */ + png_init_io(png_, fp_); + + png_read_png(png_, info_, png_transforms, 0); + + rows_ = png_get_rows(png_, info_); + + return true; + } + unsigned int width() const { return png_get_image_width(png_, info_); } + unsigned int height() const { return png_get_image_height(png_, info_); } + unsigned int pixelBytes() const + { + if (png_get_color_type(png_, info_) == PNG_COLOR_TYPE_RGB) + { + return 3; + } + return 4; + } + const unsigned char* row(unsigned int idx) const { return rows_[idx]; } +private: + FILE* fp_; + png_structp png_; + png_infop info_; + png_bytepp rows_; +}; + class ImageData { -public: - ImageData() : pixels(0), width(0), height(0), bpp(0) {} - ~ImageData() { delete [] pixels; } - bool load_png(const std::string &filename); - void resize(int w, int h, int b) + void resize(unsigned int w, unsigned int h, unsigned int b) { width = w; height = h; bpp = b; delete [] pixels; - pixels = new unsigned char[bpp * w * h]; + pixels = new unsigned char[bpp * width * height]; } +public: + ImageData() : pixels(0), width(0), height(0), bpp(0) {} + ~ImageData() { delete [] pixels; } + bool load_png(const std::string &filename); + unsigned char *pixels; - int width; - int height; - int bpp; + unsigned int width; + unsigned int height; + unsigned int bpp; }; bool ImageData::load_png(const std::string &filename) { - bool ret = false; - png_structp png_ptr = 0; - png_infop info_ptr = 0; - png_bytepp row_pointers = 0; - static const int png_transforms = PNG_TRANSFORM_STRIP_16 | - PNG_TRANSFORM_GRAY_TO_RGB | - PNG_TRANSFORM_PACKING | - PNG_TRANSFORM_EXPAND; - - Log::debug("Reading PNG file %s\n", filename.c_str()); - - FILE *fp = fopen(filename.c_str(), "rb"); - if (!fp) { - Log::error("Cannot open file %s!\n", filename.c_str()); - goto out; - } - - /* Set up all the libpng structs we need */ - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - if (!png_ptr) { - Log::error("Couldn't create libpng read struct\n"); - goto out; - } - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - Log::error("Couldn't create libpng info struct\n"); - goto out; - } - - /* Set up libpng error handling */ - if (setjmp(png_jmpbuf(png_ptr))) { - Log::error("libpng error while reading file %s\n", filename.c_str()); - goto out; - } - - /* Read the image information and data */ - png_init_io(png_ptr, fp); - - png_read_png(png_ptr, info_ptr, png_transforms, 0); - - row_pointers = png_get_rows(png_ptr, info_ptr); - - resize(png_get_image_width(png_ptr, info_ptr), - png_get_image_height(png_ptr, info_ptr), - png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB ? 3 : 4); - + PNGState png; + bool ret = png.gotData(filename); + if (!ret) + { + return ret; + } + + resize(png.width(), png.height(), png.pixelBytes()); Log::debug(" Height: %d Width: %d Bpp: %d\n", width, height, bpp); @@ -104,23 +146,12 @@ * Copy the image data to a contiguous memory area suitable for texture * upload. */ - for (int i = 0; i < height; i++) { + for (unsigned int i = 0; i < height; i++) { memcpy(&pixels[bpp * width * i], - row_pointers[height - i - 1], + png.row(height - i - 1), width * bpp); } - ret = true; - -out: - if (fp) - fclose(fp); - - if (png_ptr) - png_destroy_read_struct(&png_ptr, - info_ptr != 0 ? &info_ptr : 0, - 0); - return ret; }