Repository: pydicom/pydicom

Issue:
Support for DICOM files with implicit VR file meta
#### Description
Up to pydicom 0.9.9, it was possible to read a DICOM file that lacked any file meta. When using pydicom from the current master branch, this is no longer the case. When no file meta is present in a DICOM file, the `_read_file_meta` function returns a dataset containing only a group length data element, and then a crash occurs when the TransferSyntaxUID is requested from the file_meta_dataset (line 634 in filereader.py).

It can be fixed by having the `_read_file_meta_info` function return an empty dataset instead. For my solution, see https://github.com/rzinkstok/pydicom/commit/d246f92066a7b4fc8b28ed7f18b28281fc1568f0. I can start a pull request if that is appreciated.

I'm not sure whether the current behavior is intended. Of course, files without meta info are not DICOM-compliant, but our DICOM archives contains a huge amount of old files without file meta, so it would be really convenient if pydicom could read these files without too much fuss. 

#### Steps/Code to Reproduce
Get a file without file meta (I can supply such a file) and run the following:
```py
from pydicom import read_file
f = read_file("very_old_ct_slice.dcm", force=True)
print(f.PatientName)
```

#### Expected Results
No error is thrown and the name of the patient is printed.

#### Actual Results
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/vagrant/Projects/pydicom/src/pydicom/pydicom/filereader.py", line 804, in read_file
    force=force, specific_tags=specific_tags)
  File "/home/vagrant/Projects/pydicom/src/pydicom/pydicom/filereader.py", line 634, in read_partial
    transfer_syntax = file_meta_dataset.get("TransferSyntaxUID")
  File "/home/vagrant/Projects/pydicom/src/pydicom/pydicom/dataset.py", line 431, in get
    return getattr(self, key)
  File "/home/vagrant/Projects/pydicom/src/pydicom/pydicom/dataset.py", line 475, in __getattr__
    return self[tag].value
  File "/home/vagrant/Projects/pydicom/src/pydicom/pydicom/dataset.py", line 554, in __getitem__
    self[tag] = DataElement_from_raw(data_elem, character_set)
  File "/home/vagrant/Projects/pydicom/src/pydicom/pydicom/dataelem.py", line 493, in DataElement_from_raw
    raise NotImplementedError("{0:s} in tag {1!r}".format(str(e), raw.tag))
NotImplementedError: Unknown Value Representation '' in tag (0002, 0010)
```


#### Versions
Platform: Linux-4.4.0-93-generic-x86_64-with-Ubuntu-16.04-xenial
Python: ('Python', '2.7.11+ (default, Apr 17 2016, 14:00:29) \n[GCC 5.3.1 20160413]')
Pydicom: 1.0.0a1, at commit ac905d951c95f1d2474b8cd1c35c8eb055e5273b



Discussion:
pep8speaks: Hello @rzinkstok! Thanks for submitting the PR.

 - In the file [`pydicom/filereader.py`](https://github.com/pydicom/pydicom/blob/22a0ca81718f71d3f38328a0f747a0d17b2dd1ab/pydicom/filereader.py), following are the PEP8 issues :

> [Line 489:80](https://github.com/pydicom/pydicom/blob/22a0ca81718f71d3f38328a0f747a0d17b2dd1ab/pydicom/filereader.py#L489): [E501](https://duckduckgo.com/?q=pep8%20E501) line too long (86 > 79 characters)
> [Line 505:80](https://github.com/pydicom/pydicom/blob/22a0ca81718f71d3f38328a0f747a0d17b2dd1ab/pydicom/filereader.py#L505): [E501](https://duckduckgo.com/?q=pep8%20E501) line too long (98 > 79 characters)


darcymason: I think this looks good. Thanks.  
@pydicom/pydcom-fff, can someone do a second check?
mrbean-bremen: Looks good for me.

Patch:
diff --git a/pydicom/filereader.py b/pydicom/filereader.py
index 427791b16..8fd751fa1 100644
--- a/pydicom/filereader.py
+++ b/pydicom/filereader.py
@@ -488,6 +488,20 @@ def _read_file_meta_info(fp):
     start_file_meta = fp.tell()
     file_meta = read_dataset(fp, is_implicit_VR=False, is_little_endian=True,
                              stop_when=_not_group_0002)
+    if not file_meta:
+        return file_meta
+
+    # Test the file meta for correct interpretation by requesting the first
+    #   data element: if it fails, retry loading the file meta with an
+    #   implicit VR (issue #503)
+    try:
+        file_meta[list(file_meta)[0].tag]
+    except NotImplementedError:
+        fp.seek(start_file_meta)
+        file_meta = read_dataset(fp, is_implicit_VR=True,
+                                 is_little_endian=True,
+                                 stop_when=_not_group_0002)
+
     # Log if the Group Length doesn't match actual length
     if 'FileMetaInformationGroupLength' in file_meta:
         # FileMetaInformationGroupLength must be 12 bytes long and its value
@@ -501,6 +515,7 @@ def _read_file_meta_info(fp):
                         "bytes)."
                         .format(file_meta.FileMetaInformationGroupLength,
                                 length_file_meta))
+
     return file_meta
 
 


Test patch:
diff --git a/pydicom/tests/test_filereader.py b/pydicom/tests/test_filereader.py
index 9941e488c..dd2c44cc4 100644
--- a/pydicom/tests/test_filereader.py
+++ b/pydicom/tests/test_filereader.py
@@ -664,6 +664,17 @@ class ReaderTests(unittest.TestCase):
         self.assertTrue(ds.preamble is None)
         self.assertEqual(ds.file_meta, Dataset())
 
+    def test_file_meta_dataset_implicit_vr(self):
+        """Test reading a file meta dataset that is implicit VR"""
+
+        bytestream = (b'\x02\x00\x10\x00\x12\x00\x00\x00'
+                      b'\x31\x2e\x32\x2e\x38\x34\x30\x2e'
+                      b'\x31\x30\x30\x30\x38\x2e\x31\x2e'
+                      b'\x32\x00')
+        fp = BytesIO(bytestream)
+        ds = read_file(fp, force=True)
+        self.assertTrue('TransferSyntaxUID' in ds.file_meta)
+
     def test_no_dataset(self):
         """Test reading no elements or preamble produces empty Dataset"""
         bytestream = b''