Team Ai
Datasetpublic

Brunobkr/llama.cpp_AlgMor24_github

ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.

sourceHugging Faceupdated 2mo agoView on Hugging Face
0likes3kdownloads
common.cc1184 linesDownload Raw Back to src
1/*!2  Copyright 2013 Lovell Fuller and others.3  SPDX-License-Identifier: Apache-2.04*/5 6#include <algorithm>7#include <cstdlib>8#include <map>9#include <mutex>10#include <queue>11#include <string>12#include <tuple>13#include <utility>14#include <vector>15 16#include <napi.h>17#include <vips/vips8>18 19#include "./common.h"20 21using vips::VImage;22 23namespace sharp {24 25  // Convenience methods to access the attributes of a Napi::Object26  bool HasAttr(Napi::Object obj, std::string attr) {27    return obj.Has(attr);28  }29  std::string AttrAsStr(Napi::Object obj, std::string attr) {30    return obj.Get(attr).As<Napi::String>();31  }32  std::string AttrAsStr(Napi::Object obj, unsigned int const attr) {33    return obj.Get(attr).As<Napi::String>();34  }35  uint32_t AttrAsUint32(Napi::Object obj, std::string attr) {36    return obj.Get(attr).As<Napi::Number>().Uint32Value();37  }38  int32_t AttrAsInt32(Napi::Object obj, std::string attr) {39    return obj.Get(attr).As<Napi::Number>().Int32Value();40  }41  int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr) {42    return obj.Get(attr).As<Napi::Number>().Int32Value();43  }44  int64_t AttrAsInt64(Napi::Object obj, std::string attr) {45    return obj.Get(attr).As<Napi::Number>().Int64Value();46  }47  double AttrAsDouble(Napi::Object obj, std::string attr) {48    return obj.Get(attr).As<Napi::Number>().DoubleValue();49  }50  double AttrAsDouble(Napi::Object obj, unsigned int const attr) {51    return obj.Get(attr).As<Napi::Number>().DoubleValue();52  }53  bool AttrAsBool(Napi::Object obj, std::string attr) {54    return obj.Get(attr).As<Napi::Boolean>().Value();55  }56  std::vector<double> AttrAsVectorOfDouble(Napi::Object obj, std::string attr) {57    Napi::Array napiArray = obj.Get(attr).As<Napi::Array>();58    std::vector<double> vectorOfDouble(napiArray.Length());59    for (unsigned int i = 0; i < napiArray.Length(); i++) {60      vectorOfDouble[i] = AttrAsDouble(napiArray, i);61    }62    return vectorOfDouble;63  }64  std::vector<int32_t> AttrAsInt32Vector(Napi::Object obj, std::string attr) {65    Napi::Array array = obj.Get(attr).As<Napi::Array>();66    std::vector<int32_t> vector(array.Length());67    for (unsigned int i = 0; i < array.Length(); i++) {68      vector[i] = AttrAsInt32(array, i);69    }70    return vector;71  }72 73  // Create an InputDescriptor instance from a Napi::Object describing an input image74  InputDescriptor* CreateInputDescriptor(Napi::Object input) {75    InputDescriptor *descriptor = new InputDescriptor;76    if (HasAttr(input, "file")) {77      descriptor->file = AttrAsStr(input, "file");78    } else if (HasAttr(input, "buffer")) {79      Napi::Buffer<char> buffer = input.Get("buffer").As<Napi::Buffer<char>>();80      descriptor->bufferLength = buffer.Length();81      descriptor->buffer = buffer.Data();82      descriptor->isBuffer = true;83    }84    descriptor->failOn = AttrAsEnum<VipsFailOn>(input, "failOn", VIPS_TYPE_FAIL_ON);85    // Density for vector-based input86    if (HasAttr(input, "density")) {87      descriptor->density = AttrAsDouble(input, "density");88    }89    // Should we ignore any embedded ICC profile90    if (HasAttr(input, "ignoreIcc")) {91      descriptor->ignoreIcc = AttrAsBool(input, "ignoreIcc");92    }93    // Raw pixel input94    if (HasAttr(input, "rawChannels")) {95      descriptor->rawDepth = AttrAsEnum<VipsBandFormat>(input, "rawDepth", VIPS_TYPE_BAND_FORMAT);96      descriptor->rawChannels = AttrAsUint32(input, "rawChannels");97      descriptor->rawWidth = AttrAsUint32(input, "rawWidth");98      descriptor->rawHeight = AttrAsUint32(input, "rawHeight");99      descriptor->rawPremultiplied = AttrAsBool(input, "rawPremultiplied");100      descriptor->rawPageHeight = AttrAsUint32(input, "rawPageHeight");101    }102    // Multi-page input (GIF, TIFF, PDF)103    if (HasAttr(input, "pages")) {104      descriptor->pages = AttrAsInt32(input, "pages");105    }106    if (HasAttr(input, "page")) {107      descriptor->page = AttrAsUint32(input, "page");108    }109    // SVG110    if (HasAttr(input, "svgStylesheet")) {111      descriptor->svgStylesheet = AttrAsStr(input, "svgStylesheet");112    }113    if (HasAttr(input, "svgHighBitdepth")) {114      descriptor->svgHighBitdepth = AttrAsBool(input, "svgHighBitdepth");115    }116    // Multi-level input (OpenSlide)117    if (HasAttr(input, "openSlideLevel")) {118      descriptor->openSlideLevel = AttrAsUint32(input, "openSlideLevel");119    }120    // subIFD (OME-TIFF)121    if (HasAttr(input, "subifd")) {122      descriptor->tiffSubifd = AttrAsInt32(input, "tiffSubifd");123    }124    // // PDF background color125    if (HasAttr(input, "pdfBackground")) {126      descriptor->pdfBackground = AttrAsVectorOfDouble(input, "pdfBackground");127    }128    // Use JPEG 2000 oneshot mode?129    if (HasAttr(input, "jp2Oneshot")) {130      descriptor->jp2Oneshot = AttrAsBool(input, "jp2Oneshot");131    }132    // Create new image133    if (HasAttr(input, "createChannels")) {134      descriptor->createChannels = AttrAsUint32(input, "createChannels");135      descriptor->createWidth = AttrAsUint32(input, "createWidth");136      descriptor->createHeight = AttrAsUint32(input, "createHeight");137      descriptor->createPageHeight = AttrAsUint32(input, "createPageHeight");138      if (HasAttr(input, "createNoiseType")) {139        descriptor->createNoiseType = AttrAsStr(input, "createNoiseType");140        descriptor->createNoiseMean = AttrAsDouble(input, "createNoiseMean");141        descriptor->createNoiseSigma = AttrAsDouble(input, "createNoiseSigma");142      } else {143        descriptor->createBackground = AttrAsVectorOfDouble(input, "createBackground");144      }145    }146    // Create new image with text147    if (HasAttr(input, "textValue")) {148      descriptor->textValue = AttrAsStr(input, "textValue");149      if (HasAttr(input, "textFont")) {150        descriptor->textFont = AttrAsStr(input, "textFont");151      }152      if (HasAttr(input, "textFontfile")) {153        descriptor->textFontfile = AttrAsStr(input, "textFontfile");154      }155      if (HasAttr(input, "textWidth")) {156        descriptor->textWidth = AttrAsUint32(input, "textWidth");157      }158      if (HasAttr(input, "textHeight")) {159        descriptor->textHeight = AttrAsUint32(input, "textHeight");160      }161      if (HasAttr(input, "textAlign")) {162        descriptor->textAlign = AttrAsEnum<VipsAlign>(input, "textAlign", VIPS_TYPE_ALIGN);163      }164      if (HasAttr(input, "textJustify")) {165        descriptor->textJustify = AttrAsBool(input, "textJustify");166      }167      if (HasAttr(input, "textDpi")) {168        descriptor->textDpi = AttrAsUint32(input, "textDpi");169      }170      if (HasAttr(input, "textRgba")) {171        descriptor->textRgba = AttrAsBool(input, "textRgba");172      }173      if (HasAttr(input, "textSpacing")) {174        descriptor->textSpacing = AttrAsUint32(input, "textSpacing");175      }176      if (HasAttr(input, "textWrap")) {177        descriptor->textWrap = AttrAsEnum<VipsTextWrap>(input, "textWrap", VIPS_TYPE_TEXT_WRAP);178      }179    }180    // Join images together181    if (HasAttr(input, "joinAnimated")) {182      descriptor->joinAnimated = AttrAsBool(input, "joinAnimated");183    }184    if (HasAttr(input, "joinAcross")) {185      descriptor->joinAcross = AttrAsUint32(input, "joinAcross");186    }187    if (HasAttr(input, "joinShim")) {188      descriptor->joinShim = AttrAsUint32(input, "joinShim");189    }190    if (HasAttr(input, "joinBackground")) {191      descriptor->joinBackground = AttrAsVectorOfDouble(input, "joinBackground");192    }193    if (HasAttr(input, "joinHalign")) {194      descriptor->joinHalign = AttrAsEnum<VipsAlign>(input, "joinHalign", VIPS_TYPE_ALIGN);195    }196    if (HasAttr(input, "joinValign")) {197      descriptor->joinValign = AttrAsEnum<VipsAlign>(input, "joinValign", VIPS_TYPE_ALIGN);198    }199    descriptor->limitInputPixels = static_cast<uint64_t>(AttrAsInt64(input, "limitInputPixels"));200    descriptor->limitInputChannels = static_cast<uint64_t>(AttrAsInt64(input, "limitInputChannels"));201    if (HasAttr(input, "access")) {202      descriptor->access = AttrAsBool(input, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM;203    }204    // Remove safety features and allow unlimited input205    descriptor->unlimited = AttrAsBool(input, "unlimited");206    // Use the EXIF orientation to auto orient the image207    descriptor->autoOrient = AttrAsBool(input, "autoOrient");208    return descriptor;209  }210 211  // How many tasks are in the queue?212  std::atomic<int> counterQueue{0};213 214  // How many tasks are being processed?215  std::atomic<int> counterProcess{0};216 217  // Filename extension checkers218  static bool EndsWith(std::string const &str, std::string const &end) {219    return str.length() >= end.length() && 0 == str.compare(str.length() - end.length(), end.length(), end);220  }221  bool IsJpeg(std::string const &str) {222    return EndsWith(str, ".jpg") || EndsWith(str, ".jpeg") || EndsWith(str, ".JPG") || EndsWith(str, ".JPEG");223  }224  bool IsPng(std::string const &str) {225    return EndsWith(str, ".png") || EndsWith(str, ".PNG");226  }227  bool IsWebp(std::string const &str) {228    return EndsWith(str, ".webp") || EndsWith(str, ".WEBP");229  }230  bool IsGif(std::string const &str) {231    return EndsWith(str, ".gif") || EndsWith(str, ".GIF");232  }233  bool IsJp2(std::string const &str) {234    return EndsWith(str, ".jp2") || EndsWith(str, ".jpx") || EndsWith(str, ".j2k") || EndsWith(str, ".j2c")235      || EndsWith(str, ".JP2") || EndsWith(str, ".JPX") || EndsWith(str, ".J2K") || EndsWith(str, ".J2C");236  }237  bool IsTiff(std::string const &str) {238    return EndsWith(str, ".tif") || EndsWith(str, ".tiff") || EndsWith(str, ".TIF") || EndsWith(str, ".TIFF");239  }240  bool IsHeic(std::string const &str) {241    return EndsWith(str, ".heic") || EndsWith(str, ".HEIC");242  }243  bool IsHeif(std::string const &str) {244    return EndsWith(str, ".heif") || EndsWith(str, ".HEIF") || IsHeic(str) || IsAvif(str);245  }246  bool IsAvif(std::string const &str) {247    return EndsWith(str, ".avif") || EndsWith(str, ".AVIF");248  }249  bool IsJxl(std::string const &str) {250    return EndsWith(str, ".jxl") || EndsWith(str, ".JXL");251  }252  bool IsDz(std::string const &str) {253    return EndsWith(str, ".dzi") || EndsWith(str, ".DZI");254  }255  bool IsDzZip(std::string const &str) {256    return EndsWith(str, ".zip") || EndsWith(str, ".ZIP") || EndsWith(str, ".szi") || EndsWith(str, ".SZI");257  }258  bool IsV(std::string const &str) {259    return EndsWith(str, ".v") || EndsWith(str, ".V") || EndsWith(str, ".vips") || EndsWith(str, ".VIPS");260  }261 262  /*263    Trim space from end of string.264  */265  std::string TrimEnd(std::string const &str) {266    return str.substr(0, str.find_last_not_of(" \n\r\f") + 1);267  }268 269  /*270    Provide a string identifier for the given image type.271  */272  std::string ImageTypeId(ImageType const imageType) {273    std::string id;274    switch (imageType) {275      case ImageType::JPEG: id = "jpeg"; break;276      case ImageType::PNG: id = "png"; break;277      case ImageType::WEBP: id = "webp"; break;278      case ImageType::TIFF: id = "tiff"; break;279      case ImageType::GIF: id = "gif"; break;280      case ImageType::JP2: id = "jp2"; break;281      case ImageType::SVG: id = "svg"; break;282      case ImageType::HEIF: id = "heif"; break;283      case ImageType::PDF: id = "pdf"; break;284      case ImageType::MAGICK: id = "magick"; break;285      case ImageType::OPENSLIDE: id = "openslide"; break;286      case ImageType::PPM: id = "ppm"; break;287      case ImageType::FITS: id = "fits"; break;288      case ImageType::EXR: id = "exr"; break;289      case ImageType::JXL: id = "jxl"; break;290      case ImageType::RAD: id = "rad"; break;291      case ImageType::DCRAW: id = "dcraw"; break;292      case ImageType::UHDR: id = "uhdr"; break;293      case ImageType::VIPS: id = "vips"; break;294      case ImageType::RAW: id = "raw"; break;295      case ImageType::UNKNOWN: id = "unknown"; break;296      case ImageType::MISSING: id = "missing"; break;297    }298    return id;299  }300 301  /**302   * Regenerate this table with something like:303   *304   * $ vips -l foreign | grep -i load | awk '{ print $2, $1; }'305   *306   * Plus a bit of editing.307   */308  std::map<std::string, ImageType> loaderToType = {309    { "VipsForeignLoadJpegFile", ImageType::JPEG },310    { "VipsForeignLoadJpegBuffer", ImageType::JPEG },311    { "VipsForeignLoadPngFile", ImageType::PNG },312    { "VipsForeignLoadPngBuffer", ImageType::PNG },313    { "VipsForeignLoadWebpFile", ImageType::WEBP },314    { "VipsForeignLoadWebpBuffer", ImageType::WEBP },315    { "VipsForeignLoadTiffFile", ImageType::TIFF },316    { "VipsForeignLoadTiffBuffer", ImageType::TIFF },317    { "VipsForeignLoadGifFile", ImageType::GIF },318    { "VipsForeignLoadGifBuffer", ImageType::GIF },319    { "VipsForeignLoadNsgifFile", ImageType::GIF },320    { "VipsForeignLoadNsgifBuffer", ImageType::GIF },321    { "VipsForeignLoadJp2kBuffer", ImageType::JP2 },322    { "VipsForeignLoadJp2kFile", ImageType::JP2 },323    { "VipsForeignLoadSvgFile", ImageType::SVG },324    { "VipsForeignLoadSvgBuffer", ImageType::SVG },325    { "VipsForeignLoadHeifFile", ImageType::HEIF },326    { "VipsForeignLoadHeifBuffer", ImageType::HEIF },327    { "VipsForeignLoadPdfFile", ImageType::PDF },328    { "VipsForeignLoadPdfBuffer", ImageType::PDF },329    { "VipsForeignLoadMagickFile", ImageType::MAGICK },330    { "VipsForeignLoadMagickBuffer", ImageType::MAGICK },331    { "VipsForeignLoadMagick7File", ImageType::MAGICK },332    { "VipsForeignLoadMagick7Buffer", ImageType::MAGICK },333    { "VipsForeignLoadOpenslideFile", ImageType::OPENSLIDE },334    { "VipsForeignLoadPpmFile", ImageType::PPM },335    { "VipsForeignLoadFitsFile", ImageType::FITS },336    { "VipsForeignLoadOpenexr", ImageType::EXR },337    { "VipsForeignLoadJxlFile", ImageType::JXL },338    { "VipsForeignLoadJxlBuffer", ImageType::JXL },339    { "VipsForeignLoadRadFile", ImageType::RAD },340    { "VipsForeignLoadRadBuffer", ImageType::RAD },341    { "VipsForeignLoadDcRawFile", ImageType::DCRAW },342    { "VipsForeignLoadDcRawBuffer", ImageType::DCRAW },343    { "VipsForeignLoadUhdr", ImageType::UHDR },344    { "VipsForeignLoadUhdrFile", ImageType::UHDR },345    { "VipsForeignLoadUhdrBuffer", ImageType::UHDR },346    { "VipsForeignLoadVips", ImageType::VIPS },347    { "VipsForeignLoadVipsFile", ImageType::VIPS },348    { "VipsForeignLoadRaw", ImageType::RAW }349  };350 351  /*352    Determine image format of a buffer.353  */354  ImageType DetermineImageType(void *buffer, size_t const length) {355    ImageType imageType = ImageType::UNKNOWN;356    char const *load = vips_foreign_find_load_buffer(buffer, length);357    if (load != nullptr) {358      auto it = loaderToType.find(load);359      if (it != loaderToType.end()) {360        imageType = it->second;361      }362    }363    if (imageType == ImageType::UHDR) {364      imageType = ImageType::JPEG;365    }366    return imageType;367  }368 369  /*370    Determine image format, reads the first few bytes of the file371  */372  ImageType DetermineImageType(char const *file) {373    ImageType imageType = ImageType::UNKNOWN;374    char const *load = vips_foreign_find_load(file);375    if (load != nullptr) {376      auto it = loaderToType.find(load);377      if (it != loaderToType.end()) {378        imageType = it->second;379      }380    } else {381      if (EndsWith(vips::VError().what(), " does not exist\n")) {382        imageType = ImageType::MISSING;383      }384    }385    if (imageType == ImageType::UHDR) {386      imageType = ImageType::JPEG;387    }388    return imageType;389  }390 391  /*392    Does this image type support multiple pages?393  */394  bool ImageTypeSupportsPage(ImageType imageType) {395    return396      imageType == ImageType::WEBP ||397      imageType == ImageType::MAGICK ||398      imageType == ImageType::GIF ||399      imageType == ImageType::JP2 ||400      imageType == ImageType::TIFF ||401      imageType == ImageType::HEIF ||402      imageType == ImageType::PDF;403  }404 405  /*406    Does this image type support removal of safety limits?407  */408  bool ImageTypeSupportsUnlimited(ImageType imageType) {409    return410      imageType == ImageType::JPEG ||411      imageType == ImageType::PNG ||412      imageType == ImageType::SVG ||413      imageType == ImageType::TIFF ||414      imageType == ImageType::HEIF;415  }416 417  /*418    Format-specific options builder419  */420  vips::VOption* GetOptionsForImageType(ImageType imageType, InputDescriptor *descriptor) {421    vips::VOption *option = VImage::option()422      ->set("access", descriptor->access)423      ->set("fail_on", descriptor->failOn);424    if (descriptor->unlimited && ImageTypeSupportsUnlimited(imageType)) {425      option->set("unlimited", true);426    }427    if (ImageTypeSupportsPage(imageType)) {428      option->set("n", descriptor->pages);429      option->set("page", std::max(0, descriptor->page));430    }431    switch (imageType) {432      case ImageType::SVG:433        option->set("dpi", descriptor->density)434              ->set("stylesheet", descriptor->svgStylesheet.data())435              ->set("high_bitdepth", descriptor->svgHighBitdepth);436        break;437      case ImageType::TIFF:438        option->set("subifd", descriptor->tiffSubifd);439        break;440      case ImageType::PDF:441        option->set("dpi", descriptor->density)442              ->set("background", descriptor->pdfBackground);443        break;444      case ImageType::OPENSLIDE:445        option->set("level", descriptor->openSlideLevel);446        break;447      case ImageType::JP2:448        option->set("oneshot", descriptor->jp2Oneshot);449        break;450      case ImageType::MAGICK:451        option->set("density", std::to_string(descriptor->density).data());452        break;453      default:454        break;455    }456    return option;457  }458 459  /*460    Should HEIF image be re-opened using the primary item?461  */462  static bool HeifPrimaryPageReopen(VImage image, InputDescriptor *descriptor) {463    if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT && image.get_typeof("heif-primary") == G_TYPE_INT) {464      if (image.get_int(VIPS_META_N_PAGES) > 1 && descriptor->pages == 1 && descriptor->page == -1) {465        int const pagePrimary = image.get_int("heif-primary");466        if (pagePrimary != 0) {467          descriptor->page = pagePrimary;468          return true;469        }470      }471    }472    return false;473  }474 475  /*476    Open an image from the given InputDescriptor (filesystem, compressed buffer, raw pixel data)477  */478  std::tuple<VImage, ImageType> OpenInput(InputDescriptor *descriptor) {479    VImage image;480    ImageType imageType;481    if (descriptor->isBuffer) {482      if (descriptor->rawChannels > 0) {483        // Raw, uncompressed pixel data484        bool const is8bit = vips_band_format_is8bit(descriptor->rawDepth);485        image = VImage::new_from_memory(descriptor->buffer, descriptor->bufferLength,486          descriptor->rawWidth, descriptor->rawHeight, descriptor->rawChannels, descriptor->rawDepth);487        if (descriptor->rawChannels < 3) {488          image.get_image()->Type = is8bit ? VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_GREY16;489        } else {490          image.get_image()->Type = is8bit ? VIPS_INTERPRETATION_sRGB : VIPS_INTERPRETATION_RGB16;491        }492        if (descriptor->rawPageHeight > 0) {493          image.set(VIPS_META_PAGE_HEIGHT, descriptor->rawPageHeight);494          image.set(VIPS_META_N_PAGES, static_cast<int>(descriptor->rawHeight / descriptor->rawPageHeight));495        }496        if (descriptor->rawPremultiplied) {497          image = image.unpremultiply();498        }499        imageType = ImageType::RAW;500      } else {501        // Compressed data502        imageType = DetermineImageType(descriptor->buffer, descriptor->bufferLength);503        if (imageType != ImageType::UNKNOWN) {504          try {505            vips::VOption *option = GetOptionsForImageType(imageType, descriptor);506            image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);507            if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {508              image = SetDensity(image, descriptor->density);509            } else if (imageType == ImageType::HEIF && HeifPrimaryPageReopen(image, descriptor)) {510              option = GetOptionsForImageType(imageType, descriptor);511              image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);512            }513          } catch (std::runtime_error const &err) {514            throw std::runtime_error(std::string("Input buffer has corrupt header: ") + err.what());515          }516        } else {517          throw std::runtime_error("Input buffer contains unsupported image format");518        }519      }520    } else {521      int const channels = descriptor->createChannels;522      if (channels > 0) {523        // Create new image524        if (descriptor->createNoiseType == "gaussian") {525          std::vector<VImage> bands = {};526          bands.reserve(channels);527          for (int _band = 0; _band < channels; _band++) {528            bands.push_back(VImage::gaussnoise(descriptor->createWidth, descriptor->createHeight, VImage::option()529              ->set("mean", descriptor->createNoiseMean)530              ->set("sigma", descriptor->createNoiseSigma)));531          }532          image = VImage::bandjoin(bands).copy(VImage::option()->set("interpretation",533            channels < 3 ? VIPS_INTERPRETATION_B_W: VIPS_INTERPRETATION_sRGB));534        } else {535          std::vector<double> background = {536            descriptor->createBackground[0],537            descriptor->createBackground[1],538            descriptor->createBackground[2]539          };540          if (channels == 4) {541            background.push_back(descriptor->createBackground[3]);542          }543          image = VImage::new_matrix(descriptor->createWidth, descriptor->createHeight)544            .copy(VImage::option()->set("interpretation",545              channels < 3 ? VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_sRGB))546            .new_from_image(background);547        }548        if (descriptor->createPageHeight > 0) {549          image.set(VIPS_META_PAGE_HEIGHT, descriptor->createPageHeight);550          image.set(VIPS_META_N_PAGES, static_cast<int>(descriptor->createHeight / descriptor->createPageHeight));551        }552        image = image.cast(VIPS_FORMAT_UCHAR);553        imageType = ImageType::RAW;554      } else if (descriptor->textValue.length() > 0) {555        // Create a new image with text556        vips::VOption *textOptions = VImage::option()557          ->set("align", descriptor->textAlign)558          ->set("justify", descriptor->textJustify)559          ->set("rgba", descriptor->textRgba)560          ->set("spacing", descriptor->textSpacing)561          ->set("wrap", descriptor->textWrap)562          ->set("autofit_dpi", &descriptor->textAutofitDpi);563        if (descriptor->textWidth > 0) {564          textOptions->set("width", descriptor->textWidth);565        }566        // Ignore dpi if height is set567        if (descriptor->textWidth > 0 && descriptor->textHeight > 0) {568          textOptions->set("height", descriptor->textHeight);569        } else if (descriptor->textDpi > 0) {570          textOptions->set("dpi", descriptor->textDpi);571        }572        if (descriptor->textFont.length() > 0) {573          textOptions->set("font", const_cast<char*>(descriptor->textFont.data()));574        }575        if (descriptor->textFontfile.length() > 0) {576          textOptions->set("fontfile", const_cast<char*>(descriptor->textFontfile.data()));577        }578        image = VImage::text(const_cast<char *>(descriptor->textValue.data()), textOptions);579        if (!descriptor->textRgba) {580          image = image.copy(VImage::option()->set("interpretation", VIPS_INTERPRETATION_B_W));581        }582        imageType = ImageType::RAW;583      } else {584        // From filesystem585        imageType = DetermineImageType(descriptor->file.data());586        if (imageType == ImageType::MISSING) {587          if (descriptor->file.find("<svg") != std::string::npos) {588            throw std::runtime_error("Input file is missing, did you mean "589              "sharp(Buffer.from('" + descriptor->file.substr(0, 8) + "...')?");590          }591          throw std::runtime_error("Input file is missing: " + descriptor->file);592        }593        if (imageType != ImageType::UNKNOWN) {594          try {595            vips::VOption *option = GetOptionsForImageType(imageType, descriptor);596            image = VImage::new_from_file(descriptor->file.data(), option);597            if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {598              image = SetDensity(image, descriptor->density);599            } else if (imageType == ImageType::HEIF && HeifPrimaryPageReopen(image, descriptor)) {600              option = GetOptionsForImageType(imageType, descriptor);601              image = VImage::new_from_file(descriptor->file.data(), option);602            }603          } catch (std::runtime_error const &err) {604            throw std::runtime_error(std::string("Input file has corrupt header: ") + err.what());605          }606        } else {607          throw std::runtime_error("Input file contains unsupported image format");608        }609      }610    }611 612    // Limit input images to a given number of pixels, where pixels = width * height613    if (descriptor->limitInputPixels > 0 &&614      static_cast<uint64_t>(image.width()) * image.height() > descriptor->limitInputPixels) {615      throw std::runtime_error("Input image exceeds pixel limit");616    }617    if (descriptor->limitInputChannels > 0 && static_cast<uint64_t>(image.bands()) > descriptor->limitInputChannels) {618      throw std::runtime_error("Input image exceeds channel limit");619    }620    return std::make_tuple(image, imageType);621  }622 623  /*624    Does this image have an embedded profile?625  */626  bool HasProfile(VImage image) {627    return image.get_typeof(VIPS_META_ICC_NAME) == VIPS_TYPE_BLOB;628  }629 630  /*631    Get copy of embedded profile.632  */633  std::pair<char*, size_t> GetProfile(VImage image) {634    std::pair<char*, size_t> icc(nullptr, 0);635    if (HasProfile(image)) {636      size_t length;637      const void *data = image.get_blob(VIPS_META_ICC_NAME, &length);638      icc.first = static_cast<char*>(vips_malloc(reinterpret_cast<VipsObject*>(image.get_image()), length));639      icc.second = length;640      memcpy(icc.first, data, length);641    }642    return icc;643  }644 645  /*646    Set embedded profile.647  */648  VImage SetProfile(VImage image, std::pair<char*, size_t> icc) {649    if (icc.first != nullptr) {650      image = image.copy();651      image.set(VIPS_META_ICC_NAME, nullptr, icc.first, icc.second);652    }653    return image;654  }655 656  static void* RemoveExifCallback(VipsImage *image, char const *field, GValue *value, void *data) {657    std::vector<std::string> *fieldNames = static_cast<std::vector<std::string> *>(data);658    std::string fieldName(field);659    if (fieldName.substr(0, 8) == ("exif-ifd")) {660      fieldNames->push_back(fieldName);661    }662    return nullptr;663  }664 665  /*666    Remove all EXIF-related image fields.667  */668  VImage RemoveExif(VImage image) {669    std::vector<std::string> fieldNames;670    vips_image_map(image.get_image(), static_cast<VipsImageMapFn>(RemoveExifCallback), &fieldNames);671    for (const auto& f : fieldNames) {672      image.remove(f.data());673    }674    return image;675  }676 677  /*678    Get EXIF Orientation of image, if any.679  */680  int ExifOrientation(VImage image) {681    int orientation = 0;682    if (image.get_typeof(VIPS_META_ORIENTATION) != 0) {683      orientation = image.get_int(VIPS_META_ORIENTATION);684    }685    return orientation;686  }687 688  /*689    Set EXIF Orientation of image.690  */691  VImage SetExifOrientation(VImage image, int const orientation) {692    VImage copy = image.copy();693    copy.set(VIPS_META_ORIENTATION, orientation);694    return copy;695  }696 697  /*698    Remove EXIF Orientation from image.699  */700  VImage RemoveExifOrientation(VImage image) {701    VImage copy = image.copy();702    copy.remove(VIPS_META_ORIENTATION);703    copy.remove("exif-ifd0-Orientation");704    return copy;705  }706 707  /*708    Set animation properties if necessary.709  */710  VImage SetAnimationProperties(VImage image, int nPages, int pageHeight, std::vector<int> delay, int loop) {711    bool hasDelay = !delay.empty();712    VImage copy = image.copy();713 714    // Only set page-height if we have more than one page, or this could715    // accidentally turn into an animated image later.716    if (nPages > 1) copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);717    if (hasDelay) {718      if (delay.size() == 1) {719        // We have just one delay, repeat that value for all frames.720        delay.insert(delay.end(), nPages - 1, delay[0]);721      }722      copy.set("delay", delay);723    }724    if (nPages == 1 && !hasDelay && loop == -1) {725      loop = 1;726    }727    if (loop != -1) copy.set("loop", loop);728 729    return copy;730  }731 732  /*733    Remove animation properties from image.734  */735  VImage RemoveAnimationProperties(VImage image) {736    VImage copy = image.copy();737    copy.remove(VIPS_META_PAGE_HEIGHT);738    copy.remove("delay");739    copy.remove("loop");740    return copy;741  }742 743  /*744    Remove GIF palette from image.745  */746  VImage RemoveGifPalette(VImage image) {747    VImage copy = image.copy();748    copy.remove("gif-palette");749    return copy;750  }751 752  /*753    Does this image have a non-default density?754  */755  bool HasDensity(VImage image) {756    return image.xres() > 1.0;757  }758 759  /*760    Get pixels/mm resolution as pixels/inch density.761  */762  int GetDensity(VImage image) {763    return static_cast<int>(round(image.xres() * 25.4));764  }765 766  /*767    Set pixels/mm resolution based on a pixels/inch density.768  */769  VImage SetDensity(VImage image, const double density) {770    const double pixelsPerMm = density / 25.4;771    VImage copy = image.copy();772    copy.get_image()->Xres = pixelsPerMm;773    copy.get_image()->Yres = pixelsPerMm;774    return copy;775  }776 777  /*778    Multi-page images can have a page height. Fetch it, and sanity check it.779    If page-height is not set, it defaults to the image height780  */781  int GetPageHeight(VImage image) {782    return vips_image_get_page_height(image.get_image());783  }784 785  /*786    Check the proposed format supports the current dimensions.787  */788  void AssertImageTypeDimensions(VImage image, ImageType const imageType) {789    const int height = image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT790      ? image.get_int(VIPS_META_PAGE_HEIGHT)791      : image.height();792    if (imageType == ImageType::JPEG) {793      if (image.width() > 65535 || height > 65535) {794        throw std::runtime_error("Processed image is too large for the JPEG format");795      }796    } else if (imageType == ImageType::WEBP) {797      if (image.width() > 16383 || height > 16383) {798        throw std::runtime_error("Processed image is too large for the WebP format");799      }800    } else if (imageType == ImageType::GIF) {801      if (image.width() > 65535 || height > 65535) {802        throw std::runtime_error("Processed image is too large for the GIF format");803      }804    } else if (imageType == ImageType::HEIF) {805      if (image.width() > 16384 || height > 16384) {806        throw std::runtime_error("Processed image is too large for the HEIF format");807      }808    }809  }810 811  /*812    Called when a Buffer undergoes GC, required to support mixed runtime libraries in Windows813  */814  std::function<void(void*, char*)> FreeCallback = [](void*, char* data) {815    g_free(data);816  };817 818  /*819    Temporary buffer of warnings820  */821  std::queue<std::string> vipsWarnings;822  std::mutex vipsWarningsMutex;823 824  /*825    Called with warnings from the glib-registered "VIPS" domain826  */827  void VipsWarningCallback(char const* log_domain, GLogLevelFlags log_level, char const* message, void* ignore) {828    std::lock_guard<std::mutex> lock(vipsWarningsMutex);829    vipsWarnings.emplace(message);830  }831 832  /*833    Pop the oldest warning message from the queue834  */835  std::string VipsWarningPop() {836    std::string warning;837    std::lock_guard<std::mutex> lock(vipsWarningsMutex);838    if (!vipsWarnings.empty()) {839      warning = vipsWarnings.front();840      vipsWarnings.pop();841    }842    return warning;843  }844 845  /*846    Attach an event listener for progress updates, used to detect timeout847  */848  void SetTimeout(VImage image, int const seconds) {849    if (seconds > 0) {850      VipsImage *im = image.get_image();851      if (im->progress_signal == NULL) {852        int *timeout = VIPS_NEW(im, int);853        *timeout = seconds;854        g_signal_connect(im, "eval", G_CALLBACK(VipsProgressCallBack), timeout);855        vips_image_set_progress(im, true);856      }857    }858  }859 860  /*861    Event listener for progress updates, used to detect timeout862  */863  void VipsProgressCallBack(VipsImage *im, VipsProgress *progress, int *timeout) {864    if (*timeout > 0 && progress->run >= *timeout) {865      vips_image_set_kill(im, true);866      vips_error("timeout", "%d%% complete", progress->percent);867      *timeout = 0;868    }869  }870 871  /*872    Calculate the (left, top) coordinates of the output image873    within the input image, applying the given gravity during an embed.874 875    @Azurebyte: We are basically swapping the inWidth and outWidth, inHeight and outHeight from the CalculateCrop function.876  */877  std::tuple<int, int> CalculateEmbedPosition(int const inWidth, int const inHeight,878    int const outWidth, int const outHeight, int const gravity) {879 880    int left = 0;881    int top = 0;882    switch (gravity) {883      case 1:884        // North885        left = (outWidth - inWidth) / 2;886        break;887      case 2:888        // East889        left = outWidth - inWidth;890        top = (outHeight - inHeight) / 2;891        break;892      case 3:893        // South894        left = (outWidth - inWidth) / 2;895        top = outHeight - inHeight;896        break;897      case 4:898        // West899        top = (outHeight - inHeight) / 2;900        break;901      case 5:902        // Northeast903        left = outWidth - inWidth;904        break;905      case 6:906        // Southeast907        left = outWidth - inWidth;908        top = outHeight - inHeight;909        break;910      case 7:911        // Southwest912        top = outHeight - inHeight;913        break;914      case 8:915        // Northwest916        // Which is the default is 0,0 so we do not assign anything here.917        break;918      default:919        // Centre920        left = (outWidth - inWidth) / 2;921        top = (outHeight - inHeight) / 2;922    }923    return std::make_tuple(left, top);924  }925 926  /*927    Calculate the (left, top) coordinates of the output image928    within the input image, applying the given gravity during a crop.929  */930  std::tuple<int, int> CalculateCrop(int const inWidth, int const inHeight,931    int const outWidth, int const outHeight, int const gravity) {932 933    int left = 0;934    int top = 0;935    switch (gravity) {936      case 1:937        // North938        left = (inWidth - outWidth + 1) / 2;939        break;940      case 2:941        // East942        left = inWidth - outWidth;943        top = (inHeight - outHeight + 1) / 2;944        break;945      case 3:946        // South947        left = (inWidth - outWidth + 1) / 2;948        top = inHeight - outHeight;949        break;950      case 4:951        // West952        top = (inHeight - outHeight + 1) / 2;953        break;954      case 5:955        // Northeast956        left = inWidth - outWidth;957        break;958      case 6:959        // Southeast960        left = inWidth - outWidth;961        top = inHeight - outHeight;962        break;963      case 7:964        // Southwest965        top = inHeight - outHeight;966        break;967      case 8:968        // Northwest969        break;970      default:971        // Centre972        left = (inWidth - outWidth + 1) / 2;973        top = (inHeight - outHeight + 1) / 2;974    }975    return std::make_tuple(left, top);976  }977 978  /*979    Calculate the (left, top) coordinates of the output image980    within the input image, applying the given x and y offsets.981  */982  std::tuple<int, int> CalculateCrop(int const inWidth, int const inHeight,983    int const outWidth, int const outHeight, int const x, int const y) {984 985    // default values986    int left = 0;987    int top = 0;988 989    // assign only if valid990    if (x < (inWidth - outWidth)) {991      left = x;992    } else if (x >= (inWidth - outWidth)) {993      left = inWidth - outWidth;994    }995 996    if (y < (inHeight - outHeight)) {997      top = y;998    } else if (y >= (inHeight - outHeight)) {999      top = inHeight - outHeight;1000    }1001 1002    return std::make_tuple(left, top);1003  }1004 1005  /*1006    Are pixel values in this image 16-bit integer?1007  */1008  bool Is16Bit(VipsInterpretation const interpretation) {1009    return interpretation == VIPS_INTERPRETATION_RGB16 || interpretation == VIPS_INTERPRETATION_GREY16;1010  }1011 1012  /*1013    Convert RGBA value to another colourspace1014  */1015  std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba,1016    VipsInterpretation const interpretation, bool premultiply) {1017    int const bands = static_cast<int>(rgba.size());1018    if (bands < 3) {1019      return rgba;1020    }1021    VImage pixel = VImage::new_matrix(1, 1);1022    pixel.set("bands", bands);1023    pixel = pixel1024      .new_from_image(rgba)1025      .colourspace(interpretation, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB));1026    if (premultiply) {1027      pixel = pixel.premultiply();1028    }1029    return pixel(0, 0);1030  }1031 1032  /*1033    Apply the alpha channel to a given colour1034  */1035  std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour, bool premultiply) {1036    // Scale up 8-bit values to match 16-bit input image1037    double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;1038    // Create alphaColour colour1039    std::vector<double> alphaColour;1040    if (image.bands() > 2) {1041      alphaColour = {1042        multiplier * colour[0],1043        multiplier * colour[1],1044        multiplier * colour[2]1045      };1046    } else {1047      // Convert sRGB to greyscale1048      alphaColour = { multiplier * (1049        0.2126 * colour[0] +1050        0.7152 * colour[1] +1051        0.0722 * colour[2])1052      };1053    }1054    // Add alpha channel(s) to alphaColour colour1055    if (colour[3] < 255.0 || image.has_alpha()) {1056      int extraBands = image.bands() > 4 ? image.bands() - 3 : 1;1057      alphaColour.insert(alphaColour.end(), extraBands, colour[3] * multiplier);1058    }1059    // Ensure alphaColour colour uses correct colourspace1060    alphaColour = sharp::GetRgbaAsColourspace(alphaColour, image.interpretation(), premultiply);1061    // Add non-transparent alpha channel, if required1062    if (colour[3] < 255.0 && !image.has_alpha()) {1063      image = image.bandjoin_const({ 255 * multiplier });1064    }1065    return std::make_tuple(image, alphaColour);1066  }1067 1068  /*1069    Removes alpha channels, if any.1070  */1071  VImage RemoveAlpha(VImage image) {1072    while (image.bands() > 1 && image.has_alpha()) {1073      image = image.extract_band(0, VImage::option()->set("n", image.bands() - 1));1074    }1075    return image;1076  }1077 1078  /*1079    Ensures alpha channel, if missing.1080  */1081  VImage EnsureAlpha(VImage image, double const value) {1082    if (!image.has_alpha()) {1083      image = image.bandjoin_const({ value * vips_interpretation_max_alpha(image.interpretation()) });1084    }1085    return image;1086  }1087 1088  std::pair<double, double> ResolveShrink(int width, int height, int targetWidth, int targetHeight,1089    Canvas canvas, bool withoutEnlargement, bool withoutReduction) {1090    double hshrink = 1.0;1091    double vshrink = 1.0;1092 1093    if (targetWidth > 0 && targetHeight > 0) {1094      // Fixed width and height1095      hshrink = static_cast<double>(width) / targetWidth;1096      vshrink = static_cast<double>(height) / targetHeight;1097 1098      switch (canvas) {1099        case Canvas::CROP:1100        case Canvas::MIN:1101          if (hshrink < vshrink) {1102            vshrink = hshrink;1103          } else {1104            hshrink = vshrink;1105          }1106          break;1107        case Canvas::EMBED:1108        case Canvas::MAX:1109          if (hshrink > vshrink) {1110            vshrink = hshrink;1111          } else {1112            hshrink = vshrink;1113          }1114          break;1115        case Canvas::IGNORE_ASPECT:1116          break;1117      }1118    } else if (targetWidth > 0) {1119      // Fixed width1120      hshrink = static_cast<double>(width) / targetWidth;1121 1122      if (canvas != Canvas::IGNORE_ASPECT) {1123        // Auto height1124        vshrink = hshrink;1125      }1126    } else if (targetHeight > 0) {1127      // Fixed height1128      vshrink = static_cast<double>(height) / targetHeight;1129 1130      if (canvas != Canvas::IGNORE_ASPECT) {1131        // Auto width1132        hshrink = vshrink;1133      }1134    }1135 1136    // We should not reduce or enlarge the output image, if1137    // withoutReduction or withoutEnlargement is specified.1138    if (withoutReduction) {1139      // Equivalent of VIPS_SIZE_UP1140      hshrink = std::min(1.0, hshrink);1141      vshrink = std::min(1.0, vshrink);1142    } else if (withoutEnlargement) {1143      // Equivalent of VIPS_SIZE_DOWN1144      hshrink = std::max(1.0, hshrink);1145      vshrink = std::max(1.0, vshrink);1146    }1147 1148    // We don't want to shrink so much that we send an axis to 01149    hshrink = std::min(hshrink, static_cast<double>(width));1150    vshrink = std::min(vshrink, static_cast<double>(height));1151 1152    return std::make_pair(hshrink, vshrink);1153  }1154 1155  /*1156    Ensure decoding remains sequential.1157  */1158  VImage StaySequential(VImage image, bool condition) {1159    if (vips_image_is_sequential(image.get_image()) && condition) {1160      image = image.copy_memory().copy();1161      image.remove(VIPS_META_SEQUENTIAL);1162    }1163    return image;1164  }1165 1166  /*1167    Does this image have a gain map?1168  */1169  bool HasGainMap(VImage image) {1170    return image.get_typeof("gainmap") == VIPS_TYPE_BLOB ||1171      image.get_typeof("gainmap-data") == VIPS_TYPE_BLOB;1172  }1173 1174  /*1175    Removes gain map, if any.1176  */1177  VImage RemoveGainMap(VImage image) {1178    VImage copy = image.copy();1179    copy.remove("gainmap");1180    copy.remove("gainmap-data");1181    return copy;1182  }1183}  // namespace sharp1184 
Brunobkr/llama.cpp_AlgMor24_github · Team Ai