{"action":"created","comment":{"url":"https://api.github.com/repos/pydicom/pydicom/pulls/comments/131807607","pull_request_review_id":54820970,"id":131807607,"diff_hunk":"@@ -0,0 +1,219 @@\n+import sys\n+import pydicom.uid\n+import pydicom.encaps\n+from struct import unpack\n+have_numpy = True\n+try:\n+    import numpy\n+except ImportError:\n+    have_numpy = False\n+    raise\n+\n+sys_is_little_endian = (sys.byteorder == 'little')\n+\n+RLESupportedTransferSyntaxes = [\n+    pydicom.uid.RLELossless,\n+]\n+\n+\n+def supports_transfer_syntax(dicom_dataset):\n+    return (dicom_dataset.file_meta.TransferSyntaxUID in\n+            RLESupportedTransferSyntaxes)\n+\n+\n+def get_pixeldata(dicom_dataset):\n+    \"\"\"If NumPy is available, return an ndarray of the Pixel Data.\n+    Raises\n+    ------\n+    TypeError\n+        If there is no Pixel Data or not a supported data type.\n+    ImportError\n+        If NumPy isn't found\n+    NotImplementedError\n+        If cannot handle the format\n+    Returns\n+    -------\n+    numpy.ndarray\n+       The contents of the Pixel Data element (7FE0,0010) as an ndarray.\n+    \"\"\"\n+    if (dicom_dataset.file_meta.TransferSyntaxUID not in\n+            RLESupportedTransferSyntaxes):\n+        raise NotImplementedError(\"Pixel Data is compressed in a \"\n+                                  \"format this RLE decompressor\"\n+                                  \"does not yet handle. \"\n+                                  \"Cannot return array. Pydicom might \"\n+                                  \"be able to convert the pixel data \"\n+                                  \"using GDCM if it is installed.\")\n+    if not have_numpy:\n+        msg = (\"The Numpy package is required to use pixel_array, and \"\n+               \"numpy could not be imported.\")\n+        raise ImportError(msg)\n+\n+    if 'PixelData' not in dicom_dataset:\n+        raise TypeError(\"No pixel data found in this dataset.\")\n+\n+    # Make NumPy format code, e.g. \"uint16\", \"int32\" etc\n+    # from two pieces of info:\n+    # dicom_dataset.PixelRepresentation -- 0 for unsigned, 1 for signed;\n+    # dicom_dataset.BitsAllocated -- 8, 16, or 32\n+    if dicom_dataset.PixelRepresentation == 0:\n+        format_str = 'uint{}'.format(dicom_dataset.BitsAllocated)\n+    elif dicom_dataset.PixelRepresentation == 1:\n+        format_str = 'int{}'.format(dicom_dataset.BitsAllocated)\n+    else:\n+        format_str = 'bad_pixel_representation'\n+\n+    try:\n+        numpy_format = numpy.dtype(format_str)\n+    except TypeError:\n+        msg = (\"Data type not understood by NumPy: \"\n+               \"format='{}', PixelRepresentation={}, \"\n+               \"BitsAllocated={}\".format(\n+                   format_str,\n+                   dicom_dataset.PixelRepresentation,\n+                   dicom_dataset.BitsAllocated))\n+        raise TypeError(msg)\n+\n+    UncompressedPixelData = bytearray()\n+\n+    if ('NumberOfFrames' in dicom_dataset and\n+            dicom_dataset.NumberOfFrames > 1):\n+\n+        CompressedPixelDataSeq = pydicom.encaps.decode_data_sequence(\n+            dicom_dataset.PixelData)\n+\n+        for frame in CompressedPixelDataSeq:\n+            decompressed_frame = _rle_decode_frame(frame,\n+                                                   rows=dicom_dataset.Rows,\n+                                                   columns=dicom_dataset.Columns,  # noqa\n+                                                   samples_per_pixel=dicom_dataset.SamplesPerPixel,  # noqa\n+                                                   bits_allocated=dicom_dataset.BitsAllocated)  # noqa\n+\n+            UncompressedPixelData.extend(decompressed_frame)\n+\n+    else:\n+\n+        CompressedPixelData = pydicom.encaps.defragment_data(\n+            dicom_dataset.PixelData)\n+\n+        decompressed_frame = _rle_decode_frame(CompressedPixelData,\n+                                               rows=dicom_dataset.Rows,\n+                                               columns=dicom_dataset.Columns,\n+                                               samples_per_pixel=dicom_dataset.SamplesPerPixel,  # noqa\n+                                               bits_allocated=dicom_dataset.BitsAllocated)  # noqa\n+\n+        UncompressedPixelData.extend(decompressed_frame)\n+\n+    pixel_array = numpy.frombuffer(UncompressedPixelData, numpy_format)\n+\n+    return pixel_array\n+\n+\n+def _rle_decode_frame(d, rows, columns, samples_per_pixel, bits_allocated):\n+    \"\"\"Decodes a single frame of RLE encoded data.\n+    Reads the plane information at the beginning of the data.","path":"pydicom/pixel_data_handlers/rle_handler.py","position":114,"original_position":114,"commit_id":"dce695df6f1c752fbbcedc151d23f08f4c9a61a6","original_commit_id":"dce695df6f1c752fbbcedc151d23f08f4c9a61a6","user":{"login":"scaramallion","id":10226372,"avatar_url":"https://avatars2.githubusercontent.com/u/10226372?v=4","gravatar_id":"","url":"https://api.github.com/users/scaramallion","html_url":"https://github.com/scaramallion","followers_url":"https://api.github.com/users/scaramallion/followers","following_url":"https://api.github.com/users/scaramallion/following{/other_user}","gists_url":"https://api.github.com/users/scaramallion/gists{/gist_id}","starred_url":"https://api.github.com/users/scaramallion/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scaramallion/subscriptions","organizations_url":"https://api.github.com/users/scaramallion/orgs","repos_url":"https://api.github.com/users/scaramallion/repos","events_url":"https://api.github.com/users/scaramallion/events{/privacy}","received_events_url":"https://api.github.com/users/scaramallion/received_events","type":"User","site_admin":false},"body":"Can you use variable names at least two letters long please?","created_at":"2017-08-08T02:18:54Z","updated_at":"2017-08-08T02:18:54Z","html_url":"https://github.com/pydicom/pydicom/pull/460#discussion_r131807607","pull_request_url":"https://api.github.com/repos/pydicom/pydicom/pulls/460","_links":{"self":{"href":"https://api.github.com/repos/pydicom/pydicom/pulls/comments/131807607"},"html":{"href":"https://github.com/pydicom/pydicom/pull/460#discussion_r131807607"},"pull_request":{"href":"https://api.github.com/repos/pydicom/pydicom/pulls/460"}}},"pull_request":{"url":"https://api.github.com/repos/pydicom/pydicom/pulls/460","id":134322197,"html_url":"https://github.com/pydicom/pydicom/pull/460","diff_url":"https://github.com/pydicom/pydicom/pull/460.diff","patch_url":"https://github.com/pydicom/pydicom/pull/460.patch","issue_url":"https://api.github.com/repos/pydicom/pydicom/issues/460","number":460,"state":"open","locked":false,"title":"[WIP] Add RLE pixel_data_handler","user":{"login":"mshunshin","id":1478710,"avatar_url":"https://avatars2.githubusercontent.com/u/1478710?v=4","gravatar_id":"","url":"https://api.github.com/users/mshunshin","html_url":"https://github.com/mshunshin","followers_url":"https://api.github.com/users/mshunshin/followers","following_url":"https://api.github.com/users/mshunshin/following{/other_user}","gists_url":"https://api.github.com/users/mshunshin/gists{/gist_id}","starred_url":"https://api.github.com/users/mshunshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mshunshin/subscriptions","organizations_url":"https://api.github.com/users/mshunshin/orgs","repos_url":"https://api.github.com/users/mshunshin/repos","events_url":"https://api.github.com/users/mshunshin/events{/privacy}","received_events_url":"https://api.github.com/users/mshunshin/received_events","type":"User","site_admin":false},"body":"Addition of an RLE pixel_data_handler.\r\n\r\nNotes\r\n=====\r\n1) Uses numpy only\r\n2) Uses bytearray to allow relatively efficient concatenation of bytes (other pixel handlers should probably do this).\r\n3) Preallocates bytearray (so Rows, Columns, SamplesPerPixel, and BitsAllocated must be correct in the DICOM file).\r\n4) Does the above as the order of bytes in planes is first high and low, then each color.\r\n5) It is a little bit slow - the RLE decoder for a single 1024*768 RGB uint frame takes 30ms on my laptop (which when there are 400 frames - takes 12s). For reference jpg decompression takes 3ms on my laptop. PLEASE - if anyone could speed up the RLE decoding function I would be very, very, grateful.\r\n6) It can decompress the sample files in the data directory,\r\n\r\n\r\n","created_at":"2017-08-06T10:56:24Z","updated_at":"2017-08-08T02:18:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d7ee0ac731ea364b0dfa1bc1a209e56a74d60ff6","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/pydicom/pydicom/pulls/460/commits","review_comments_url":"https://api.github.com/repos/pydicom/pydicom/pulls/460/comments","review_comment_url":"https://api.github.com/repos/pydicom/pydicom/pulls/comments{/number}","comments_url":"https://api.github.com/repos/pydicom/pydicom/issues/460/comments","statuses_url":"https://api.github.com/repos/pydicom/pydicom/statuses/dce695df6f1c752fbbcedc151d23f08f4c9a61a6","head":{"label":"mshunshin:Add_RLE_Syntax","ref":"Add_RLE_Syntax","sha":"dce695df6f1c752fbbcedc151d23f08f4c9a61a6","user":{"login":"mshunshin","id":1478710,"avatar_url":"https://avatars2.githubusercontent.com/u/1478710?v=4","gravatar_id":"","url":"https://api.github.com/users/mshunshin","html_url":"https://github.com/mshunshin","followers_url":"https://api.github.com/users/mshunshin/followers","following_url":"https://api.github.com/users/mshunshin/following{/other_user}","gists_url":"https://api.github.com/users/mshunshin/gists{/gist_id}","starred_url":"https://api.github.com/users/mshunshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mshunshin/subscriptions","organizations_url":"https://api.github.com/users/mshunshin/orgs","repos_url":"https://api.github.com/users/mshunshin/repos","events_url":"https://api.github.com/users/mshunshin/events{/privacy}","received_events_url":"https://api.github.com/users/mshunshin/received_events","type":"User","site_admin":false},"repo":{"id":98518174,"name":"pydicom","full_name":"mshunshin/pydicom","owner":{"login":"mshunshin","id":1478710,"avatar_url":"https://avatars2.githubusercontent.com/u/1478710?v=4","gravatar_id":"","url":"https://api.github.com/users/mshunshin","html_url":"https://github.com/mshunshin","followers_url":"https://api.github.com/users/mshunshin/followers","following_url":"https://api.github.com/users/mshunshin/following{/other_user}","gists_url":"https://api.github.com/users/mshunshin/gists{/gist_id}","starred_url":"https://api.github.com/users/mshunshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mshunshin/subscriptions","organizations_url":"https://api.github.com/users/mshunshin/orgs","repos_url":"https://api.github.com/users/mshunshin/repos","events_url":"https://api.github.com/users/mshunshin/events{/privacy}","received_events_url":"https://api.github.com/users/mshunshin/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mshunshin/pydicom","description":"Read, modify and write DICOM files with python code","fork":true,"url":"https://api.github.com/repos/mshunshin/pydicom","forks_url":"https://api.github.com/repos/mshunshin/pydicom/forks","keys_url":"https://api.github.com/repos/mshunshin/pydicom/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mshunshin/pydicom/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mshunshin/pydicom/teams","hooks_url":"https://api.github.com/repos/mshunshin/pydicom/hooks","issue_events_url":"https://api.github.com/repos/mshunshin/pydicom/issues/events{/number}","events_url":"https://api.github.com/repos/mshunshin/pydicom/events","assignees_url":"https://api.github.com/repos/mshunshin/pydicom/assignees{/user}","branches_url":"https://api.github.com/repos/mshunshin/pydicom/branches{/branch}","tags_url":"https://api.github.com/repos/mshunshin/pydicom/tags","blobs_url":"https://api.github.com/repos/mshunshin/pydicom/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mshunshin/pydicom/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mshunshin/pydicom/git/refs{/sha}","trees_url":"https://api.github.com/repos/mshunshin/pydicom/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mshunshin/pydicom/statuses/{sha}","languages_url":"https://api.github.com/repos/mshunshin/pydicom/languages","stargazers_url":"https://api.github.com/repos/mshunshin/pydicom/stargazers","contributors_url":"https://api.github.com/repos/mshunshin/pydicom/contributors","subscribers_url":"https://api.github.com/repos/mshunshin/pydicom/subscribers","subscription_url":"https://api.github.com/repos/mshunshin/pydicom/subscription","commits_url":"https://api.github.com/repos/mshunshin/pydicom/commits{/sha}","git_commits_url":"https://api.github.com/repos/mshunshin/pydicom/git/commits{/sha}","comments_url":"https://api.github.com/repos/mshunshin/pydicom/comments{/number}","issue_comment_url":"https://api.github.com/repos/mshunshin/pydicom/issues/comments{/number}","contents_url":"https://api.github.com/repos/mshunshin/pydicom/contents/{+path}","compare_url":"https://api.github.com/repos/mshunshin/pydicom/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mshunshin/pydicom/merges","archive_url":"https://api.github.com/repos/mshunshin/pydicom/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mshunshin/pydicom/downloads","issues_url":"https://api.github.com/repos/mshunshin/pydicom/issues{/number}","pulls_url":"https://api.github.com/repos/mshunshin/pydicom/pulls{/number}","milestones_url":"https://api.github.com/repos/mshunshin/pydicom/milestones{/number}","notifications_url":"https://api.github.com/repos/mshunshin/pydicom/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mshunshin/pydicom/labels{/name}","releases_url":"https://api.github.com/repos/mshunshin/pydicom/releases{/id}","deployments_url":"https://api.github.com/repos/mshunshin/pydicom/deployments","created_at":"2017-07-27T09:24:47Z","updated_at":"2017-07-27T09:24:49Z","pushed_at":"2017-08-07T15:13:23Z","git_url":"git://github.com/mshunshin/pydicom.git","ssh_url":"git@github.com:mshunshin/pydicom.git","clone_url":"https://github.com/mshunshin/pydicom.git","svn_url":"https://github.com/mshunshin/pydicom","homepage":null,"size":15833,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"pydicom:master","ref":"master","sha":"1598021302fdc07a10cfbc46b31ffffcbda6920b","user":{"login":"pydicom","id":28906941,"avatar_url":"https://avatars2.githubusercontent.com/u/28906941?v=4","gravatar_id":"","url":"https://api.github.com/users/pydicom","html_url":"https://github.com/pydicom","followers_url":"https://api.github.com/users/pydicom/followers","following_url":"https://api.github.com/users/pydicom/following{/other_user}","gists_url":"https://api.github.com/users/pydicom/gists{/gist_id}","starred_url":"https://api.github.com/users/pydicom/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pydicom/subscriptions","organizations_url":"https://api.github.com/users/pydicom/orgs","repos_url":"https://api.github.com/users/pydicom/repos","events_url":"https://api.github.com/users/pydicom/events{/privacy}","received_events_url":"https://api.github.com/users/pydicom/received_events","type":"Organization","site_admin":false},"repo":{"id":14006067,"name":"pydicom","full_name":"pydicom/pydicom","owner":{"login":"pydicom","id":28906941,"avatar_url":"https://avatars2.githubusercontent.com/u/28906941?v=4","gravatar_id":"","url":"https://api.github.com/users/pydicom","html_url":"https://github.com/pydicom","followers_url":"https://api.github.com/users/pydicom/followers","following_url":"https://api.github.com/users/pydicom/following{/other_user}","gists_url":"https://api.github.com/users/pydicom/gists{/gist_id}","starred_url":"https://api.github.com/users/pydicom/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pydicom/subscriptions","organizations_url":"https://api.github.com/users/pydicom/orgs","repos_url":"https://api.github.com/users/pydicom/repos","events_url":"https://api.github.com/users/pydicom/events{/privacy}","received_events_url":"https://api.github.com/users/pydicom/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pydicom/pydicom","description":"Read, modify and write DICOM files with python code","fork":false,"url":"https://api.github.com/repos/pydicom/pydicom","forks_url":"https://api.github.com/repos/pydicom/pydicom/forks","keys_url":"https://api.github.com/repos/pydicom/pydicom/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pydicom/pydicom/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pydicom/pydicom/teams","hooks_url":"https://api.github.com/repos/pydicom/pydicom/hooks","issue_events_url":"https://api.github.com/repos/pydicom/pydicom/issues/events{/number}","events_url":"https://api.github.com/repos/pydicom/pydicom/events","assignees_url":"https://api.github.com/repos/pydicom/pydicom/assignees{/user}","branches_url":"https://api.github.com/repos/pydicom/pydicom/branches{/branch}","tags_url":"https://api.github.com/repos/pydicom/pydicom/tags","blobs_url":"https://api.github.com/repos/pydicom/pydicom/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pydicom/pydicom/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pydicom/pydicom/git/refs{/sha}","trees_url":"https://api.github.com/repos/pydicom/pydicom/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pydicom/pydicom/statuses/{sha}","languages_url":"https://api.github.com/repos/pydicom/pydicom/languages","stargazers_url":"https://api.github.com/repos/pydicom/pydicom/stargazers","contributors_url":"https://api.github.com/repos/pydicom/pydicom/contributors","subscribers_url":"https://api.github.com/repos/pydicom/pydicom/subscribers","subscription_url":"https://api.github.com/repos/pydicom/pydicom/subscription","commits_url":"https://api.github.com/repos/pydicom/pydicom/commits{/sha}","git_commits_url":"https://api.github.com/repos/pydicom/pydicom/git/commits{/sha}","comments_url":"https://api.github.com/repos/pydicom/pydicom/comments{/number}","issue_comment_url":"https://api.github.com/repos/pydicom/pydicom/issues/comments{/number}","contents_url":"https://api.github.com/repos/pydicom/pydicom/contents/{+path}","compare_url":"https://api.github.com/repos/pydicom/pydicom/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pydicom/pydicom/merges","archive_url":"https://api.github.com/repos/pydicom/pydicom/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pydicom/pydicom/downloads","issues_url":"https://api.github.com/repos/pydicom/pydicom/issues{/number}","pulls_url":"https://api.github.com/repos/pydicom/pydicom/pulls{/number}","milestones_url":"https://api.github.com/repos/pydicom/pydicom/milestones{/number}","notifications_url":"https://api.github.com/repos/pydicom/pydicom/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pydicom/pydicom/labels{/name}","releases_url":"https://api.github.com/repos/pydicom/pydicom/releases{/id}","deployments_url":"https://api.github.com/repos/pydicom/pydicom/deployments","created_at":"2013-10-31T02:58:52Z","updated_at":"2017-07-29T19:57:11Z","pushed_at":"2017-08-07T22:54:21Z","git_url":"git://github.com/pydicom/pydicom.git","ssh_url":"git@github.com:pydicom/pydicom.git","clone_url":"https://github.com/pydicom/pydicom.git","svn_url":"https://github.com/pydicom/pydicom","homepage":null,"size":15850,"stargazers_count":263,"watchers_count":263,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":131,"mirror_url":null,"open_issues_count":62,"forks":131,"open_issues":62,"watchers":263,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/pydicom/pydicom/pulls/460"},"html":{"href":"https://github.com/pydicom/pydicom/pull/460"},"issue":{"href":"https://api.github.com/repos/pydicom/pydicom/issues/460"},"comments":{"href":"https://api.github.com/repos/pydicom/pydicom/issues/460/comments"},"review_comments":{"href":"https://api.github.com/repos/pydicom/pydicom/pulls/460/comments"},"review_comment":{"href":"https://api.github.com/repos/pydicom/pydicom/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/pydicom/pydicom/pulls/460/commits"},"statuses":{"href":"https://api.github.com/repos/pydicom/pydicom/statuses/dce695df6f1c752fbbcedc151d23f08f4c9a61a6"}}}}
{"actor":{"display_login":"scaramallion"}}