mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-06 01:26:22 +00:00
Everywhere: Hoist the Libraries folder to the top-level
This commit is contained in:
parent
950e819ee7
commit
93712b24bf
Notes:
github-actions[bot]
2024-11-10 11:51:52 +00:00
Author: https://github.com/trflynn89
Commit: 93712b24bf
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2256
Reviewed-by: https://github.com/sideshowbarker
4547 changed files with 104 additions and 113 deletions
113
Libraries/LibGfx/ImageFormats/JPEGWriter.cpp
Normal file
113
Libraries/LibGfx/ImageFormats/JPEGWriter.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Lucas Chollet <lucas.chollet@serenityos.org>
|
||||
* Copyright (c) 2024, Andreas Kling <andreas@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Stream.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/CMYKBitmap.h>
|
||||
#include <LibGfx/ImageFormats/JPEGWriter.h>
|
||||
#include <jpeglib.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
struct MemoryDestinationManager : public jpeg_destination_mgr {
|
||||
Vector<u8>& buffer;
|
||||
static constexpr size_t BUFFER_SIZE_INCREMENT = 65536;
|
||||
|
||||
MemoryDestinationManager(Vector<u8>& buffer)
|
||||
: buffer(buffer)
|
||||
{
|
||||
init_destination = [](j_compress_ptr cinfo) {
|
||||
auto* dest = static_cast<MemoryDestinationManager*>(cinfo->dest);
|
||||
dest->buffer.resize(BUFFER_SIZE_INCREMENT);
|
||||
dest->next_output_byte = dest->buffer.data();
|
||||
dest->free_in_buffer = dest->buffer.capacity();
|
||||
};
|
||||
|
||||
empty_output_buffer = [](j_compress_ptr cinfo) -> boolean {
|
||||
auto* dest = static_cast<MemoryDestinationManager*>(cinfo->dest);
|
||||
size_t old_size = dest->buffer.size();
|
||||
dest->buffer.resize(old_size + BUFFER_SIZE_INCREMENT);
|
||||
dest->next_output_byte = dest->buffer.data() + old_size;
|
||||
dest->free_in_buffer = BUFFER_SIZE_INCREMENT;
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
term_destination = [](j_compress_ptr cinfo) {
|
||||
auto* dest = static_cast<MemoryDestinationManager*>(cinfo->dest);
|
||||
dest->buffer.resize(dest->buffer.size() - dest->free_in_buffer);
|
||||
};
|
||||
|
||||
next_output_byte = nullptr;
|
||||
free_in_buffer = 0;
|
||||
}
|
||||
};
|
||||
|
||||
ErrorOr<void> JPEGWriter::encode_impl(Stream& stream, auto const& bitmap, Options const& options, ColorSpace color_space)
|
||||
{
|
||||
struct jpeg_compress_struct cinfo { };
|
||||
struct jpeg_error_mgr jerr { };
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
Vector<u8> buffer;
|
||||
MemoryDestinationManager dest_manager(buffer);
|
||||
cinfo.dest = &dest_manager;
|
||||
|
||||
cinfo.image_width = bitmap.size().width();
|
||||
cinfo.image_height = bitmap.size().height();
|
||||
cinfo.input_components = 4;
|
||||
|
||||
switch (color_space) {
|
||||
case ColorSpace::RGB:
|
||||
cinfo.in_color_space = JCS_EXT_BGRX;
|
||||
break;
|
||||
case ColorSpace::CMYK:
|
||||
cinfo.in_color_space = JCS_CMYK;
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_colorspace(&cinfo, JCS_YCbCr);
|
||||
jpeg_set_quality(&cinfo, options.quality, TRUE);
|
||||
|
||||
if (options.icc_data.has_value()) {
|
||||
jpeg_write_icc_profile(&cinfo, options.icc_data->data(), options.icc_data->size());
|
||||
}
|
||||
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
Vector<JSAMPLE> row_buffer;
|
||||
row_buffer.resize(bitmap.size().width() * 4);
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height) {
|
||||
auto const* row_ptr = reinterpret_cast<u8 const*>(bitmap.scanline(cinfo.next_scanline));
|
||||
JSAMPROW row_pointer = const_cast<JSAMPROW>(row_ptr);
|
||||
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
TRY(stream.write_until_depleted(buffer));
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> JPEGWriter::encode(Stream& stream, Bitmap const& bitmap, Options const& options)
|
||||
{
|
||||
return encode_impl(stream, bitmap, options, ColorSpace::RGB);
|
||||
}
|
||||
|
||||
ErrorOr<void> JPEGWriter::encode(Stream& stream, CMYKBitmap const& bitmap, Options const& options)
|
||||
{
|
||||
return encode_impl(stream, bitmap, options, ColorSpace::CMYK);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue