package Ġedu . stanford . cf ull er . image an alys ist ools . image . io Ċ Ċ import Ġedu . stanford . cf ull er . image an alys ist ools . frontend . Logging Utilities Ċ import Ġedu . stanford . cf ull er . image an alys ist ools . image . Image Ċ import Ġedu . stanford . cf ull er . image an alys ist ools . image . Image Factory Ċ import Ġedu . stanford . cf ull er . image an alys ist ools . image . Image Coordinate Ċ Ċ import Ġedu . stanford . cf ull er . image an alys ist ools . image . Pixel Data Factory Ċ import Ġedu . stanford . cf ull er . image an alys ist ools . image . Pixel Data ĊĊ Ċ import Ġjava . util . Hashtable Ċ Ċ /** Ċ Ġ* ĠThis Ġclass Ġreads Ġan ĠImage Ġfrom Ġa Ġfile Ġon Ġdisk . Ċ Ġ* Ċ Ġ* ĠUses Ġthe ĠLO CI Ġbio - formats Ġlibrary Ġto Ġdo Ġthe Ġreading Ġ( http :// www . loc i . w isc . edu / software / bio - formats ), Ġso Ċ Ġ* Ġall Ġformats Ġsupported Ġby Ġthat Ġlibrary Ġare Ġsupported Ġin Ġthis Ġreader . Ċ Ġ* Ċ Ġ* ĠFor Ġimage Ġformats Ġthat Ġsupport Ġmultiple Ġseries Ġper Ġfile Ġ( that Ġis , Ġmultiple Ġ( X , Y , Z , C , T ) Ġ 5 D Ġimages Ġper Ġfile ), Ġthe Ġreader Ċ Ġ* Ġwill Ġreturn Ġonly Ġa Ġsingle Ġseries Ġat Ġa Ġtime , Ġkeeps Ġtrack Ġof Ġwhat Ġseries Ġit Ġhas Ġlast Ġread , Ġand Ġwill Ġreturn Ġthe Ġsubsequent Ġseries Ċ Ġ* Ġon Ġsubsequent Ġcalls Ġto Ġthe Ġread Ġmethod . Ċ Ġ* Ġ@ author ĠCol in ĠJ . ĠFull er Ċ Ġ*/ ĊĊ Ċ open Ġclass ĠImage Reader Ġ{ ĊĠĠĠ Ġprotected Ġvar Ġlo ci Reader : Ġlo ci . formats . Image Reader Ġ= Ġlo ci . formats . Image Reader () ĊĠĠĠ Ġprotected Ġvar Ġseries Counts : Ġjava . util . HashMap < String , ĠInt > Ġ= Ġjava . util . HashMap < String , ĠInt >() ĊĠĠĠ Ġprotected Ġvar Ġcurrent Series : Ġjava . util . HashMap < String , ĠInt > Ġ= Ġjava . util . HashMap < String , ĠInt >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChecks Ġif Ġthe Ġfile Ġspecified Ġin Ġthe Ġsupplied Ġfilename Ġhas Ġmore Ġ 5 D Ġimage Ġseries Ġthat Ġhave Ġnot Ġyet Ġbeen Ġread Ġby Ġthis Ġreader . ĊĠĠĠĠ Ġ* Ġ@ param Ġfilename Ġ ĠThe Ġfull Ġabsolute Ġfilename Ġof Ġthe Ġimage Ġfile Ġto Ġcheck . ĊĠĠĠĠ Ġ* Ġ@ return ĠĠĠĠĠĠĠĠĠ Ġtrue Ġif Ġthere Ġare Ġmore Ġseries Ġthat Ġhave Ġnot Ġyet Ġbeen Ġread ; Ġfalse Ġotherwise ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġhas More Series ( filename : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! current Series . containsKey ( filename )) Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Series [ filename ] !! Ġ< Ġseries Counts [ filename ] !! ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGets Ġthe Ġnumber Ġof Ġ 5 D Ġimage Ġseries Ġin Ġthe Ġfile Ġspecified Ġin Ġthe Ġsupplied Ġfilename . ĊĠĠĠĠ Ġ* ĠThis Ġcan Ġonly Ġbe Ġcalled Ġafter Ġthe Ġread Ġmethod Ġhas Ġbeen Ġcalled Ġon Ġthis Ġfilename Ġat Ġleast Ġonce ; Ġotherwise Ġit ĊĠĠĠĠ Ġ* Ġwill Ġcause Ġan Ġexception . ĊĠĠĠĠ Ġ* Ġ@ param Ġfilename Ġ ĠThe Ġfull Ġabsolute Ġfilename Ġof Ġthe Ġimage Ġfile Ġto Ġcheck . ĊĠĠĠĠ Ġ* Ġ@ return ĠĠĠĠĠĠĠĠĠ ĠThe Ġnumber Ġof Ġ 5 D Ġimage Ġseries Ġin Ġthe Ġspecified Ġfile . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Series Count ( filename : ĠString ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġseries Counts [ filename ] Ġ?: Ġthrow ĠIllegalArgumentException (" Must Ġcall Ġ. read () Ġon Ġthe Ġsame Ġfilename Ġfirst .") ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGets Ġthe Ġindex Ġ( starting Ġat Ġzero ) Ġof Ġthe Ġnext Ġ 5 D Ġimage Ġseries Ġthat Ġwould Ġbe Ġread Ġby Ġa Ġcall Ġto Ġthe Ġread Ġmethod . ĊĠĠĠĠ Ġ* ĠThis Ġmethod Ġcan Ġonly Ġbe Ġcalled Ġafter Ġthe Ġread Ġmethod Ġhas Ġbeen Ġcalled Ġon Ġthis Ġfilename Ġat Ġleast Ġonce ; Ġotherwise Ġit ĊĠĠĠĠ Ġ* Ġwill Ġcause Ġan Ġexception . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠNote Ġthat Ġthe Ġvalue Ġreturned Ġby Ġthis Ġmethod Ġwill Ġalways Ġbe Ġbetween Ġ 1 Ġand Ġthe Ġresult Ġof Ġget Series Count ( filename ), Ġinclusive . ĊĠĠĠĠ Ġ* ĠSince Ġthe Ġread Ġmethod Ġmust Ġhave Ġbeen Ġcalled Ġonce Ġbefore Ġcalling Ġthis Ġmethod , Ġthe Ġ 0 th Ġseries Ġwill Ġalways Ġhave Ġbeen Ġread Ġalready , ĊĠĠĠĠ Ġ* Ġso Ġat Ġminimum Ġthe Ġnext Ġseries Ġwill Ġbe Ġthe Ġfirst Ġseries . Ġ ĠIf Ġthere Ġare Ġno Ġmore Ġseries Ġremaining Ġin Ġthe Ġfile , Ġthe Ġnext Ġthat ĊĠĠĠĠ Ġ* Ġwould Ġbe Ġread Ġwould Ġbe Ġone Ġmore Ġthan Ġthe Ġmax imal Ġseries Ġindex Ġ( which Ġis Ġget Series Count ( filename ) Ġ- Ġ 1 ). ĊĠĠĠĠ Ġ* Ġ@ param Ġfilename Ġ ĠThe Ġfull Ġabsolute Ġfilename Ġof Ġthe Ġimage Ġfile Ġto Ġcheck . ĊĠĠĠĠ Ġ* Ġ@ return ĠĠĠĠĠĠĠĠĠ ĠThe Ġseries Ġthat Ġwill Ġbe Ġthe Ġnext Ġto Ġbe Ġread Ġby Ġthis Ġreader . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun ĠgetCurrent Series ( filename : ĠString ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Series [ filename ] Ġ?: Ġthrow ĠIllegalArgumentException (" Must Ġcall Ġ. read () Ġon Ġthe Ġsame Ġfilename Ġfirst .") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReads Ġan Ġimage Ġfile Ġfrom Ġdisk Ġto Ġan ĠImage . ĊĠĠĠĠ Ġ* Ġ@ param Ġfilename Ġ ĠThe Ġfull Ġabsolute Ġfilename Ġof Ġthe Ġimage Ġfile Ġto Ġread . ĊĠĠĠĠ Ġ* Ġ@ return ĠĠĠĠĠĠĠĠĠ ĠAn ĠImage Ġcontaining Ġthe Ġpixel Ġdata Ġand Ġ( if Ġsupported Ġby Ġthe Ġformat ) Ġmetadata Ġfrom Ġthe Ġimage Ġfile . ĊĠĠĠĠ Ġ* Ġ@ throws Ġjava . io . IOException Ġ Ġif Ġthere Ġis Ġan Ġerror Ġreading Ġthe ĠImage Ġfile Ġfrom Ġdisk . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized Ġ@ Throws ( java . io . IOException :: class ) ĊĠĠĠ Ġopen Ġfun Ġread ( filename : ĠString ): ĠImage ? Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmeta Ġ= Ġlo ci . common . services . Service Factory (). getInstance ( loc i . formats . services . O ME XML Service :: class . java ). create O ME XML Metadata () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlo ci Reader . metadata Store Ġ= Ġmeta ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalStateException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlo ci Reader . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlo ci Reader . metadata Store Ġ= Ġmeta ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : Ġlo ci . common . services . ServiceException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : Ġlo ci . common . services . Dependency Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlock ( filename ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogging Utilities . logger . warning (" inter rupted Ġwhile Ġattempting Ġto Ġlock Ġimage Ġfile ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlo ci Reader . setId ( filename ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalStateException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlo ci Reader . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlo ci Reader . setId ( filename ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : Ġlo ci . formats . FormatException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġjava . io . IOException ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlo ci . formats . Metadata Tools . populate Pixels ( loc i Reader . metadata Store , Ġlo ci Reader ) ĊĠĠĠĠĠĠĠ Ġval Ġp Ġ= ĠPixel Data Factory . create Pixel Data ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlo ci Reader . size X , Ġlo ci Reader . size Y , Ġlo ci Reader . size Z , Ġlo ci Reader . size C , Ġlo ci Reader . size T , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlo ci Reader . pixel Type , Ġlo ci Reader . dimension Order ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ(!( loc i Reader . metadata Store Ġas Ġlo ci . formats . meta . IM et adata ). get Pixels Bin Data BigEndian ( 0 , Ġ 0 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġp . set Byte Order ( java . nio . Byte Order . LIT TLE _ ENDIAN ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! series Counts . containsKey ( filename ) Ġ|| Ġ! hasMore Series ( filename )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseries Counts . put ( filename , Ġlo ci Reader . series Count ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Series . put ( filename , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlo ci Reader . series Ġ= Ġcurrent Series [ filename ] !! ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. loc i Reader . image Count Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurr Plane Ġ= Ġlo ci Reader . open Bytes ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġz ct Ġ= Ġlo ci Reader . getZ CT Coords ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp . set Plane ( z ct [ 0 ], Ġz ct [ 1 ], Ġz ct [ 2 ], Ġcurr Plane ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : Ġlo ci . formats . FormatException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : Ġjava . io . IOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġto Return Ġ= ĠImage Factory . create ( loc i Reader . metadata Store Ġas Ġlo ci . formats . meta . IM et adata , Ġp ) ĊĠĠĠĠĠĠĠ Ġlo ci Reader . close () ĊĠĠĠĠĠĠĠ Ġcurrent Series . put ( filename , Ġcurrent Series [ filename ] !! Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġrelease ( filename , ĠThread . currentThread ()) ĊĠĠĠĠĠĠĠ Ġreturn Ġto Return ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRelease s Ġthe Ġlock Ġon Ġthe Ġspecified Ġfile , Ġwith Ġthe Ġspecified ĠThread Ġthat Ġholds Ġthe Ġlock . ĊĠĠĠĠ Ġ* Ġ@ param Ġfilename ĠĠĠĠĠ ĠThe Ġfile Ġto Ġunlock . ĊĠĠĠĠ Ġ* Ġ@ param Ġlock Object ĠĠĠ ĠThe ĠThread Ġthat Ġholds Ġthe Ġlock . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġfun Ġrelease ( filename : ĠString , Ġlock Object : ĠThread ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsynchronized ( Image Reader :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( lock Object Ġ== Ġfile Locks [ filename ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Locks . remove ( filename ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprotected Ġvar Ġfile Locks : Ġjava . util . Hashtable < String , ĠThread > Ġ= ĠHashtable < String , ĠThread >() ĊĠĠĠĠĠĠĠ Ġprotected Ġvar ĠLOCK _ WAIT _ TIME _ MS : ĠLong Ġ= Ġ 1 0 0 0 0 ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠLock s Ġthe Ġfile Ġat Ġthe Ġspecified Ġfilename Ġfor Ġreading Ġby Ġan ĠImage Reader . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġfilename Ġ ĠThe Ġfile Ġto Ġlock . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠĠĠĠĠĠĠĠĠ ĠThe ĠThread Ġthat Ġholds Ġthe Ġlock . Ġ ĠThis Ġshould Ġalways Ġbe Ġthe Ġcurrent Ġthread Ġon Ġnormal Ġreturn . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ throws ĠInterruptedException ĊĠĠĠĠĠĠĠĠ Ġ* ĠTODO ( col in ): Ġwhy Ġdo Ġwe Ġneed Ġto Ġlock Ġfor Ġreading ? ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Throws ( InterruptedException :: class ) ĊĠĠĠĠĠĠĠ Ġfun Ġlock ( filename : ĠString ): ĠThread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( Image Reader :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! file Locks . containsKey ( filename )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Locks . put ( filename , ĠThread . currentThread ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( Thread . currentThread () Ġ!= Ġfile Locks [ filename ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( LOCK _ WAIT _ TIME _ MS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( Image Reader :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! file Locks . containsKey ( filename )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Locks . put ( filename , ĠThread . currentThread ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠThread . currentThread () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠLock s Ġthe Ġfile Ġat Ġthe Ġspecified Ġfilename Ġfor Ġreading Ġby Ġa Ġspecified ĠThread . ĊĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġcurrent ĠThread Ġmust Ġstill Ġbe Ġthe Ġholder Ġof Ġthe Ġlock , Ġor Ġthe Ġfile Ġmust Ġbe Ġun locked , Ġor Ġthis Ġmethod Ġwill Ġblock . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġfilename Ġ ĠThe Ġfile Ġto Ġlock . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġto Hold Lock ĠĠĠ ĠThe ĠThread Ġthat Ġshould Ġhold Ġthe Ġlock . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThe ĠThread Ġthat Ġholds Ġthe Ġlock . Ġ ĠThis Ġshould Ġalways Ġbe Ġthe Ġspecified Ġthread Ġon Ġnormal Ġreturn . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ throws ĠInterruptedException ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Throws ( InterruptedException :: class ) ĊĠĠĠĠĠĠĠ Ġfun Ġlock With Thread ( filename : ĠString , Ġto Hold Lock : ĠThread ): ĠThread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġdid Lock Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( Image Reader :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! file Locks . containsKey ( filename )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdid Lock Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Locks . put ( filename , Ġto Hold Lock ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ(! did Lock Ġ&& ĠThread . currentThread () Ġ!= Ġfile Locks [ filename ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( LOCK _ WAIT _ TIME _ MS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( Image Reader :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! file Locks . containsKey ( filename )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdid Lock Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Locks . put ( filename , Ġto Hold Lock ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġto Hold Lock ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