示例#1
0
文件: BitmapIO.cpp 项目: Virolea/gosu
void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, Gosu::Writer writer,
    const std::wstring& formatHint)
{
    unsigned char* rgba =
        const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(bitmap.data()));
    
    // TODO: Use the new *_to_func functions in stb_imagewrite.h instead:
    // https://github.com/nothings/stb/blob/master/stb_image_write.h#L39
    int length;
    unsigned char* png =
        stbi_write_png_to_mem(rgba, 0, bitmap.width(), bitmap.height(), 4, &length);
    
    if (png == 0)
        throw std::runtime_error("Could not save image data to memory");
    
    try
    {
        writer.write(png, length);
    }
    catch (...)
    {
        STBIW_FREE(png);
        throw;
    }
    
    STBIW_FREE(png);
}
示例#2
0
文件: BitmapIO.cpp 项目: johan--/gosu
void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, Gosu::Writer writer,
    const std::wstring& formatHint)
{
    unsigned char* rgba =
        const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(bitmap.data()));
    
    int length;
    unsigned char* png =
        stbi_write_png_to_mem(rgba, 0, bitmap.width(), bitmap.height(), 4, &length);
    
    if (png == 0)
        throw std::runtime_error("Could not save image data to memory");
    
    try
    {
        writer.write(png, length);
    }
    catch (...)
    {
        STBIW_FREE(png);
        throw;
    }
    
    STBIW_FREE(png);
}
Containers::Array<char> StbPngImageConverter::doExportToData(const ImageView2D& image) {
    #ifndef MAGNUM_TARGET_GLES
    if(image.storage().swapBytes()) {
        Error() << "Trade::StbPngImageConverter::exportToData(): pixel byte swap is not supported";
        return nullptr;
    }
    #endif

    if(image.type() != PixelType::UnsignedByte) {
        Error() << "Trade::StbPngImageConverter::exportToData(): unsupported pixel type" << image.type();
        return nullptr;
    }

    Int components;
    switch(image.format()) {
        #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
        case PixelFormat::Red:
        #endif
        #ifdef MAGNUM_TARGET_GLES2
        case PixelFormat::Luminance:
        #endif
            components = 1;
            break;
        #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
        case PixelFormat::RG:
        #endif
        #ifdef MAGNUM_TARGET_GLES2
        case PixelFormat::LuminanceAlpha:
        #endif
            components = 2;
            break;
        case PixelFormat::RGB: components = 3; break;
        case PixelFormat::RGBA: components = 4; break;
        default:
            Error() << "Trade::StbPngImageConverter::exportToData(): unsupported pixel format" << image.format();
            return nullptr;
    }

    /* Data properties */
    std::size_t offset;
    Math::Vector2<std::size_t> dataSize;
    std::tie(offset, dataSize, std::ignore) = image.dataProperties();

    /* Reverse rows in image data */
    Containers::Array<unsigned char> reversedData{image.data().size()};
    for(Int y = 0; y != image.size().y(); ++y) {
        std::copy(image.data<unsigned char>() + offset + y*dataSize.x(), image.data<unsigned char>() + offset + (y + 1)*dataSize.x(), reversedData + (image.size().y() - y - 1)*dataSize.x());
    }

    Int size;
    unsigned char* const data = stbi_write_png_to_mem(reversedData, dataSize.x(), image.size().x(), image.size().y(), components, &size);
    CORRADE_INTERNAL_ASSERT(data);

    /* Wrap the data in an array with custom deleter (we can't use delete[]) */
    Containers::Array<char> fileData{reinterpret_cast<char*>(data), std::size_t(size),
        [](char* data, std::size_t) { std::free(data); }};

    return fileData;
}
示例#4
0
文件: gtk.c 项目: baloo79/uTox
static void ugtk_openavatarthread(void *UNUSED(args)) {
    void *dialog =
        utoxGTK_file_chooser_dialog_new((const char *)S(SELECT_AVATAR_TITLE), NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
                                        "_Cancel", GTK_RESPONSE_CANCEL, "_Open", GTK_RESPONSE_ACCEPT, NULL);
    void *filter = utoxGTK_file_filter_new();
    utoxGTK_file_filter_add_mime_type(filter, "image/jpeg");
    utoxGTK_file_filter_add_mime_type(filter, "image/png");
    utoxGTK_file_filter_add_mime_type(filter, "image/bmp");
    utoxGTK_file_filter_add_mime_type(filter, "image/gif");
    utoxGTK_file_chooser_set_filter(dialog, filter);

    void *preview = utoxGTK_image_new();
    utoxGTK_file_chooser_set_preview_widget(dialog, preview);
    utoxGTK_signal_connect_data(dialog, "update-preview", update_image_preview, preview, NULL, 0);

    while (utoxGTK_dialog_run(dialog) == GTK_RESPONSE_ACCEPT) {
        char *filename = utoxGTK_file_chooser_get_filename(dialog);
        int   size;

        int      width, height, bpp;
        uint8_t *img       = stbi_load(filename, &width, &height, &bpp, 0);
        uint8_t *file_data = stbi_write_png_to_mem(img, 0, width, height, bpp, &size);
        free(img);

        utoxGTK_free(filename);
        if (!file_data) {
            void *message_dialog = utoxGTK_message_dialog_new(dialog, 0, 1, 2, (const char *)S(CANT_FIND_FILE_OR_EMPTY));
            utoxGTK_dialog_run(message_dialog);
            utoxGTK_widget_destroy(message_dialog);
        } else if (size > UTOX_AVATAR_MAX_DATA_LENGTH) {
            free(file_data);
            char size_str[16];
            int  len          = sprint_humanread_bytes(size_str, sizeof(size_str), UTOX_AVATAR_MAX_DATA_LENGTH);
            char err_str[265] = { 0 };
            snprintf((char *)err_str, 265, "%s%.*s (%ikb loaded)", S(AVATAR_TOO_LARGE_MAX_SIZE_IS), len, size_str,
                     (size / 1024));
            void *message_dialog = utoxGTK_message_dialog_new(dialog, 0, 1, 2, err_str);
            utoxGTK_dialog_run(message_dialog);
            utoxGTK_widget_destroy(message_dialog);
        } else {
            postmessage_utox(SELF_AVATAR_SET, size, 0, file_data);
            break;
        }
    }

    utoxGTK_widget_destroy(dialog);
    while (utoxGTK_events_pending()) {
        utoxGTK_main_iteration();
    }

    utoxGTK_open = false;
}
示例#5
0
    //---------------------------------------------------------------------
    DataStreamPtr STBIImageCodec::encode(MemoryDataStreamPtr& input, Codec::CodecDataPtr& pData) const
    {
        if(mType != "png") {
            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                        "currently only encoding to PNG supported",
                        "STBIImageCodec::encode" ) ;
        }

        ImageData* pImgData = static_cast<ImageData*>(pData.getPointer());
        int channels = PixelUtil::getComponentCount(pImgData->format);

        int len;
        uchar *data = stbi_write_png_to_mem(input->getPtr(), pImgData->width*channels,
                pImgData->width, pImgData->height, channels, &len);

        if (!data) {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                "Error encoding image: " + String(stbi_failure_reason()),
                "STBIImageCodec::encode");
        }

        return DataStreamPtr(new MemoryDataStream(data, len, true));
    }
