~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to frmts/pcidsk/sdk/channel/cbandinterleavedchannel.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include "pcidsk_file.h"
38
38
#include "core/pcidsk_utils.h"
39
39
#include "core/cpcidskfile.h"
 
40
#include "core/clinksegment.h"
40
41
#include "channel/cbandinterleavedchannel.h"
41
42
#include <cassert>
42
43
#include <cstring>
43
44
#include <cstdio>
 
45
#include <cstdlib>
44
46
 
45
47
using namespace PCIDSK;
46
48
 
49
51
/************************************************************************/
50
52
 
51
53
CBandInterleavedChannel::CBandInterleavedChannel( PCIDSKBuffer &image_header, 
 
54
                                                  uint64 ih_offset, 
52
55
                                                  PCIDSKBuffer &file_header,
53
56
                                                  int channelnum,
54
57
                                                  CPCIDSKFile *file,
55
58
                                                  uint64 image_offset,
56
59
                                                  eChanType pixel_type )
57
 
        : CPCIDSKChannel( image_header, file, pixel_type, channelnum )
 
60
        : CPCIDSKChannel( image_header, ih_offset, file, pixel_type, channelnum)
58
61
 
59
62
{
60
63
    io_handle_p = NULL;
81
84
/* -------------------------------------------------------------------- */
82
85
    image_header.Get(64,64,filename);
83
86
 
 
87
    filename = MassageLink( filename );
 
88
 
84
89
    if( filename.length() == 0 )
85
90
        file->GetIODetails( &io_handle_p, &io_mutex_p );
 
91
 
 
92
    else
 
93
        filename = MergeRelativePath( file->GetInterfaces()->io,
 
94
                                      file->GetFilename(), 
 
95
                                      filename );
86
96
}
87
97
 
88
98
/************************************************************************/
139
149
/*      Get file access handles if we don't already have them.          */
140
150
/* -------------------------------------------------------------------- */
141
151
    if( io_handle_p == NULL )
142
 
        file->GetIODetails( &io_handle_p, &io_mutex_p, filename.c_str() );
 
152
        file->GetIODetails( &io_handle_p, &io_mutex_p, filename.c_str(),
 
153
                            file->GetUpdatable() );
143
154
 
144
155
/* -------------------------------------------------------------------- */
145
156
/*      If the imagery is packed, we can read directly into the         */
166
177
        MutexHolder holder( *io_mutex_p );
167
178
        
168
179
        interfaces->io->Seek( *io_handle_p, offset, SEEK_SET );
169
 
        interfaces->io->Read( buffer, 1, line_from_disk.buffer_size, 
 
180
        interfaces->io->Read( line_from_disk.buffer, 
 
181
                              1, line_from_disk.buffer_size, 
170
182
                              *io_handle_p );
171
183
 
172
184
        for( i = 0, this_pixel = line_from_disk.buffer; i < xsize; i++ )
181
193
/*      Do byte swapping if needed.                                     */
182
194
/* -------------------------------------------------------------------- */
183
195
    if( needs_swap )
184
 
        SwapData( buffer, pixel_size, xsize );
 
196
        SwapPixels( buffer, pixel_type, xsize );
185
197
 
186
198
    return 1;
187
199
}
198
210
    if( !file->GetUpdatable() )
199
211
        throw PCIDSKException( "File not open for update in WriteBlock()" );
200
212
 
 
213
    InvalidateOverviews();
 
214
 
201
215
/* -------------------------------------------------------------------- */
202
216
/*      Establish region to read.                                       */
203
217
/* -------------------------------------------------------------------- */
209
223
/*      Get file access handles if we don't already have them.          */
210
224
/* -------------------------------------------------------------------- */
211
225
    if( io_handle_p == NULL )
212
 
        file->GetIODetails( &io_handle_p, &io_mutex_p, filename.c_str() );
 
226
        file->GetIODetails( &io_handle_p, &io_mutex_p, filename.c_str(),
 
227
                            file->GetUpdatable() );
213
228
 
214
229
/* -------------------------------------------------------------------- */
215
230
/*      If the imagery is packed, we can read directly into the         */
220
235
        MutexHolder holder( *io_mutex_p );
221
236
 
222
237
        if( needs_swap ) // swap before write.
