GDCM 2.2.1

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Examples

Extracting_All_Resolution.cxx
/*=========================================================================
Program: GDCM (Grassroots DICOM). A DICOM library
Copyright (c) 2006-2011 Mathieu Malaterre
All rights reserved.
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// This work was realised during the GSOC 2011 by Manoj Alwani
#include <fstream>
#include <openjpeg.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <gdcm_j2k.h>
#include <gdcm_jp2.h>
#include<iostream>
#include <cstring>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "gdcmImageReader.h"
#include "gdcmSequenceOfItems.h"
#include "gdcmSystem.h"
#include <fstream>
#include "gdcmMediaStorage.h"
#include "gdcmWriter.h"
#include "gdcmItem.h"
#include "gdcmImageReader.h"
#include "gdcmAttribute.h"
#include "gdcmFile.h"
#include "gdcmTag.h"
#include "gdcmTransferSyntax.h"
#include "gdcmUIDGenerator.h"
#include "gdcmAnonymizer.h"
#include "gdcmStreamImageWriter.h"
#include "gdcmImageHelper.h"
#include "gdcmTrace.h"
void error_callback(const char *msg, void *) {
(void)msg;
}
void warning_callback(const char *msg, void *) {
(void)msg;
}
void info_callback(const char *msg, void *) {
(void)msg;
}
bool Write_Resolution(gdcm::StreamImageWriter & theStreamWriter, const char *filename, int res, std::ostream& of, int flag, gdcm::SequenceOfItems *sq, int No_Of_Resolutions)
{
std::ifstream is;
is.open( filename );
opj_dparameters_t parameters; /* decompression parameters */
opj_event_mgr_t event_mgr; /* event manager */
opj_dinfo_t* dinfo; /* handle to a decompressor */
opj_cio_t *cio;
opj_image_t *image = NULL;
// FIXME: Do some stupid work:
is.seekg( 0, std::ios::end);
std::streampos buf_size = is.tellg();
char *dummy_buffer = new char[(unsigned int)buf_size];
is.seekg(0, std::ios::beg);
is.read( dummy_buffer, buf_size);
unsigned char *src = (unsigned char*)dummy_buffer;
uint32_t file_length = (uint32_t)buf_size; // 32bits truncation should be ok since DICOM cannot have larger than 2Gb image
/* configure the event callbacks (not required) */
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set decoding parameters to default values */
opj_set_default_decoder_parameters(&parameters);
// default blindly copied
parameters.cp_layer=0;
parameters.cp_reduce= res;
// parameters.decod_format=-1;
// parameters.cod_format=-1;
const char jp2magic[] = "\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A";
if( memcmp( src, jp2magic, sizeof(jp2magic) ) == 0 )
{
/* JPEG-2000 compressed image data ... sigh */
// gdcmData/ELSCINT1_JP2vsJ2K.dcm
// gdcmData/MAROTECH_CT_JP2Lossy.dcm
//gdcmWarningMacro( "J2K start like JPEG-2000 compressed image data instead of codestream" );
parameters.decod_format = 1; //JP2_CFMT;
//assert(parameters.decod_format == JP2_CFMT);
}
else
{
/* JPEG-2000 codestream */
//parameters.decod_format = J2K_CFMT;
//assert(parameters.decod_format == J2K_CFMT);
assert( 0 );
}
parameters.cod_format = 11; // PGX_DFMT;
//assert(parameters.cod_format == PGX_DFMT);
/* get a decoder handle */
dinfo = opj_create_decompress(CODEC_JP2);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);
/* setup the decoder decoding parameters using user parameters */
opj_setup_decoder(dinfo, &parameters);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
/* decode the stream and fill the image structure */
image = opj_decode(dinfo, cio);
if(!image) {
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
//gdcmErrorMacro( "opj_decode failed" );
return 1;
}
opj_cp_t * cp = ((opj_jp2_t*)dinfo->jp2_handle)->j2k->cp;
opj_tcp_t *tcp = &cp->tcps[0];
opj_tccp_t *tccp = &tcp->tccps[0];
/* std::cout << "\n No of Cols In Image" << image->x1;
std::cout << "\n No of Rows In Image" << image->y1;
std::cout << "\n No of Components in Image" << image->numcomps;
std::cout << "\n No of Resolutions"<< tccp->numresolutions << "\n";
*/
opj_j2k_t* j2k = NULL;
opj_jp2_t* jp2 = NULL;
jp2 = (opj_jp2_t*)dinfo->jp2_handle;
int reversible = jp2->j2k->cp->tcps->tccps->qmfbid;
//std:: cout << reversible;
int compno = 0;
opj_image_comp_t *comp = &image->comps[compno];
int Dimensions[2];
Dimensions[0]= comp->w;
Dimensions[1] = comp->h;
opj_cio_close(cio);
unsigned long len = Dimensions[0]*Dimensions[1] * image->numcomps;
//std::cout << "\nTest" <<image->comps[0].factor;
char *raw = new char[len];
for (unsigned int compno = 0; compno < (unsigned int)image->numcomps; compno++)
{
opj_image_comp_t *comp = &image->comps[compno];
int w = image->comps[compno].w;
int h = image->comps[compno].h;
uint8_t *data8 = (uint8_t*)raw + compno;
for (int i = 0; i < w * h ; i++)
{
int v = image->comps[compno].data[i];
*data8 = (uint8_t)v;
data8 += image->numcomps;
}
}
gdcm::Writer w;
gdcm::File &file = w.GetFile();
gdcm::DataSet &ds = file.GetDataSet();
file.GetHeader().SetDataSetTransferSyntax( gdcm::TransferSyntax::ExplicitVRLittleEndian );
gdcm::UIDGenerator uid;
gdcm::DataElement de( gdcm::Tag(0x8,0x18) ); // SOP Instance UID
de.SetVR( gdcm::VR::UI );
const char *u = uid.Generate();
de.SetByteValue( u, strlen(u) );
ds.Insert( de );
gdcm::DataElement de1( gdcm::Tag(0x8,0x16) );
de1.SetVR( gdcm::VR::UI );
gdcm::MediaStorage ms( gdcm::MediaStorage::CTImageStorage );
de1.SetByteValue( ms.GetString(), strlen(ms.GetString()));
ds.Insert( de1 );
const char mystr[] = "MONOCHROME2 ";
gdcm::DataElement de2( gdcm::Tag(0x28,0x04) );
//de.SetTag(gdcm::Tag(0x28,0x04));
de2.SetVR( gdcm::VR::CS );
de2.SetByteValue(mystr, strlen(mystr));
ds.Insert( de2 );
gdcm::Attribute<0x0028,0x0010> row = {image->comps[0].w};
//row.SetValue(512);
ds.Insert( row.GetAsDataElement() );
// w.SetCheckFileMetaInformation( true );
gdcm::Attribute<0x0028,0x0011> col = {image->comps[0].h};
ds.Insert( col.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0008> Number_Of_Frames = {1};
ds.Insert( Number_Of_Frames.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0100> at = {8};
ds.Insert( at.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0002> at1 = {image->numcomps};
ds.Insert( at1.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0101> at2 = {8};
ds.Insert( at2.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0102> at3 = {7};
ds.Insert( at3.GetAsDataElement() );
if (flag == 1)
{
for (int i=0; i < No_Of_Resolutions; i++)
{
int a = 1;
int b =1;
while(a!=((No_Of_Resolutions)-i))
{
b = b*2;
a = a+1;
}
uint16_t row = (image->y1)/b;
uint16_t col = (image->x1)/b;
//std::cout << row;
gdcm::Element<gdcm::VR::IS,gdcm::VM::VM1> el2;
el2.SetValue(i+1);
gdcm::DataElement rfn = el2.GetAsDataElement(); //ulr --> upper left row
rfn.SetTag( gdcm::Tag(0x0008,0x1160) );
gdcm::Element<gdcm::VR::US,gdcm::VM::VM2> el;
el.SetValue(1,0);
el.SetValue(1,1);
gdcm::DataElement ulr = el.GetAsDataElement(); //ulr --> upper left col/row
ulr.SetTag( gdcm::Tag(0x0048,0x0201) );
gdcm::Element<gdcm::VR::US,gdcm::VM::VM2> el1;
el1.SetValue(col,0);
el1.SetValue(row,1);
gdcm::DataElement brr = el1.GetAsDataElement();
brr.SetTag( gdcm::Tag(0x0048,0x0202) ); //brr --> bottom right col/row
gdcm::Item it;
gdcm::DataSet &nds = it.GetNestedDataSet();
nds.Insert( rfn );
nds.Insert(ulr);
nds.Insert(brr);
sq->AddItem(it);
}
gdcm::Writer w1;
gdcm::File &file1 = w1.GetFile();
gdcm::DataSet &ds1 = file1.GetDataSet();
file1.GetHeader().SetDataSetTransferSyntax( gdcm::TransferSyntax::ExplicitVRLittleEndian );
gdcm::UIDGenerator uid1;
gdcm::DataElement dea( gdcm::Tag(0x8,0x18) ); // SOP Instance UID
dea.SetVR( gdcm::VR::UI );
const char *u1 = uid1.Generate();
dea.SetByteValue( u1, strlen(u1) );
ds1.Insert( dea );
gdcm::DataElement deb( gdcm::Tag(0x8,0x16) );
deb.SetVR( gdcm::VR::UI );
gdcm::MediaStorage ms1( gdcm::MediaStorage::VLWholeSlideMicroscopyImageStorage );
deb.SetByteValue( ms1.GetString(), strlen(ms1.GetString()));
ds1.Insert( deb );
const char mystr1[] = "MONOCHROME2 ";
gdcm::DataElement dec( gdcm::Tag(0x28,0x04) );
//de.SetTag(gdcm::Tag(0x28,0x04));
dec.SetVR( gdcm::VR::CS );
dec.SetByteValue(mystr, strlen(mystr1));
ds1.Insert( dec );
gdcm::Attribute<0x0028,0x0010> row1 = {image->y1};
//row.SetValue(512);
ds1.Insert( row1.GetAsDataElement() );
// w.SetCheckFileMetaInformation( true );
gdcm::Attribute<0x0028,0x0011> col1 = {image->x1};
ds1.Insert( col1.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0008> Number_Of_Frames1 = {tccp->numresolutions};
ds1.Insert( Number_Of_Frames1.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0100> ata = {8};
ds1.Insert( ata.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0002> atb = {image->numcomps};
ds1.Insert( atb.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0101> atc = {8};
ds1.Insert( atc.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0102> atd = {7};
ds1.Insert( atd.GetAsDataElement() );
theStreamWriter.SetFile(file1);
gdcm::DataElement des( gdcm::Tag(0x0048,0x0200) );
des.SetVR(gdcm::VR::SQ);
//des.SetVR(gdcm::VM::VM1);
des.SetValue(*sq);
des.SetVLToUndefined();
ds1.Insert(des);
if (!theStreamWriter.WriteImageInformation()){
std::cerr << "unable to write image information" << std::endl;
return 1; //the CanWrite function should prevent getting here, else,
//that's a test failure
}
}
theStreamWriter.SetFile(file);
if (!theStreamWriter.CanWriteFile()){
delete [] raw;
std::cout << "Not able to write";
return 0;//this means that the file was unwritable, period.
//very similar to a ReadImageInformation failure
}
else
std::cout<<"\nabletoread";
// Important to write here
std::vector<unsigned int> extent = gdcm::ImageHelper::GetDimensionsValue(file);
unsigned short xmax = extent[0];
unsigned short ymax = extent[1];
unsigned short theChunkSize = 4;
unsigned short ychunk = extent[1]/theChunkSize; //go in chunk sizes of theChunkSize
unsigned short zmax = extent[2];
std::cout << "\n"<<xmax << "\n" << ymax<<"\n"<<zmax<<"\n" << image->numcomps<<"\n";
if (xmax == 0 || ymax == 0)
{
std::cerr << "Image has no size, unable to write zero-sized image." << std::endl;
return 0;
}
int z, y, nexty;
unsigned long prevLen = 0; //when going through the char buffer, make sure to grab
//the bytes sequentially. So, store how far you got in the buffer with each iteration.
for (z = 0; z < zmax; ++z){
for (y = 0; y < ymax; y += ychunk){
nexty = y + ychunk;
if (nexty > ymax) nexty = ymax;
theStreamWriter.DefinePixelExtent(0, xmax, y, nexty, z, z+1);
unsigned long len = theStreamWriter.DefineProperBufferLength();
std::cout << "\n" <<len;
char* finalBuffer = new char[len];
memcpy(finalBuffer, &(raw[prevLen]), len);
std::cout << "\nable to write";
if (!theStreamWriter.Write(finalBuffer, len)){
std::cerr << "writing failure:" << "output.dcm" << " at y = " << y << " and z= " << z << std::endl;
delete [] raw;
delete [] finalBuffer;
return 1;
}
delete [] finalBuffer;
prevLen += len;
}
}
delete raw;
delete[] src; //FIXME
if(dinfo) {
opj_destroy_decompress(dinfo);
}
opj_image_destroy(image);
return true;
}
bool Different_Resolution( gdcm::StreamImageWriter & theStreamWriter, const char *filename, int res, std::ostream& of)
{
//std::vector<std::string>::const_iterator it = filenames.begin();
bool b = true;
int flag = 1;
gdcm::SmartPointer<gdcm::SequenceOfItems> sq = new gdcm::SequenceOfItems();
sq->SetLengthToUndefined();
for(int i = res-1 ; i>=0; --i)
{
b = b && Write_Resolution( theStreamWriter, filename, i, of ,flag,sq,res);
// b = b && Get_Resolution( theStreamWriter, filename, i, of ,0);
flag = 0;
}
//b = b && Get_Lowest_Resolution( writer, sq, filename, res-1 );
//b = b && PopulateSingeFile( writer, sq, jpeg, filename2 );
//image.SetDimension(2, res )
return b;
}
int main(int argc, char *argv[])
{
if( argc < 4 )
{
std::cerr << argv[0] << " input.jp2 output.dcm No. Of Resolutions " << std::endl;
return 1;
}
const char *filename = argv[1];
const char *outfilename = argv[2];
char *resolutions = argv[3];
int res = int((*resolutions)-48);
//std:: cout << "\nres"<< res;
gdcm::StreamImageWriter theStreamWriter;
std::ofstream of;
of.open( outfilename, std::ios::out | std::ios::binary );
theStreamWriter.SetStream(of);
if( !Different_Resolution( theStreamWriter, filename,res,of ) ) return 1;
uint16_t firstTag1 = 0xfffe;
uint16_t secondTag1 = 0xe0dd;
uint32_t thirdTag1 = 0x00000000;
//uint16_t fourthTag1 = 0xffff;
const int theBufferSize1 = 2*sizeof(uint16_t)+sizeof(uint32_t);
char* tmpBuffer2 = new char[theBufferSize1];
memcpy(&(tmpBuffer2[0]), &firstTag1, sizeof(uint16_t));
memcpy(&(tmpBuffer2[sizeof(uint16_t)]), &secondTag1, sizeof(uint16_t));
memcpy(&(tmpBuffer2[2*sizeof(uint16_t)]), &thirdTag1, sizeof(uint32_t));
//memcpy(&(tmpBuffer2[3*sizeof(uint16_t)]), &fourthTag1, sizeof(uint16_t));
assert( of && !of.eof() && of.good() );
of.write(tmpBuffer2, theBufferSize1);
of.flush();
assert( of );
return 0;
}