Stitch many images in one using Libtiff - c++

I want to copy many images in one big image in different positions and then save it to .tif, but I don't want to store them in memory all at once, so I need to define tiff file stored on disk, and then write my images one by one.
I'm using Libtiff. The problem that I can't see method that can write pixels to some address with displacement like
RGB* p= init_pointer+dy*width+dx
Is there any solution? (Maybe I should create just binary file and write header by my own, but it's a hard way, maybe libtiff can make it easier?)
So if I rephrase my question: how to obtain raw pointer to tiff data stored on disk for write pixel data?
For example I can create file on disk and write header by hand, and then write my images with offset using raw pointer, something like:
FILE* f = _tfopen(fileName, _T("wb"));
uint64 fileSize = headerSize + (uint64)im.Width() * im.Height() * (grayscale ? 1 : 3);
// Allocate file space
if( _fseeki64(f, fileSize - 1, SEEK_SET) == 0 &&
fputc(0, f) != EOF )
{
_fseeki64(f, 0, SEEK_SET);
// Write header
//write img using pointer with offset
int64 posPixels = headerSize + (rc.top - rcClip.top) * width + (rc.left - rcClip.left);
Once more time: I need to write many images into one image of tiff format like this http://upload.wikimedia.org/wikipedia/commons/a/a0/Rochester_NY.jpg and I must avoid creation of large image in RAM, so I need to write images one by one to file(only one image in RAM in the same time) and I trying to do this using libtiff.
Or another simple example: I have main image M(10000,10000) and I have some image m1(200,200) and I need to write image m1 to M at location (200,300)

Related

Is there a way to convert an image in the FLIR proprietary .seq format into .png?

I'm trying to convert a frame in .SEQ format into .PNG
I used the pleora ebus-sdk to automatically find and connect to my gigE FLIR camera.
Then I used:
PvBuffer* data = (PvBuffer*)myFLIR.GetFrameData();
void* data1 = myFLIR.PrepareTauSEQ(data);
size_t size = sizeof(FFF_FILE_HEADER) + sizeof(BI_DATA_T) + sizeof(GEOMETRIC_INFO_T) + data->GetAcquiredSize();
If I write data1 with size to a .seq file using std::ofstream, I can then open this .seq file in any FLIR software with no problem.
But, I want to have a PNG instead of a SEQ. How should I do this?

How to convert a string into a Standard C File ?

Hi I have an image in my memory and I want to sent it through an external FTP library.
This FTP library accepts only and only standard C FILE and the sample codes provided by this library reads data only from hard disk. In my application I don't want to store my images in the hard disk and then read them using FILE variable, instead I want to do the conversion in my memory so it's faster and more professional.
My image is in the form of uchar * but I can change it to std::String or QByteArray or any other type of string. Now I want to know how can I have a file which is filled by my image data so I will get rid of storing it into the hard disk and read it again.
My pseudo code:
uchar * image = readImage();
FILE * New_Image = String2FileConverter(image); //I need this function
FTP_Upload(New_Image);
On Posix systems, you can use fmemopen to create a memory-backed file handle.

Writing image header data using jpeglib

I want to write the header data of a JPEG image using jpeglib. Unfortunately, I am not exactly sure which header data I really do need. I am sure of:
- quantization table
- Huffman tables
- shared image info (I am not exactly sure which data this contains, somebody wrote about 5 unchangable bytes)
and I know that the usual header size should be 624 bytes.
My code looks like:
jpeg_mem_dest(&cinfo, &buffer, &bufferSize);
cinfo.image_width = imageWidth;
cinfo.image_height = imageHeight;
cinfo.input_components = inputComponents;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, false);
jpeg_write_tables(&cinfo);
jpeg_start_compress(&cinfo, false);
headerSize = bufferSize;
How to write only tables is taken from the jpeglib doc section "Abbreviated datastreams and multiple images".
Unfortunately, it writes only 574 bytes and when prepending the written header data to the image data without header it says "JPEG datastream contains no image" when trying to decompress it again.
Analysing an original file which uses a shared header I found the following markers:
markers found are:
FFD8 // Start Of Image
FFE0 // Application-specific
FFFE // Comment
FFDB // Define Quantization Table(s)
FFDB // Define Quantization Table(s)
FFC4 // Define Huffman Table(s)
FFC0 // Start Of Frame (Baseline DCT)
MIP maps (4 mip maps):
FFDA
FFD9
FFDA
FFD9
FFDA
FFD9
FFDA
FFD9
Descriptions are taken from
https://en.wikipedia.org/wiki/JPEG#Syntax_and_structure
From a comment in the original image I do even know the original JPEG compression lib:
Intel(R) JPEG Library, version 1,5,4,36
The point is I want to get the schema behind the format to write exactly the data which is required (apparently some essential image header information is missing otherwise it would at least find a JPEG image I guess).
In the reading process I always prepend the shared header to the image data of one single JPEG image.

Saving output frame as an image file CUDA decoder

I am trying to save the decoded image file back as a BMP image using the code in CUDA Decoder project.
if (g_bReadback && g_ReadbackSID)
{
CUresult result = cuMemcpyDtoHAsync(g_bFrameData[active_field], pDecodedFrame[active_field], (nDecodedPitch * nHeight * 3 / 2), g_ReadbackSID);
long padded_size = (nWidth * nHeight * 3 );
CString output_file;
output_file.Format(_T("image/sample_45.BMP"));
SaveBMP(g_bFrameData[active_field],nWidth,nHeight,padded_size,output_file );
if (result != CUDA_SUCCESS)
{
printf("cuMemAllocHost returned %d\n", (int)result);
}
}
But the saved image looks like this
Can anybody help me out here what am i doing wrong .. Thank you.
After investigating further, there were several modifications I made to your approach.
pDecodedFrame is actually in some non-RGB format, I think it is NV12 format which I believe is a particular YUV variant.
pDecodedFrame gets converted to an RGB format on the GPU using a particular CUDA kernel
the target buffer for this conversion will either be a surface provided by OpenGL if g_bUseInterop is specified, or else an ordinary region allocated by the driver API version of cudaMalloc if interop is not specified.
The target buffer mentioned above is pInteropFrame (even in the non-interop case). So to make an example for you, for simplicity I chose to only use the non-interop case, because it's much easier to grab the RGB buffer (pInteropFrame) in that case.
The method here copies pInteropFrame back to the host, after it has been populated with the appropriate RGB image by cudaPostProcessFrame. There is also a routine to save the image as a bitmap file. All of my modifications are delineated with comments that include RMC so search for that if you want to find all the changes/additions I made.
To use, drop this file in the cudaDecodeGL project as a replacement for the videoDecodeGL.cpp source file. Then rebuild the project. Then run the executable normally to display the video. To capture a specific frame, run the executable with the nointerop command-line switch, eg. cudaDecodGL nointerop and the video will not display, but the decode operation and frame capture will take place, and the frame will be saved in a framecap.bmp file. If you want to change the specific frame number that is captured, modify the g_FrameCapSelect = 37; variable to some other number besides 37, and recompile.
Here is the replacement for videoDecodeGL.cpp I used pastebin because SO has a limit on the number of characters that can be entered in a question body.
Note that my approach is independent of whether readback is specified. I would recommend not using readback for this sequence.

Using libtiff's TIFFReadRawTile to get a jpeg tile without decompression/compression

i've a pyramidal tiled tiff file and I want to extract the tiles without decoding and re-encoding the jpeg, i've seen that using TIFFReadRawTile() function you can extract the raw tile without decoding, how can i write the extracted buffer to a readable jpeg file?
The task you are up to is not a trivial one. You might want to take a closer look at tiff2pdf utility's source code. The utility does what you need and you might extract relevant parts from it.
The problem is, the utility does many other things you will have to discard. Also, not any JPEG-in-TIFF could be successfully processed by the utility. Basically, because there is enough semi-broken TIFFs out there.
I've found that actually there is no way to get the encoded tile without directly messing with the huffmann tables of the tiff, which is pretty tricky.
The only way I've found is to read the decoded tile and then do some magic with vips to output to jpeg directly.
tdata_t buf;
tsize_t len;
buf = _TIFFmalloc( TIFFTileSize( tif ) );
len = TIFFReadEncodedTile(tif, tile, buf, (tsize_t) -1);
VImage result ((void *) buf, 256, 256, 3, VImage::FMTUCHAR);
void *outBuffer;
unsigned long len;
vips_jpegsave_buffer(result, &outBuffer, &len, "Q", 90, NULL);
and the use cout to output the image after some headers.