diff options
author | José Fonseca <jose.r.fonseca@gmail.com> | 2012-12-01 10:08:33 +0000 |
---|---|---|
committer | José Fonseca <jose.r.fonseca@gmail.com> | 2012-12-01 10:08:33 +0000 |
commit | 77373c35010d89e5ab3f030e4c60f8f6e3fdbe82 (patch) | |
tree | f62bd12820dcf0ab935301a29b5378ffd585bfdf /common | |
parent | 6e4768b0714ceb189621e75af8511629a6c8a5e4 (diff) | |
parent | 0dc18e795c47098d94447c2b8deabbf265737559 (diff) |
Merge branch 'master' into trim-auto
Diffstat (limited to 'common')
-rw-r--r-- | common/image.hpp | 18 | ||||
-rw-r--r-- | common/image_png.cpp | 171 | ||||
-rw-r--r-- | common/os.hpp | 3 | ||||
-rw-r--r-- | common/trace_tools_trace.cpp | 156 |
4 files changed, 159 insertions, 189 deletions
diff --git a/common/image.hpp b/common/image.hpp index e930512f..7dd18c12 100644 --- a/common/image.hpp +++ b/common/image.hpp @@ -94,16 +94,21 @@ public: return true; } - bool writePNG(const char *filename) const; + bool + writePNG(std::ostream &os) const; + + inline bool + writePNG(const char *filename) const { + std::ofstream os(filename, std::ofstream::binary); + if (!os) { + return false; + } + return writePNG(os); + } double compare(Image &ref); }; -bool writePixelsToBuffer(unsigned char *pixels, - unsigned w, unsigned h, unsigned numChannels, - bool flipped, - char **buffer, - int *size); Image * readPNG(const char *filename); @@ -111,6 +116,7 @@ readPNG(const char *filename); const char * readPNMHeader(const char *buffer, size_t size, unsigned *channels, unsigned *width, unsigned *height); + } /* namespace image */ diff --git a/common/image_png.cpp b/common/image_png.cpp index cc6d3f2c..dba07d45 100644 --- a/common/image_png.cpp +++ b/common/image_png.cpp @@ -43,34 +43,20 @@ namespace image { static const int png_compression_level = Z_BEST_SPEED; +static void +pngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length) +{ + std::ostream *os = (std::ostream *) png_get_io_ptr(png_ptr); + os->write((const char *)data, length); +} + bool -Image::writePNG(const char *filename) const { - FILE *fp; +Image::writePNG(std::ostream &os) const +{ png_structp png_ptr; png_infop info_ptr; - - fp = fopen(filename, "wb"); - if (!fp) - goto no_fp; - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) - goto no_png; - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, NULL); - goto no_png; - } - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); - goto no_png; - } - - png_init_io(png_ptr, fp); - int color_type; + switch (channels) { case 4: color_type = PNG_COLOR_TYPE_RGB_ALPHA; @@ -86,11 +72,29 @@ Image::writePNG(const char *filename) const { break; default: assert(0); - return false; + goto no_png; } - png_set_IHDR(png_ptr, info_ptr, width, height, 8, color_type, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + goto no_png; + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr, NULL); + goto no_png; + } + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_write_struct(&png_ptr, &info_ptr); + goto no_png; + } + + png_set_write_fn(png_ptr, &os, pngWriteCallback, NULL); + + png_set_IHDR(png_ptr, info_ptr, width, height, 8, + color_type, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_set_compression_level(png_ptr, png_compression_level); @@ -112,12 +116,9 @@ Image::writePNG(const char *filename) const { png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); return true; no_png: - fclose(fp); -no_fp: return false; } @@ -201,115 +202,5 @@ no_fp: } -struct png_tmp_buffer -{ - char *buffer; - size_t size; -}; - -static void -pngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length) -{ - struct png_tmp_buffer *buf = (struct png_tmp_buffer*) png_get_io_ptr(png_ptr); - size_t nsize = buf->size + length; - - /* allocate or grow buffer */ - if (buf->buffer) - buf->buffer = (char*)realloc(buf->buffer, nsize); - else - buf->buffer = (char*)malloc(nsize); - - if (!buf->buffer) - png_error(png_ptr, "Buffer allocation error"); - - memcpy(buf->buffer + buf->size, data, length); - buf->size += length; -} - -bool writePixelsToBuffer(unsigned char *pixels, - unsigned width, unsigned height, unsigned numChannels, - bool flipped, - char **buffer, - int *size) -{ - struct png_tmp_buffer png_mem; - png_structp png_ptr; - png_infop info_ptr; - int type; - - png_mem.buffer = NULL; - png_mem.size = 0; - - switch (numChannels) { - case 4: - type = PNG_COLOR_TYPE_RGB_ALPHA; - break; - case 3: - type = PNG_COLOR_TYPE_RGB; - break; - case 2: - type = PNG_COLOR_TYPE_GRAY_ALPHA; - break; - case 1: - type = PNG_COLOR_TYPE_GRAY; - break; - default: - goto no_png; - } - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) - goto no_png; - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, NULL); - goto no_png; - } - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); - goto no_png; - } - - png_set_write_fn(png_ptr, &png_mem, pngWriteCallback, NULL); - - png_set_IHDR(png_ptr, info_ptr, width, height, 8, - type, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - png_set_compression_level(png_ptr, png_compression_level); - - png_write_info(png_ptr, info_ptr); - - if (!flipped) { - for (unsigned y = 0; y < height; ++y) { - png_bytep row = (png_bytep)(pixels + y*width*numChannels); - png_write_rows(png_ptr, &row, 1); - } - } else { - unsigned y = height; - while (y--) { - png_bytep row = (png_bytep)(pixels + y*width*numChannels); - png_write_rows(png_ptr, &row, 1); - } - } - - png_write_end(png_ptr, info_ptr); - png_destroy_write_struct(&png_ptr, &info_ptr); - - *buffer = png_mem.buffer; - *size = png_mem.size; - - return true; - -no_png: - *buffer = NULL; - *size = 0; - - if (png_mem.buffer) - free(png_mem.buffer); - return false; -} } /* namespace image */ diff --git a/common/os.hpp b/common/os.hpp index cc72a0ea..91c819fc 100644 --- a/common/os.hpp +++ b/common/os.hpp @@ -42,6 +42,9 @@ #ifndef vsnprintf #define vsnprintf _vsnprintf #endif +#ifndef strcasecmp +#define strcasecmp stricmp +#endif #endif /* !_WIN32 */ namespace os { diff --git a/common/trace_tools_trace.cpp b/common/trace_tools_trace.cpp index 387e2e25..4c0082d7 100644 --- a/common/trace_tools_trace.cpp +++ b/common/trace_tools_trace.cpp @@ -52,13 +52,83 @@ namespace trace { #endif +static inline bool +copyWrapper(const os::String & wrapperPath, + const char *programPath, + bool verbose) +{ + os::String wrapperFilename(wrapperPath); + wrapperFilename.trimDirectory(); + + os::String tmpWrapper(programPath); + tmpWrapper.trimFilename(); + tmpWrapper.join(wrapperFilename); + + if (verbose) { + std::cerr << wrapperPath << " -> " << tmpWrapper << "\n"; + } + + if (tmpWrapper.exists()) { + std::cerr << "error: not overwriting " << tmpWrapper << "\n"; + return false; + } + + if (!os::copyFile(wrapperPath, tmpWrapper, false)) { + std::cerr << "error: failed to copy " << wrapperPath << " into " << tmpWrapper << "\n"; + return false; + } + + return true; +} + + +static const char *glWrappers[] = { + GL_TRACE_WRAPPER, + NULL +}; + +#ifdef EGL_TRACE_WRAPPER +static const char *eglWrappers[] = { + EGL_TRACE_WRAPPER, + NULL +}; +#endif + +#ifdef _WIN32 +static const char *d3d7Wrappers[] = { + "ddraw.dll", + NULL +}; + +static const char *d3d8Wrappers[] = { + "d3d8.dll", + NULL +}; + +static const char *d3d9Wrappers[] = { + "d3d9.dll", + NULL +}; + +static const char *dxgiWrappers[] = { + "dxgitrace.dll", + //"dxgi.dll", + "d3d10.dll", + "d3d10_1.dll", + "d3d11.dll", + NULL +}; +#endif + int traceProgram(API api, char * const *argv, const char *output, bool verbose) { - const char *wrapperFilename; + const char **wrapperFilenames; + unsigned numWrappers; + int status = 1; /* * TODO: simplify code @@ -66,31 +136,27 @@ traceProgram(API api, switch (api) { case API_GL: - wrapperFilename = GL_TRACE_WRAPPER; + wrapperFilenames = glWrappers; break; #ifdef EGL_TRACE_WRAPPER case API_EGL: - wrapperFilename = EGL_TRACE_WRAPPER; + wrapperFilenames = eglWrappers; break; #endif #ifdef _WIN32 case API_D3D7: - wrapperFilename = "ddraw.dll"; + wrapperFilenames = d3d7Wrappers; break; case API_D3D8: - wrapperFilename = "d3d8.dll"; + wrapperFilenames = d3d8Wrappers; break; case API_D3D9: - wrapperFilename = "d3d9.dll"; + wrapperFilenames = d3d9Wrappers; break; case API_D3D10: - wrapperFilename = "d3d10.dll"; - break; case API_D3D10_1: - wrapperFilename = "d3d10_1.dll"; - break; case API_D3D11: - wrapperFilename = "d3d11.dll"; + wrapperFilenames = dxgiWrappers; break; #endif default: @@ -98,48 +164,45 @@ traceProgram(API api, return 1; } - os::String wrapperPath = findWrapper(wrapperFilename); - - if (!wrapperPath.length()) { - std::cerr << "error: failed to find " << wrapperFilename << "\n"; - return 1; + numWrappers = 0; + while (wrapperFilenames[numWrappers]) { + ++numWrappers; } -#if defined(_WIN32) - /* On Windows copy the wrapper to the program directory. - */ - os::String tmpWrapper(argv[0]); - tmpWrapper.trimFilename(); - tmpWrapper.join(wrapperFilename); + unsigned i; + for (i = 0; i < numWrappers; ++i) { + const char *wrapperFilename = wrapperFilenames[i]; - if (verbose) { - std::cerr << wrapperPath << " -> " << tmpWrapper << "\n"; - } + os::String wrapperPath = findWrapper(wrapperFilename); - if (tmpWrapper.exists()) { - std::cerr << "error: not overwriting " << tmpWrapper << "\n"; - return 1; - } + if (!wrapperPath.length()) { + std::cerr << "error: failed to find " << wrapperFilename << "\n"; + goto exit; + } - if (!os::copyFile(wrapperPath, tmpWrapper, false)) { - std::cerr << "error: failed to copy " << wrapperPath << " into " << tmpWrapper << "\n"; - return 1; - } +#if defined(_WIN32) + /* On Windows copy the wrapper to the program directory. + */ + if (!copyWrapper(wrapperPath, argv[0], verbose)) { + goto exit; + } #endif /* _WIN32 */ #if defined(__APPLE__) - /* On Mac OS X, using DYLD_LIBRARY_PATH, we actually set the - * directory, not the file. */ - wrapperPath.trimFilename(); + /* On Mac OS X, using DYLD_LIBRARY_PATH, we actually set the + * directory, not the file. */ + wrapperPath.trimFilename(); #endif #if defined(TRACE_VARIABLE) - if (verbose) { - std::cerr << TRACE_VARIABLE << "=" << wrapperPath.str() << "\n"; - } - /* FIXME: Don't modify the current environment */ - os::setEnvironment(TRACE_VARIABLE, wrapperPath.str()); + assert(numWrappers == 1); + if (verbose) { + std::cerr << TRACE_VARIABLE << "=" << wrapperPath.str() << "\n"; + } + /* FIXME: Don't modify the current environment */ + os::setEnvironment(TRACE_VARIABLE, wrapperPath.str()); #endif /* TRACE_VARIABLE */ + } if (output) { os::setEnvironment("TRACE_FILE", output); @@ -154,13 +217,20 @@ traceProgram(API api, std::cerr << "\n"; } - int status = os::execute(argv); + status = os::execute(argv); +exit: #if defined(TRACE_VARIABLE) os::unsetEnvironment(TRACE_VARIABLE); #endif #if defined(_WIN32) - os::removeFile(tmpWrapper); + for (unsigned j = 0; j < i; ++j) { + const char *wrapperFilename = wrapperFilenames[j]; + os::String tmpWrapper(argv[0]); + tmpWrapper.trimFilename(); + tmpWrapper.join(wrapperFilename); + os::removeFile(tmpWrapper); + } #endif if (output) { |