Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/sai.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ class Document : public VirtualFileSystem
// Returns (0,0) if an error has occured
std::tuple<std::uint32_t, std::uint32_t> GetCanvasSize();

// Returns (RGBA Pixel Data, Width, Height).
// Returns (BGRA Pixel Data, Width, Height).
// Returns (null,0,0) if an error has occured.
std::tuple<std::unique_ptr<std::byte[]>, std::uint32_t, std::uint32_t> GetThumbnail();

Expand Down
14 changes: 14 additions & 0 deletions samples/Thumbnail-Sai1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Sample code for extracting the thumbnail image from a user-created sai file
#include <iostream>
#include <sai.hpp>
#include <utility>
#include <algorithm>

#include "stb_image_write.h"

Expand All @@ -19,6 +20,18 @@ const char* const Help
"\tThumbnail (filename) (output)\n"
"\tWunkolo - Wunkolo@gmail.com";

void ConvertBGRA8ToRGBA8(std::span<std::byte> Pixels)
{
std::size_t i = 0;
std::size_t Count = Pixels.size();

while(i < Count)
{
std::swap<std::byte>(Pixels[i], Pixels[i + 2]);
i += 4;
}
}

int main(int argc, char* argv[])
{
if( argc < 3 )
Expand All @@ -39,6 +52,7 @@ int main(int argc, char* argv[])
Width = Height = 0;
std::unique_ptr<std::byte[]> Pixels = {};
std::tie(Pixels, Width, Height) = FileIn.GetThumbnail();
ConvertBGRA8ToRGBA8({ Pixels.get(), Width * Height * 4 });

stbi_write_png(argv[2], Width, Height, 4, Pixels.get(), 0);

Expand Down
81 changes: 39 additions & 42 deletions samples/Thumbnail-Sai2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ using ThumbnailT
= std::tuple<std::unique_ptr<std::byte[]>, std::uint32_t, std::uint32_t>;

bool IterateCanvasItem(
const std::filesystem::path& FilePath, const sai2::CanvasHeader& Header,
const std::filesystem::path& FilePath,
const std::filesystem::path& DestPath,
const sai2::CanvasHeader& Header,
const sai2::CanvasEntry& TableEntry, std::span<const std::byte> Bytes
)
{
Expand All @@ -47,10 +49,6 @@ bool IterateCanvasItem(
if( const auto JpegStream = sai2::ExtractJssfToJpeg(Bytes);
!std::get<0>(JpegStream).empty() )
{
std::filesystem::path DestPath(FilePath);
DestPath.replace_filename(FilePath.stem().string() + "-thumbnail");
DestPath.replace_extension("png");

// Decode jpeg stream
const auto JpegData = std::get<0>(JpegStream);

Expand Down Expand Up @@ -85,10 +83,6 @@ bool IterateCanvasItem(
if( auto Extracted = sai2::ExtractDpcmToBGRA(Header, Bytes);
!std::get<0>(Extracted).empty() )
{
std::filesystem::path DestPath(FilePath);
DestPath.replace_filename(FilePath.stem().string() + "-thumbnail");
DestPath.replace_extension("png");

std::vector<std::byte>& ThumbnailData = std::get<0>(Extracted);

const std::span<std::uint32_t> ThumbnailImage(
Expand Down Expand Up @@ -133,42 +127,45 @@ int main(int argc, char* argv[])
Args.emplace_back(argv[i]);
}

for( const std::string_view& Arg : Args )
if(Args.size() < 2)
{
std::puts(Arg.data());
const std::filesystem::path FilePath(Arg);
if( !(std::filesystem::exists(FilePath)
&& std::filesystem::is_regular_file(FilePath)) )
{
// Not a file
std::printf("Invalid path %s\n", Arg.data());
continue;
}
const std::uintmax_t FileSize = std::filesystem::file_size(FilePath);
std::puts("Input and output paths required.");
return EXIT_FAILURE;
}

std::ifstream File(FilePath);
std::vector<std::byte> FileData(FileSize);
const std::filesystem::path FilePath(Args[0]);
const std::filesystem::path DestPath(Args[1]);
if( !(std::filesystem::exists(FilePath)
&& std::filesystem::is_regular_file(FilePath)) )
{
// Not a file
std::printf("Invalid path %s\n", FilePath.string().c_str());
return EXIT_FAILURE;
}
const std::uintmax_t FileSize = std::filesystem::file_size(FilePath);

if( File.is_open() )
{
File.read(reinterpret_cast<char*>(FileData.data()), FileSize);
File.close();

const auto CanvasDataProc = [&FilePath](
const sai2::CanvasHeader& Header,
const sai2::CanvasEntry& TableEntry,
std::span<const std::byte> Bytes
) {
return IterateCanvasItem(FilePath, Header, TableEntry, Bytes);
};

sai2::IterateCanvasData(FileData, CanvasDataProc);
}
else
{
std::printf("Error reading file contents %s\n", Arg.data());
continue;
}
std::ifstream File(FilePath);
std::vector<std::byte> FileData(FileSize);

if( File.is_open() )
{
File.read(reinterpret_cast<char*>(FileData.data()), FileSize);
File.close();

const auto CanvasDataProc = [&FilePath, &DestPath](
const sai2::CanvasHeader& Header,
const sai2::CanvasEntry& TableEntry,
std::span<const std::byte> Bytes
) {
return IterateCanvasItem(FilePath, DestPath, Header, TableEntry, Bytes);
};

sai2::IterateCanvasData(FileData, CanvasDataProc);
}
else
{
std::printf("Error reading file contents %s\n", FilePath.string().c_str());
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
Expand Down
28 changes: 0 additions & 28 deletions source/document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@

#include <sai.hpp>

#ifdef __x86_64__
#include <immintrin.h>
#endif
namespace sai
{

Expand Down Expand Up @@ -52,31 +49,6 @@ std::tuple<std::unique_ptr<std::byte[]>, std::uint32_t, std::uint32_t> Document:

Thumbnail->Read({Pixels.get(), PixelCount * sizeof(std::uint32_t)});

#if 0
//// BGRA to RGBA
std::size_t i = 0;

//// Simd speedup, four pixels at a time
while( i < ((PixelCount * sizeof(std::uint32_t)) & ~0xF) )
{
const __m128i Swizzle
= _mm_set_epi8(15, 12, 13, 14, 11, 8, 9, 10, 7, 4, 5, 6, 3, 0, 1, 2);

__m128i QuadPixel = _mm_loadu_si128(reinterpret_cast<__m128i*>(&Pixels[i]));

QuadPixel = _mm_shuffle_epi8(QuadPixel, Swizzle);

_mm_store_si128(reinterpret_cast<__m128i*>(&Pixels[i]), QuadPixel);

i += (sizeof(std::uint32_t) * 4);
}

for( ; i < PixelCount * sizeof(std::uint32_t); i += sizeof(std::uint32_t) )
{
std::swap<std::byte>(Pixels[i], Pixels[i + 2]);
}
#endif

return std::make_tuple(std::move(Pixels), Header.Width, Header.Height);
}
return std::make_tuple(nullptr, 0, 0);
Expand Down
Loading