Containers::Array<char> StbPngImageConverter::doExportToData(const ImageReference2D& image) const {
    if(image.type() != ColorType::UnsignedByte) {
        Error() << "Trade::StbPngImageConverter::exportToData(): unsupported color type" << image.type();
        return nullptr;
    }

    Int components;
    switch(image.format()) {
        case ColorFormat::Red: components = 1; break;
        case ColorFormat::RG: components = 2; break;
        case ColorFormat::RGB: components = 3; break;
        case ColorFormat::RGBA: components = 4; break;
        default:
            Error() << "Trade::StbPngImageConverter::exportToData(): unsupported color format" << image.format();
            return nullptr;
    }

    /* Reverse rows in image data */
    Containers::Array<unsigned char> reversedData{std::size_t(image.size().product()*components)};
    for(Int y = 0; y != image.size().y(); ++y) {
        const Int stride = image.size().x()*components;
        std::copy(image.data<unsigned char>() + y*stride, image.data<unsigned char>() + (y + 1)*stride, reversedData + (image.size().y() - y - 1)*stride);
    }

    Int size;
    unsigned char* const data = stbi_write_png_to_mem(reversedData, 0, image.size().x(), image.size().y(), components, &size);
    CORRADE_INTERNAL_ASSERT(data);

    /* Copy the data to a new[]-allocated array so we can delete[] it later,
       then delete the original data with free() */
    Containers::Array<char> fileData{std::size_t(size)};
    std::copy(data, data + size, fileData.begin());
    std::free(data);

    return fileData;
}