223
 
            SwapData( buffer, pixel_size, width );
 
238
            SwapPixels( buffer, pixel_type, width );
224
239
 
225
240
        interfaces->io->Seek( *io_handle_p, offset, SEEK_SET );
226
241
        interfaces->io->Write( buffer, 1, window_size, *io_handle_p );
227
242
 
228
243
        if( needs_swap ) // restore to original order.
229
 
            SwapData( buffer, pixel_size, width );
 
244
            SwapPixels( buffer, pixel_type, width );
230
245
    }
231
246
 
232
247
/* -------------------------------------------------------------------- */
251
266
                    pixel_size );
252
267
 
253
268
            if( needs_swap ) // swap before write.
254
 
                SwapData( this_pixel, pixel_size, 1 );
 
269
                SwapPixels( this_pixel, pixel_type, 1 );
255
270
 
256
271
            this_pixel += pixel_size;
257
272
        }
268
283
    return 1;
269
284
}
270
285
 
 
286
/************************************************************************/
 
287
/*                            GetChanInfo()                             */
 
288
/************************************************************************/
 
289
void CBandInterleavedChannel
 
290
::GetChanInfo( std::string &filename_ret, uint64 &image_offset, 
 
291
               uint64 &pixel_offset, uint64 &line_offset, 
 
292
               bool &little_endian ) const
 
293
 
 
294
{
 
295
    image_offset = start_byte;
 
296
    pixel_offset = this->pixel_offset;
 
297
    line_offset = this->line_offset;
 
298
    little_endian = (byte_order == 'S');
 
299
 
 
300
/* -------------------------------------------------------------------- */
 
301
/*      We fetch the filename from the header since it will be the      */
 
302
/*      "clean" version without any paths.                              */
 
303
/* -------------------------------------------------------------------- */
 
304
    PCIDSKBuffer ih(64);
 
305
    file->ReadFromFile( ih.buffer, ih_offset+64, 64 );
 
306
 
 
307
    ih.Get(0,64,filename_ret);
 
308
    filename_ret = MassageLink( filename_ret );
 
309
}
 
310
 
 
311
/************************************************************************/
 
312
/*                            SetChanInfo()                             */
 
313
/************************************************************************/
 
314
 
 
315
void CBandInterleavedChannel
 
316
::SetChanInfo( std::string filename, uint64 image_offset, 
 
317
               uint64 pixel_offset, uint64 line_offset, 
 
318
               bool little_endian )
 
