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

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
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 // TODO(gman): Use the one in chrome or skia or some other place this function
267 bool Bitmap::SaveToPNGFile(const char* filename) { 284 // is implemented.
apatrick 2009/08/07 18:25:45 isn't this also in core/cross/base64.cc
gman 2009/08/07 21:34:31 doh, forgot to delete this. Done
285 namespace {
286
287 const int kEncodePad = 64;
288
289 const char kEncode[] =
290 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
291 "abcdefghijklmnopqrstuvwxyz"
292 "0123456789+/=";
293
294 size_t GetBase64EncodeLength(size_t length) {
295 return (length + 2) / 3 * 4;
296 }
297
298 size_t Base64Encode(const void* srcPtr, size_t length, void* dstPtr) {
apatrick 2009/08/07 18:25:45 src_ptr, dst_ptr
gman 2009/08/07 21:34:31 Done.
299 const uint8* src = (const uint8*) srcPtr;
300 uint8* dst = (uint8*) dstPtr;
301 if (dst) {
302 size_t remainder = length % 3;
303 const uint8* end = &src[length - remainder];
304 while (src < end) {
305 unsigned a = *src++;
306 unsigned b = *src++;
307 unsigned c = *src++;
308 unsigned d = c & 0x3F;
309 c = (c >> 6 | b << 2) & 0x3F;
310 b = (b >> 4 | a << 4) & 0x3F;
311 a = a >> 2;
312 *dst++ = kEncode[a];
313 *dst++ = kEncode[b];
314 *dst++ = kEncode[c];
315 *dst++ = kEncode[d];
316 }
317 if (remainder > 0) {
318 unsigned k1 = 0;
319 unsigned k2 = kEncodePad;
320 unsigned a = (uint8) *src++;
321 if (remainder == 2)
322 {
323 int b = *src++;
324 k1 = b >> 4;
325 k2 = (b << 2) & 0x3F;
326 }
327 *dst++ = kEncode[a >> 2];
328 *dst++ = kEncode[(k1 | a << 4) & 0x3F];
329 *dst++ = kEncode[k2];
330 *dst++ = kEncode[kEncodePad];
331 }
332 }
333 return GetBase64EncodeLength(length);
334 }
335
336 } // anonymous namespace
337
338 String Bitmap::ToDataURL() {
268 if (format_ != Texture::ARGB8) { 339 if (format_ != Texture::ARGB8) {
269 DLOG(ERROR) << "Can only save ARGB8 images."; 340 O3D_ERROR(service_locator()) << "Can only get data URL from ARGB8 images.";
270 return false; 341 return String("data:,");
apatrick 2009/08/07 18:25:45 Could these refer to a constant for empty data url
gman 2009/08/07 21:34:31 strange. for some reason this didn't get uploaded
271 } 342 }
272 if (num_mipmaps_ != 1 || is_cubemap_) { 343 if (num_mipmaps_ != 1 || is_cubemap_) {
273 DLOG(ERROR) << "Only 2D images with only the base level can be saved."; 344 O3D_ERROR(service_locator()) <<
274 return false; 345 "Can only get data URL from images with no mips.";
275 } 346 return String("data:,");
276 FILE *fp = fopen(filename, "wb");
277 if (!fp) {
278 DLOG(ERROR) << "Could not open file " << filename << " for writing.";
279 return false;
280 } 347 }
281 348
282 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, 349 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
283 NULL, NULL); 350 NULL, NULL);
284 if (!png_ptr) { 351 if (!png_ptr) {
285 DLOG(ERROR) << "Could not create PNG structure."; 352 DLOG(ERROR) << "Could not create PNG structure.";
286 fclose(fp); 353 return String("data:,");
287 return false;
288 } 354 }
289 355
290 png_infop info_ptr = png_create_info_struct(png_ptr); 356 png_infop info_ptr = png_create_info_struct(png_ptr);
291 if (!info_ptr) { 357 if (!info_ptr) {
292 DLOG(ERROR) << "Could not create PNG info structure."; 358 DLOG(ERROR) << "Could not create PNG info structure.";
293 png_destroy_write_struct(&png_ptr, png_infopp_NULL); 359 png_destroy_write_struct(&png_ptr, png_infopp_NULL);
294 fclose(fp); 360 return String("data:,");
295 return false;
296 } 361 }
297 362
298 scoped_array<png_bytep> row_pointers(new png_bytep[height_]); 363 scoped_array<png_bytep> row_pointers(new png_bytep[height_]);
299 for (int i = 0; i < height_; ++i) { 364 for (int i = 0; i < height_; ++i) {
300 row_pointers[height_-1-i] = image_data_.get() + i * width_ * 4; 365 row_pointers[height_-1-i] = image_data_.get() + i * width_ * 4;
301 } 366 }
302 367
303 if (setjmp(png_jmpbuf(png_ptr))) { 368 if (setjmp(png_jmpbuf(png_ptr))) {
apatrick 2009/08/07 18:25:45 setjmp messes up invocation of constructors and de
piman 2009/08/07 19:04:32 setjmp/longjmp are unfortunately the standard way
gman 2009/08/07 21:34:31 I put it in another function and hope that's enoug
304 // If we get here, we had a problem reading the file. 369 // If we get here, we had a problem reading the file.
305 DLOG(ERROR) << "Error while writing file " << filename << "."; 370 DLOG(ERROR) << "Error while getting dataURL.";
306 png_destroy_write_struct(&png_ptr, &info_ptr); 371 png_destroy_write_struct(&png_ptr, &info_ptr);
307 fclose(fp); 372 return String("data:,");
308 return false;
309 } 373 }
310 374
311 png_init_io(png_ptr, fp); 375 // Set up our STL stream output.
376 std::vector<uint8> stream;
377 png_set_write_fn(png_ptr, &stream, &StreamWriteData, &StreamFlush);
312 378
313 png_set_IHDR(png_ptr, info_ptr, width_, height_, 8, 379 png_set_IHDR(png_ptr, info_ptr, width_, height_, 8,
314 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, 380 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
315 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 381 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
316 png_set_bgr(png_ptr); 382 png_set_bgr(png_ptr);
317 png_set_rows(png_ptr, info_ptr, row_pointers.get()); 383 png_set_rows(png_ptr, info_ptr, row_pointers.get());
318 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL); 384 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL);
319 385
320 png_destroy_write_struct(&png_ptr, &info_ptr); 386 png_destroy_write_struct(&png_ptr, &info_ptr);
321 fclose(fp); 387
322 return true; 388 return dataurl::ToDataURL("image/png", &stream[0], stream.size());
323 } 389 }
324 390
325 } // namespace o3d 391 } // namespace o3d
OLDNEW
« no previous file with comments | « core/cross/bitmap.cc ('k') | core/cross/client.h » ('j') | core/win/d3d9/renderer_d3d9.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698