@@ -586,71 +586,6 @@ EditISIS3MetadataForBandChange(const char *pszJSON, int nSrcBandCount,
586
586
return oRoot.Format (CPLJSONObject::PrettyFormat::Pretty);
587
587
}
588
588
589
- /* ***********************************************************************/
590
- /* AdjustNoDataValue() */
591
- /* ***********************************************************************/
592
-
593
- static double AdjustNoDataValue (double dfInputNoDataValue,
594
- GDALRasterBand *poBand,
595
- const GDALTranslateOptions *psOptions)
596
- {
597
- bool bSignedByte = false ;
598
- const char *pszPixelType =
599
- psOptions->aosCreateOptions .FetchNameValue (" PIXELTYPE" );
600
- if (pszPixelType == nullptr && poBand->GetRasterDataType () == GDT_Byte)
601
- {
602
- poBand->EnablePixelTypeSignedByteWarning (false );
603
- pszPixelType = poBand->GetMetadataItem (" PIXELTYPE" , " IMAGE_STRUCTURE" );
604
- poBand->EnablePixelTypeSignedByteWarning (true );
605
- }
606
- if (pszPixelType != nullptr && EQUAL (pszPixelType, " SIGNEDBYTE" ))
607
- bSignedByte = true ;
608
- int bClamped = FALSE ;
609
- int bRounded = FALSE ;
610
- double dfVal = 0.0 ;
611
- const GDALDataType eBandType = poBand->GetRasterDataType ();
612
- if (bSignedByte)
613
- {
614
- if (dfInputNoDataValue < -128.0 )
615
- {
616
- dfVal = -128.0 ;
617
- bClamped = TRUE ;
618
- }
619
- else if (dfInputNoDataValue > 127.0 )
620
- {
621
- dfVal = 127.0 ;
622
- bClamped = TRUE ;
623
- }
624
- else
625
- {
626
- dfVal = static_cast <int >(floor (dfInputNoDataValue + 0.5 ));
627
- if (dfVal != dfInputNoDataValue)
628
- bRounded = TRUE ;
629
- }
630
- }
631
- else
632
- {
633
- dfVal = GDALAdjustValueToDataType (eBandType, dfInputNoDataValue,
634
- &bClamped, &bRounded);
635
- }
636
-
637
- if (bClamped)
638
- {
639
- CPLError (CE_Warning, CPLE_AppDefined,
640
- " for band %d, nodata value has been clamped "
641
- " to %.0f, the original value being out of range." ,
642
- poBand->GetBand (), dfVal);
643
- }
644
- else if (bRounded)
645
- {
646
- CPLError (CE_Warning, CPLE_AppDefined,
647
- " for band %d, nodata value has been rounded "
648
- " to %.0f, %s being an integer datatype." ,
649
- poBand->GetBand (), dfVal, GDALGetDataTypeName (eBandType));
650
- }
651
- return dfVal;
652
- }
653
-
654
589
/* ***********************************************************************/
655
590
/* GDALTranslate() */
656
591
/* ***********************************************************************/
@@ -2508,87 +2443,46 @@ GDALDatasetH GDALTranslate(const char *pszDest, GDALDatasetH hSrcDataset,
2508
2443
*/
2509
2444
if (psOptions->bSetNoData )
2510
2445
{
2511
- if (poVRTBand->GetRasterDataType () == GDT_Int64)
2512
- {
2513
- if (psOptions->osNoData .find (' .' ) != std::string::npos ||
2514
- CPLGetValueType (psOptions->osNoData .c_str ()) ==
2515
- CPL_VALUE_STRING)
2516
- {
2517
- const double dfNoData =
2518
- CPLAtof (psOptions->osNoData .c_str ());
2519
- if (GDALIsValueExactAs<int64_t >(dfNoData))
2520
- {
2521
- poVRTBand->SetNoDataValueAsInt64 (
2522
- static_cast <int64_t >(dfNoData));
2523
- }
2524
- else
2525
- {
2526
- CPLError (CE_Warning, CPLE_AppDefined,
2527
- " Cannot set nodata value %s on a Int64 band" ,
2528
- psOptions->osNoData .c_str ());
2529
- }
2530
- }
2531
- else
2532
- {
2533
- errno = 0 ;
2534
- const auto val =
2535
- std::strtoll (psOptions->osNoData .c_str (), nullptr , 10 );
2536
- if (errno == 0 )
2537
- {
2538
- poVRTBand->SetNoDataValueAsInt64 (
2539
- static_cast <int64_t >(val));
2540
- }
2541
- else
2542
- {
2543
- CPLError (CE_Warning, CPLE_AppDefined,
2544
- " Cannot set nodata value %s on a Int64 band" ,
2545
- psOptions->osNoData .c_str ());
2546
- }
2547
- }
2446
+ const char *pszPixelType =
2447
+ psOptions->aosCreateOptions .FetchNameValue (" PIXELTYPE" );
2448
+ if (pszPixelType == nullptr &&
2449
+ poVRTBand->GetRasterDataType () == GDT_Byte)
2450
+ {
2451
+ poVRTBand->EnablePixelTypeSignedByteWarning (false );
2452
+ pszPixelType =
2453
+ poVRTBand->GetMetadataItem (" PIXELTYPE" , " IMAGE_STRUCTURE" );
2454
+ poVRTBand->EnablePixelTypeSignedByteWarning (true );
2548
2455
}
2549
- else if (poVRTBand->GetRasterDataType () == GDT_UInt64)
2456
+
2457
+ bool bCannotBeExactlyRepresented = false ;
2458
+
2459
+ if (pszPixelType != nullptr && EQUAL (pszPixelType, " SIGNEDBYTE" ))
2550
2460
{
2551
- if (psOptions->osNoData .find (' .' ) != std::string::npos ||
2552
- CPLGetValueType (psOptions->osNoData .c_str ()) ==
2553
- CPL_VALUE_STRING)
2461
+ char *endptr = nullptr ;
2462
+ const double dfVal =
2463
+ CPLStrtod (psOptions->osNoData .c_str (), &endptr);
2464
+ if (endptr == psOptions->osNoData .c_str () +
2465
+ psOptions->osNoData .size () &&
2466
+ dfVal >= -128.0 && dfVal <= 127.0 &&
2467
+ static_cast <int8_t >(dfVal) == dfVal)
2554
2468
{
2555
- const double dfNoData =
2556
- CPLAtof (psOptions->osNoData .c_str ());
2557
- if (GDALIsValueExactAs<uint64_t >(dfNoData))
2558
- {
2559
- poVRTBand->SetNoDataValueAsUInt64 (
2560
- static_cast <uint64_t >(dfNoData));
2561
- }
2562
- else
2563
- {
2564
- CPLError (CE_Warning, CPLE_AppDefined,
2565
- " Cannot set nodata value %s on a UInt64 band" ,
2566
- psOptions->osNoData .c_str ());
2567
- }
2469
+ poVRTBand->SetNoDataValue (dfVal);
2568
2470
}
2569
2471
else
2570
2472
{
2571
- errno = 0 ;
2572
- const auto val =
2573
- std::strtoull (psOptions->osNoData .c_str (), nullptr , 10 );
2574
- if (errno == 0 )
2575
- {
2576
- poVRTBand->SetNoDataValueAsUInt64 (
2577
- static_cast <uint64_t >(val));
2578
- }
2579
- else
2580
- {
2581
- CPLError (CE_Warning, CPLE_AppDefined,
2582
- " Cannot set nodata value %s on a UInt64 band" ,
2583
- psOptions->osNoData .c_str ());
2584
- }
2473
+ bCannotBeExactlyRepresented = true ;
2585
2474
}
2586
2475
}
2587
2476
else
2588
2477
{
2589
- const double dfVal = AdjustNoDataValue (
2590
- CPLAtof (psOptions->osNoData .c_str ()), poVRTBand, psOptions);
2591
- poVRTBand->SetNoDataValue (dfVal);
2478
+ poVRTBand->SetNoDataValueAsString (psOptions->osNoData .c_str (),
2479
+ &bCannotBeExactlyRepresented);
2480
+ }
2481
+ if (bCannotBeExactlyRepresented)
2482
+ {
2483
+ CPLError (CE_Warning, CPLE_AppDefined,
2484
+ " Nodata value was not set to output band, "
2485
+ " as it cannot be represented on its data type." );
2592
2486
}
2593
2487
}
2594
2488
@@ -2770,7 +2664,7 @@ static void AttachDomainMetadata(GDALDatasetH hDS,
2770
2664
static void CopyBandInfo (GDALRasterBand *poSrcBand, GDALRasterBand *poDstBand,
2771
2665
int bCanCopyStatsMetadata, int bCopyScale,
2772
2666
int bCopyNoData, bool bCopyRAT,
2773
- const GDALTranslateOptions *psOptions)
2667
+ const GDALTranslateOptions * /* psOptions*/ )
2774
2668
2775
2669
{
2776
2670
@@ -2821,24 +2715,20 @@ static void CopyBandInfo(GDALRasterBand *poSrcBand, GDALRasterBand *poDstBand,
2821
2715
2822
2716
if (bCopyNoData)
2823
2717
{
2824
- if (poSrcBand->GetRasterDataType () != GDT_Int64 &&
2825
- poSrcBand->GetRasterDataType () != GDT_UInt64 &&
2826
- poDstBand->GetRasterDataType () != GDT_Int64 &&
2827
- poDstBand->GetRasterDataType () != GDT_UInt64)
2718
+ int bSuccess = FALSE ;
2719
+ CPL_IGNORE_RET_VAL (poSrcBand->GetNoDataValue (&bSuccess));
2720
+ if (bSuccess)
2828
2721
{
2829
- int bSuccess = FALSE ;
2830
- double dfNoData = poSrcBand->GetNoDataValue (&bSuccess);
2831
- if (bSuccess)
2722
+ bool bCannotBeExactlyRepresented = false ;
2723
+ if (!GDALCopyNoDataValue (poDstBand, poSrcBand,
2724
+ &bCannotBeExactlyRepresented) &&
2725
+ bCannotBeExactlyRepresented)
2832
2726
{
2833
- const double dfVal =
2834
- AdjustNoDataValue (dfNoData, poDstBand, psOptions);
2835
- poDstBand-> SetNoDataValue (dfVal );
2727
+ CPLError (CE_Warning, CPLE_AppDefined,
2728
+ " Source nodata value was not copied to output band, "
2729
+ " as it cannot be represented on its data type. " );
2836
2730
}
2837
2731
}
2838
- else
2839
- {
2840
- GDALCopyNoDataValue (poDstBand, poSrcBand);
2841
- }
2842
2732
}
2843
2733
2844
2734
if (bCopyScale)
0 commit comments