Opened 12 years ago

Closed 12 years ago

#4779 closed defect (fixed)

ARG Driver: byte order should never change

Reported by: dzwarg Owned by: dzwarg
Priority: normal Milestone: 1.10.0
Component: GDAL_Raster Version: unspecified
Severity: normal Keywords: arg
Cc:

Description

The byte order of .ARG files is fixed in the spec, and should not vary. Remove checks for CPL_LSB, and always set bNative to TRUE

Attachments (2)

networkorder.patch (4.5 KB ) - added by dzwarg 12 years ago.
Better fix for reading/writing properly ordered bytes.
networkorder+test.patch (6.7 KB ) - added by dzwarg 12 years ago.
Fix for blocking in X and Y; addition of tests to verify bug & fix

Download all attachments as: .zip

Change History (10)

comment:1 by Even Rouault, 12 years ago

The current code looks correct to me. It enforces that the on-file order is LSB.

#ifdef CPL_LSB

int bNative = TRUE;

#else

int bNative = FALSE;

#endif

If your machine has LSB ordering, the bNative = TRUE, and indeed the on-file order is your native CPU order. If your machine has MSB ordering, bNative = FALSE and RawRasterBand() will do the byte-swapping

Am I missing something ?

comment:2 by dzwarg, 12 years ago

The .arg file should always have the same byte order, so no swapping should be happening. According to the spec (https://github.com/azavea/geotrellis/wiki/ARG-Specification):

"All data is stored in network byte order (big-endian)"

comment:3 by Even Rouault, 12 years ago

Ok, then you need to invert the values :

#ifdef CPL_LSB
    int	bNative = FALSE;
#else
    int bNative = TRUE;
#endif

The #ifdef CPL_LSB test is true if the CPU is little-endian. We definitely need different values for bNative if the CPU is little-endian or big-endian. If I understand well, they are just inverted right now.

comment:4 by Even Rouault, 12 years ago

Your patch will not do what you want. On Intel CPUs, it will assume that the data is stored in little-endian order on the disk, which contradicts with "All data is stored in network byte order (big-endian)"

by dzwarg, 12 years ago

Attachment: networkorder.patch added

Better fix for reading/writing properly ordered bytes.

comment:5 by dzwarg, 12 years ago

The problem here is two-fold:

  1. ARGDataset had the flags reversed for bNative during open.
  2. ARGDataset read data straight from the source dataset into the raw destination '.arg' file, bypassing any proper handling.

The fixes to the above are:

  1. Reverse the flags during open.
  2. Use the RasterIO method on the RasterBands to read from the source dataset, and write to the destination dataset. These RasterIO calls respect the byte order, whereas the raw write with VSIFWriteL did not.

The patch 'networkorder.patch' replaces the earlier bogus patch with the correct behavior, modeled after the mffdataset

This patch also addressses #4780

comment:6 by Even Rouault, 12 years ago

Your patch looks saner, although I suspect there's a bug in the RasterIO() call (both the read and write). The second argument should be, I think, nXBlock * nXBlockSize, instead of just nXBlock. You wouldn't notice the difference with a scanline oriented input file, but you could likely see the bug if you use for example a tiled geotiff as input of CreateCopy()

comment:7 by dzwarg, 12 years ago

Thanks! Will update the patch with this fix.

by dzwarg, 12 years ago

Attachment: networkorder+test.patch added

Fix for blocking in X and Y; addition of tests to verify bug & fix

comment:8 by dzwarg, 12 years ago

Resolution: fixed
Status: newclosed

Fixed in r24795

Note: See TracTickets for help on using tickets.