Repository: pydicom/pydicom

Issue:
LUT Descriptor tag with no value yields TypeError
**Describe the bug**
I have a DICOM image with the following tag (copied from ImageJ)

```
0028,1101  Red Palette Color Lookup Table Descriptor: 
```

which corresponds to the raw data element, produced by [`DataElement_from_raw`](https://github.com/pydicom/pydicom/blob/v1.4.1/pydicom/dataelem.py#L699):
```
RawDataElement(tag=(0028, 1101), VR='US', length=0, value=None, value_tell=1850, is_implicit_VR=False, is_little_endian=True)
```

Because this tag is matched by the [LUT Descriptor tags](https://github.com/pydicom/pydicom/blob/v1.4.1/pydicom/dataelem.py#L696) and the value is empty (`None`), the [following line](https://github.com/pydicom/pydicom/blob/v1.4.1/pydicom/dataelem.py#L761):
```
if raw.tag in _LUT_DESCRIPTOR_TAGS and value[0] < 0:
```
results in 
```
TypeError: 'NoneType' object is not subscriptable
```

**Expected behavior**

Given that I discovered this by parsing what seems to be a set of faulty DICOMs (mangled pixel data), I'm not sure if an error should be raised if the colour attribute value is not provided.

However, given that `value` can be `None` for other tags, the simple fix is

```python
try:
    if raw.tag in _LUT_DESCRIPTOR_TAGS and value[0] < 0:
        # We only fix the first value as the third value is 8 or 16
        value[0] += 65536
except TypeError:
    pass
```

(or test if `value` is iterable).

**Your environment**
```
Darwin-19.3.0-x86_64-i386-64bit
Python  3.7.6 | packaged by conda-forge | (default, Jan  7 2020, 22:05:27)
[Clang 9.0.1 ]
pydicom  1.4.1
```

Many thanks!

Discussion:
pep8speaks: Hello @scaramallion! Thanks for opening this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:



* In the file [`pydicom/tests/test_filereader.py`](https://github.com/pydicom/pydicom/blob/6cdf6a627720818098ac06afd83cc6e579e0acab/pydicom/tests/test_filereader.py):

> [Line 684:27](https://github.com/pydicom/pydicom/blob/6cdf6a627720818098ac06afd83cc6e579e0acab/pydicom/tests/test_filereader.py#L684): [E711](https://duckduckgo.com/?q=pep8%20E711) comparison to None should be 'if cond is None:'



Patch:
diff --git a/doc/release_notes/v2.0.0.rst b/doc/release_notes/v2.0.0.rst
index b01df1926..82b405932 100644
--- a/doc/release_notes/v2.0.0.rst
+++ b/doc/release_notes/v2.0.0.rst
@@ -12,3 +12,5 @@ Fixes
 .....
 * Fixed reading of datasets with an empty `Specific Character Set` tag
   (regression, :issue:`1038`)
+* Fix failure to parse dataset with an empty *LUT Descriptor* or
+  *Red/Green/Blue Palette Color LUT Descriptor* element. (:issue:`1049`)
diff --git a/pydicom/dataelem.py b/pydicom/dataelem.py
index e0b303005..2387c3c2b 100644
--- a/pydicom/dataelem.py
+++ b/pydicom/dataelem.py
@@ -741,9 +741,13 @@ def DataElement_from_raw(raw_data_element, encoding=None):
     except NotImplementedError as e:
         raise NotImplementedError("{0:s} in tag {1!r}".format(str(e), raw.tag))
 
-    if raw.tag in _LUT_DESCRIPTOR_TAGS and value[0] < 0:
+    if raw.tag in _LUT_DESCRIPTOR_TAGS and value:
         # We only fix the first value as the third value is 8 or 16
-        value[0] += 65536
+        try:
+            if value[0] < 0:
+                value[0] += 65536
+        except TypeError:
+            pass
 
     return DataElement(raw.tag, VR, value, raw.value_tell,
                        raw.length == 0xFFFFFFFF, already_converted=True)


Test patch:
diff --git a/pydicom/tests/test_filereader.py b/pydicom/tests/test_filereader.py
index d7d86cf5e..d27f30725 100644
--- a/pydicom/tests/test_filereader.py
+++ b/pydicom/tests/test_filereader.py
@@ -674,6 +674,27 @@ class TestReader(object):
             assert elem.VR == 'SS'
             assert elem.value == [62720, -2048, 16]
 
+    def test_lut_descriptor_empty(self):
+        """Regression test for #1049: LUT empty raises."""
+        bs = DicomBytesIO(b'\x28\x00\x01\x11\x53\x53\x00\x00')
+        bs.is_little_endian = True
+        bs.is_implicit_VR = False
+        ds = dcmread(bs, force=True)
+        elem = ds[0x00281101]
+        assert elem.value is None
+        assert elem.VR == 'SS'
+
+    def test_lut_descriptor_singleton(self):
+        """Test LUT Descriptor with VM = 1"""
+        bs = DicomBytesIO(b'\x28\x00\x01\x11\x53\x53\x02\x00\x00\xf5')
+        bs.is_little_endian = True
+        bs.is_implicit_VR = False
+        ds = dcmread(bs, force=True)
+        elem = ds[0x00281101]
+        # No conversion to US if not a triplet
+        assert elem.value == -2816
+        assert elem.VR == 'SS'
+
 
 class TestIncorrectVR(object):
     def setup(self):