/**
* Orthanc - A Lightweight, RESTful DICOM Store
* Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
* Department, University Hospital of Liege, Belgium
* Copyright (C) 2017-2023 Osimis S.A., Belgium
* Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
* Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see
* .
**/
#pragma once
#include "../OrthancFramework.h"
#include "../DicomFormat/DicomImageInformation.h"
#include "ImageAccessor.h"
#include
#include
#include
namespace Orthanc
{
class ORTHANC_PUBLIC ImageProcessing : public boost::noncopyable
{
public:
class ORTHANC_PUBLIC ImagePoint
{
private:
int32_t x_;
int32_t y_;
public:
ImagePoint(int32_t x,
int32_t y);
int32_t GetX() const;
int32_t GetY() const;
void Set(int32_t x, int32_t y);
void ClipTo(int32_t minX,
int32_t maxX,
int32_t minY,
int32_t maxY);
double GetDistanceTo(const ImagePoint& other) const;
double GetDistanceToLine(double a,
double b,
double c) const; // where ax + by + c = 0 is the equation of the line
};
class ORTHANC_PUBLIC IPolygonFiller : public boost::noncopyable
{
public:
virtual ~IPolygonFiller()
{
}
virtual void Fill(int y,
int x1,
int x2) = 0;
};
static void Copy(ImageAccessor& target,
const ImageAccessor& source);
static void Convert(ImageAccessor& target,
const ImageAccessor& source);
static void ApplyWindowing_Deprecated(ImageAccessor& target,
const ImageAccessor& source,
float windowCenter,
float windowWidth,
float rescaleSlope,
float rescaleIntercept,
bool invert);
static void Set(ImageAccessor& image,
int64_t value);
static void Set(ImageAccessor& image,
uint8_t red,
uint8_t green,
uint8_t blue,
uint8_t alpha);
static void Set(ImageAccessor& image,
uint8_t red,
uint8_t green,
uint8_t blue,
ImageAccessor& alpha);
static void ShiftRight(ImageAccessor& target,
unsigned int shift);
static void ShiftLeft(ImageAccessor& target,
unsigned int shift);
static void GetMinMaxIntegerValue(int64_t& minValue,
int64_t& maxValue,
const ImageAccessor& image);
static void GetMinMaxFloatValue(float& minValue,
float& maxValue,
const ImageAccessor& image);
static void AddConstant(ImageAccessor& image,
int64_t value);
// "useRound" is expensive
static void MultiplyConstant(ImageAccessor& image,
float factor,
bool useRound);
// Computes "(x + offset) * scaling" inplace. "useRound" is expensive.
static void ShiftScale(ImageAccessor& image,
float offset,
float scaling,
bool useRound);
static void ShiftScale(ImageAccessor& target,
const ImageAccessor& source,
float offset,
float scaling,
bool useRound);
// Computes "x * scaling + offset" inplace. "useRound" is expensive.
static void ShiftScale2(ImageAccessor& image,
float offset,
float scaling,
bool useRound);
static void ShiftScale2(ImageAccessor& target,
const ImageAccessor& source,
float offset,
float scaling,
bool useRound);
static void Invert(ImageAccessor& image);
static void Invert(ImageAccessor& image, int64_t maxValue);
static void DrawLineSegment(ImageAccessor& image,
int x0,
int y0,
int x1,
int y1,
int64_t value);
static void DrawLineSegment(ImageAccessor& image,
int x0,
int y0,
int x1,
int y1,
uint8_t red,
uint8_t green,
uint8_t blue,
uint8_t alpha);
static void FillPolygon(IPolygonFiller& filler,
const std::vector& points);
static void FillPolygon(ImageAccessor& image,
const std::vector& points,
int64_t value);
static void Resize(ImageAccessor& target,
const ImageAccessor& source);
static ImageAccessor* Halve(const ImageAccessor& source,
bool forceMinimalPitch);
static void FlipX(ImageAccessor& image);
static void FlipY(ImageAccessor& image);
static void SeparableConvolution(ImageAccessor& image /* inplace */,
const std::vector& horizontal,
size_t horizontalAnchor,
const std::vector& vertical,
size_t verticalAnchor,
bool useRound /* this is expensive */);
static void SmoothGaussian5x5(ImageAccessor& image,
bool useRound /* this is expensive */);
static void FitSize(ImageAccessor& target,
const ImageAccessor& source);
// Resize the image to the given width/height. The resized image
// occupies the entire canvas (aspect ratio is not preserved).
static ImageAccessor* FitSize(const ImageAccessor& source,
unsigned int width,
unsigned int height);
// Resize an image, but keeps its original aspect ratio. Zeros are
// added around the image to reach the specified size.
static ImageAccessor* FitSizeKeepAspectRatio(const ImageAccessor& source,
unsigned int width,
unsigned int height);
// https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion
static void ConvertJpegYCbCrToRgb(ImageAccessor& image /* inplace */);
static void SwapEndianness(ImageAccessor& image /* inplace */);
static void Maximum(ImageAccessor& image /* inout */,
const ImageAccessor& other);
static void Render(ImageAccessor& target,
const DicomImageInformation& info,
const ImageAccessor& source,
const Window& window);
static void RenderDefaultWindow(ImageAccessor& target,
const DicomImageInformation& info,
const ImageAccessor& source);
};
}