Posts by bmegli

    Hi guys,


    K-PACS version: 1.6.0
    Our side: Coala System (server under development)


    K-PACS pads DICOM value representation AE with NULL instead of space.


    This is specified in DICOM PS 3.5-2011 6.2


    Our server handles such case properly but this might induce problems with some applications.


    Scenario where it might be problem:


    1. K-PACS sends C-MOVE request to server X.
    2. X replies with C-STORE to application entity entity encoded in C-MOVE-RQ using vr AE


    Now, X received vr of AE with, let's assume that it was "KPA\0" (KPA followed by NULL), value length is 4


    3. X strips padding according to DICOM, the NULL character is not stripped.
    4. X stores AE value in c++ using command like:


    std::string ae_with_null("KPA\0",4) //those are naturally some variables


    5. X has some dictionary with known ae titles, filled with strings
    The entry for KPA was created using:


    ae_without_null("KPA");


    6. X searches for received AE in it's dictionary
    *****************************************************
    now, ae_with_null==ae_without_null is false //gcc, msvc
    ****************************************************
    7. X doesn't match received AE to anything and C-STORE fails.


    *** This is only one of the scenarios where it may be problem. ***
    I can think of other as well.


    K-PACS is working with a lot of DICOM applications correctly because most can handle incorrect padding correctly (same with our server)
    That is not guaranteed though.


    Kind regards,


    Bartosz Meglicki

    National Centre for Nuclear Research
    Department of Nuclear Equipment
    ul. Andrzeja Sołtana 7
    05-400 Otwock, Poland

    Hi Marcel,


    I believe almost any reasonable PACS implementation will handle it correctly. Nontheless the provided example is DICOM conformant and would give unexpected results.


    Very strict DICOM implementation might complain about control characters forbidden for value representation of LO (apart from ESC).


    I only got this issue using some early test code of our server that behaved as in example (handled padding as in PS 3.5 and passed the result to database query).


    btw. as odd numbers supplied into Patient ID I meant odd length naturally.


    B.M.

    Hi Marcel,


    You are correct. It is Query/Move tab page of GUI, (Windows 1.4.16 version)


    The exact steps to reproduce the problem would be:


    1. Start CONQUEST
    2. In GUI switch to Query/Move tab page
    3. Enter odd length number into Patient ID, for example '111'
    4. Click on 'Query selected DICOM system'


    Expected output: Patient ID in a data set encoded as '111 ' (111 followed by space character)
    CONQUEST output: Patient ID in a data set encoded as '111\0' (111 followed by ascii NULL character)


    Rationale: DICOM PS 3.5, table 6.2-1, table row with LO encoding rules:


    Possible consequences: CONQUEST GUI, Query/Move tab page will not find Patient, despite supplying correct Patient ID


    Example: the queried server passes Patient ID '111\0' received from ConQuest directly to database using ODBC and specifying the length of the string as 4 and not as null terminated string. If exact matching is used '111\0' doesn't match '111'.


    Regards,


    B.M.

    Hi guys,


    I am currently implementing DICOM server and sometimes testing it with CONQUEST.


    My code is reporting that CONQUEST encodes padding incorrectly for value representation of LO (and perhaps some other string value representations)


    According to DICOM standard LO value representation may be padded with leading and/or trailing spaces and CONQUEST uses NULL(0 ascii character)
    NULL can be used for padding in UI value representation, not in LO. Moreover control characters like NULL are forbidden in LO.


    Excerpt from PS 3.5 for LO encoding:
    "character string that may be padded with
    leading and/or trailing spaces. The character
    code 5CH (the BACKSLASH “\” in ISO-IR 6)
    shall not be present, as it is used as the
    delimiter between values in multiple valued
    data elements. The string shall not have
    Control Characters except for ESC."


    One good thing here is that this bug is usually non fatal. If other DICOM AE parses the value from LO into some numeric value, the NULL value is treated as the end of the string and value is correctly parsed.


    If however, somebody would use the value directly as it was received the problem may arise.


    Here is a scenario where the problem can occur:


    Other server receives from CONQUEST value with VR of LO and uses it directly to query database. The padding is not ommitted since it is not the expected space character.


    On other server side we end up with a query like:


    SELECT ... FROM ... WHERE patient.id='some odd number padded with NULL'


    Now, this *doesn't* match entity in a database with id from the query!!!


    The version of CONQUEST I am using is 1.4.16.
    The problem can be reproduced by using QUERY/MOVE and entering odd patient id.


    Regards,


    Bartosz Meglicki


    National Centre for Nuclear Research
    Department of Nuclear Equipment
    ul. Andrzeja Sołtana 7
    05-400 Otwock, Poland

    Hello guys,


    I am currently implementing DICOM server and testing it sometimes with K-PACS.


    My server is reporting that K-PACS proposes transfer syntax with empty UID during association establishment.


    The A-ASSOCIATE-RQ sent by K-PACS looks like this:
    ( bytes counted from 1 like in PS 3.8 )


    Bytes 1-74 - OK, all the usual stuff
    Bytes 75-99 - Application Context Item, OK
    Byte 100 - Presentation Context Start
    Bytes 108-138 - Abstract Syntax, OK
    **************** Bytes 139-142 - Transfer Syntax with zero length UID *****************
    Bytes 143-163 - Transfer Syntax with DICOM Implicit VR Little Endian, OK
    164-... - The rest of the A-ASSOCIATE-RQ, OK


    The bug is ussualy not fatal, other DICOM AEs will just select transfer syntaxes that are supported and ignore this 0 length one.


    Here is a detailed dump of A-ASSOCIATE-RQ received from K-PACS.


    The code used to dump it was:


    for(int i=0;i<len;++i)
    out << i+1 << ": " << "\thex " << std::hex << (int)src[i] << "\tdec " << std::dec << (int)src[i] << "\tchar " << (char)src[i] << std::endl;


    So the columns are: byte counted from zero, hexadecimal value of byte, decimal value, byte ascii character


    1: hex 1 dec 1 char
    2: hex 0 dec 0 char
    3: hex 0 dec 0 char
    4: hex 0 dec 0 char
    5: hex 0 dec 0 char
    6: hex db dec 219 char Ű
    7: hex 0 dec 0 char
    8: hex 1 dec 1 char
    9: hex 0 dec 0 char
    10: hex 0 dec 0 char
    11: hex 5a dec 90 char Z
    12: hex 44 dec 68 char D
    13: hex 41 dec 65 char A
    14: hex 4a dec 74 char J
    15: hex 43 dec 67 char C
    16: hex 4f dec 79 char O
    17: hex 4d dec 77 char M
    18: hex 53 dec 83 char S
    19: hex 52 dec 82 char R
    20: hex 56 dec 86 char V
    21: hex 20 dec 32 char
    22: hex 20 dec 32 char
    23: hex 20 dec 32 char
    24: hex 20 dec 32 char
    25: hex 20 dec 32 char
    26: hex 20 dec 32 char
    27: hex 4b dec 75 char K
    28: hex 50 dec 80 char P
    29: hex 53 dec 83 char S
    30: hex 65 dec 101 char e
    31: hex 72 dec 114 char r
    32: hex 76 dec 118 char v
    33: hex 65 dec 101 char e
    34: hex 72 dec 114 char r
    35: hex 20 dec 32 char
    36: hex 20 dec 32 char
    37: hex 20 dec 32 char
    38: hex 20 dec 32 char
    39: hex 20 dec 32 char
    40: hex 20 dec 32 char
    41: hex 20 dec 32 char
    42: hex 20 dec 32 char
    43: hex 0 dec 0 char
    44: hex 0 dec 0 char
    45: hex 0 dec 0 char
    46: hex 0 dec 0 char
    47: hex 0 dec 0 char
    48: hex 0 dec 0 char
    49: hex 0 dec 0 char
    50: hex 0 dec 0 char
    51: hex 0 dec 0 char
    52: hex 0 dec 0 char
    53: hex 0 dec 0 char
    54: hex 0 dec 0 char
    55: hex 0 dec 0 char
    56: hex 0 dec 0 char
    57: hex 0 dec 0 char
    58: hex 0 dec 0 char
    59: hex 0 dec 0 char
    60: hex 0 dec 0 char
    61: hex 0 dec 0 char
    62: hex 0 dec 0 char
    63: hex 0 dec 0 char
    64: hex 0 dec 0 char
    65: hex 0 dec 0 char
    66: hex 0 dec 0 char
    67: hex 0 dec 0 char
    68: hex 0 dec 0 char
    69: hex 0 dec 0 char
    70: hex 0 dec 0 char
    71: hex 0 dec 0 char
    72: hex 0 dec 0 char
    73: hex 0 dec 0 char
    74: hex 0 dec 0 char
    75: hex 10 dec 16 char //Variable Items Start, Application Context, Start
    76: hex 0 dec 0 char //Reserved byte
    77: hex 0 dec 0 char //Item length
    78: hex 15 dec 21 char //Item length=21
    79: hex 31 dec 49 char 1 //Application Context UID Start
    80: hex 2e dec 46 char .
    81: hex 32 dec 50 char 2
    82: hex 2e dec 46 char .
    83: hex 38 dec 56 char 8
    84: hex 34 dec 52 char 4
    85: hex 30 dec 48 char 0
    86: hex 2e dec 46 char .
    87: hex 31 dec 49 char 1
    88: hex 30 dec 48 char 0
    89: hex 30 dec 48 char 0
    90: hex 30 dec 48 char 0
    91: hex 38 dec 56 char 8
    92: hex 2e dec 46 char .
    93: hex 33 dec 51 char 3
    94: hex 2e dec 46 char .
    95: hex 31 dec 49 char 1
    96: hex 2e dec 46 char .
    97: hex 31 dec 49 char 1
    98: hex 2e dec 46 char .
    99: hex 31 dec 49 char 1 //Application Context UID end, Application Context end
    100: hex 20 dec 32 char //Presentation Context Start
    101: hex 0 dec 0 char //Reserved
    102: hex 0 dec 0 char //Item lenght
    103: hex 3c dec 60 char < //Item length=60
    104: hex 1 dec 1 char //Context ID=1
    105: hex 0 dec 0 char //Reserved
    106: hex 0 dec 0 char //Reserved
    107: hex 0 dec 0 char //Reserved
    108: hex 30 dec 48 char 0 //Abstract/Transfer Syntax Subitems start, Abstract Syntax start
    109: hex 0 dec 0 char //Reserved
    110: hex 0 dec 0 char //Item length
    111: hex 1b dec 27 char //Item length=27
    112: hex 31 dec 49 char 1 //Abstract syntax UID start
    113: hex 2e dec 46 char .
    114: hex 32 dec 50 char 2
    115: hex 2e dec 46 char .
    116: hex 38 dec 56 char 8
    117: hex 34 dec 52 char 4
    118: hex 30 dec 48 char 0
    119: hex 2e dec 46 char .
    120: hex 31 dec 49 char 1
    121: hex 30 dec 48 char 0
    122: hex 30 dec 48 char 0
    123: hex 30 dec 48 char 0
    124: hex 38 dec 56 char 8
    125: hex 2e dec 46 char .
    126: hex 35 dec 53 char 5
    127: hex 2e dec 46 char .
    128: hex 31 dec 49 char 1
    129: hex 2e dec 46 char .
    130: hex 34 dec 52 char 4
    131: hex 2e dec 46 char .
    132: hex 31 dec 49 char 1
    133: hex 2e dec 46 char .
    134: hex 32 dec 50 char 2
    135: hex 2e dec 46 char .
    136: hex 32 dec 50 char 2
    137: hex 2e dec 46 char .
    138: hex 31 dec 49 char 1 //Abstract Syntax UID end
    139: hex 40 dec 64 char @ //Transfer Syntax start
    140: hex 0 dec 0 char //Reserved
    141: hex 0 dec 0 char //Item Length !!!
    142: hex 0 dec 0 char //Item Length !!! ZERO LENGTH TRANSFER SYNTAX, Transfer syntax end
    143: hex 40 dec 64 char @ //Transfer syntax start
    144: hex 0 dec 0 char //Reserved
    145: hex 0 dec 0 char //Item length
    146: hex 11 dec 17 char //Item length=17
    147: hex 31 dec 49 char 1 //Transfer Syntax UID start
    148: hex 2e dec 46 char .
    149: hex 32 dec 50 char 2
    150: hex 2e dec 46 char .
    151: hex 38 dec 56 char 8
    152: hex 34 dec 52 char 4
    153: hex 30 dec 48 char 0
    154: hex 2e dec 46 char .
    155: hex 31 dec 49 char 1
    156: hex 30 dec 48 char 0
    157: hex 30 dec 48 char 0
    158: hex 30 dec 48 char 0
    159: hex 38 dec 56 char 8
    160: hex 2e dec 46 char .
    161: hex 31 dec 49 char 1
    162: hex 2e dec 46 char .
    163: hex 32 dec 50 char 2 //Transfer syntax UID end, Transfer Syntax end
    164: hex 50 dec 80 char P //User Information Item Start...
    ...


    Regards,


    Bartosz Meglicki


    National Centre for Nuclear Research
    Department of Nuclear Equipment
    ul. Andrzeja Sołtana 7
    05-400 Otwock, Poland