diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.TablesByName.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.TablesByName.atx new file mode 100644 index 000000000000..0f518f7a271f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.TablesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.gdbindexes new file mode 100644 index 000000000000..b02aa7510589 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.gdbtable new file mode 100644 index 000000000000..39aa11c24edc Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.gdbtablx new file mode 100644 index 000000000000..936805dcc60b Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000001.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000002.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000002.gdbtable new file mode 100644 index 000000000000..a0af90eaae1f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000002.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000002.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000002.gdbtablx new file mode 100644 index 000000000000..7c12c5681950 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000002.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000003.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000003.gdbindexes new file mode 100644 index 000000000000..58df68d525b4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000003.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000003.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000003.gdbtable new file mode 100644 index 000000000000..e7801afe8f9d Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000003.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000003.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000003.gdbtablx new file mode 100644 index 000000000000..2f80ed4fe5fe Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000003.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000004.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000004.gdbindexes new file mode 100644 index 000000000000..a4f334d7ba2a Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000004.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000004.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000004.gdbtable new file mode 100644 index 000000000000..5b77f9f26420 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000004.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000004.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000004.gdbtablx new file mode 100644 index 000000000000..cd59dfbb52fa Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000004.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.CatItemTypesByName.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.CatItemTypesByName.atx new file mode 100644 index 000000000000..c01991aa9c1f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.CatItemTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.CatItemTypesByParentTypeID.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.CatItemTypesByParentTypeID.atx new file mode 100644 index 000000000000..fed8da66b6a1 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.CatItemTypesByParentTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.CatItemTypesByUUID.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.CatItemTypesByUUID.atx new file mode 100644 index 000000000000..8392ebcd41f9 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.CatItemTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.gdbindexes new file mode 100644 index 000000000000..bc887093f340 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.gdbtable new file mode 100644 index 000000000000..9a9af20d7cd1 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.gdbtablx new file mode 100644 index 000000000000..cd82d543ccb6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000005.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.CatRelsByDestinationID.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.CatRelsByDestinationID.atx new file mode 100644 index 000000000000..8fcc74c8b7c7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.CatRelsByDestinationID.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.CatRelsByOriginID.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.CatRelsByOriginID.atx new file mode 100644 index 000000000000..8a21e3378091 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.CatRelsByOriginID.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.CatRelsByType.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.CatRelsByType.atx new file mode 100644 index 000000000000..5143e308957b Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.CatRelsByType.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.FDO_UUID.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.FDO_UUID.atx new file mode 100644 index 000000000000..c2af0446a52f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.FDO_UUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.gdbindexes new file mode 100644 index 000000000000..c608a88be082 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.gdbtable new file mode 100644 index 000000000000..0b9171d2e217 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.gdbtablx new file mode 100644 index 000000000000..431307d13c60 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000006.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByBackwardLabel.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByBackwardLabel.atx new file mode 100644 index 000000000000..e8d13d4268fe Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByBackwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByDestItemTypeID.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByDestItemTypeID.atx new file mode 100644 index 000000000000..e2a366ba5cc1 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByDestItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByForwardLabel.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByForwardLabel.atx new file mode 100644 index 000000000000..5e8ff3f66ab2 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByForwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByName.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByName.atx new file mode 100644 index 000000000000..88108cf1ae90 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx new file mode 100644 index 000000000000..33cb6e8c58da Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByUUID.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByUUID.atx new file mode 100644 index 000000000000..5a6033e77a59 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.CatRelTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.gdbindexes new file mode 100644 index 000000000000..2a98c93adab6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.gdbtable new file mode 100644 index 000000000000..2ac1a6e43ef6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.gdbtablx new file mode 100644 index 000000000000..a6247b20b804 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000007.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.gdbindexes new file mode 100644 index 000000000000..8211a233625e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.gdbtable new file mode 100644 index 000000000000..2eb61193296f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.gdbtablx new file mode 100644 index 000000000000..7d06cc0fe240 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.spx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.spx new file mode 100644 index 000000000000..6d236bdee5ca Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a00000009.spx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000a.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000a.gdbindexes new file mode 100644 index 000000000000..240144ef31ae Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000a.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000a.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000a.gdbtable new file mode 100644 index 000000000000..84260044f7fd Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000a.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000a.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000a.gdbtablx new file mode 100644 index 000000000000..b48fa99a8c38 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000a.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.freelist b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.freelist new file mode 100644 index 000000000000..e8d168993dd6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.freelist differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.gdbindexes new file mode 100644 index 000000000000..0449ced6cb12 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.gdbtable new file mode 100644 index 000000000000..e30d5838eff4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.gdbtablx new file mode 100644 index 000000000000..7d097093679d Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000b.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.blk_key_index.atx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.blk_key_index.atx new file mode 100644 index 000000000000..a97b98ff4700 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.blk_key_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.gdbindexes new file mode 100644 index 000000000000..031560094ed7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.gdbtable new file mode 100644 index 000000000000..21e020fd37bf Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.gdbtablx new file mode 100644 index 000000000000..fdab6ccd0fde Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000c.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000d.gdbindexes b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000d.gdbindexes new file mode 100644 index 000000000000..142048fb144f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000d.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000d.gdbtable b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000d.gdbtable new file mode 100644 index 000000000000..b94f6bb43e15 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000d.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000d.gdbtablx b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000d.gdbtablx new file mode 100644 index 000000000000..b9e6995672ad Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/a0000000d.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/gdb b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/gdb new file mode 100644 index 000000000000..a786e127004d Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/gdb differ diff --git a/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/timestamps b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/timestamps new file mode 100644 index 000000000000..9de55b8e5aa2 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/NCH_ES_WATER_LOGGING_HAZARD.gdb/timestamps differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.TablesByName.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.TablesByName.atx new file mode 100644 index 000000000000..b809dc174e13 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.TablesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.gdbindexes new file mode 100644 index 000000000000..b02aa7510589 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.gdbtable new file mode 100644 index 000000000000..556cf5ef7901 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.gdbtablx new file mode 100644 index 000000000000..66911b806aae Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000001.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000002.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000002.gdbtable new file mode 100644 index 000000000000..a0af90eaae1f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000002.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000002.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000002.gdbtablx new file mode 100644 index 000000000000..7c12c5681950 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000002.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000003.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000003.gdbindexes new file mode 100644 index 000000000000..58df68d525b4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000003.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000003.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000003.gdbtable new file mode 100644 index 000000000000..ea35310fe368 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000003.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000003.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000003.gdbtablx new file mode 100644 index 000000000000..861811b21cfb Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000003.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.CatItemsByPhysicalName.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.CatItemsByPhysicalName.atx new file mode 100644 index 000000000000..c280648d3b44 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.CatItemsByPhysicalName.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.freelist b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.freelist new file mode 100644 index 000000000000..273470c5754f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.freelist differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.gdbindexes new file mode 100644 index 000000000000..a4f334d7ba2a Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.gdbtable new file mode 100644 index 000000000000..a20e01c323b9 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.gdbtablx new file mode 100644 index 000000000000..368220b6d37e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.spx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.spx new file mode 100644 index 000000000000..944cb05feeda Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000004.spx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.CatItemTypesByName.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.CatItemTypesByName.atx new file mode 100644 index 000000000000..6055e63d1770 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.CatItemTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.CatItemTypesByParentTypeID.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.CatItemTypesByParentTypeID.atx new file mode 100644 index 000000000000..c1c65c4f79f2 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.CatItemTypesByParentTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.CatItemTypesByUUID.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.CatItemTypesByUUID.atx new file mode 100644 index 000000000000..8e1903699b1f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.CatItemTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.gdbindexes new file mode 100644 index 000000000000..bc887093f340 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.gdbtable new file mode 100644 index 000000000000..57f1fb88b85f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.gdbtablx new file mode 100644 index 000000000000..ab1f2d304e3a Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000005.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.CatRelsByDestinationID.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.CatRelsByDestinationID.atx new file mode 100644 index 000000000000..b102e220825c Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.CatRelsByDestinationID.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.CatRelsByOriginID.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.CatRelsByOriginID.atx new file mode 100644 index 000000000000..2b9a3acb76e2 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.CatRelsByOriginID.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.CatRelsByType.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.CatRelsByType.atx new file mode 100644 index 000000000000..c16389e728f3 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.CatRelsByType.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.FDO_UUID.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.FDO_UUID.atx new file mode 100644 index 000000000000..bad1aa860de5 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.FDO_UUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.gdbindexes new file mode 100644 index 000000000000..c608a88be082 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.gdbtable new file mode 100644 index 000000000000..8c1524314e68 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.gdbtablx new file mode 100644 index 000000000000..7cc0413957f6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000006.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByBackwardLabel.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByBackwardLabel.atx new file mode 100644 index 000000000000..838d1c6d393e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByBackwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByDestItemTypeID.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByDestItemTypeID.atx new file mode 100644 index 000000000000..0d75fb7df19e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByDestItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByForwardLabel.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByForwardLabel.atx new file mode 100644 index 000000000000..36eeea63e0e6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByForwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByName.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByName.atx new file mode 100644 index 000000000000..c4046b406157 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx new file mode 100644 index 000000000000..9c26599a8436 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByUUID.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByUUID.atx new file mode 100644 index 000000000000..41eba5828189 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.CatRelTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.gdbindexes new file mode 100644 index 000000000000..2a98c93adab6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.gdbtable new file mode 100644 index 000000000000..e34b91812105 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.gdbtablx new file mode 100644 index 000000000000..316722e09bf2 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000007.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a0000004f.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a0000004f.gdbtable new file mode 100644 index 000000000000..c8b9ae2b32c8 --- /dev/null +++ b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a0000004f.gdbtable @@ -0,0 +1,19 @@ + + + + + + + + + + 0x3E434A8A5E4E45C1 + 0xC0790000 0 + 0x4078FFFFFFFFFFFC + 0xC0790000 0 + 0x4078FFFFFFFFFFFC + 0x 0 0 + 1 +
+
+
diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a0000004f.gdbtable.FDO_OID.gdbtabidx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a0000004f.gdbtable.FDO_OID.gdbtabidx new file mode 100644 index 000000000000..31002a2ef011 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a0000004f.gdbtable.FDO_OID.gdbtabidx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a0000004f.gdbtable.cdf b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a0000004f.gdbtable.cdf new file mode 100644 index 000000000000..28508f802cc5 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a0000004f.gdbtable.cdf differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000050.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000050.gdbindexes new file mode 100644 index 000000000000..240144ef31ae Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000050.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000050.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000050.gdbtable new file mode 100644 index 000000000000..d5ee79cc6414 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000050.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000050.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000050.gdbtablx new file mode 100644 index 000000000000..b48fa99a8c38 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000050.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.freelist b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.freelist new file mode 100644 index 000000000000..e8d168993dd6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.freelist differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.gdbindexes new file mode 100644 index 000000000000..0449ced6cb12 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.gdbtable new file mode 100644 index 000000000000..8bff3edab090 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.gdbtablx new file mode 100644 index 000000000000..fc5ec35b3e67 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000051.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.band_index.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.band_index.atx new file mode 100644 index 000000000000..5792f523b51a Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.band_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.blk_key_index.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.blk_key_index.atx new file mode 100644 index 000000000000..8943ed345530 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.blk_key_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.col_index.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.col_index.atx new file mode 100644 index 000000000000..a0ffa8a81bad Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.col_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.gdbindexes new file mode 100644 index 000000000000..031560094ed7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.gdbtable new file mode 100644 index 000000000000..a00b9c5808ce Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.gdbtablx new file mode 100644 index 000000000000..2f134dad77d1 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.row_index.atx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.row_index.atx new file mode 100644 index 000000000000..e3c0c26cfe7e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000052.row_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000053.gdbindexes b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000053.gdbindexes new file mode 100644 index 000000000000..142048fb144f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000053.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000053.gdbtable b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000053.gdbtable new file mode 100644 index 000000000000..8948c07589d4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000053.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000053.gdbtablx b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000053.gdbtablx new file mode 100644 index 000000000000..b9e6995672ad Binary files /dev/null and b/autotest/gdrivers/data/filegdb/dem_1bit_ScalePixelValue.gdb/a00000053.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.TablesByName.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.TablesByName.atx new file mode 100644 index 000000000000..b508febb9945 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.TablesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.gdbindexes new file mode 100644 index 000000000000..b02aa7510589 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.gdbtable new file mode 100644 index 000000000000..70525ab59499 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.gdbtablx new file mode 100644 index 000000000000..887096e3328e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000001.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000002.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a00000002.gdbtable new file mode 100644 index 000000000000..a0af90eaae1f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000002.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000002.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000002.gdbtablx new file mode 100644 index 000000000000..7c12c5681950 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000002.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000003.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a00000003.gdbindexes new file mode 100644 index 000000000000..58df68d525b4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000003.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000003.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a00000003.gdbtable new file mode 100644 index 000000000000..8a5cdad5df4a Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000003.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000003.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000003.gdbtablx new file mode 100644 index 000000000000..2f80ed4fe5fe Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000003.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.CatItemsByPhysicalName.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.CatItemsByPhysicalName.atx new file mode 100644 index 000000000000..74df5486b83f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.CatItemsByPhysicalName.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.CatItemsByType.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.CatItemsByType.atx new file mode 100644 index 000000000000..22f3bc1dc4cd Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.CatItemsByType.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.FDO_UUID.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.FDO_UUID.atx new file mode 100644 index 000000000000..667de8b4967b Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.FDO_UUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.gdbindexes new file mode 100644 index 000000000000..a4f334d7ba2a Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.gdbtable new file mode 100644 index 000000000000..a97854051ce8 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.gdbtablx new file mode 100644 index 000000000000..93fec31b61e3 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.horizon b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.horizon new file mode 100644 index 000000000000..b64b92356a70 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.horizon differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.spx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.spx new file mode 100644 index 000000000000..6d236bdee5ca Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000004.spx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.CatItemTypesByName.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.CatItemTypesByName.atx new file mode 100644 index 000000000000..5f5004620ba9 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.CatItemTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.CatItemTypesByParentTypeID.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.CatItemTypesByParentTypeID.atx new file mode 100644 index 000000000000..269f1f31a465 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.CatItemTypesByParentTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.CatItemTypesByUUID.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.CatItemTypesByUUID.atx new file mode 100644 index 000000000000..44d74cc880f4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.CatItemTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.gdbindexes new file mode 100644 index 000000000000..bc887093f340 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.gdbtable new file mode 100644 index 000000000000..bf93ec49a465 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.gdbtablx new file mode 100644 index 000000000000..4d8932a45d48 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000005.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.CatRelsByDestinationID.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.CatRelsByDestinationID.atx new file mode 100644 index 000000000000..f3b659ac7091 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.CatRelsByDestinationID.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.CatRelsByOriginID.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.CatRelsByOriginID.atx new file mode 100644 index 000000000000..80df1d23b0c3 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.CatRelsByOriginID.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.CatRelsByType.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.CatRelsByType.atx new file mode 100644 index 000000000000..5143e308957b Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.CatRelsByType.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.FDO_UUID.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.FDO_UUID.atx new file mode 100644 index 000000000000..8a80ea06050f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.FDO_UUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.gdbindexes new file mode 100644 index 000000000000..c608a88be082 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.gdbtable new file mode 100644 index 000000000000..d3ccf1c026b4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.gdbtablx new file mode 100644 index 000000000000..431307d13c60 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000006.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByBackwardLabel.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByBackwardLabel.atx new file mode 100644 index 000000000000..8797338e7a9c Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByBackwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByDestItemTypeID.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByDestItemTypeID.atx new file mode 100644 index 000000000000..47d2132ee8b7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByDestItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByForwardLabel.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByForwardLabel.atx new file mode 100644 index 000000000000..233026824883 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByForwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByName.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByName.atx new file mode 100644 index 000000000000..70ed36c3fea8 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx new file mode 100644 index 000000000000..139b478cc0a4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByUUID.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByUUID.atx new file mode 100644 index 000000000000..dea48d3ebdbb Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.CatRelTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.gdbindexes new file mode 100644 index 000000000000..2a98c93adab6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.gdbtable new file mode 100644 index 000000000000..a25ba57b9184 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.gdbtablx new file mode 100644 index 000000000000..bf096e13d28f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000007.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.gdbindexes new file mode 100644 index 000000000000..8211a233625e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.gdbtable new file mode 100644 index 000000000000..679dc7e5cb49 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.gdbtablx new file mode 100644 index 000000000000..b116630f70d1 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.horizon b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.horizon new file mode 100644 index 000000000000..18907a331eac --- /dev/null +++ b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.horizon @@ -0,0 +1 @@ +ï{~܈SÁ•Y5ÉÇcÁï{~lYWA•Y5ÉÇcA \ No newline at end of file diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.spx b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.spx new file mode 100644 index 000000000000..6d236bdee5ca Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a00000009.spx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000a.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000a.gdbindexes new file mode 100644 index 000000000000..240144ef31ae Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000a.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000a.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000a.gdbtable new file mode 100644 index 000000000000..2ffa16e397a2 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000a.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000a.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000a.gdbtablx new file mode 100644 index 000000000000..b48fa99a8c38 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000a.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.freelist b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.freelist new file mode 100644 index 000000000000..e8d168993dd6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.freelist differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.gdbindexes new file mode 100644 index 000000000000..0449ced6cb12 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.gdbtable new file mode 100644 index 000000000000..834acd28fc87 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.gdbtablx new file mode 100644 index 000000000000..91d7478a2b8c Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000b.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.band_index.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.band_index.atx new file mode 100644 index 000000000000..870a5e390e91 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.band_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.blk_key_index.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.blk_key_index.atx new file mode 100644 index 000000000000..3aef81009529 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.blk_key_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.col_index.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.col_index.atx new file mode 100644 index 000000000000..2ba7bf150642 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.col_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.gdbindexes new file mode 100644 index 000000000000..031560094ed7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.gdbtable new file mode 100644 index 000000000000..e012cc3df9b7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.gdbtablx new file mode 100644 index 000000000000..146f894185c8 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.row_index.atx b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.row_index.atx new file mode 100644 index 000000000000..2ba7bf150642 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000c.row_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000d.gdbindexes b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000d.gdbindexes new file mode 100644 index 000000000000..142048fb144f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000d.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000d.gdbtable b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000d.gdbtable new file mode 100644 index 000000000000..e1cc3a70f7fa Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000d.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/a0000000d.gdbtablx b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000d.gdbtablx new file mode 100644 index 000000000000..b9e6995672ad Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/a0000000d.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/gdb b/autotest/gdrivers/data/filegdb/int8.gdb/gdb new file mode 100644 index 000000000000..a786e127004d Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/gdb differ diff --git a/autotest/gdrivers/data/filegdb/int8.gdb/timestamps b/autotest/gdrivers/data/filegdb/int8.gdb/timestamps new file mode 100644 index 000000000000..862c08a4950f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/int8.gdb/timestamps differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.TablesByName.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.TablesByName.atx new file mode 100644 index 000000000000..d5b33644e4ab Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.TablesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.gdbindexes new file mode 100644 index 000000000000..b02aa7510589 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.gdbtable new file mode 100644 index 000000000000..e99dbe25323e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.gdbtablx new file mode 100644 index 000000000000..6ad8b8ccfa85 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000001.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000002.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000002.gdbtable new file mode 100644 index 000000000000..a0af90eaae1f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000002.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000002.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000002.gdbtablx new file mode 100644 index 000000000000..7c12c5681950 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000002.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000003.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000003.gdbindexes new file mode 100644 index 000000000000..58df68d525b4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000003.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000003.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000003.gdbtable new file mode 100644 index 000000000000..d2447c437693 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000003.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000003.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000003.gdbtablx new file mode 100644 index 000000000000..2f80ed4fe5fe Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000003.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.CatItemsByPhysicalName.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.CatItemsByPhysicalName.atx new file mode 100644 index 000000000000..6fc0edaf2ce8 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.CatItemsByPhysicalName.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.CatItemsByType.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.CatItemsByType.atx new file mode 100644 index 000000000000..22f3bc1dc4cd Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.CatItemsByType.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.FDO_UUID.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.FDO_UUID.atx new file mode 100644 index 000000000000..3b5c1c9dd9ee Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.FDO_UUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.gdbindexes new file mode 100644 index 000000000000..a4f334d7ba2a Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.gdbtable new file mode 100644 index 000000000000..5f431921bd0c Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.gdbtablx new file mode 100644 index 000000000000..93fec31b61e3 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.horizon b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.horizon new file mode 100644 index 000000000000..b64b92356a70 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.horizon differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.spx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.spx new file mode 100644 index 000000000000..920fd545043e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000004.spx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.CatItemTypesByName.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.CatItemTypesByName.atx new file mode 100644 index 000000000000..5f5004620ba9 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.CatItemTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.CatItemTypesByParentTypeID.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.CatItemTypesByParentTypeID.atx new file mode 100644 index 000000000000..269f1f31a465 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.CatItemTypesByParentTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.CatItemTypesByUUID.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.CatItemTypesByUUID.atx new file mode 100644 index 000000000000..44d74cc880f4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.CatItemTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.gdbindexes new file mode 100644 index 000000000000..bc887093f340 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.gdbtable new file mode 100644 index 000000000000..bf93ec49a465 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.gdbtablx new file mode 100644 index 000000000000..4d8932a45d48 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000005.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.CatRelsByDestinationID.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.CatRelsByDestinationID.atx new file mode 100644 index 000000000000..6c78976086ea Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.CatRelsByDestinationID.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.CatRelsByOriginID.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.CatRelsByOriginID.atx new file mode 100644 index 000000000000..80df1d23b0c3 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.CatRelsByOriginID.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.CatRelsByType.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.CatRelsByType.atx new file mode 100644 index 000000000000..5143e308957b Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.CatRelsByType.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.FDO_UUID.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.FDO_UUID.atx new file mode 100644 index 000000000000..b86804c03ad6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.FDO_UUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.gdbindexes new file mode 100644 index 000000000000..c608a88be082 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.gdbtable new file mode 100644 index 000000000000..09e5f09c72fb Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.gdbtablx new file mode 100644 index 000000000000..431307d13c60 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000006.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByBackwardLabel.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByBackwardLabel.atx new file mode 100644 index 000000000000..8797338e7a9c Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByBackwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByDestItemTypeID.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByDestItemTypeID.atx new file mode 100644 index 000000000000..47d2132ee8b7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByDestItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByForwardLabel.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByForwardLabel.atx new file mode 100644 index 000000000000..233026824883 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByForwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByName.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByName.atx new file mode 100644 index 000000000000..70ed36c3fea8 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx new file mode 100644 index 000000000000..139b478cc0a4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByUUID.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByUUID.atx new file mode 100644 index 000000000000..dea48d3ebdbb Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.CatRelTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.gdbindexes new file mode 100644 index 000000000000..2a98c93adab6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.gdbtable new file mode 100644 index 000000000000..a25ba57b9184 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.gdbtablx new file mode 100644 index 000000000000..bf096e13d28f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000007.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.gdbindexes new file mode 100644 index 000000000000..8211a233625e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.gdbtable new file mode 100644 index 000000000000..2f57afe612e0 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.gdbtablx new file mode 100644 index 000000000000..914f32e6f5a4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.horizon b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.horizon new file mode 100644 index 000000000000..6b4ea069980c Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.horizon differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.spx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.spx new file mode 100644 index 000000000000..6d236bdee5ca Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a00000009.spx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000a.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000a.gdbindexes new file mode 100644 index 000000000000..240144ef31ae Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000a.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000a.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000a.gdbtable new file mode 100644 index 000000000000..ad6992afd433 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000a.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000a.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000a.gdbtablx new file mode 100644 index 000000000000..b48fa99a8c38 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000a.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.freelist b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.freelist new file mode 100644 index 000000000000..58c2e81df609 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.freelist differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.gdbindexes new file mode 100644 index 000000000000..0449ced6cb12 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.gdbtable new file mode 100644 index 000000000000..3dfde046d7d1 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.gdbtablx new file mode 100644 index 000000000000..f79309ac9d59 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000b.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.band_index.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.band_index.atx new file mode 100644 index 000000000000..2ea17a12cc00 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.band_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.blk_key_index.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.blk_key_index.atx new file mode 100644 index 000000000000..63dfd80b2d64 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.blk_key_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.col_index.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.col_index.atx new file mode 100644 index 000000000000..71f5e80927be Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.col_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.gdbindexes new file mode 100644 index 000000000000..031560094ed7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.gdbtable new file mode 100644 index 000000000000..397f10b528fd Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.gdbtablx new file mode 100644 index 000000000000..b1a7e93b9319 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.row_index.atx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.row_index.atx new file mode 100644 index 000000000000..709fc8c55c36 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000c.row_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.freelist b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.freelist new file mode 100644 index 000000000000..e8d168993dd6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.freelist differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.gdbindexes new file mode 100644 index 000000000000..142048fb144f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.gdbtable new file mode 100644 index 000000000000..3875a6ef80d1 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.gdbtablx new file mode 100644 index 000000000000..ac6a3def3cc4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000d.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000e.gdbindexes b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000e.gdbindexes new file mode 100644 index 000000000000..0449ced6cb12 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000e.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000e.gdbtable b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000e.gdbtable new file mode 100644 index 000000000000..785f9d6ad872 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000e.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000e.gdbtablx b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000e.gdbtablx new file mode 100644 index 000000000000..e446ce106ea3 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/a0000000e.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/gdb b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/gdb new file mode 100644 index 000000000000..a786e127004d Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/gdb differ diff --git a/autotest/gdrivers/data/filegdb/lu_4bit.gdb/timestamps b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/timestamps new file mode 100644 index 000000000000..293cdffd1d09 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/lu_4bit.gdb/timestamps differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.TablesByName.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.TablesByName.atx new file mode 100644 index 000000000000..79d3153cb959 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.TablesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.gdbindexes new file mode 100644 index 000000000000..b02aa7510589 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.gdbtable new file mode 100644 index 000000000000..3c5b1110d377 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.gdbtablx new file mode 100644 index 000000000000..0c92e11f01a1 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000001.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000002.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a00000002.gdbtable new file mode 100644 index 000000000000..a0af90eaae1f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000002.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000002.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000002.gdbtablx new file mode 100644 index 000000000000..7c12c5681950 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000002.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000003.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a00000003.gdbindexes new file mode 100644 index 000000000000..58df68d525b4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000003.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000003.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a00000003.gdbtable new file mode 100644 index 000000000000..8a5cdad5df4a Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000003.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000003.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000003.gdbtablx new file mode 100644 index 000000000000..2f80ed4fe5fe Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000003.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.CatItemsByPhysicalName.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.CatItemsByPhysicalName.atx new file mode 100644 index 000000000000..74df5486b83f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.CatItemsByPhysicalName.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.CatItemsByType.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.CatItemsByType.atx new file mode 100644 index 000000000000..22f3bc1dc4cd Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.CatItemsByType.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.FDO_UUID.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.FDO_UUID.atx new file mode 100644 index 000000000000..667de8b4967b Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.FDO_UUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.gdbindexes new file mode 100644 index 000000000000..a4f334d7ba2a Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.gdbtable new file mode 100644 index 000000000000..0f8328f90c96 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.gdbtablx new file mode 100644 index 000000000000..93fec31b61e3 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.horizon b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.horizon new file mode 100644 index 000000000000..b64b92356a70 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.horizon differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.spx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.spx new file mode 100644 index 000000000000..6d236bdee5ca Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000004.spx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.CatItemTypesByName.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.CatItemTypesByName.atx new file mode 100644 index 000000000000..5f5004620ba9 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.CatItemTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.CatItemTypesByParentTypeID.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.CatItemTypesByParentTypeID.atx new file mode 100644 index 000000000000..269f1f31a465 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.CatItemTypesByParentTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.CatItemTypesByUUID.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.CatItemTypesByUUID.atx new file mode 100644 index 000000000000..44d74cc880f4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.CatItemTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.gdbindexes new file mode 100644 index 000000000000..bc887093f340 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.gdbtable new file mode 100644 index 000000000000..bf93ec49a465 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.gdbtablx new file mode 100644 index 000000000000..4d8932a45d48 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000005.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.CatRelsByDestinationID.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.CatRelsByDestinationID.atx new file mode 100644 index 000000000000..f3b659ac7091 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.CatRelsByDestinationID.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.CatRelsByOriginID.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.CatRelsByOriginID.atx new file mode 100644 index 000000000000..80df1d23b0c3 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.CatRelsByOriginID.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.CatRelsByType.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.CatRelsByType.atx new file mode 100644 index 000000000000..5143e308957b Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.CatRelsByType.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.FDO_UUID.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.FDO_UUID.atx new file mode 100644 index 000000000000..8a80ea06050f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.FDO_UUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.gdbindexes new file mode 100644 index 000000000000..c608a88be082 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.gdbtable new file mode 100644 index 000000000000..d3ccf1c026b4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.gdbtablx new file mode 100644 index 000000000000..431307d13c60 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000006.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByBackwardLabel.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByBackwardLabel.atx new file mode 100644 index 000000000000..8797338e7a9c Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByBackwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByDestItemTypeID.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByDestItemTypeID.atx new file mode 100644 index 000000000000..47d2132ee8b7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByDestItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByForwardLabel.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByForwardLabel.atx new file mode 100644 index 000000000000..233026824883 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByForwardLabel.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByName.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByName.atx new file mode 100644 index 000000000000..70ed36c3fea8 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByName.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx new file mode 100644 index 000000000000..139b478cc0a4 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByOriginItemTypeID.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByUUID.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByUUID.atx new file mode 100644 index 000000000000..dea48d3ebdbb Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.CatRelTypesByUUID.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.gdbindexes new file mode 100644 index 000000000000..2a98c93adab6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.gdbtable new file mode 100644 index 000000000000..a25ba57b9184 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.gdbtablx new file mode 100644 index 000000000000..bf096e13d28f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000007.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.gdbindexes new file mode 100644 index 000000000000..8211a233625e Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.gdbtable new file mode 100644 index 000000000000..37624b1fc924 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.gdbtablx new file mode 100644 index 000000000000..b116630f70d1 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.horizon b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.horizon new file mode 100644 index 000000000000..18907a331eac --- /dev/null +++ b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.horizon @@ -0,0 +1 @@ +ï{~܈SÁ•Y5ÉÇcÁï{~lYWA•Y5ÉÇcA \ No newline at end of file diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.spx b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.spx new file mode 100644 index 000000000000..0de47208061c Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a00000009.spx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000a.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000a.gdbindexes new file mode 100644 index 000000000000..240144ef31ae Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000a.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000a.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000a.gdbtable new file mode 100644 index 000000000000..2ffa16e397a2 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000a.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000a.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000a.gdbtablx new file mode 100644 index 000000000000..b48fa99a8c38 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000a.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.freelist b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.freelist new file mode 100644 index 000000000000..e8d168993dd6 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.freelist differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.gdbindexes new file mode 100644 index 000000000000..0449ced6cb12 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.gdbtable new file mode 100644 index 000000000000..834acd28fc87 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.gdbtablx new file mode 100644 index 000000000000..91d7478a2b8c Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000b.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.band_index.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.band_index.atx new file mode 100644 index 000000000000..870a5e390e91 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.band_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.blk_key_index.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.blk_key_index.atx new file mode 100644 index 000000000000..3aef81009529 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.blk_key_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.col_index.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.col_index.atx new file mode 100644 index 000000000000..2ba7bf150642 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.col_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.gdbindexes new file mode 100644 index 000000000000..031560094ed7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.gdbtable new file mode 100644 index 000000000000..e012cc3df9b7 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.gdbtablx new file mode 100644 index 000000000000..146f894185c8 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.row_index.atx b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.row_index.atx new file mode 100644 index 000000000000..2ba7bf150642 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000c.row_index.atx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000d.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000d.gdbindexes new file mode 100644 index 000000000000..142048fb144f Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000d.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000d.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000d.gdbtable new file mode 100644 index 000000000000..e1cc3a70f7fa Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000d.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000d.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000d.gdbtablx new file mode 100644 index 000000000000..b9e6995672ad Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000d.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.freelist b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.freelist new file mode 100644 index 000000000000..eddbb452a9b5 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.freelist differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.gdbindexes b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.gdbindexes new file mode 100644 index 000000000000..0449ced6cb12 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.gdbindexes differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.gdbtable b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.gdbtable new file mode 100644 index 000000000000..dadbfcb2a9bd Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.gdbtable differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.gdbtablx b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.gdbtablx new file mode 100644 index 000000000000..bb6a6b0e06b0 Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/a0000000e.gdbtablx differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/gdb b/autotest/gdrivers/data/filegdb/rat.gdb/gdb new file mode 100644 index 000000000000..a786e127004d Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/gdb differ diff --git a/autotest/gdrivers/data/filegdb/rat.gdb/timestamps b/autotest/gdrivers/data/filegdb/rat.gdb/timestamps new file mode 100644 index 000000000000..333cbccd94cc Binary files /dev/null and b/autotest/gdrivers/data/filegdb/rat.gdb/timestamps differ diff --git a/autotest/gdrivers/openfilegdb.py b/autotest/gdrivers/openfilegdb.py new file mode 100755 index 000000000000..2448300bd510 --- /dev/null +++ b/autotest/gdrivers/openfilegdb.py @@ -0,0 +1,373 @@ +#!/usr/bin/env pytest +# -*- coding: utf-8 -*- +############################################################################### +# Project: GDAL/OGR Test Suite +# Purpose: OpenFileGDB raster driver testing. +# Author: Even Rouault +# +############################################################################### +# Copyright (c) 2023, Even Rouault +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +############################################################################### + +import struct + +import gdaltest +import pytest + +from osgeo import gdal + +pytestmark = pytest.mark.require_driver("OpenFileGDB") + + +############################################################################### +# Open dataset with subdatasets + + +def test_openfilegb_raster_subdatasets(): + + ds = gdal.Open("data/filegdb/gdal_test_data.gdb.zip") + assert ds + assert len(ds.GetSubDatasets()) == 44 + ds = gdal.Open(ds.GetSubDatasets()[0][0]) + assert ds + assert ds.RasterXSize == 20 + assert ds.RasterYSize == 20 + + ds = gdal.OpenEx( + "data/filegdb/gdal_test_data.gdb.zip", gdal.OF_RASTER | gdal.OF_VECTOR + ) + assert ds + + ds = gdal.OpenEx("data/filegdb/gdal_test_data.gdb.zip", gdal.OF_VECTOR) + assert ds is None + + +############################################################################### +# Test various band types + + +@pytest.mark.parametrize( + "name,datatype,checksum", + [ + ("byte_lz77", gdal.GDT_Byte, 4672), + ("byte_lzw", gdal.GDT_Byte, 4672), # no compression actually + ("uint16_lz77", gdal.GDT_UInt16, 4672), + ("uint16_lzw", gdal.GDT_UInt16, 4672), # no compression actually + ("int16_lz77", gdal.GDT_Int16, 4672), + ("int16_lzw", gdal.GDT_Int16, 4672), # no compression actually + ("uint32_lz77", gdal.GDT_UInt32, 4672), + ("uint32_lzw", gdal.GDT_UInt32, 4672), # no compression actually + ("int32_lz77", gdal.GDT_Int32, 4672), + ("int32_lzw", gdal.GDT_Int32, 4672), # no compression actually + ("float32_lz77", gdal.GDT_Float32, 4672), + ("float32_lzw", gdal.GDT_Float32, 4672), # no compression actually + ("float64_lz77", gdal.GDT_Float64, 4672), + ], +) +def test_openfilegb_raster_band_types(name, datatype, checksum): + + ds = gdal.Open("OpenFileGDB:data/filegdb/gdal_test_data.gdb.zip:" + name) + assert ds + assert ds.GetRasterBand(1).DataType == datatype + assert ds.GetRasterBand(1).Checksum() == checksum + + +############################################################################### +# Test mask band + + +def test_openfilegb_raster_mask_band(): + + ds = gdal.Open("OpenFileGDB:data/filegdb/gdal_test_data.gdb.zip:byte_lz77") + assert ds.GetRasterBand(1).GetMaskBand().Checksum() == 4873 + assert ds.GetRasterBand(1).Checksum() == 4672 + + ds = gdal.Open("OpenFileGDB:data/filegdb/gdal_test_data.gdb.zip:byte_lz77") + assert ds.GetRasterBand(1).Checksum() == 4672 + assert ds.GetRasterBand(1).GetMaskBand().Checksum() == 4873 + + +############################################################################### +# Test multi band + + +def test_openfilegb_raster_multi_band(): + + ds = gdal.Open("OpenFileGDB:data/filegdb/gdal_test_data.gdb.zip:small_world_lz77") + assert ds.RasterXSize == 400 + assert ds.RasterYSize == 200 + assert ds.RasterCount == 3 + assert ds.GetMetadata("IMAGE_STRUCTURE") == { + "COMPRESSION": "DEFLATE", + "INTERLEAVE": "BAND", + } + assert [ds.GetRasterBand(i + 1).Checksum() for i in range(3)] == [ + 30111, + 32302, + 40026, + ] + assert ds.GetRasterBand(1).GetMaskBand().Checksum() == 64269 + assert ds.GetRasterBand(2).GetMaskBand().Checksum() == 64269 + assert ds.GetRasterBand(3).GetMaskBand().Checksum() == 64269 + band = ds.GetRasterBand(1) + assert band.GetOverviewCount() == 3 + assert band.GetOverview(-1) is None + assert band.GetOverview(3) is None + assert band.GetOverview(0).Checksum() == 7309 + assert band.GetOverview(0).GetMaskFlags() == gdal.GMF_PER_DATASET + assert band.GetOverview(0).GetMaskBand().Checksum() == 48827 + band = ds.GetRasterBand(2) + assert band.GetOverviewCount() == 3 + assert band.GetOverview(-1) is None + assert band.GetOverview(3) is None + assert band.GetOverview(0).Checksum() == 7850 + assert band.GetOverview(0).GetMaskFlags() == gdal.GMF_PER_DATASET + assert band.GetOverview(0).GetMaskBand().Checksum() == 48827 + + +############################################################################### +# Test 1-bit depth + + +def test_openfilegb_raster_one_bit(): + + ds = gdal.Open("data/filegdb/dem_1bit_ScalePixelValue.gdb") + assert ds.GetRasterBand(1).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "1" + assert ds.GetRasterBand(1).Checksum() == 17197 + assert ds.GetRasterBand(1).GetMaskBand().Checksum() == 29321 + + +############################################################################### +# Test 4-bit depth and a rasterband_id == 2 + + +def test_openfilegb_raster_four_bit(): + + ds = gdal.Open("data/filegdb/lu_4bit.gdb") + assert ds.GetRasterBand(1).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "4" + assert ds.GetRasterBand(1).Checksum() == 40216 + assert ds.GetRasterBand(1).GetMaskBand().Checksum() == 42040 + + +############################################################################### +# Test JPEG compression + + +def test_openfilegb_raster_jpeg(): + + ds = gdal.Open("OpenFileGDB:data/filegdb/gdal_test_data.gdb.zip:small_world_jpeg") + assert ds.RasterXSize == 400 + assert ds.RasterYSize == 200 + assert ds.RasterCount == 3 + if gdal.GetDriverByName("JPEG") is not None: + assert ds.GetMetadata("IMAGE_STRUCTURE") == { + "COMPRESSION": "JPEG", + "INTERLEAVE": "BAND", + "JPEG_QUALITY": "75", + } + + if gdal.GetDriverByName("JPEG") is None: + with gdaltest.error_handler(): + assert ds.GetRasterBand(1).Checksum() == -1 + else: + assert [ds.GetRasterBand(i + 1).Checksum() for i in range(3)] == [ + 23495, + 18034, + 36999, + ] + assert ds.GetRasterBand(1).GetMaskBand().Checksum() == 64269 + + +############################################################################### +# Test JPEG2000 compression + + +def test_openfilegb_raster_jpeg2000(): + + ds = gdal.Open( + "OpenFileGDB:data/filegdb/gdal_test_data.gdb.zip:small_world_jpeg2000" + ) + assert ds.RasterXSize == 400 + assert ds.RasterYSize == 200 + assert ds.RasterCount == 3 + assert ds.GetMetadata("IMAGE_STRUCTURE") == { + "COMPRESSION": "JPEG2000", + "INTERLEAVE": "BAND", + } + + if gdal.GetDriverByName("JP2OpenJPEG") is None: + pytest.skip("JP2OpenJPEG driver not available") + + assert [ds.GetRasterBand(i + 1).Checksum() for i in range(3)] != [-1, -1, -1] + assert ds.GetRasterBand(1).GetMaskBand().Checksum() == 64269 + + +############################################################################### +# Open dataset with Int8 data type + + +def test_openfilegb_raster_int8(): + + ds = gdal.Open("data/filegdb/int8.gdb") + assert ds + assert ds.RasterXSize == 20 + assert ds.RasterYSize == 20 + assert ds.RasterCount == 1 + assert ds.GetGeoTransform() == (440720, 60, 0, 3751320, 0, -60) + assert ds.GetSpatialRef().GetAuthorityCode(None) == "26711" + assert ds.GetMetadata("IMAGE_STRUCTURE") == {"COMPRESSION": "DEFLATE"} + assert ds.GetMetadata("xml:definition")[0].startswith("` documentation page + + +Credits +------- + +Thanks to Richard Barnes and his ArcRescue tool for the deciphering of +the band_types field which indicates the compression method and the data type. diff --git a/ogr/ogrsf_frmts/openfilegdb/gdalopenfilegdbrasterband.cpp b/ogr/ogrsf_frmts/openfilegdb/gdalopenfilegdbrasterband.cpp new file mode 100644 index 000000000000..39b6944b89b7 --- /dev/null +++ b/ogr/ogrsf_frmts/openfilegdb/gdalopenfilegdbrasterband.cpp @@ -0,0 +1,1840 @@ +/****************************************************************************** + * + * Project: OpenGIS Simple Features Reference Implementation + * Purpose: Implements Open FileGDB raster driver. + * Author: Even Rouault, + * + ****************************************************************************** + * Copyright (c) 2023, Even Rouault + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************/ + +#include "cpl_port.h" +#include "cpl_conv.h" +#include "cpl_minixml.h" + +#include "ogr_openfilegdb.h" + +#include "gdal_rat.h" +#include "filegdbtable_priv.h" + +#include +#include +#include +#include + +using namespace OpenFileGDB; + +/***********************************************************************/ +/* OpenRaster() */ +/***********************************************************************/ + +bool OGROpenFileGDBDataSource::OpenRaster(const GDALOpenInfo *poOpenInfo, + const std::string &osLayerName, + const std::string &osDefinition, + const std::string &osDocumentation) +{ + m_osRasterLayerName = osLayerName; + + const std::string osBndTableName( + std::string("fras_bnd_").append(osLayerName).c_str()); + const auto oIter = m_osMapNameToIdx.find(osBndTableName); + if (oIter == m_osMapNameToIdx.end()) + { + CPLError(CE_Failure, CPLE_AppDefined, "Cannot find table %s", + osBndTableName.c_str()); + return false; + } + const int nBndIdx = oIter->second; + + FileGDBTable oTable; + + const CPLString osBndFilename(CPLFormFilename( + m_osDirName, CPLSPrintf("a%08x.gdbtable", nBndIdx), nullptr)); + if (!oTable.Open(osBndFilename, false)) + { + CPLError(CE_Failure, CPLE_AppDefined, "Cannot open table %s", + osBndTableName.c_str()); + return false; + } + + const int i_rasterband_id = oTable.GetFieldIdx("rasterband_id"); + const int i_sequence_nbr = oTable.GetFieldIdx("sequence_nbr"); + const int i_raster_id = oTable.GetFieldIdx("raster_id"); + const int i_band_width = oTable.GetFieldIdx("band_width"); + const int i_band_height = oTable.GetFieldIdx("band_height"); + const int i_band_types = oTable.GetFieldIdx("band_types"); + const int i_block_width = oTable.GetFieldIdx("block_width"); + const int i_block_height = oTable.GetFieldIdx("block_height"); + const int i_block_origin_x = oTable.GetFieldIdx("block_origin_x"); + const int i_block_origin_y = oTable.GetFieldIdx("block_origin_y"); + const int i_eminx = oTable.GetFieldIdx("eminx"); + const int i_eminy = oTable.GetFieldIdx("eminy"); + const int i_emaxx = oTable.GetFieldIdx("emaxx"); + const int i_emaxy = oTable.GetFieldIdx("emaxy"); + const int i_srid = oTable.GetFieldIdx("srid"); + if (i_rasterband_id < 0 || i_sequence_nbr < 0 || i_raster_id < 0 || + i_band_width < 0 || i_band_height < 0 || i_band_types < 0 || + i_block_width < 0 || i_block_height < 0 || i_block_origin_x < 0 || + i_block_origin_y < 0 || i_eminx < 0 || i_eminy < 0 || i_emaxx < 0 || + i_emaxy < 0 || i_srid < 0 || + oTable.GetField(i_rasterband_id)->GetType() != FGFT_OBJECTID || + oTable.GetField(i_sequence_nbr)->GetType() != FGFT_INT32 || + oTable.GetField(i_raster_id)->GetType() != FGFT_INT32 || + oTable.GetField(i_band_width)->GetType() != FGFT_INT32 || + oTable.GetField(i_band_height)->GetType() != FGFT_INT32 || + oTable.GetField(i_band_types)->GetType() != FGFT_INT32 || + oTable.GetField(i_block_width)->GetType() != FGFT_INT32 || + oTable.GetField(i_block_height)->GetType() != FGFT_INT32 || + oTable.GetField(i_block_origin_x)->GetType() != FGFT_FLOAT64 || + oTable.GetField(i_block_origin_y)->GetType() != FGFT_FLOAT64 || + oTable.GetField(i_eminx)->GetType() != FGFT_FLOAT64 || + oTable.GetField(i_eminy)->GetType() != FGFT_FLOAT64 || + oTable.GetField(i_emaxx)->GetType() != FGFT_FLOAT64 || + oTable.GetField(i_emaxy)->GetType() != FGFT_FLOAT64 || + oTable.GetField(i_srid)->GetType() != FGFT_INT32) + { + CPLError(CE_Failure, CPLE_AppDefined, "Wrong structure for %s table", + osBndTableName.c_str()); + return false; + } + + int iRow = 0; + while (iRow < oTable.GetTotalRecordCount() && + (iRow = oTable.GetAndSelectNextNonEmptyRow(iRow)) >= 0) + { + auto psField = oTable.GetFieldValue(i_raster_id); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "raster_id", + osBndTableName.c_str()); + return false; + } + if (psField->Integer != 1) + { + CPLError(CE_Warning, CPLE_AppDefined, + "Raster with raster_id = %d (!= 1) ignored", + psField->Integer); + continue; + } + + const int nGDBRasterBandId = iRow + 1; + + psField = oTable.GetFieldValue(i_sequence_nbr); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "sequence_nbr", + osBndTableName.c_str()); + return false; + } + const int nSequenceNr = psField->Integer; + + m_oMapGDALBandToGDBBandId[nSequenceNr] = nGDBRasterBandId; + + ++iRow; + } + + if (m_oMapGDALBandToGDBBandId.empty()) + { + CPLError(CE_Failure, CPLE_AppDefined, "Cannot read record in %s table", + osBndTableName.c_str()); + return false; + } + + auto psField = oTable.GetFieldValue(i_band_width); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "band_width", + osBndTableName.c_str()); + return false; + } + int nWidth = psField->Integer; + + psField = oTable.GetFieldValue(i_band_height); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "band_height", + osBndTableName.c_str()); + return false; + } + int nHeight = psField->Integer; + + const int l_nBands = static_cast(m_oMapGDALBandToGDBBandId.size()); + if (!GDALCheckDatasetDimensions(nWidth, nHeight) || + !GDALCheckBandCount(l_nBands, /*bIsZeroAllowed=*/false)) + { + return false; + } + + psField = oTable.GetFieldValue(i_block_width); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "block_width", + osBndTableName.c_str()); + return false; + } + const int nBlockWidth = psField->Integer; + + // 32768 somewhat arbitrary + if (nBlockWidth <= 0 || nBlockWidth > 32768) + { + CPLError(CE_Failure, CPLE_AppDefined, "Invalid %s in %s table", + "block_width", osBndTableName.c_str()); + return false; + } + + psField = oTable.GetFieldValue(i_block_height); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "block_height", + osBndTableName.c_str()); + return false; + } + const int nBlockHeight = psField->Integer; + + // 32768 somewhat arbitrary + if (nBlockHeight <= 0 || nBlockHeight > 32768) + { + CPLError(CE_Failure, CPLE_AppDefined, "Invalid %s in %s table", + "block_height", osBndTableName.c_str()); + return false; + } + + psField = oTable.GetFieldValue(i_band_types); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "band_types", + osBndTableName.c_str()); + return false; + } + const int nBandTypes = psField->Integer; + + psField = oTable.GetFieldValue(i_eminx); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "eminx", + osBndTableName.c_str()); + return false; + } + const double dfMinX = psField->Real; + + psField = oTable.GetFieldValue(i_eminy); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "eminy", + osBndTableName.c_str()); + return false; + } + const double dfMinY = psField->Real; + + psField = oTable.GetFieldValue(i_emaxx); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "emaxx", + osBndTableName.c_str()); + return false; + } + const double dfMaxX = psField->Real; + + psField = oTable.GetFieldValue(i_emaxy); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "emaxy", + osBndTableName.c_str()); + return false; + } + const double dfMaxY = psField->Real; + + psField = oTable.GetFieldValue(i_block_origin_x); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "block_origin_x", + osBndTableName.c_str()); + return false; + } + const double dfBlockOriginX = psField->Real; + + psField = oTable.GetFieldValue(i_block_origin_y); + if (!psField) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read field %s in %s table", "block_origin_y", + osBndTableName.c_str()); + return false; + } + const double dfBlockOriginY = psField->Real; + + // Figure out data type + GDALDataType eDT = GDT_Byte; + const int nBitWidth = (nBandTypes >> 19) & ((1 << 7) - 1); + const int nBitType = (nBandTypes >> 16) & ((1 << 2) - 1); + constexpr int IS_UNSIGNED = 0; + constexpr int IS_SIGNED = 1; + constexpr int IS_FLOATING_POINT = 2; + if ((nBitWidth >= 1 && nBitWidth < 8) && nBitType == IS_UNSIGNED) + { + eDT = GDT_Byte; + } + else if (nBitWidth == 8 && nBitType <= IS_SIGNED) + { + eDT = nBitType == IS_SIGNED ? GDT_Int8 : GDT_Byte; + } + else if (nBitWidth == 16 && nBitType <= IS_SIGNED) + { + eDT = nBitType == IS_SIGNED ? GDT_Int16 : GDT_UInt16; + } + else if (nBitWidth == 32 && nBitType <= IS_FLOATING_POINT) + { + eDT = nBitType == IS_FLOATING_POINT ? GDT_Float32 + : nBitType == IS_SIGNED ? GDT_Int32 + : GDT_UInt32; + } + else if (nBitWidth == 64 && nBitType == 0) + { + eDT = GDT_Float64; + } + else + { + CPLError(CE_Failure, CPLE_AppDefined, + "Unhandled nBitWidth=%d, nBitType=%d in %s table", nBitWidth, + nBitType, osBndTableName.c_str()); + return false; + } + + // To avoid potential integer overflows in IReadBlock() + if (nBlockWidth * nBlockHeight > + std::numeric_limits::max() / nBitWidth) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Too large block %dx%d in %s table", nBlockWidth, nBlockHeight, + osBndTableName.c_str()); + return false; + } + + // Figure out compression + const int nCompression = (nBandTypes >> 8) & 0xff; + switch (nCompression) + { + case 0: + m_eRasterCompression = Compression::NONE; + break; + case 4: + m_eRasterCompression = Compression::LZ77; + SetMetadataItem("COMPRESSION", "DEFLATE", "IMAGE_STRUCTURE"); + break; + case 8: + m_eRasterCompression = Compression::JPEG; + SetMetadataItem("COMPRESSION", "JPEG", "IMAGE_STRUCTURE"); + break; + case 12: + m_eRasterCompression = Compression::JPEG2000; + SetMetadataItem("COMPRESSION", "JPEG2000", "IMAGE_STRUCTURE"); + break; + default: + { + CPLError(CE_Failure, CPLE_AppDefined, + "Unhandled compression %d in %s table", nCompression, + osBndTableName.c_str()); + return false; + } + } + + // Figure out geotransform + + if (!(dfMaxX > dfMinX && dfMaxY > dfMinY)) + { + CPLError(CE_Warning, CPLE_AppDefined, + "!(dfMaxX > dfMinX && dfMaxY > dfMinY)"); + } + else if (nWidth == 1 || nHeight == 1) + { + CPLError(CE_Warning, CPLE_AppDefined, + "nWidth == 1 || nHeight == 1: cannot determine geotransform"); + } + else + { + // FileGDB uses a center-of-pixel convention for georeferencing + // Transform to GDAL's corner-of-pixel convention. + const double dfResX = (dfMaxX - dfMinX) / (nWidth - 1); + const double dfResY = (dfMaxY - dfMinY) / (nHeight - 1); + m_bHasGeoTransform = true; + m_adfGeoTransform[0] = dfBlockOriginX - dfResX / 2; + m_adfGeoTransform[1] = dfResX; + m_adfGeoTransform[2] = 0.0; + m_adfGeoTransform[3] = dfBlockOriginY + dfResY / 2; + m_adfGeoTransform[4] = 0.0; + m_adfGeoTransform[5] = -dfResY; + + // If the block origin is within the full raster extent, reduce the + // advertized raster width/height + if (dfBlockOriginX > dfMinX && dfBlockOriginX < dfMaxX) + { + const int nWidthDiff = static_cast( + std::round((dfMinX - dfBlockOriginX) / dfResX)); + if (nWidthDiff < nWidth) + nWidth -= nWidthDiff; + } + if (dfBlockOriginY < dfMaxY && dfBlockOriginY > dfMinY) + { + const int nHeightDiff = static_cast( + std::round((dfMaxY - dfBlockOriginY) / dfResY)); + if (nHeightDiff < nHeight) + nHeight -= nHeightDiff; + } + } + + // Get SRID, and fetch WKT from GDBSpatialRefs table + psField = oTable.GetFieldValue(i_srid); + if (!psField) + { + CPLError(CE_Warning, CPLE_AppDefined, + "Cannot read field %s in %s table", "srid", + osBndTableName.c_str()); + } + else if (m_osGDBSpatialRefsFilename.empty()) + { + CPLError(CE_Warning, CPLE_AppDefined, "No GDBSpatialRefs table"); + } + else + { + const int nSRID = psField->Integer; + FileGDBTable oTableSRS; + if (oTableSRS.Open(m_osGDBSpatialRefsFilename.c_str(), false)) + { + const int iSRTEXT = oTableSRS.GetFieldIdx("SRTEXT"); + if (iSRTEXT < 0 || + oTableSRS.GetField(iSRTEXT)->GetType() != FGFT_STRING) + { + CPLError(CE_Warning, CPLE_AppDefined, + "Could not find field %s in table %s", "SRTEXT", + oTableSRS.GetFilename().c_str()); + } + else if (nSRID == 0) + { + // BldgHeights.gdb is such. We must fetch the SRS from the + // Definition column of the GDB_Items table + CPLXMLTreeCloser psTree( + CPLParseXMLString(osDefinition.c_str())); + if (psTree == nullptr) + { + CPLError( + CE_Warning, CPLE_AppDefined, + "Cannot parse XML definition. SRS will be missing"); + } + else + { + CPLStripXMLNamespace(psTree.get(), nullptr, TRUE); + const CPLXMLNode *psInfo = + CPLSearchXMLNode(psTree.get(), "=DERasterDataset"); + if (psInfo) + { + auto poSRS = BuildSRS(psInfo); + if (poSRS) + m_oRasterSRS = *poSRS; + } + if (m_oRasterSRS.IsEmpty()) + { + CPLError(CE_Warning, CPLE_AppDefined, + "Cannot get SRS from XML definition"); + } + } + } + else if (nSRID < 0 || !oTableSRS.SelectRow(nSRID - 1) || + oTableSRS.HasGotError()) + { + CPLError(CE_Warning, CPLE_AppDefined, + "Cannot find record corresponding to SRID = %d", + nSRID); + } + else + { + const auto psSRTEXT = oTableSRS.GetFieldValue(iSRTEXT); + if (psSRTEXT && psSRTEXT->String) + { + auto poSRS = BuildSRS(psSRTEXT->String); + if (poSRS) + m_oRasterSRS = *poSRS; + } + else + { + CPLError(CE_Warning, CPLE_AppDefined, + "Cannot get SRTEXT corresponding to SRID = %d", + nSRID); + } + } + } + } + + // Open the fras_blk_XXX table, which contains pixel data, as a OGR layer + const std::string osBlkTableName( + std::string("fras_blk_").append(osLayerName).c_str()); + m_poBlkLayer = BuildLayerFromName(osBlkTableName.c_str()); + if (!m_poBlkLayer) + { + CPLError(CE_Failure, CPLE_AppDefined, "Cannot find table %s", + osBlkTableName.c_str()); + return false; + } + auto poFDefn = m_poBlkLayer->GetLayerDefn(); + if (poFDefn->GetFieldIndex("rasterband_id") < 0 || + poFDefn->GetFieldIndex("rrd_factor") < 0 || + poFDefn->GetFieldIndex("row_nbr") < 0 || + poFDefn->GetFieldIndex("col_nbr") < 0 || + poFDefn->GetFieldIndex("block_data") < 0 || + poFDefn->GetFieldIndex("block_key") < 0) + { + CPLError(CE_Failure, CPLE_AppDefined, "Wrong structure for %s table", + osBlkTableName.c_str()); + return false; + } + + nRasterXSize = nWidth; + nRasterYSize = nHeight; + + if (m_oMapGDALBandToGDBBandId.size() > 1) + { + SetMetadataItem("INTERLEAVE", "BAND", "IMAGE_STRUCTURE"); + } + + // Figure out number of overviews by looking at the biggest block_key + // (should only involve looking in the corresponding index). + int nOverviewCount = 0; + CPLString osSQL; + osSQL.Printf("SELECT MAX(block_key) FROM \"%s\"", osBlkTableName.c_str()); + auto poSQLLyr = ExecuteSQL(osSQL.c_str(), nullptr, nullptr); + if (poSQLLyr) + { + auto poFeat = std::unique_ptr(poSQLLyr->GetNextFeature()); + if (poFeat) + { + const char *pszMaxKey = poFeat->GetFieldAsString(0); + if (strlen(pszMaxKey) == strlen("0000BANDOVYYYYXXXX ")) + { + char szHex[3] = {0}; + memcpy(szHex, pszMaxKey + 8, 2); + unsigned nMaxRRD = 0; + sscanf(szHex, "%02X", &nMaxRRD); + nOverviewCount = + static_cast(std::min(31, nMaxRRD)); + } + } + ReleaseResultSet(poSQLLyr); + } + + if (m_eRasterCompression == Compression::JPEG) + { + GuessJPEGQuality(nOverviewCount); + } + + // It seems that the top left corner of overviews is registered against + // (eminx, emaxy), contrary to the full resolution layer which is registered + // against (block_origin_x, block_origin_y). + // At least, that's what was observed on the dataset + // ftp://ftp.gisdata.mn.gov/pub/gdrs/data/pub/us_mn_state_dnr/water_lake_bathymetry/fgdb_water_lake_bathymetry.zip + if ((dfBlockOriginX != dfMinX || dfBlockOriginY != dfMaxY) && + nOverviewCount > 0) + { + CPLDebug("OpenFileGDB", + "Ignoring overviews as block origin != (minx, maxy)"); + nOverviewCount = 0; + } + + // Create raster bands + + // Create mask band of full resolution, if we don't assign a nodata value + std::unique_ptr poMaskBand; + + // Default "nodata" padding in areas whose validity mask is 0 ? + // Not reliable on integer data types. + // Byte -> 0 + // Int8 -> -128 ? + // Int16 -> 32767 + // UInt16 -> 0 + // (u)int10 -> 65535 + // (u)int12 -> 65535 + // Int32 -> 2147483647 + // UInt32 -> 2147483647 + // Float32 -> 3.4e+38 + // Float64 -> 1.79e+308 + + bool bHasNoData = false; + double dfNoData = 0.0; + const char *pszNoDataOrMask = CSLFetchNameValueDef( + poOpenInfo->papszOpenOptions, "NODATA_OR_MASK", "AUTO"); + if (EQUAL(pszNoDataOrMask, "AUTO")) + { + // In AUTO mode, we only set nodata for Float32/Float64 + // For other data types, report a mask band. + if (eDT == GDT_Float32) + { + bHasNoData = true; + dfNoData = static_cast(static_cast(3.4e+38)); + } + else if (eDT == GDT_Float64) + { + bHasNoData = true; + dfNoData = 1.79e+308; + } + else + { + poMaskBand = cpl::make_unique( + this, 1, GDT_Byte, 8, nBlockWidth, nBlockHeight, 0, true); + } + } + else if (EQUAL(pszNoDataOrMask, "MASK")) + { + poMaskBand = cpl::make_unique( + this, 1, GDT_Byte, 8, nBlockWidth, nBlockHeight, 0, true); + } + else if (!EQUAL(pszNoDataOrMask, "NONE")) + { + dfNoData = CPLAtof(pszNoDataOrMask); + if (eDT == GDT_Float64) + { + bHasNoData = true; + } + else if (eDT == GDT_Float32) + { + if (std::fabs(dfNoData) > std::numeric_limits::max()) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Invalid nodata value %.18g for Float32", dfNoData); + return false; + } + bHasNoData = true; + } + else if (GDALDataTypeIsInteger(eDT)) + { + double dfMin = 0, dfMax = 0; + switch (eDT) + { + case GDT_Int8: + dfMin = std::numeric_limits::min(); + dfMax = std::numeric_limits::max(); + break; + case GDT_Byte: + dfMin = std::numeric_limits::min(); + dfMax = std::numeric_limits::max(); + break; + case GDT_Int16: + dfMin = std::numeric_limits::min(); + dfMax = std::numeric_limits::max(); + break; + case GDT_UInt16: + dfMin = std::numeric_limits::min(); + dfMax = std::numeric_limits::max(); + break; + case GDT_Int32: + dfMin = std::numeric_limits::min(); + dfMax = std::numeric_limits::max(); + break; + case GDT_UInt32: + dfMin = std::numeric_limits::min(); + dfMax = std::numeric_limits::max(); + break; + default: + CPLAssert(false); + return false; + } + if (!std::isfinite(dfNoData) || dfNoData < dfMin || + dfNoData > dfMax || + dfNoData != static_cast(static_cast(dfNoData))) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Invalid nodata value %.18g for %s", dfNoData, + GDALGetDataTypeName(eDT)); + return false; + } + bHasNoData = true; + } + } + + GDALOpenFileGDBRasterBand *poMaskBandRef = poMaskBand.get(); + + for (int iBand = 1; iBand <= l_nBands; ++iBand) + { + auto poBand = new GDALOpenFileGDBRasterBand( + this, iBand, eDT, nBitWidth, nBlockWidth, nBlockHeight, 0, false); + if (poMaskBandRef) + { + if (iBand == 1) + { + // Make the mask band owned by the first raster band + poBand->m_poMaskBandOwned = std::move(poMaskBand); + poMaskBandRef = poBand->m_poMaskBandOwned.get(); + poMaskBandRef->m_poMainBand = poBand; + } + poBand->m_poMaskBand = poMaskBandRef; + } + else if (bHasNoData) + { + poBand->m_dfNoData = dfNoData; + poBand->m_bHasNoData = true; + } + + // Create overview bands + for (int iOvr = 0; iOvr < nOverviewCount; ++iOvr) + { + auto poOvrBand = cpl::make_unique( + this, iBand, eDT, nBitWidth, nBlockWidth, nBlockHeight, + iOvr + 1, false); + if (poBand->m_bHasNoData) + { + poOvrBand->m_dfNoData = dfNoData; + poOvrBand->m_bHasNoData = true; + } + poBand->m_apoOverviewBands.emplace_back(std::move(poOvrBand)); + } + + SetBand(iBand, poBand); + } + + // Create mask band of overview bands + if (poMaskBandRef) + { + for (int iOvr = 0; iOvr < nOverviewCount; ++iOvr) + { + for (int iBand = 1; iBand <= l_nBands; ++iBand) + { + auto poOvrBand = cpl::down_cast( + GetRasterBand(iBand)) + ->m_apoOverviewBands[iOvr] + .get(); + if (iBand == 1) + { + // Make the mask band owned by the first raster band + poOvrBand->m_poMaskBandOwned = + cpl::make_unique( + this, 1, GDT_Byte, 8, nBlockWidth, nBlockHeight, + iOvr + 1, true); + poMaskBandRef = poOvrBand->m_poMaskBandOwned.get(); + poMaskBandRef->m_poMainBand = poOvrBand; + } + poOvrBand->m_poMaskBand = poMaskBandRef; + } + } + } + + ReadAuxTable(osLayerName); + + if (!osDefinition.empty()) + { + const char *const apszMD[] = {osDefinition.c_str(), nullptr}; + SetMetadata(const_cast(apszMD), "xml:definition"); + } + + if (!osDocumentation.empty()) + { + const char *const apszMD[] = {osDocumentation.c_str(), nullptr}; + SetMetadata(const_cast(apszMD), "xml:documentation"); + } + + // We are all fine after all those preliminary checks and setups ! + return true; +} + +/************************************************************************/ +/* GuessJPEGQuality() */ +/************************************************************************/ + +void OGROpenFileGDBDataSource::GuessJPEGQuality(int nOverviewCount) +{ + // For JPEG, fetch JPEG_QUALITY from the data of the smallest overview level + CPLString osFilter; + osFilter.Printf("block_key = '0000%04X%02X%04X%04X'", + 1, // band + nOverviewCount, + 0, // nBlockYOff + 0 // nBlockXOff + ); + + CPLAssert(m_poBlkLayer); + m_poBlkLayer->SetAttributeFilter(osFilter.c_str()); + auto poFeature = + std::unique_ptr(m_poBlkLayer->GetNextFeature()); + if (poFeature) + { + const int nFieldIdx = poFeature->GetFieldIndex("block_data"); + CPLAssert(nFieldIdx >= 0); + if (poFeature->IsFieldSetAndNotNull(nFieldIdx)) + { + int nInBytes = 0; + const GByte *pabyData = + poFeature->GetFieldAsBinary(nFieldIdx, &nInBytes); + if (nInBytes >= 5) + { + uint32_t nJPEGSize = nInBytes - 1; + uint32_t nJPEGOffset = 1; + if (pabyData[0] == 0xFE) + { + // JPEG followed by binary mask + memcpy(&nJPEGSize, pabyData + 1, sizeof(uint32_t)); + CPL_LSBPTR32(&nJPEGSize); + if (nJPEGSize > static_cast(nInBytes - 5)) + { + nJPEGSize = 0; + } + nJPEGOffset = 5; + } + else if (pabyData[0] != 1) + { + nJPEGSize = 0; + } + if (nJPEGSize) + { + CPLString osTmpFilename; + osTmpFilename.Printf("/vsimem/_openfilegdb/%p.jpg", this); + VSIFCloseL(VSIFileFromMemBuffer( + osTmpFilename.c_str(), + const_cast(pabyData + nJPEGOffset), nJPEGSize, + false)); + const char *const apszDrivers[] = {"JPEG", nullptr}; + auto poJPEGDS = std::unique_ptr( + GDALDataset::Open(osTmpFilename.c_str(), GDAL_OF_RASTER, + apszDrivers)); + if (poJPEGDS) + { + const char *pszQuality = poJPEGDS->GetMetadataItem( + "JPEG_QUALITY", "IMAGE_STRUCTURE"); + if (pszQuality) + { + SetMetadataItem("JPEG_QUALITY", pszQuality, + "IMAGE_STRUCTURE"); + } + } + VSIUnlink(osTmpFilename); + } + } + } + } +} + +/************************************************************************/ +/* ReadAuxTable() */ +/************************************************************************/ + +// Record type=9 of table fras_ras_XXXX contains a PropertySet object, +// which may contain statistics +// For example on +// https://listdata.thelist.tas.gov.au/opendata/data/NCH_ES_WATER_LOGGING_HAZARD_STATEWIDE.zip +void OGROpenFileGDBDataSource::ReadAuxTable(const std::string &osLayerName) +{ + const std::string osAuxTableName( + std::string("fras_aux_").append(osLayerName).c_str()); + auto poLayer = BuildLayerFromName(osAuxTableName.c_str()); + if (!poLayer) + { + CPLDebug("OpenFileGDB", "Cannot find table %s", osAuxTableName.c_str()); + return; + } + auto poFDefn = poLayer->GetLayerDefn(); + const int iFieldObjectIdx = poFDefn->GetFieldIndex("object"); + if (poFDefn->GetFieldIndex("type") < 0 || iFieldObjectIdx < 0) + { + CPLDebug("OpenFileGDB", "Wrong structure for %s table", + osAuxTableName.c_str()); + return; + } + poLayer->SetAttributeFilter("type = 9"); + auto poFeature = std::unique_ptr(poLayer->GetNextFeature()); + if (!poFeature) + return; + if (!poFeature->IsFieldSetAndNotNull(iFieldObjectIdx)) + return; + int nBytes = 0; + const GByte *pabyData = + poFeature->GetFieldAsBinary(iFieldObjectIdx, &nBytes); + if (!pabyData || nBytes == 0) + return; + int iOffset = 0; + + const auto ReadString = [pabyData, &iOffset, nBytes](std::string &osStr) + { + if (iOffset > nBytes - 4) + return false; + int nStrLength; + memcpy(&nStrLength, pabyData + iOffset, 4); + CPL_LSBPTR32(&nStrLength); + iOffset += 4; + if (nStrLength <= 2 || iOffset > nBytes - nStrLength) + return false; + if ((nStrLength % 2) != 0) + return false; + // nStrLength / 2 to get the number of characters + // and - 1 to remove the null terminating one + osStr = ReadUTF16String(pabyData + iOffset, nStrLength / 2 - 1); + iOffset += nStrLength; + return true; + }; + + // pabyData is an ArcObject "PropertySet" object, which is key/value + // dictionary. This is hard to parse given there are variable-length value + // whose size is not explicit. So let's use a heuristics by looking for + // the beginning of a inner PropertySet with band properties that starts + // with a KIND=BAND key value pair. + constexpr GByte abyNeedle[] = { + 'K', 0, 'I', 0, 'N', 0, 'D', 0, 0, 0, 8, 0, // 8 = string + 10, 0, 0, 0, // number of bytes of following value + 'B', 0, 'A', 0, 'N', 0, 'D', 0, 0, 0}; + constexpr int nNeedleSize = static_cast(sizeof(abyNeedle)); + + for (int iBand = 1; iBand <= nBands; ++iBand) + { + int iNewOffset = -1; + for (int i = iOffset; i < nBytes - nNeedleSize; ++i) + { + if (pabyData[i] == 'K' && + memcmp(pabyData + i, abyNeedle, nNeedleSize) == 0) + { + iNewOffset = i + nNeedleSize; + break; + } + } + if (iNewOffset < 0) + return; + iOffset = iNewOffset; + + // Try to read as many key/value pairs as possible + while (true) + { + // Read key + std::string osKey; + if (!ReadString(osKey)) + return; + + // Read value type as a short + uint16_t nValueType; + if (iOffset > nBytes - 2) + return; + memcpy(&nValueType, pabyData + iOffset, 2); + CPL_LSBPTR16(&nValueType); + iOffset += 2; + + // Skip over non-string values + if (nValueType == 0 || nValueType == 1) // null / empty value + { + continue; + } + if (nValueType == 2) // short value + { + if (iOffset > nBytes - 2) + return; + iOffset += 2; + continue; + } + + if (nValueType == 3 || nValueType == 4) // int or long value + { + if (iOffset > nBytes - 4) + return; + iOffset += 4; + continue; + } + + if (nValueType == 5 || nValueType == 7) // double or date value + { + if (iOffset > nBytes - 8) + return; + iOffset += 8; + continue; + } + + if (nValueType != 8) // 8 = string + { + // Give up with this band as the value type is not handled, + // and we can't skip over it. + break; + } + + // Read string value + std::string osValue; + if (!ReadString(osValue)) + return; + + GetRasterBand(iBand)->SetMetadataItem(osKey.c_str(), + osValue.c_str()); + } + } +} + +/************************************************************************/ +/* GetGeoTransform() */ +/************************************************************************/ + +CPLErr OGROpenFileGDBDataSource::GetGeoTransform(double *padfGeoTransform) +{ + memcpy(padfGeoTransform, m_adfGeoTransform.data(), + sizeof(m_adfGeoTransform)); + return m_bHasGeoTransform ? CE_None : CE_Failure; +} + +/************************************************************************/ +/* GetSpatialRef() */ +/************************************************************************/ + +const OGRSpatialReference *OGROpenFileGDBDataSource::GetSpatialRef() const +{ + return m_oRasterSRS.IsEmpty() ? nullptr : &m_oRasterSRS; +} + +/************************************************************************/ +/* GDALOpenFileGDBRasterBand() */ +/************************************************************************/ + +GDALOpenFileGDBRasterBand::GDALOpenFileGDBRasterBand( + OGROpenFileGDBDataSource *poDSIn, int nBandIn, GDALDataType eDT, + int nBitWidth, int nBlockWidth, int nBlockHeight, int nOverviewLevel, + bool bIsMask) + : m_nBitWidth(nBitWidth), m_nOverviewLevel(nOverviewLevel), + m_bIsMask(bIsMask) +{ + poDS = poDSIn; + nBand = nBandIn; + eDataType = eDT; + nRasterXSize = std::max(1, poDSIn->GetRasterXSize() >> nOverviewLevel); + nRasterYSize = std::max(1, poDSIn->GetRasterYSize() >> nOverviewLevel); + nBlockXSize = nBlockWidth; + nBlockYSize = nBlockHeight; + if (nBitWidth < 8) + { + SetMetadataItem("NBITS", CPLSPrintf("%d", nBitWidth), + "IMAGE_STRUCTURE"); + } +} + +/************************************************************************/ +/* SetNoDataFromMask() */ +/************************************************************************/ + +template +static void SetNoDataFromMask(void *pImage, const GByte *pabyMask, + size_t nPixels, double dfNoData) +{ + const T noData = static_cast(dfNoData); + const T noDataReplacement = + noData == std::numeric_limits::max() ? noData - 1 : noData + 1; + bool bHasWarned = false; + for (size_t i = 0; i < nPixels; ++i) + { + if (pabyMask && !(pabyMask[i / 8] & (0x80 >> (i & 7)))) + { + static_cast(pImage)[i] = noData; + } + else if (static_cast(pImage)[i] == noData) + { + static_cast(pImage)[i] = noDataReplacement; + if (!bHasWarned) + { + bHasWarned = true; + CPLError(CE_Warning, CPLE_AppDefined, + "Valid data found with value equal to nodata (%.0f). " + "Got substituted with %.0f", + static_cast(noData), + static_cast(noDataReplacement)); + } + } + } +} + +/************************************************************************/ +/* IReadBlock() */ +/************************************************************************/ + +CPLErr GDALOpenFileGDBRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, + void *pImage) +{ + auto poGDS = cpl::down_cast(poDS); + auto &poLyr = poGDS->m_poBlkLayer; + + // Return (pointer to image data, owner block). Works when called from main band + // or mask band. owner block must be DropLock() once done (if not null) + const auto GetImageData = [this, nBlockXOff, nBlockYOff, pImage]() + { + void *pImageData = nullptr; + GDALRasterBlock *poBlock = nullptr; + if (m_bIsMask) + { + CPLAssert(m_poMainBand); + poBlock = + m_poMainBand->TryGetLockedBlockRef(nBlockXOff, nBlockYOff); + if (poBlock) + { + // The block is already in cache. Return (null, null) + poBlock->DropLock(); + poBlock = nullptr; + } + else + { + poBlock = m_poMainBand->GetLockedBlockRef(nBlockXOff, + nBlockYOff, true); + if (poBlock) + pImageData = poBlock->GetDataRef(); + } + } + else + { + pImageData = pImage; + } + return std::make_pair(pImageData, poBlock); + }; + + // Return (pointer to mask data, owner block). Works when called from main band + // or mask band. owner block must be DropLock() once done (if not null) + const auto GetMaskData = [this, nBlockXOff, nBlockYOff, pImage]() + { + void *pMaskData = nullptr; + GDALRasterBlock *poBlock = nullptr; + if (m_bIsMask) + { + pMaskData = pImage; + } + else + { + CPLAssert(m_poMaskBand); + poBlock = + m_poMaskBand->TryGetLockedBlockRef(nBlockXOff, nBlockYOff); + if (poBlock) + { + // The block is already in cache. Return (null, null) + poBlock->DropLock(); + poBlock = nullptr; + } + else + { + poBlock = m_poMaskBand->GetLockedBlockRef(nBlockXOff, + nBlockYOff, true); + if (poBlock) + pMaskData = poBlock->GetDataRef(); + } + } + return std::make_pair(pMaskData, poBlock); + }; + + const GDALDataType eImageDT = + m_poMainBand ? m_poMainBand->GetRasterDataType() : eDataType; + const size_t nPixels = static_cast(nBlockXSize) * nBlockYSize; + + const auto FillMissingBlock = + [this, eImageDT, nPixels, &GetImageData, &GetMaskData]() + { + // Set image data to nodata / 0 + { + auto imageDataAndBlock = GetImageData(); + auto pImageData = imageDataAndBlock.first; + auto poBlock = imageDataAndBlock.second; + if (pImageData) + { + const int nDTSize = GDALGetDataTypeSizeBytes(eImageDT); + if (m_bHasNoData) + { + GDALCopyWords64(&m_dfNoData, GDT_Float64, 0, pImageData, + eImageDT, nDTSize, nPixels); + } + else + { + memset(pImageData, 0, nPixels * nDTSize); + } + } + if (poBlock) + poBlock->DropLock(); + } + + // Set mask band to 0 (when it exists) + if (m_poMaskBand || m_bIsMask) + { + auto maskDataAndBlock = GetMaskData(); + auto pMaskData = maskDataAndBlock.first; + auto poBlock = maskDataAndBlock.second; + if (pMaskData) + { + const size_t nSize = + static_cast(nBlockXSize) * nBlockYSize; + memset(pMaskData, 0, nSize); + } + if (poBlock) + poBlock->DropLock(); + } + }; + + // Fetch block data from fras_blk_XXX layer + const int nGDALBandId = m_bIsMask ? 1 : nBand; + auto oIter = poGDS->m_oMapGDALBandToGDBBandId.find(nGDALBandId); + if (oIter == poGDS->m_oMapGDALBandToGDBBandId.end()) + { + CPLError(CE_Failure, CPLE_AppDefined, + "poGDS->m_oMapGDALBandToGDBBandId.find(%d) failed", + nGDALBandId); + } + const int nGDBRasterBandId = oIter->second; + + CPLString osFilter; + /* osFilter.Printf("rasterband_id = %d AND rrd_factor = %d AND row_nbr = %d " + "AND col_nbr = %d", + nGDBRasterBandId, + m_nOverviewLevel, nBlockYOff, nBlockXOff); + */ + osFilter.Printf("block_key = '0000%04X%02X%04X%04X'", nGDBRasterBandId, + m_nOverviewLevel, nBlockYOff, nBlockXOff); + // CPLDebug("OpenFileGDB", "Request %s", osFilter.c_str()); + poLyr->SetAttributeFilter(osFilter.c_str()); + auto poFeature = std::unique_ptr(poLyr->GetNextFeature()); + const int nImageDTSize = GDALGetDataTypeSizeBytes(eImageDT); + if (!poFeature) + { + // Missing blocks are legit + FillMissingBlock(); + return CE_None; + } + const int nFieldIdx = poFeature->GetFieldIndex("block_data"); + CPLAssert(nFieldIdx >= 0); + int nInBytes = 0; + if (!poFeature->IsFieldSetAndNotNull(nFieldIdx)) + { + // block_data unset found on ForestFalls.gdb + FillMissingBlock(); + return CE_None; + } + const GByte *pabyData = poFeature->GetFieldAsBinary(nFieldIdx, &nInBytes); + if (nInBytes == 0) + { + CPLError(CE_Failure, CPLE_AppDefined, "Image block is empty"); + return CE_Failure; + } + + // The input buffer may be concatenated with a 1-bit binary mask + const size_t nImageSize = nPixels * nImageDTSize; + const int nImageBitWidth = + m_poMainBand ? m_poMainBand->m_nBitWidth : m_nBitWidth; + const size_t nImageSizePacked = (nPixels * nImageBitWidth + 7) / 8; + const size_t nBinaryMaskSize = (nPixels + 7) / 8; + const size_t nImageSizeWithBinaryMask = nImageSizePacked + nBinaryMaskSize; + + // Unpack 1-bit, 2-bit, 4-bit data to full byte + const auto ExpandSubByteData = + [nPixels, nImageBitWidth](const GByte *pabyInput, void *pDstBuffer) + { + CPLAssert(nImageBitWidth < 8); + + size_t iBitOffset = 0; + for (size_t i = 0; i < nPixels; ++i) + { + unsigned nOutWord = 0; + + for (int iBit = 0; iBit < nImageBitWidth; ++iBit) + { + if (pabyInput[iBitOffset >> 3] & (0x80 >> (iBitOffset & 7))) + { + nOutWord |= (1 << (nImageBitWidth - 1 - iBit)); + } + ++iBitOffset; + } + + static_cast(pDstBuffer)[i] = static_cast(nOutWord); + } + }; + + const GByte *pabyMask = nullptr; + auto &abyTmpBuffer = + m_poMainBand ? m_poMainBand->m_abyTmpBuffer : m_abyTmpBuffer; + + switch (poGDS->m_eRasterCompression) + { + case OGROpenFileGDBDataSource::Compression::NONE: + { + if (static_cast(nInBytes) != nImageSizePacked && + static_cast(nInBytes) != nImageSizeWithBinaryMask) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Not expected number of input bytes: %d", nInBytes); + return CE_Failure; + } + + auto imageDataAndBlock = GetImageData(); + auto pImageData = imageDataAndBlock.first; + auto poBlock = imageDataAndBlock.second; + + if (pImageData) + { + if (nImageSizePacked == nImageSize) + { + memcpy(pImageData, pabyData, nImageSize); +#ifdef CPL_LSB + if (nImageDTSize > 1) + { + GDALSwapWordsEx(pImageData, nImageDTSize, nPixels, + nImageDTSize); + } +#endif + } + else + { + ExpandSubByteData(pabyData, pImageData); + } + } + if (poBlock) + poBlock->DropLock(); + + if (static_cast(nInBytes) == nImageSizeWithBinaryMask) + pabyMask = pabyData + nImageSizePacked; + break; + } + + case OGROpenFileGDBDataSource::Compression::LZ77: + { + if (abyTmpBuffer.empty()) + { + try + { + abyTmpBuffer.resize(nImageSizeWithBinaryMask); + } + catch (const std::bad_alloc &e) + { + CPLError(CE_Failure, CPLE_OutOfMemory, "%s", e.what()); + return CE_Failure; + } + } + + size_t nOutBytes = 0; + if (!CPLZLibInflate(pabyData, nInBytes, abyTmpBuffer.data(), + abyTmpBuffer.size(), &nOutBytes) || + !(nOutBytes == nImageSizePacked || + nOutBytes == nImageSizeWithBinaryMask)) + { + CPLError( + CE_Failure, CPLE_AppDefined, + "CPLZLibInflate() failed: nInBytes = %u, nOutBytes = %u, " + "nImageSizePacked = %u, " + "nImageSizeWithBinaryMask = %u", + unsigned(nInBytes), unsigned(nOutBytes), + unsigned(nImageSizePacked), + unsigned(nImageSizeWithBinaryMask)); + return CE_Failure; + } + + auto imageDataAndBlock = GetImageData(); + auto pImageData = imageDataAndBlock.first; + auto poBlock = imageDataAndBlock.second; + + if (pImageData) + { + if (nImageSizePacked == nImageSize) + { + memcpy(pImageData, abyTmpBuffer.data(), nImageSize); +#ifdef CPL_LSB + if (nImageDTSize > 1) + { + GDALSwapWordsEx(pImageData, nImageDTSize, nPixels, + nImageDTSize); + } +#endif + } + else + { + ExpandSubByteData(abyTmpBuffer.data(), pImageData); + } + } + if (poBlock) + poBlock->DropLock(); + + if (nOutBytes == nImageSizeWithBinaryMask) + pabyMask = abyTmpBuffer.data() + nImageSizePacked; + break; + } + + case OGROpenFileGDBDataSource::Compression::JPEG: + { + if (GDALGetDriverByName("JPEG") == nullptr) + { + CPLError(CE_Failure, CPLE_AppDefined, "JPEG driver missing"); + return CE_Failure; + } + + if (static_cast(nInBytes) < 5) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Not expected number of input bytes: %d", nInBytes); + return CE_Failure; + } + uint32_t nJPEGSize = nInBytes - 1; + uint32_t nJPEGOffset = 1; + if (pabyData[0] == 0xFE) + { + // JPEG followed by binary mask + memcpy(&nJPEGSize, pabyData + 1, sizeof(uint32_t)); + CPL_LSBPTR32(&nJPEGSize); + if (nJPEGSize > static_cast(nInBytes - 5)) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Invalid nJPEGSize = %u", nJPEGSize); + return CE_Failure; + } + nJPEGOffset = 5; + + if (abyTmpBuffer.empty()) + { + try + { + abyTmpBuffer.resize(nBinaryMaskSize); + } + catch (const std::bad_alloc &e) + { + CPLError(CE_Failure, CPLE_OutOfMemory, "%s", e.what()); + return CE_Failure; + } + } + size_t nOutBytes = 0; + if (CPLZLibInflate( + pabyData + 5 + nJPEGSize, nInBytes - 5 - nJPEGSize, + abyTmpBuffer.data(), nBinaryMaskSize, &nOutBytes) && + nOutBytes == nBinaryMaskSize) + { + pabyMask = abyTmpBuffer.data(); + } + else + { + CPLError(CE_Warning, CPLE_AppDefined, + "Cannot decompress binary mask"); + } + } + else if (pabyData[0] != 1) + { + CPLError(CE_Failure, CPLE_AppDefined, "Invalid JPEG blob"); + return CE_Failure; + } + + VSILFILE *fp = VSIFOpenL("tmp.jpg", "wb"); + VSIFWriteL(pabyData + nJPEGOffset, nJPEGSize, 1, fp); + VSIFCloseL(fp); + + CPLString osTmpFilename; + osTmpFilename.Printf("/vsimem/_openfilegdb/%p.jpg", this); + VSIFCloseL(VSIFileFromMemBuffer( + osTmpFilename.c_str(), + const_cast(pabyData + nJPEGOffset), nJPEGSize, false)); + const char *const apszDrivers[] = {"JPEG", nullptr}; + auto poJPEGDS = std::unique_ptr(GDALDataset::Open( + osTmpFilename.c_str(), GDAL_OF_RASTER, apszDrivers)); + if (!poJPEGDS) + { + VSIUnlink(osTmpFilename.c_str()); + CPLError(CE_Failure, CPLE_AppDefined, "Cannot open JPEG blob"); + return CE_Failure; + } + if (poJPEGDS->GetRasterCount() != 1 || + poJPEGDS->GetRasterXSize() != nBlockXSize || + poJPEGDS->GetRasterYSize() != nBlockYSize) + { + VSIUnlink(osTmpFilename.c_str()); + CPLError(CE_Failure, CPLE_AppDefined, + "Inconsistent characteristics of JPEG blob"); + return CE_Failure; + } + + auto imageDataAndBlock = GetImageData(); + auto pImageData = imageDataAndBlock.first; + auto poBlock = imageDataAndBlock.second; + + const CPLErr eErr = + pImageData + ? poJPEGDS->GetRasterBand(1)->RasterIO( + GF_Read, 0, 0, nBlockXSize, nBlockYSize, pImageData, + nBlockXSize, nBlockYSize, eImageDT, 0, 0, nullptr) + : CE_None; + VSIUnlink(osTmpFilename.c_str()); + if (poBlock) + poBlock->DropLock(); + + if (eErr != CE_None) + { + CPLError(CE_Failure, CPLE_AppDefined, "Cannot read JPEG blob"); + return CE_Failure; + } + + break; + } + + case OGROpenFileGDBDataSource::Compression::JPEG2000: + { + const char *const apszDrivers[] = {"JP2KAK", "JP2ECW", + "JP2OpenJPEG", "JP2MrSID", + "JP2Lura", nullptr}; + bool bFoundJP2Driver = false; + for (const char *pszDriver : apszDrivers) + { + if (pszDriver && GDALGetDriverByName(pszDriver)) + { + bFoundJP2Driver = true; + break; + } + } + if (!bFoundJP2Driver) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Did not find any JPEG2000 capable driver"); + return CE_Failure; + } + + if (static_cast(nInBytes) < 5) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Not expected number of input bytes: %d", nInBytes); + return CE_Failure; + } + uint32_t nJPEGSize = nInBytes - 1; + uint32_t nJPEGOffset = 1; + if (pabyData[0] == 0xFF) + { + // JPEG2000 followed by binary mask + memcpy(&nJPEGSize, pabyData + 1, sizeof(uint32_t)); + CPL_LSBPTR32(&nJPEGSize); + if (nJPEGSize > static_cast(nInBytes - 5)) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Invalid nJPEGSize = %u", nJPEGSize); + return CE_Failure; + } + nJPEGOffset = 5; + + if (abyTmpBuffer.empty()) + { + try + { + abyTmpBuffer.resize(nBinaryMaskSize); + } + catch (const std::bad_alloc &e) + { + CPLError(CE_Failure, CPLE_OutOfMemory, "%s", e.what()); + return CE_Failure; + } + } + size_t nOutBytes = 0; + if (CPLZLibInflate( + pabyData + 5 + nJPEGSize, nInBytes - 5 - nJPEGSize, + abyTmpBuffer.data(), nBinaryMaskSize, &nOutBytes) && + nOutBytes == nBinaryMaskSize) + { + pabyMask = abyTmpBuffer.data(); + } + else + { + CPLError(CE_Warning, CPLE_AppDefined, + "Cannot decompress binary mask"); + } + } + else if (pabyData[0] != 0) + { + CPLError(CE_Failure, CPLE_AppDefined, "Invalid JPEG2000 blob"); + return CE_Failure; + } + + CPLString osTmpFilename; + osTmpFilename.Printf("/vsimem/_openfilegdb/%p.j2k", this); + VSIFCloseL(VSIFileFromMemBuffer( + osTmpFilename.c_str(), + const_cast(pabyData + nJPEGOffset), nJPEGSize, false)); + auto poJP2KDS = std::unique_ptr(GDALDataset::Open( + osTmpFilename.c_str(), GDAL_OF_RASTER, apszDrivers)); + if (!poJP2KDS) + { + VSIUnlink(osTmpFilename.c_str()); + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot open JPEG2000 blob"); + return CE_Failure; + } + if (poJP2KDS->GetRasterCount() != 1 || + poJP2KDS->GetRasterXSize() != nBlockXSize || + poJP2KDS->GetRasterYSize() != nBlockYSize) + { + VSIUnlink(osTmpFilename.c_str()); + CPLError(CE_Failure, CPLE_AppDefined, + "Inconsistent characteristics of JPEG2000 blob"); + return CE_Failure; + } + + auto imageDataAndBlock = GetImageData(); + auto pImageData = imageDataAndBlock.first; + auto poBlock = imageDataAndBlock.second; + + const CPLErr eErr = + pImageData + ? poJP2KDS->GetRasterBand(1)->RasterIO( + GF_Read, 0, 0, nBlockXSize, nBlockYSize, pImageData, + nBlockXSize, nBlockYSize, eImageDT, 0, 0, nullptr) + : CE_None; + VSIUnlink(osTmpFilename.c_str()); + if (poBlock) + poBlock->DropLock(); + + if (eErr != CE_None) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot read JPEG2000 blob"); + return CE_Failure; + } + + break; + } + } + + if (m_bIsMask || m_poMaskBand) + { + auto maskDataAndBlock = GetMaskData(); + auto pMaskData = maskDataAndBlock.first; + auto poBlock = maskDataAndBlock.second; + + if (pMaskData) + { + if (pabyMask) + { + // Unpack 1-bit array + for (size_t i = 0; i < nPixels; ++i) + { + static_cast(pMaskData)[i] = + (pabyMask[i / 8] & (0x80 >> (i & 7))) ? 255 : 0; + } + } + else + { + // No explicit mask in source block --> all valid + memset(pMaskData, 255, nPixels); + } + } + + if (poBlock) + poBlock->DropLock(); + } + else if (m_bHasNoData) + { + if (eImageDT == GDT_Byte) + { + SetNoDataFromMask(pImage, pabyMask, nPixels, m_dfNoData); + } + else if (eImageDT == GDT_Int8) + { + SetNoDataFromMask(pImage, pabyMask, nPixels, m_dfNoData); + } + else if (eImageDT == GDT_UInt16) + { + SetNoDataFromMask(pImage, pabyMask, nPixels, m_dfNoData); + } + else if (eImageDT == GDT_Int16) + { + SetNoDataFromMask(pImage, pabyMask, nPixels, m_dfNoData); + } + else if (eImageDT == GDT_UInt32) + { + SetNoDataFromMask(pImage, pabyMask, nPixels, m_dfNoData); + } + else if (eImageDT == GDT_Int32) + { + SetNoDataFromMask(pImage, pabyMask, nPixels, m_dfNoData); + } + else if (eImageDT == GDT_Float32) + { + if (pabyMask) + { + for (size_t i = 0; i < nPixels; ++i) + { + if (!(pabyMask[i / 8] & (0x80 >> (i & 7)))) + { + static_cast(pImage)[i] = + static_cast(m_dfNoData); + } + } + } + } + else if (eImageDT == GDT_Float64) + { + if (pabyMask) + { + for (size_t i = 0; i < nPixels; ++i) + { + if (!(pabyMask[i / 8] & (0x80 >> (i & 7)))) + { + static_cast(pImage)[i] = m_dfNoData; + } + } + } + } + else + { + CPLAssert(false); + } + } + +#if 0 + printf("Data:\n"); // ok + if (eDataType == GDT_Byte) + { + for (int y = 0; y < nBlockYSize; ++y) + { + for (int x = 0; x < nBlockXSize; ++x) + { + printf("%d ", // ok + static_cast(pImage)[y * nBlockXSize + x]); + } + printf("\n"); // ok + } + } + else if (eDataType == GDT_Int8) + { + for (int y = 0; y < nBlockYSize; ++y) + { + for (int x = 0; x < nBlockXSize; ++x) + { + printf("%d ", // ok + static_cast(pImage)[y * nBlockXSize + x]); + } + printf("\n"); // ok + } + } + else if (eDataType == GDT_UInt16) + { + for (int y = 0; y < nBlockYSize; ++y) + { + for (int x = 0; x < nBlockXSize; ++x) + { + printf("%d ", // ok + static_cast(pImage)[y * nBlockXSize + x]); + } + printf("\n"); // ok + } + } + else if (eDataType == GDT_Int16) + { + for (int y = 0; y < nBlockYSize; ++y) + { + for (int x = 0; x < nBlockXSize; ++x) + { + printf("%d ", // ok + static_cast(pImage)[y * nBlockXSize + x]); + } + printf("\n"); // ok + } + } + else if (eDataType == GDT_UInt32) + { + for (int y = 0; y < nBlockYSize; ++y) + { + for (int x = 0; x < nBlockXSize; ++x) + { + printf("%d ", // ok + static_cast(pImage)[y * nBlockXSize + x]); + } + printf("\n"); // ok + } + } + else if (eDataType == GDT_Int32) + { + for (int y = 0; y < nBlockYSize; ++y) + { + for (int x = 0; x < nBlockXSize; ++x) + { + printf("%d ", // ok + static_cast(pImage)[y * nBlockXSize + x]); + } + printf("\n"); // ok + } + } + else if (eDataType == GDT_Float32) + { + for (int y = 0; y < nBlockYSize; ++y) + { + for (int x = 0; x < nBlockXSize; ++x) + { + printf("%.8g ", // ok + static_cast(pImage)[y * nBlockXSize + x]); + } + printf("\n"); // ok + } + } + else if (eDataType == GDT_Float64) + { + for (int y = 0; y < nBlockYSize; ++y) + { + for (int x = 0; x < nBlockXSize; ++x) + { + printf("%.18g ", // ok + static_cast(pImage)[y * nBlockXSize + x]); + } + printf("\n"); // ok + } + } +#endif + +#if 0 + if (pabyMask) + { + printf("Mask:\n"); // ok + for (int y = 0; y < nBlockYSize; ++y) + { + for (int x = 0; x < nBlockXSize; ++x) + { + printf("%d ", // ok + (pabyMask[(y * nBlockXSize + x) / 8] & + (0x80 >> ((y * nBlockXSize + x) & 7))) + ? 1 + : 0); + } + printf("\n"); // ok + } + } +#endif + + return CE_None; +} + +/************************************************************************/ +/* GetDefaultRAT() */ +/************************************************************************/ + +GDALRasterAttributeTable *GDALOpenFileGDBRasterBand::GetDefaultRAT() +{ + if (m_poRAT) + return m_poRAT.get(); + if (poDS->GetRasterCount() > 1 || m_bIsMask) + return nullptr; + auto poGDS = cpl::down_cast(poDS); + const std::string osVATTableName( + std::string("VAT_").append(poGDS->m_osRasterLayerName)); + // Instanciate a new dataset, os that the RAT is standalone + auto poDSNew = cpl::make_unique(); + GDALOpenInfo oOpenInfo(poGDS->m_osDirName.c_str(), GA_ReadOnly); + if (!poDSNew->Open(&oOpenInfo)) + return nullptr; + auto poVatLayer = poDSNew->BuildLayerFromName(osVATTableName.c_str()); + if (!poVatLayer) + return nullptr; + m_poRAT = cpl::make_unique( + std::move(poDSNew), osVATTableName, std::move(poVatLayer)); + return m_poRAT.get(); +}