319
 
 
320
{
 
321
    if( ih_offset == 0 )
 
322
        ThrowPCIDSKException( "No Image Header available for this channel." );
 
323
 
 
324
/* -------------------------------------------------------------------- */
 
325
/*      Fetch the existing image header.                                */
 
326
/* -------------------------------------------------------------------- */
 
327
    PCIDSKBuffer ih(1024);
 
328
 
 
329
    file->ReadFromFile( ih.buffer, ih_offset, 1024 );
 
330
 
 
331
/* -------------------------------------------------------------------- */
 
332
/*      If the linked filename is too long to fit in the 64             */
 
333
/*      character IHi.2 field, then we need to use a link segment to    */
 
334
/*      store the filename.                                             */
 
335
/* -------------------------------------------------------------------- */
 
336
    std::string IHi2_filename;
 
337
    
 
338
    if( filename.size() > 64 )
 
339
    {
 
340
        int link_segment;
 
341
        
 
342
        ih.Get( 64, 64, IHi2_filename );
 
343
                
 
344
        if( IHi2_filename.substr(0,3) == "LNK" )
 
345
        {
 
346
            link_segment = std::atoi( IHi2_filename.c_str() + 4 );
 
347
        }
 
348
        else
 
349
        {
 
350
            char link_filename[64];
 
351
           
 
352
            link_segment = 
 
353
                file->CreateSegment( "Link    ", 
 
354
                                     "Long external channel filename link.", 
 
355
                                     SEG_SYS, 1 );
 
356
 
 
357
            sprintf( link_filename, "LNK %4d", link_segment );
 
358
            IHi2_filename = link_filename;
 
359
        }
 
360
 
 
361
        CLinkSegment *link = 
 
362
            dynamic_cast<CLinkSegment*>( file->GetSegment( link_segment ) );
 
363
        
 
364
        if( link != NULL )
 
365
        {
 
366
            link->SetPath( filename );
 
367
            link->Synchronize();
 
368
        }
 
369
    }
 
370
    
 
371
/* -------------------------------------------------------------------- */
 
372
/*      If we used to have a link segment but no longer need it, we     */
 
373
/*      need to delete the link segment.                                */
 
374
/* -------------------------------------------------------------------- */
 
375
    else
 
376
    {
 
377
        ih.Get( 64, 64, IHi2_filename );
 
378
                
 
379
        if( IHi2_filename.substr(0,3) == "LNK" )
 
380
        {
 
381
            int link_segment = std::atoi( IHi2_filename.c_str() + 4 );
 
382
 
 
383
            file->DeleteSegment( link_segment );
 
384
        }
 
385
        
 
386
        IHi2_filename = filename;
 
387
    }
 
388
        
 
389
/* -------------------------------------------------------------------- */
 
390
/*      Update the image header.                                        */
 
391
/* -------------------------------------------------------------------- */
 
392
    // IHi.2
 
393
    ih.Put( IHi2_filename.c_str(), 64, 64 );
 
394
 
 
395
    // IHi.6.1
 
396
    ih.Put( image_offset, 168, 16 );
 
397
 
 
398
    // IHi.6.2
 
399
    ih.Put( pixel_offset, 184, 8 );
 
400
 
 
401
    // IHi.6.3
 
402
    ih.Put( line_offset, 192, 8 );
 
403
 
 
404
    // IHi.6.5
 
405
    if( little_endian )
 
406
        ih.Put( "S", 201, 1 );
 
407
    else
 
408
        ih.Put( "N", 201, 1 );
 
409
 
 
410
    file->WriteToFile( ih.buffer, ih_offset, 1024 );
 
411
 
 
412
/* -------------------------------------------------------------------- */
 
413
/*      Update local configuration.                                     */
 
414
/* -------------------------------------------------------------------- */
 
415
    this->filename = MergeRelativePath( file->GetInterfaces()->io,
 
416
                                        file->GetFilename(), 
 
417
                                        filename );
 
418
 
 
419
    start_byte = image_offset;
 
420
    this->pixel_offset = pixel_offset;
 
421
    this->line_offset = line_offset;
 
422
    
 
423
    if( little_endian )
 
424
        byte_order = 'S';
 
425
    else
 
426
        byte_order = 'N';
 
427
 
 
428
/* -------------------------------------------------------------------- */
 
429
/*      Determine if we need byte swapping.                             */
 
430
/* -------------------------------------------------------------------- */
 
431
    unsigned short test_value = 1;
 
432
 
 
433
    if( ((uint8 *) &test_value)[0] == 1 )
 
434
        needs_swap = (byte_order != 'S');
 
435
    else
 
436
        needs_swap = (byte_order == 'S');
 
437
    
 
438
    if( pixel_type == CHN_8U )
 
439
        needs_swap = 0;
 
440
}
 
441
 
 
442
/************************************************************************/
 
443
/*                            MassageLink()                             */
 
444
/*                                                                      */
 
445
/*      Return the filename after applying translation of long          */
 
446
/*      linked filenames using a link segment.                          */
 
447
/************************************************************************/
 
448
 
 
449
std::string CBandInterleavedChannel::MassageLink( std::string filename_in ) const
 
450
 
 
451
{
 
452
    if (filename_in.find("LNK") == 0)
 
453
    {
 
454
        std::string seg_str(filename_in, 4, 4);
 
455
        unsigned int seg_num = std::atoi(seg_str.c_str());
 
456
        
 
457
        if (seg_num == 0)
 
458
        {
 
459
            throw PCIDSKException("Unable to find link segment. Link name: %s",
 
460
                                  filename_in.c_str());
 
461
        }
 
462
        
 
463
        CLinkSegment* link_seg = 
 
464
            dynamic_cast<CLinkSegment*>(file->GetSegment(seg_num));
 
465
        if (link_seg == NULL)
 
466
        {
 
467
            throw PCIDSKException("Failed to get Link Information Segment.");
 
468
        }
 
469
        
 
470
        filename_in = link_seg->GetPath();
 
471
    }
 
472
 
 
473
    return filename_in;
 
474
}
 
475