Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Further calls to RasterIO on a jpeg dataset don't work after reading full image at full resolution #1947

Closed
cdufty opened this issue Oct 23, 2019 · 0 comments
Milestone

Comments

@cdufty
Copy link

cdufty commented Oct 23, 2019

Expected behavior and actual behavior.

For various reasons we use GDALOpenShared to open the dataset and sometimes have the same dataset open for different purposes. If the same dataset is used first to load the full image at full resolution and then to load a subset of the image then the second read will fail to read new lines from the image and instead fills the buffer with many copies of the last line of the image.

I suspect this problem might have been introduced by this commit. I think previously when nLoadedScanline was not set to -1 then the next read would have cause a Restart.
I'm not sure what the correct fix would be or if it is just me doing something wrong. I couldn't think of an easy way to work around the problem apart from not using GDALOpenShared.

Steps to reproduce the problem.

int main()
{
  GDALAllRegister();
  auto pDataset = (GDALDataset*)GDALOpenShared("data/albania.jpg", GA_ReadOnly);
  if (pDataset == nullptr)
    return -1;

  CPLErr ioError;
  int nXSize = pDataset->GetRasterXSize();
  int nYSize = pDataset->GetRasterYSize();
  int nBandCount = 3;
  int anBandMap[3] = { 1, 2, 3 };
  GSpacing nPixelSpace = 4;
  GSpacing nLineSpace = nXSize * nPixelSpace;
  GSpacing nBandSpace = 1;
  GDALRasterIOExtraArg* pExtraArgs = nullptr;
  std::vector<unsigned char> data(nLineSpace * nYSize, '\0');

  // Read the full image at full resolution
  //  This goes into an optimised path that reads directly into the passed in buffer and
  //  leaves the dataset in a state where the next read causes an error.
  ioError = pDataset->RasterIO(GF_Read, 0, 0, nXSize, nYSize, &data[0], nXSize, nYSize, GDT_Byte,
                               nBandCount, anBandMap, nPixelSpace, nLineSpace, nBandSpace, pExtraArgs);

  int nYSize2 = nYSize / 2;
  std::vector<unsigned char> data2(nLineSpace * nYSize2, '\0');
  // This time just read half of the image so it doesn't go down the optimised path.
  // This call causes an error in jpeg_read_scanlines from reading too many scanlines 
  // which makes it return without updating the buffer.
  ioError = pDataset->RasterIO(GF_Read, 0, 0, nXSize, nYSize2, &data2[0], nXSize, nYSize2, GDT_Byte,
                               nBandCount, anBandMap, nPixelSpace, nLineSpace, nBandSpace, pExtraArgs);
  GDALClose(pDataset);
  // The first half of data should be the same as data2 but it isn't
  int nCompareResult = memcmp(&data[0], &data2[0], data2.size());
  return nCompareResult;
  }

Operating system

Windows 10

GDAL version and provenance

version 3.0.0

rouault added a commit that referenced this issue Oct 23, 2019
@rouault rouault added this to the 2.4.3 milestone Oct 23, 2019
rouault added a commit that referenced this issue Oct 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants