cairo_t* Image::createContext(bool adjustOrigin) const { cairo_t* c = cairo_create(_surface); if(adjustOrigin && c) { cairo_translate(c, 0.0f, getSurfaceHeight()); cairo_scale(c, 1.0f, -1.0f); } return c; }
void RawImage::writeSurfaceAsPngImage(const unsigned int surfaceIndex, const std::string & filename, const bool swizzlePixels) const { assert(!filename.empty()); assert(surfaceIndex < surfaceCount); assert(isValid()); std::ofstream outFile; if (!utils::filesys::tryOpen(outFile, filename, std::ofstream::binary)) { SiegeThrow(Exception, "Unable to open file \"" << filename << "\" for writing! " << utils::filesys::getLastFileError()); } const auto surfWidth = getSurfaceWidth(surfaceIndex); const auto surfHeight = getSurfaceHeight(surfaceIndex); auto imageData = reinterpret_cast<const uint8_t *>(getSurfacePixels(surfaceIndex)); const uint8_t * imageDataPtr; ByteArray tempImage; // Only allocated if we need to swizzle the color. if (swizzlePixels) { tempImage.resize(surfWidth * surfHeight * 4); for (unsigned int i = 0, j = 0; i < surfWidth * surfHeight; ++i) { // RGBA <=> BGRA tempImage[j++] = imageData[2]; tempImage[j++] = imageData[1]; tempImage[j++] = imageData[0]; tempImage[j++] = imageData[3]; imageData += 4; } imageDataPtr = tempImage.data(); } else { imageDataPtr = imageData; } // Create the PNG image with the help of Mini-Z. // (note: must use free() to release the returned memory!) size_t pngSize = 0; uint8_t * pngData = utils::compression::writeImageToPngInMemory(imageDataPtr, surfWidth, surfHeight, /* numChans = */ 4, &pngSize, utils::compression::Level::BestCompression, /* flip = */ true); if (pngData == nullptr) { SiegeThrow(Exception, "Failed to compress PNG image \"" << filename << "\"! Null data."); } if (pngSize == 0) { std::free(pngData); SiegeThrow(Exception, "Failed to compress PNG image \"" << filename << "\"! Zero size."); } // Dump the data to a file: if (!outFile.write(reinterpret_cast<const char *>(pngData), pngSize)) { std::free(pngData); SiegeThrow(Exception, "Failed to write image pixels to PNG file \"" << filename << "\"!"); } std::free(pngData); SiegeLog("Successfully written PNG image to file \"" + filename + "\"."); }
void RawImage::writeSurfaceAsTgaImage(const unsigned int surfaceIndex, const std::string & filename, const bool swizzlePixels) const { assert(!filename.empty()); assert(surfaceIndex < surfaceCount); assert(isValid()); std::ofstream outFile; if (!utils::filesys::tryOpen(outFile, filename, std::ofstream::binary)) { SiegeThrow(Exception, "Unable to open file \"" << filename << "\" for writing! " << utils::filesys::getLastFileError()); } const auto surfWidth = getSurfaceWidth(surfaceIndex); const auto surfHeight = getSurfaceHeight(surfaceIndex); auto imageData = reinterpret_cast<const uint8_t *>(getSurfacePixels(surfaceIndex)); struct TGAImageDescriptor { uint8_t alpha : 4; uint8_t right : 1; uint8_t top : 1; uint8_t reserved : 2; }; static_assert(sizeof(TGAImageDescriptor) == 1, "Bad TGAImageDescriptor size!"); // Always BGRA/RGBA. const TGAImageDescriptor imageDesc = {8,0,0,0}; const uint8_t tgaType = 2, bpp = 32; // Other unused fields of the TGA header: const uint8_t idLenght = 0; // unused const uint8_t hasColormap = 0; // unused const uint16_t cmFirstEntry = 0; // unused const uint16_t cmLength = 0; // unused const uint8_t cmSize = 0; // unused const uint16_t xOrigin = 0; // start at x:0 const uint16_t yOrigin = 0; // start at y:0 // Image x,y dimensions: const uint16_t dimX = static_cast<uint16_t>(surfWidth); const uint16_t dimY = static_cast<uint16_t>(surfHeight); // Write the image header fields: outFile.write(reinterpret_cast<const char *>(&idLenght), sizeof(idLenght)); outFile.write(reinterpret_cast<const char *>(&hasColormap), sizeof(hasColormap)); outFile.write(reinterpret_cast<const char *>(&tgaType), sizeof(tgaType)); outFile.write(reinterpret_cast<const char *>(&cmFirstEntry), sizeof(cmFirstEntry)); outFile.write(reinterpret_cast<const char *>(&cmLength), sizeof(cmLength)); outFile.write(reinterpret_cast<const char *>(&cmSize), sizeof(cmSize)); outFile.write(reinterpret_cast<const char *>(&xOrigin), sizeof(xOrigin)); outFile.write(reinterpret_cast<const char *>(&yOrigin), sizeof(yOrigin)); outFile.write(reinterpret_cast<const char *>(&dimX), sizeof(dimX)); outFile.write(reinterpret_cast<const char *>(&dimY), sizeof(dimY)); outFile.write(reinterpret_cast<const char *>(&bpp), sizeof(bpp)); outFile.write(reinterpret_cast<const char *>(&imageDesc), sizeof(imageDesc)); // Check for IO problems: if (outFile.fail()) { SiegeThrow(Exception, "Error while writing TGA header for file \"" << filename << "\"!"); } // Now write the pixels: if (swizzlePixels) { uint8_t pixel[4]; for (unsigned int i = 0; i < surfWidth * surfHeight; ++i) { // RGBA <=> BGRA pixel[0] = imageData[2]; pixel[1] = imageData[1]; pixel[2] = imageData[0]; pixel[3] = imageData[3]; imageData += 4; if (!outFile.write(reinterpret_cast<const char *>(pixel), sizeof(pixel))) { SiegeThrow(Exception, "Failed to write image pixels to TGA file \"" << filename << "\"!"); } } } else { // No need to swizzle pixels, write data as it is: if (!outFile.write(reinterpret_cast<const char *>(imageData), surfWidth * surfHeight * 4)) { SiegeThrow(Exception, "Failed to write image pixels to TGA file \"" << filename << "\"!"); } } SiegeLog("Successfully written TGA image to file \"" + filename + "\"."); }
unsigned int RawImage::getSurfacePixelCount(const unsigned int surfaceIndex) const { return getSurfaceWidth(surfaceIndex) * getSurfaceHeight(surfaceIndex); }