Esempio n. 1
0
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);
}