libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

mmap.cc (4010B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #include "mmap.h"
      7 
      8 #include <cstdint>
      9 #include <memory>
     10 
     11 #include "lib/jxl/base/common.h"
     12 
     13 #if defined(__unix__) || defined(__unix) || \
     14     defined(__APPLE__) && defined(__MACH__)
     15 #include <fcntl.h>
     16 #include <sys/mman.h>
     17 #include <unistd.h>
     18 
     19 namespace jxl {
     20 
     21 struct MemoryMappedFileImpl {
     22   static StatusOr<std::unique_ptr<MemoryMappedFileImpl>> Init(
     23       const char* path) {
     24     auto f = make_unique<MemoryMappedFileImpl>();
     25     f->fd = open(path, O_RDONLY);
     26     if (f->fd == -1) {
     27       return JXL_FAILURE("Cannot open file %s", path);
     28     }
     29     f->mmap_len = lseek(f->fd, 0, SEEK_END);
     30     lseek(f->fd, 0, SEEK_SET);
     31 
     32     f->ptr = mmap(nullptr, f->mmap_len, PROT_READ, MAP_SHARED, f->fd, 0);
     33     if (f->ptr == MAP_FAILED) {
     34       return JXL_FAILURE("mmap failure");
     35     }
     36     return f;
     37   }
     38 
     39   const uint8_t* data() const { return reinterpret_cast<const uint8_t*>(ptr); }
     40   size_t size() const { return mmap_len; }
     41 
     42   ~MemoryMappedFileImpl() {
     43     if (fd != -1) {
     44       close(fd);
     45     }
     46     if (ptr != nullptr) {
     47       munmap(ptr, mmap_len);
     48     }
     49   }
     50 
     51   int fd = -1;
     52   size_t mmap_len = 0;
     53   void* ptr = nullptr;
     54 };
     55 
     56 }  // namespace jxl
     57 
     58 #elif defined(_WIN32)
     59 #include <string.h>
     60 #include <windows.h>
     61 
     62 namespace {
     63 
     64 struct HandleDeleter {
     65   void operator()(const HANDLE handle) const {
     66     if (handle != INVALID_HANDLE_VALUE) {
     67       CloseHandle(handle);
     68     }
     69   }
     70 };
     71 using HandleUniquePtr =
     72     std::unique_ptr<std::remove_pointer<HANDLE>::type, HandleDeleter>;
     73 
     74 }  // namespace
     75 
     76 namespace jxl {
     77 
     78 struct MemoryMappedFileImpl {
     79   static StatusOr<std::unique_ptr<MemoryMappedFileImpl>> Init(
     80       const char* path) {
     81     auto f = make_unique<MemoryMappedFileImpl>();
     82     std::wstring stemp = std::wstring(path, path + strlen(path));
     83     f->handle.reset(CreateFileW(stemp.c_str(), GENERIC_READ, FILE_SHARE_READ,
     84                                 nullptr, OPEN_EXISTING,
     85                                 FILE_FLAG_SEQUENTIAL_SCAN, nullptr));
     86     if (f->handle.get() == INVALID_HANDLE_VALUE) {
     87       return JXL_FAILURE("Cannot open file %s", path);
     88     }
     89     if (!GetFileSizeEx(f->handle.get(), &f->fsize)) {
     90       return JXL_FAILURE("Cannot get file size (%s)", path);
     91     }
     92     f->handle_mapping.reset(CreateFileMappingW(f->handle.get(), nullptr,
     93                                                PAGE_READONLY, 0, 0, nullptr));
     94     if (f->handle_mapping == nullptr) {
     95       return JXL_FAILURE("Cannot create memory mapping (%s)", path);
     96     }
     97     f->ptr = MapViewOfFile(f->handle_mapping.get(), FILE_MAP_READ, 0, 0, 0);
     98     return f;
     99   }
    100 
    101   ~MemoryMappedFileImpl() { UnmapViewOfFile(ptr); }
    102 
    103   const uint8_t* data() const { return reinterpret_cast<const uint8_t*>(ptr); }
    104   size_t size() const { return fsize.QuadPart; }
    105 
    106   HandleUniquePtr handle;
    107   HandleUniquePtr handle_mapping;
    108   LARGE_INTEGER fsize;
    109   void* ptr = nullptr;
    110 };
    111 
    112 }  // namespace jxl
    113 
    114 #else
    115 
    116 namespace jxl {
    117 
    118 struct MemoryMappedFileImpl {
    119   static StatusOr<std::unique_ptr<MemoryMappedFileImpl>> Init(
    120       const char* path) {
    121     return JXL_FAILURE("Memory mapping not supported on this system");
    122   }
    123 
    124   const uint8_t* data() const { return nullptr; }
    125   size_t size() const { return 0; }
    126 };
    127 
    128 }  // namespace jxl
    129 
    130 #endif
    131 
    132 namespace jxl {
    133 
    134 StatusOr<MemoryMappedFile> MemoryMappedFile::Init(const char* path) {
    135   JXL_ASSIGN_OR_RETURN(auto mmf, MemoryMappedFileImpl::Init(path));
    136   MemoryMappedFile ret;
    137   ret.impl_ = std::move(mmf);
    138   return ret;
    139 }
    140 
    141 MemoryMappedFile::MemoryMappedFile() = default;
    142 MemoryMappedFile::~MemoryMappedFile() = default;
    143 MemoryMappedFile::MemoryMappedFile(MemoryMappedFile&&) noexcept = default;
    144 MemoryMappedFile& MemoryMappedFile::operator=(MemoryMappedFile&&) noexcept =
    145     default;
    146 
    147 const uint8_t* MemoryMappedFile::data() const { return impl_->data(); }
    148 size_t MemoryMappedFile::size() const { return impl_->size(); }
    149 }  // namespace jxl