2022-06-28 09:16:03 +00:00
|
|
|
|
#include "G4Tiff.h"
|
2022-07-18 08:56:03 +00:00
|
|
|
|
#if defined(WIN32) || defined(_WIN64)
|
2022-06-28 09:16:03 +00:00
|
|
|
|
#include <io.h>
|
|
|
|
|
#else
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#define _access access
|
|
|
|
|
#define _fileno fileno
|
|
|
|
|
#define _lseek lseek
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
G4Tiff::G4Tiff(cv::Mat & mat, Mode mode,std::string path
|
|
|
|
|
, int threshold,int res, int compression)
|
|
|
|
|
: m_threshold(threshold), m_res(res), m_mode(mode)
|
|
|
|
|
, compression_(compression)
|
|
|
|
|
{
|
|
|
|
|
m_tmppath = mode == Mode::MemoryMode ? cv::tempfile(".tif").c_str() : path;
|
|
|
|
|
m_mat = mat;
|
|
|
|
|
if (mode == Mode::MemoryMode)
|
|
|
|
|
save(mat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
G4Tiff::~G4Tiff()
|
|
|
|
|
{
|
|
|
|
|
if (m_mode == Mode::MemoryMode)
|
|
|
|
|
{
|
|
|
|
|
if (_access(m_tmppath.c_str(), 0) == 0)
|
|
|
|
|
{
|
|
|
|
|
if (!std::remove(m_tmppath.c_str())) {}//ɾ<><C9BE><EFBFBD>ɹ<EFBFBD>
|
|
|
|
|
else
|
|
|
|
|
throw std::runtime_error("File is not exist");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uchar* G4Tiff::load_mini_file(const char* file, size_t* bytes, void* (*mem_alloc)(size_t, const char*))
|
|
|
|
|
{
|
|
|
|
|
uchar* buf = nullptr;
|
|
|
|
|
|
|
|
|
|
if (bytes)
|
|
|
|
|
*bytes = 0;
|
|
|
|
|
|
|
|
|
|
FILE* src = fopen(file, "rb");
|
|
|
|
|
if (src)
|
|
|
|
|
{
|
|
|
|
|
int filesize = _lseek(_fileno(src), 0, SEEK_END); // seek to EOF
|
|
|
|
|
fseek(src, 0, SEEK_SET);
|
|
|
|
|
std::vector<uchar> ifh(8, 0);
|
|
|
|
|
fread(ifh.data(), 1, ifh.size(), src);
|
|
|
|
|
int size = (int)(*(int*)(ifh.data() + 4));
|
|
|
|
|
fseek(src, 8, SEEK_SET);
|
|
|
|
|
if (filesize)
|
|
|
|
|
{
|
|
|
|
|
if (bytes)
|
|
|
|
|
*bytes = size;
|
|
|
|
|
buf = (uchar*)mem_alloc(size, "");
|
|
|
|
|
if (buf)
|
|
|
|
|
fread(buf, 1, size, src);
|
|
|
|
|
}
|
|
|
|
|
fclose(src);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void G4Tiff::GetCompressedData(std::vector<uchar>& cmpeddata)
|
|
|
|
|
{
|
|
|
|
|
if (m_tmppath.empty())
|
|
|
|
|
throw std::runtime_error("file is not exist");
|
|
|
|
|
FILE* file = fopen(m_tmppath.c_str(), "rb");
|
|
|
|
|
if (file)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
int filesize = _lseek(_fileno(file), 0, SEEK_END); // seek to EOF
|
|
|
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
|
std::vector<uchar> ifh(8, 0);
|
|
|
|
|
fread(ifh.data(), 1, ifh.size(), file);
|
|
|
|
|
int size = (int)(*(int*)(ifh.data() + 4));
|
|
|
|
|
fseek(file, 8, SEEK_SET);
|
|
|
|
|
if (filesize)
|
|
|
|
|
{
|
|
|
|
|
cmpeddata.resize(size);
|
|
|
|
|
fread(cmpeddata.data(), 1, size, file);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fclose(file);
|
|
|
|
|
}
|
|
|
|
|
uchar* G4Tiff::get_compressed_data(size_t* bytes, void* (*mem_alloc)(size_t, const char*))
|
|
|
|
|
{
|
|
|
|
|
if (m_tmppath.empty())
|
|
|
|
|
throw std::runtime_error("file is not exist");
|
|
|
|
|
|
|
|
|
|
return G4Tiff::load_mini_file(m_tmppath.c_str(), bytes, mem_alloc);
|
|
|
|
|
}
|
|
|
|
|
void G4Tiff::SaveG4Tiff()
|
|
|
|
|
{
|
|
|
|
|
save(m_mat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void G4Tiff::save(cv::Mat& mat)
|
|
|
|
|
{
|
|
|
|
|
if (compression_ == COMPRESSION_CCITT_T6 && mat.channels() != 1)
|
|
|
|
|
throw std::runtime_error("mat channel error");
|
|
|
|
|
TIFF* pTiffHandle = TIFFOpen(m_tmppath.c_str(), "w");
|
|
|
|
|
if (!pTiffHandle)
|
|
|
|
|
{
|
|
|
|
|
printf("can't open TIFF descriptor\n");
|
|
|
|
|
}
|
|
|
|
|
int width = mat.cols;
|
|
|
|
|
int height = mat.rows;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_IMAGEWIDTH, width), "width");
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_IMAGELENGTH, height), "length");
|
|
|
|
|
if (compression_ == COMPRESSION_CCITT_T6)
|
|
|
|
|
{
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_BITSPERSAMPLE, 1), "bits per sample");
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_SAMPLESPERPIXEL, 1), "samples per pixel");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_BITSPERSAMPLE, /*mat.depth()*/8), "bits per sample");
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_SAMPLESPERPIXEL, mat.channels()), "samples per pixel");
|
|
|
|
|
}
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_ROWSPERSTRIP, height), "rows per strip");
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_COMPRESSION, compression_), "compression");
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE), "photometric");
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB), "photometric");
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG), "planar config");
|
|
|
|
|
// not necessary
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_XRESOLUTION, (float)m_res), "res x");
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_YRESOLUTION, (float)m_res), "res y");
|
|
|
|
|
except(TIFFSetField(pTiffHandle, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH), "res unit");
|
|
|
|
|
|
|
|
|
|
if (compression_ == COMPRESSION_CCITT_T6)
|
|
|
|
|
{
|
|
|
|
|
std::vector<uchar> _buffer(width / 8 + 8, 0);
|
|
|
|
|
//std::vector<uchar> _buffer(width / 8 + 1, 0);
|
|
|
|
|
uchar* buffer = &_buffer[0];
|
|
|
|
|
//int bytes = int(width / 8.0 + 0.5);
|
|
|
|
|
for (int y = 0; y < height; ++y)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* src_row = mat.ptr(y);
|
|
|
|
|
for (int x = 0; x < width; ++x, ++src_row)
|
|
|
|
|
{
|
|
|
|
|
uint8_t eight_pixels = buffer[x / 8];
|
|
|
|
|
eight_pixels = eight_pixels << 1;
|
|
|
|
|
if (*src_row < m_threshold)
|
|
|
|
|
eight_pixels = eight_pixels | 1; //
|
|
|
|
|
buffer[x / 8] = eight_pixels;
|
|
|
|
|
}
|
|
|
|
|
except(TIFFWriteScanline(pTiffHandle, buffer, y, 0) != -1, "write scanline");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int l = mat.total() / mat.rows * mat.channels();
|
|
|
|
|
for (int y = 0; y < height; ++y)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* src = mat.ptr(y);
|
|
|
|
|
except(TIFFWriteScanline(pTiffHandle, src, y, 0) != -1, "write scanline");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (const std::runtime_error& e)
|
|
|
|
|
{
|
|
|
|
|
printf("TIFF writing: %s\n", e.what());
|
|
|
|
|
// TIFFClose(pTiffHandle);
|
|
|
|
|
}
|
|
|
|
|
TIFFClose(pTiffHandle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void G4Tiff::except(bool condition, const std::string & message)
|
|
|
|
|
{
|
|
|
|
|
if (!condition)
|
|
|
|
|
throw std::runtime_error("Error " + message);
|
|
|
|
|
}
|