package Ġand o . file . compressor Ċ Ċ import Ġand o . file . core . File Global . MODE _ READ _ ONLY Ċ import Ġand o . file . core . File Global . open FileDescriptor Ċ import Ġand o . file . core . File Logger Ċ import Ġand o . file . core . FileSize Utils Ċ import Ġandroid . graphics . Bitmap Factory Ċ import Ġandroid . net . Uri Ċ import Ġandroidx . ex if interface . media . Ex if Interface Ċ import Ġjava . io . ByteArray OutputStream Ċ import Ġjava . io . IOException Ċ import Ġjava . io . InputStream Ċ import Ġkotlin . experimental . and Ċ Ċ object ĠImage Checker Ġ{ ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠJ PG Ġ= Ġ". jpg " ĊĠĠĠ Ġprivate Ġval ĠJPEG _ SIGNATURE Ġ= Ġbyte ArrayOf ( 0 xFF . to Byte (), Ġ 0 xD 8 . to Byte (), Ġ 0 xFF . to Byte ()) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDetermine Ġif Ġit Ġis ĠJ PG . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġins Ġimage Ġfile Ġinput Ġstream ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġis JPG ( ins : ĠInputStream ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġis JPG ( toByteArray ( ins )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis JPG ( data : ĠByteArray ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( data Ġ== Ġnull Ġ|| Ġdata . size Ġ< Ġ 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġsignature B Ġ= Ġbyte ArrayOf ( data [ 0 ], Ġdata [ 1 ], Ġdata [ 2 ]) ĊĠĠĠĠĠĠĠ Ġreturn ĠJPEG _ SIGNATURE . content Equals ( signature B ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġext Suffix ( uri : ĠUri ?): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBitmap Factory . Options (). run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Just Decode Bounds Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBitmap Factory . decode FileDescriptor ( open FileDescriptor ( uri , ĠMODE _ READ _ ONLY )?. file Descriptor Ġ?: Ġreturn ĠJ PG , Ġnull , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout MimeType . replace (" image /", Ġ". ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJ PG ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġneed Compress ( least Compress Size : ĠInt , Ġuri : ĠUri ?): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġif Ġ( least Compress Size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFile Size Utils . getFile Size ( uri ) Ġ> Ġleast Compress Size Ġshl Ġ 1 0 ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġtrue ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġèİ·åıĸ åĽ¾çīĩ çļĦ æĹ ĭ è½¬ è§Ĵ åº¦ ĊĠĠĠĠ Ġ* Ġåıª èĥ½ éĢļè¿ĩ åİŁå§ĭ æĸĩä»¶ èİ·åıĸ ï¼Į å¦Ĥæŀľ å·²ç»ı è¿Ľè¡Į è¿ĩ Ġbitmap Ġæĵ įä½ľ æĹłæ³ķ èİ·åıĸ ãĢĤ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Rotate Degree ( ex if : ĠEx if Interface ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġorientation : ĠInt Ġ= Ġex if . getAttribute Int ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . TAG _ OR IENTATION , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ NORMAL ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( orientation ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ ROT ATE _ 9 0 Ġ-> Ġresult Ġ= Ġ 9 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ ROT ATE _ 1 8 0 Ġ-> Ġresult Ġ= Ġ 1 8 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ ROT ATE _ 2 7 0 Ġ-> Ġresult Ġ= Ġ 2 7 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ignore : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFile Logger . e (" Orientation Ġnot Ġfound ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġdegrees Ġin Ġclock wise . ĠValues Ġare Ġ 0 , Ġ 9 0 , Ġ 1 8 0 , Ġor Ġ 2 7 0 . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Orientation ( ins : ĠInputStream ?): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġget Orientation ( toByteArray ( ins )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Orientation ( jpeg : ĠByteArray ?): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( jpeg Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġoffset Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġlength Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġ// ĠISO / IE C Ġ 1 0 9 1 8 - 1 : 1 9 9 3 ( E ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( offset Ġ+ Ġ 3 Ġ< Ġj peg . size Ġ&& Ġ( jpeg [ offset ++] Ġand Ġ( 0 xFF ). to Byte ()) Ġ== Ġ( 0 xFF ). to Byte ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmarker : ĠInt Ġ= Ġ( jpeg [ offset ] Ġand Ġ( 0 xFF ). to Byte ()). toInt () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġif Ġthe Ġmarker Ġis Ġa Ġpadding . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( marker Ġ== Ġ 0 xFF ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset ++ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġif Ġthe Ġmarker Ġis ĠSO I Ġor ĠT EM . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( marker Ġ== Ġ 0 xD 8 Ġ|| Ġmarker Ġ== Ġ 0 x 0 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġif Ġthe Ġmarker Ġis ĠE OI Ġor ĠS OS . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( marker Ġ== Ġ 0 xD 9 Ġ|| Ġmarker Ġ== Ġ 0 x DA ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġlength Ġand Ġcheck Ġif Ġit Ġis Ġreasonable . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlength Ġ= Ġpack ( jpeg , Ġoffset , Ġ 2 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( length Ġ< Ġ 2 Ġ|| Ġoffset Ġ+ Ġlength Ġ> Ġj peg . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFile Logger . e (" Invalid Ġlength ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBreak Ġif Ġthe Ġmarker Ġis ĠEX IF Ġin ĠAPP 1 . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( marker Ġ== Ġ 0 xE 1 Ġ&& Ġlength Ġ>= Ġ 8 Ġ&& Ġpack ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġj peg , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+ Ġ 2 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 4 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ== Ġ 0 x 4 5 7 8 6 9 6 6 Ġ&& Ġpack ( jpeg , Ġoffset Ġ+ Ġ 6 , Ġ 2 , Ġfalse ) Ġ== Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+= Ġ 8 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlength Ġ-= Ġ 8 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSkip Ġother Ġmarkers . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+= Ġlength ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlength Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠJ E IT A ĠCP - 3 4 5 1 ĠEx if ĠVersion Ġ 2 . 2 ĊĠĠĠĠĠĠĠ Ġif Ġ( length Ġ> Ġ 8 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIdent ify Ġthe Ġbyte Ġorder . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġtag Ġ= Ġpack ( jpeg , Ġoffset , Ġ 4 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( tag Ġ!= Ġ 0 x 4 9 4 9 2 A 0 0 Ġ&& Ġtag Ġ!= Ġ 0 x 4 D 4 D 0 0 2 A ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFile Logger . e (" Invalid Ġbyte Ġorder ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlittle Endian Ġ= Ġtag Ġ== Ġ 0 x 4 9 4 9 2 A 0 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġoffset Ġand Ġcheck Ġif Ġit Ġis Ġreasonable . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcount Ġ= Ġpack ( jpeg , Ġoffset Ġ+ Ġ 4 , Ġ 4 , Ġlittle Endian ) Ġ+ Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( count Ġ< Ġ 1 0 Ġ|| Ġcount Ġ> Ġlength ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFile Logger . e (" Invalid Ġoffset ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+= Ġcount ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlength Ġ-= Ġcount ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġcount Ġand Ġgo Ġthrough Ġall Ġthe Ġelements . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcount Ġ= Ġpack ( jpeg , Ġoffset Ġ- Ġ 2 , Ġ 2 , Ġlittle Endian ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( count -- Ġ> Ġ 0 Ġ&& Ġlength Ġ>= Ġ 1 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġtag Ġand Ġcheck Ġif Ġit Ġis Ġorientation . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtag Ġ= Ġpack ( jpeg , Ġoffset , Ġ 2 , Ġlittle Endian ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( tag Ġ== Ġ 0 x 0 1 1 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( pack ( jpeg , Ġoffset Ġ+ Ġ 8 , Ġ 2 , Ġlittle Endian )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 Ġ-> Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 3 Ġ-> Ġreturn Ġ 1 8 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 6 Ġ-> Ġreturn Ġ 9 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 8 Ġ-> Ġreturn Ġ 2 7 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFile Logger . e (" Unsupported Ġorientation ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+= Ġ 1 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlength Ġ-= Ġ 1 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠFile Logger . e (" Orientation Ġnot Ġfound ") ĊĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpack ( ĊĠĠĠĠĠĠĠ Ġbytes : ĠByteArray , ĊĠĠĠĠĠĠĠ Ġoff : ĠInt , ĊĠĠĠĠĠĠĠ Ġlen : ĠInt , ĊĠĠĠĠĠĠĠ Ġlittle Endian : ĠBoolean , ĊĠĠĠ Ġ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġoffset Ġ= Ġoff ĊĠĠĠĠĠĠĠ Ġvar Ġlength Ġ= Ġlen ĊĠĠĠĠĠĠĠ Ġvar Ġstep Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġif Ġ( little Endian ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+= Ġlength Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstep Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġvalue Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( length -- Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġvalue Ġshl Ġ 8 Ġor Ġ( bytes [ offset ] Ġand Ġ( 0 xFF ). to Byte ()). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+= Ġstep ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġvalue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġto ByteArray ( inputStream : ĠInputStream ?): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( inputStream Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠByteArray ( 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArrayOutputStream () ĊĠĠĠĠĠĠĠ Ġvar Ġread : ĠInt ĊĠĠĠĠĠĠĠ Ġval Ġdata Ġ= ĠByteArray ( 4 0 9 6 ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( inputStream . read ( data , Ġ 0 , Ġdata . size ). also Ġ{ Ġread Ġ= Ġit Ġ} Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer . write ( data , Ġ 0 , Ġread ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ignored : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠByteArray ( 0 ) ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer . close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ignored : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġbuffer . toByteArray () ĊĠĠĠ Ġ} Ċ Ċ }