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

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.

Related

Having problems loading a jpg file using libjpeg

I need to load jpg files in my application. I used libjpeg to save JPGs (from processed raw files) and it works nicely.
Reading them though is a different issue. I am getting very weird results, the image is very distorted, in 12 columns, which are mostly gray scale.
I followed the example, and the only modification I made is how to put the data in my buffer (the put_scanline_someplace() function is missing from the example.
Here is my relevant code (I need the data in BGR format):
dest=0;
while(cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, buffer, 1);
src=0;
for(i=0;i<cinfo.output_width;i++)
{
image_buffer[dest*3+2]=buffer[src*3+0];
image_buffer[dest*3+1]=buffer[src*3+1];
image_buffer[dest*3+0]=buffer[src*3+2];
src++;
dest++;
}
}
Is there something wrong with this code?
I found the solution. buffer isa pointer to an array of ints, so the code that works is like so:
image_buffer[dest*3+2]=buffer[0][src*3+0];
image_buffer[dest*3+1]=buffer[0][src*3+1];
image_buffer[dest*3+0]=buffer[0][src*3+2];

Convert decoded frames to WAV format using ffmpeg libraries

I have a stl queue of pointers to decoded frames on the heap
(e.g. decode_queue<AVFrame *>)
and I want to take those frames from the stl queue and encode them in WAV format. I tried using the examples that come with ffmpeg they break when I try to change the encoder to pcm_s32le/pcm_s16le. For example for decoding_encoding.c example, I just tried to change some parameters and all of a sudden I am getting a floating point exception.
Is there a something I can do? I am really lost.
UPDATE
In decoding_encoding.c i changed the line:
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
to
codec = avcodec_find_encoder(AV_CODEC_ID_PCM_S16LE);
this changed ended up making the c->frame_size == 0 So the buffer is never created:
buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
c->sample_fmt, 0);
In that case instead of the line:
frame->nb_samples = c->frame_size;
I changed it to
frame->nb_samples = 10000
and
buffer_size = av_samples_get_buffer_size(NULL, c->channels, 10000,
c->sample_fmt, 0);
just to see what happens(basically substituted c->frame_size for 10000). It compiles but it creates an output file but the player cannot find a stream for it or it is filled with garbage. At this point I am still stuck not sure what to do to get the output.WAV file.
Also, is a RIFF header automatically added or do I have to manually add it in as well?

Stitch many images in one using Libtiff

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)

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.

ZLib Decompression in C++

I am trying to get a function going to unzip a single text file compressed with .gz. It needs to uncompress the .gz file given its path and write the uncompressed text file given its destination. I am using C++ and what I have seen is that ZLIB does exactly what I need except I cannot find 1 single example anywhere on the net that shows it doing this. Can anyone show me an example or at least guide me in the right direction?
If you just want to inflate a file with raw deflated data (i.e. no archive) you can use something like this:
gzFile inFileZ = gzopen(fileName, "rb");
if (inFileZ == NULL) {
printf("Error: Failed to gzopen %s\n", filename);
exit(0);
}
unsigned char unzipBuffer[8192];
unsigned int unzippedBytes;
std::vector<unsigned char> unzippedData;
while (true) {
unzippedBytes = gzread(inFileZ, unzipBuffer, 8192);
if (unzippedBytes > 0) {
unzippedData.insert(unzippedData.end(), unzipBuffer, unzipBuffer + unzippedBytes);
} else {
break;
}
}
gzclose(inFileZ);
The unzippedData vector now holds your inflated data. There are probably more efficient ways to store the inflated data, especially if you know the uncompressed size in advance, but this approach works for me.
If you only want to save the inflated data to a file without any further processing you could skip the vector and just write the unzipBuffer contents to another file.
You can use the gzopen(), gzread(), and gzclose() functions of zlib, much like you would the corresponding stdio functions fopen(), etc. That will read the gzip file and decompress it. You can then use fopen(), fwrite(), etc. to write the uncompressed data back out.
You can use ZLibComplete to do this. There is a complete example in C++ on the front page of GZip decompression.
http://rudi-cilibrasi.github.io/zlibcomplete/
Ah, I'll assume http://zlib.net/zlib_how.html does what you want?