Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: core/cross/bitmap_png.cc

Issue 164130: This CL adds client.toDataURL which gets the contents... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: '' Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « core/cross/bitmap.cc ('k') | core/cross/client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2009, Google Inc. 2 * Copyright 2009, Google Inc.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 19 matching lines...) Expand all
30 */ 30 */
31 31
32 32
33 // This file contains the image codec operations for PNG files. 33 // This file contains the image codec operations for PNG files.
34 34
35 // precompiled header must appear before anything else. 35 // precompiled header must appear before anything else.
36 #include "core/cross/precompile.h" 36 #include "core/cross/precompile.h"
37 37
38 #include <fstream> 38 #include <fstream>
39 #include "core/cross/bitmap.h" 39 #include "core/cross/bitmap.h"
40 #include "core/cross/error.h"
40 #include "core/cross/types.h" 41 #include "core/cross/types.h"
41 #include "utils/cross/file_path_utils.h" 42 #include "utils/cross/file_path_utils.h"
42 #include "base/file_path.h" 43 #include "base/file_path.h"
43 #include "base/file_util.h" 44 #include "base/file_util.h"
44 #include "import/cross/memory_buffer.h" 45 #include "import/cross/memory_buffer.h"
45 #include "import/cross/memory_stream.h" 46 #include "import/cross/memory_stream.h"
46 #include "png.h" 47 #include "png.h"
48 #include "utils/cross/dataurl.h"
47 49
48 using file_util::OpenFile; 50 using file_util::OpenFile;
49 using file_util::CloseFile; 51 using file_util::CloseFile;
50 52
51 namespace o3d { 53 namespace o3d {
52 54
55 namespace {
56
53 // Helper function for LoadFromPNGFile that converts a stream into the 57 // Helper function for LoadFromPNGFile that converts a stream into the
54 // necessary abstract byte reading function. 58 // necessary abstract byte reading function.
55 static void stream_read_data(png_structp png_ptr, 59 void StreamReadData(png_structp png_ptr, png_bytep data, png_size_t length) {
56 png_bytep data,
57 png_size_t length) {
58 MemoryReadStream *stream = 60 MemoryReadStream *stream =
59 static_cast<MemoryReadStream*>(png_get_io_ptr(png_ptr)); 61 static_cast<MemoryReadStream*>(png_get_io_ptr(png_ptr));
60 stream->Read(data, length); 62 stream->Read(data, length);
61 } 63 }
62 64
65 // Helper function for ToDataURL that converts a stream into the necessary
66 // abstract byte writing function.
67 void StreamWriteData(png_structp png_ptr, png_bytep data, png_size_t length) {
68 std::vector<uint8>* stream =
69 static_cast<std::vector<uint8>*>(png_get_io_ptr(png_ptr));
70 stream->insert(stream->end(),
71 static_cast<uint8*>(data),
72 static_cast<uint8*>(data) + length);
73 }
74
75 // Because libpng requires a flush function according to the docs.
76 void StreamFlush(png_structp png_ptr) {
77 }
78
79 } // anonymous namespace
63 80
64 // Loads the raw RGB data from a compressed PNG file. 81 // Loads the raw RGB data from a compressed PNG file.
65 bool Bitmap::LoadFromPNGStream(MemoryReadStream *stream, 82 bool Bitmap::LoadFromPNGStream(MemoryReadStream *stream,
66 const String &filename, 83 const String &filename,
67 bool generate_mipmaps) { 84 bool generate_mipmaps) {
68 // Read the magic header. 85 // Read the magic header.
69 char magic[4]; 86 char magic[4];
70 size_t bytes_read = stream->Read(magic, sizeof(magic)); 87 size_t bytes_read = stream->Read(magic, sizeof(magic));
71 if (bytes_read != sizeof(magic)) { 88 if (bytes_read != sizeof(magic)) {
72 DLOG(ERROR) << "PNG file magic header not loaded \"" << filename << "\""; 89 DLOG(ERROR) << "PNG file magic header not loaded \"" << filename << "\"";
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 if (setjmp(png_jmpbuf(png_ptr))) { 127 if (setjmp(png_jmpbuf(png_ptr))) {
111 // If we reach here, a fatal error occurred so free memory and exit. 128 // If we reach here, a fatal error occurred so free memory and exit.
112 DLOG(ERROR) << "Fatal error reading PNG file \"" << filename << "\""; 129 DLOG(ERROR) << "Fatal error reading PNG file \"" << filename << "\"";
113 if (row_pointers) 130 if (row_pointers)
114 png_free(png_ptr, row_pointers); 131 png_free(png_ptr, row_pointers);
115 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 132 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
116 return false; 133 return false;
117 } 134 }
118 135
119 // Set up our STL stream input control 136 // Set up our STL stream input control
120 png_set_read_fn(png_ptr, stream, &stream_read_data); 137 png_set_read_fn(png_ptr, stream, &StreamReadData);
121 138
122 // We have already read some of the signature, advance the pointer. 139 // We have already read some of the signature, advance the pointer.
123 png_set_sig_bytes(png_ptr, sizeof(magic)); 140 png_set_sig_bytes(png_ptr, sizeof(magic));
124 141
125 // Read the PNG header information. 142 // Read the PNG header information.
126 png_uint_32 png_width = 0; 143 png_uint_32 png_width = 0;
127 png_uint_32 png_height = 0; 144 png_uint_32 png_height = 0;
128 int png_color_type = 0; 145 int png_color_type = 0;
129 int png_interlace_type = 0; 146 int png_interlace_type = 0;
130 int png_bits_per_channel = 0; 147 int png_bits_per_channel = 0;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 273
257 // Success. 274 // Success.
258 image_data_.swap(image_data); 275 image_data_.swap(image_data);
259 format_ = format; 276 format_ = format;
260 width_ = png_width; 277 width_ = png_width;
261 height_ = png_height; 278 height_ = png_height;
262 num_mipmaps_ = num_mipmaps; 279 num_mipmaps_ = num_mipmaps;
263 return true; 280 return true;
264 } 281 }
265 282
266 // Saves the BGRA data from a compressed PNG file. 283 namespace {
267 bool Bitmap::SaveToPNGFile(const char* filename) { 284
268 if (format_ != Texture::ARGB8) { 285 bool CreatePNGInUInt8Vector(const Bitmap& bitmap, std::vector<uint8>* buffer) {
269 DLOG(ERROR) << "Can only save ARGB8 images."; 286 DCHECK(bitmap.format() == Texture::ARGB8);
270 return false; 287 DCHECK(bitmap.num_mipmaps() == 1);
271 } 288 DCHECK(!bitmap.is_cubemap());
272 if (num_mipmaps_ != 1 || is_cubemap_) {
273 DLOG(ERROR) << "Only 2D images with only the base level can be saved.";
274 return false;
275 }
276 FILE *fp = fopen(filename, "wb");
277 if (!fp) {
278 DLOG(ERROR) << "Could not open file " << filename << " for writing.";
279 return false;
280 }
281 289
282 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, 290 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
283 NULL, NULL); 291 NULL, NULL);
284 if (!png_ptr) { 292 if (!png_ptr) {
285 DLOG(ERROR) << "Could not create PNG structure."; 293 DLOG(ERROR) << "Could not create PNG structure.";
286 fclose(fp);
287 return false; 294 return false;
288 } 295 }
289 296
290 png_infop info_ptr = png_create_info_struct(png_ptr); 297 png_infop info_ptr = png_create_info_struct(png_ptr);
291 if (!info_ptr) { 298 if (!info_ptr) {
292 DLOG(ERROR) << "Could not create PNG info structure."; 299 DLOG(ERROR) << "Could not create PNG info structure.";
293 png_destroy_write_struct(&png_ptr, png_infopp_NULL); 300 png_destroy_write_struct(&png_ptr, png_infopp_NULL);
294 fclose(fp);
295 return false; 301 return false;
296 } 302 }
297 303
298 scoped_array<png_bytep> row_pointers(new png_bytep[height_]); 304 unsigned width = bitmap.width();
299 for (int i = 0; i < height_; ++i) { 305 unsigned height = bitmap.height();
300 row_pointers[height_-1-i] = image_data_.get() + i * width_ * 4; 306 scoped_array<png_bytep> row_pointers(new png_bytep[height]);
307 for (int i = 0; i < height; ++i) {
308 row_pointers[height - 1 - i] = bitmap.GetMipData(0) + i * width * 4;
301 } 309 }
302 310
303 if (setjmp(png_jmpbuf(png_ptr))) { 311 if (setjmp(png_jmpbuf(png_ptr))) {
304 // If we get here, we had a problem reading the file. 312 // If we get here, we had a problem reading the file.
305 DLOG(ERROR) << "Error while writing file " << filename << "."; 313 DLOG(ERROR) << "Error while getting dataURL.";
306 png_destroy_write_struct(&png_ptr, &info_ptr); 314 png_destroy_write_struct(&png_ptr, &info_ptr);
307 fclose(fp);
308 return false; 315 return false;
309 } 316 }
310 317
311 png_init_io(png_ptr, fp); 318 // Set up our STL stream output.
319 png_set_write_fn(png_ptr, buffer, &StreamWriteData, &StreamFlush);
312 320
313 png_set_IHDR(png_ptr, info_ptr, width_, height_, 8, 321 png_set_IHDR(png_ptr, info_ptr, width, height, 8,
314 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, 322 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
315 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 323 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
316 png_set_bgr(png_ptr); 324 png_set_bgr(png_ptr);
317 png_set_rows(png_ptr, info_ptr, row_pointers.get()); 325 png_set_rows(png_ptr, info_ptr, row_pointers.get());
318 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL); 326 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL);
319 327
320 png_destroy_write_struct(&png_ptr, &info_ptr); 328 png_destroy_write_struct(&png_ptr, &info_ptr);
321 fclose(fp); 329 }
322 return true; 330
331 } // anonymous namespace
332
333 String Bitmap::ToDataURL() {
334 if (format_ != Texture::ARGB8) {
335 O3D_ERROR(service_locator()) << "Can only get data URL from ARGB8 images.";
336 return dataurl::kEmptyDataURL;
337 }
338 if (num_mipmaps_ != 1 || is_cubemap_) {
339 O3D_ERROR(service_locator()) <<
340 "Can only get data URL from 2d images with no mips.";
341 return dataurl::kEmptyDataURL;
342 }
343
344 std::vector<uint8> stream;
345 if (!CreatePNGInUInt8Vector(*this, &stream)) {
346 return dataurl::kEmptyDataURL;
347 }
348
349 return dataurl::ToDataURL("image/png", &stream[0], stream.size());
323 } 350 }
324 351
325 } // namespace o3d 352 } // namespace o3d
OLDNEW
« no previous file with comments | « core/cross/bitmap.cc ('k') | core/cross/client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698