aimsgui 6.0.16
qtformatsR.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2 * Institut Federatif de Recherche 49
3 * CEA/NeuroSpin, Batiment 145,
4 * 91191 Gif-sur-Yvette cedex
5 * France
6 *
7 * This software is governed by the CeCILL license version 2 under
8 * French law and abiding by the rules of distribution of free software.
9 * You can use, modify and/or redistribute the software under the
10 * terms of the CeCILL license version 2 as circulated by CEA, CNRS
11 * and INRIA at the following URL "http://www.cecill.info".
12 *
13 * As a counterpart to the access to the source code and rights to copy,
14 * modify and redistribute granted by the license, users are provided only
15 * with a limited warranty and the software's author, the holder of the
16 * economic rights, and the successive licensors have only limited
17 * liability.
18 *
19 * In this respect, the user's attention is drawn to the risks associated
20 * with loading, using, modifying and/or developing or reproducing the
21 * software by the user in light of its specific status of free software,
22 * that may mean that it is complicated to manipulate, and that also
23 * therefore means that it is reserved for developers and experienced
24 * professionals having in-depth computer knowledge. Users are therefore
25 * encouraged to load and test the software's suitability as regards their
26 * requirements in conditions enabling the security of their systems and/or
27 * data to be ensured and, more generally, to use and operate it in the
28 * same conditions as regards security.
29 *
30 * The fact that you are presently reading this means that you have had
31 * knowledge of the CeCILL license version 2 and that you accept its terms.
32 */
33
34#ifndef AIMS_IO_QTFORMATSR_H
35#define AIMS_IO_QTFORMATSR_H
36
37#include <cartodata/volume/volume.h>
39#include <aims/io/datatypecode.h>
40#include <aims/rgb/rgb.h>
41#include <cartobase/stream/fileutil.h>
42#include <cartobase/exception/file.h>
43#include <cartobase/exception/format.h>
44#include <soma-io/datasource/filedatasource.h>
45#include <cartobase/thread/mutex.h>
46#include <map>
47#include <qcolor.h>
48#include <QImage>
49#include <QImageReader>
50#include <QImageWriter>
51#include <QString>
52
53namespace aims
54{
55 QString getQImageFormatName(QImage::Format format) {
56 static const std::map<QImage::Format, QString> formatNames = {
57 {QImage::Format_Invalid, "Format_Invalid"},
58 {QImage::Format_Mono, "Format_Mono"},
59 {QImage::Format_MonoLSB, "Format_MonoLSB"},
60 {QImage::Format_Indexed8, "Format_Indexed8"},
61 {QImage::Format_RGB32, "Format_RGB32"},
62 {QImage::Format_ARGB32, "Format_ARGB32"},
63 {QImage::Format_ARGB32_Premultiplied, "Format_ARGB32_Premultiplied"},
64 {QImage::Format_RGB16, "Format_RGB16"},
65 {QImage::Format_ARGB8565_Premultiplied, "Format_ARGB8565_Premultiplied"},
66 {QImage::Format_RGB666, "Format_RGB666"},
67 {QImage::Format_ARGB6666_Premultiplied, "Format_ARGB6666_Premultiplied"},
68 {QImage::Format_RGB555, "Format_RGB555"},
69 {QImage::Format_ARGB8555_Premultiplied, "Format_ARGB8555_Premultiplied"},
70 {QImage::Format_RGB888, "Format_RGB888"},
71 {QImage::Format_RGB444, "Format_RGB444"},
72 {QImage::Format_ARGB4444_Premultiplied, "Format_ARGB4444_Premultiplied"},
73 {QImage::Format_RGBX8888, "Format_RGBX8888"},
74 {QImage::Format_RGBA8888, "Format_RGBA8888"},
75 {QImage::Format_RGBA8888_Premultiplied, "Format_RGBA8888_Premultiplied"},
76 {QImage::Format_BGR30, "Format_BGR30"},
77 {QImage::Format_A2BGR30_Premultiplied, "Format_A2BGR30_Premultiplied"},
78 {QImage::Format_RGB30, "Format_RGB30"},
79 {QImage::Format_A2RGB30_Premultiplied, "Format_A2RGB30_Premultiplied"},
80 {QImage::Format_Alpha8, "Format_Alpha8"},
81 {QImage::Format_Grayscale8, "Format_Grayscale8"},
82 {QImage::Format_Grayscale16, "Format_Grayscale16"},
83 };
84
85 auto it = formatNames.find(format);
86 if (it != formatNames.end()) {
87 return it->second;
88 } else {
89 return "Format_Inconnu";
90 }
91 }
92
93 template<typename T>
95 {
96 public:
97 QtFormatsReader( const std::string& name ) : _name( name ) {}
99
100 void read( carto::Volume<T>& thing,
101 const carto::AllocatorContext & context,
102 carto::Object options );
105 void readFrame( carto::Volume<T> & thing, QtFormatsHeader* hdr,
106 const std::string & filename, unsigned zfame,
107 unsigned tframe );
108
109 private:
110 std::string _name;
111 static T convertColor( const QRgb & );
112 };
113
114
115 template <typename T>
116 inline QtFormatsReader<T> &
118 {
119 reader.read( thing );
120 return reader;
121 }
122
123
124 template <typename T>
125 inline
127 const carto::AllocatorContext & context,
128 carto::Object options )
129 {
130 QtFormatsHeader *hdr = new QtFormatsHeader( _name );
131 try
132 {
133 hdr->read();
134 }
135 catch( std::exception & e )
136 {
137 delete hdr;
138 throw;
139 }
140
141 int frame = -1, border = 0;
142 options->getProperty( "frame", frame );
143 options->getProperty( "border", border );
144
145 std::vector<std::string> files = hdr->inputFilenames();
146
147 unsigned tmin = 0, tmax = hdr->dimT() - 1;
148 if( frame >= 0 )
149 {
150 if( tmax < (unsigned) frame )
151 {
152 delete hdr;
153 throw std::domain_error( "frame higher than file dimT" );
154 }
155 if( (unsigned) frame < tmax )
156 files.erase( files.begin() + ( frame + 1 ) * hdr->dimZ(),
157 files.end() );
158 if( frame > 0 )
159 files.erase( files.begin(), files.begin() + frame * hdr->dimZ() );
160 tmin = frame;
161 tmax = frame;
162 }
163
164 carto::AllocatorContext al
165 ( context.accessMode(),
167 ( new carto::FileDataSource( *files.begin(), 0,
168 carto::DataSource::Read ) ),
169 false, context.useFactor() );
170
171 carto::VolumeRef<T> data( hdr->dimX(), hdr->dimY(), hdr->dimZ(),
172 tmax - tmin + 1, border, al );
173
174 std::vector<float> vs( 4, 1. );
175 vs[0] = hdr->sizeX();
176 vs[1] = hdr->sizeY();
177 vs[2] = hdr->sizeZ();
178 vs[3] = hdr->sizeT();
179 data->header().setProperty( "voxel_size", vs );
180
181 std::vector<int> dims(4);
182 dims[0] = hdr->dimX();
183 dims[1] = hdr->dimY();
184 dims[2] = hdr->dimZ();
185 dims[3] = tmax - tmin + 1;
186 hdr->setProperty( "volume_dimension", dims );
187
188 // force data type into header
190 hdr->setType( dtc.dataType() );
191 std::string dir = carto::FileUtil::dirname( _name );
192 if( !dir.empty() )
194
195 unsigned i = 0, s, t, ns = (unsigned) data.getSizeZ(),
196 nt = tmax - tmin + 1;
197 for( t=0; t<nt; ++t )
198 for( s=0; s<ns; ++s, ++i )
199 readFrame( *data, hdr, dir + files[i], s, t );
200
201 thing = *data;
202 if( hdr->hasProperty( "filenames" ) )
203 hdr->removeProperty( "filenames" );
204 thing.header().copyProperties( hdr );
205 }
206
207 template<typename T>
208 inline
210 QtFormatsHeader * hdr,
211 const std::string & name, unsigned z,
212 unsigned t )
213 {
214 // std::cout << "volume data type: " << carto::DataTypeCode<T>::name() << "\n";
215 // std::cout << "readFrame: " << name << ", z: " << z << ", t: " << t << "\n";
216 const QImage *imp = 0;
217 QImage ima;
218 QImageReader qio;
219
220 if( hdr->filename() == name && hdr->hasRead() )
221 imp = &hdr->qimage();
222 else
223 {
224 std::string format;
225 hdr->getProperty( "file_type", format );
226 qio.setFileName( name.c_str() );
227 qio.setFormat( format.c_str() );
228 bool lock = false;
229 if( format == "JP2" )
230 {
231 lock = true;
233 }
234 ima = qio.read();
235 if( lock )
237 if( ima.isNull() )
238 throw carto::format_mismatch_error( name );
239 imp = &ima;
240 }
241
242 const QImage & im = *imp;
243 int y, dx = data.getSizeX(), dy = data.getSizeY();
244
245 // std::cout << "-- QTPLUGIN::readFrame - image format: " << getQImageFormatName(im.format()).toStdString() << std::endl
246 // << "-- QTPLUGIN::readFrame - image depth: " << carto::toString(im.depth()) << std::endl
247 // << "-- QTPLUGIN::readFrame - sizeof(T): " << carto::toString(sizeof(T)) << std::endl
248 // << "-- QTPLUGIN::readFrame - im.colorCount(): " << carto::toString(im.colorCount()) << std::endl;
249
250 // [NS-2026-04-13] : It is necessary to deal with gray levels data
251 if ( im.allGray() && (im.depth() == (sizeof(T) * 8) && im.colorCount() == 0 ) )
252 for( y=0; y<dy; ++y )
253 memcpy( &data.at( 0, y, z, t ), im.scanLine( y ), dx * sizeof( T ) );
254 else
255 // We must convert anyway because the Qt internal format is BGRA
256 for( y=0; y<dy; ++y )
257 for( int x=0; x<dx; ++x )
258 data.at( x, y, z, t ) = convertColor( im.pixel( x, y ) );
259 }
260
261
262 template<typename T> inline
263 T QtFormatsReader<T>::convertColor( const QRgb & x )
264 {
265 return (T) sqrt( ( ( (double) qRed( x ) ) * (double) qRed( x )
266 + qGreen( x ) * (double) qGreen( x )
267 + qBlue( x ) * (double) qBlue( x ) ) / 3 );
268 }
269
270
271 template<> inline
272 AimsRGB QtFormatsReader<AimsRGB>::convertColor( const QRgb & x )
273 {
274 return AimsRGB( (byte) qRed( x ), (byte) qGreen( x ), (byte) qBlue( x ) );
275 }
276
277
278 template<> inline
279 AimsRGBA QtFormatsReader<AimsRGBA>::convertColor( const QRgb & x )
280 {
281 return AimsRGBA( (byte) qRed( x ), (byte) qGreen( x ), (byte) qBlue( x ),
282 (byte) qAlpha( x ) );
283 }
284
285}
286
287#endif
288
The descriptor class of the .dim GIS header.
void setType(const std::string &t)
bool hasRead() const
static carto::Mutex & qformatsMutex()
virtual void read()
QtFormatsReader(const std::string &name)
Definition qtformatsR.h:97
void read(carto::Volume< T > &thing, const carto::AllocatorContext &context, carto::Object options)
Definition qtformatsR.h:126
void readFrame(carto::Volume< T > &thing, QtFormatsHeader *hdr, const std::string &filename, unsigned zfame, unsigned tframe)
called by read(), but you can call it for single frame reading (axial slice)
Definition qtformatsR.h:209
std::string filename() const
virtual std::vector< std::string > inputFilenames()
std::string dataType()
virtual void copyProperties(Object source)
static char separator()
static std::string dirname(const std::string &)
const PropertySet & header() const
void setProperty(const std::string &, const T &)
virtual bool getProperty(const std::string &, Object &) const
virtual bool removeProperty(const std::string &)
virtual void setProperty(const std::string &, Object)
virtual bool hasProperty(const std::string &) const
int getSizeY() const
int getSizeX() const
int getSizeZ() const
const PropertySet & header() const
const T & at(long x, long y=0, long z=0, long t=0) const
QString getQImageFormatName(QImage::Format format)
Definition qtformatsR.h:55
GenesisReader< T > & operator>>(GenesisReader< T > &reader, AimsData< T > &thing)
carto::VoxelRGBA AimsRGBA
carto::VoxelRGB AimsRGB