package Ġorg . n aho ft . org . n aho ft . sw atch Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . graphics . Bitmap Ċ import Ġandroid . graphics . Bitmap Factory Ċ import Ġandroid . media . Ex if Interface Ċ import Ġandroid . net . Uri Ċ import Ġorg . n aho ft . stencil . Capture Photo Utils Ċ import Ġorg . n aho ft . stencil . Image Size Ċ import Ġorg . n aho ft . sw atch . Sw atch Ċ import Ġorg . n aho ft . sw atch . payload Message Key Ċ import Ġorg . n aho ft . util . Save Util Ċ import Ġkotlin . math . round ToInt Ċ import Ġkotlin . math . sqrt ĊĊ Ċ class ĠEncoder Ċ { ĊĠĠĠ Ġ@ Experimental Unsigned Types ĊĠĠĠ Ġfun Ġencode ( context : ĠContext , Ġencrypted : ĠByteArray , Ġcover Uri : ĠUri , Ġsave To Gallery : ĠBoolean ): ĠUri ? ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġvar ĠinputStream Ġ= Ġcontext . content Resolver . open InputStream ( cover Uri ) ĊĠĠĠĠĠĠĠ Ġif Ġ( inputStream Ġ== Ġnull ) ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġex if Interface Ġ= ĠEx if Interface ( inputStream ) ĊĠĠĠĠĠĠĠ Ġval Ġorientation : ĠString Ġ= Ġex if Interface . getAttribute ( Ex if Interface . TAG _ OR IENTATION ) Ġ?: ĠEx if Interface . OR IENTATION _ UNDEFINED . toString () ĊĊĠĠĠĠĠĠĠ Ġ// ĠRefresh ĠinputStream ĊĠĠĠĠĠĠĠ ĠinputStream Ġ= Ġcontext . content Resolver . open InputStream ( cover Uri ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġphoto ĊĠĠĠĠĠĠĠ Ġval Ġcover Ġ= ĠBitmap Factory . decode Stream ( inputStream ) ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġencode ( encrypted , Ġcover ) ĊĠĠĠĠĠĠĠ Ġval Ġtitle Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġval Ġdescription Ġ= Ġ"" ĊĊĠĠĠĠĠĠĠ Ġif Ġ( result Ġ== Ġnull ) Ġ{ Ġreturn Ġnull Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( save To Gallery ) ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsaved Ġ= ĠSave Util . save Image To Gallery ( context , Ġresult ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( saved ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcover Uri ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCapture Photo Utils . insert Image ( context , Ġresult , Ġtitle , Ġdescription ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Experimental Unsigned Types ĊĠĠĠ Ġfun Ġencode ( encrypted : ĠByteArray , Ġcover : ĠBitmap ): ĠBitmap ? ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġworking Cover Ġ= Ġcover ĊĊĠĠĠĠĠĠĠ Ġ// ĠConvert Ġmessage Ġsize Ġfrom Ġbytes Ġto Ġbits ĊĠĠĠĠĠĠĠ Ġ// ĠPad Ġthe Ġmessage Ġbits Ġto Ġbe Ġof Ġmax Ġsize ĊĠĠĠĠĠĠĠ Ġval Ġmessage Bits Ġ= Ġbits From Bytes ( encrypted ) ĊĠĠĠĠĠĠĠ Ġval Ġmessage Bits Size Ġ= Ġmessage Bits . size ĊĊĠĠĠĠĠĠĠ Ġ// ĠScale Ġthe Ġimage Ġif Ġnecessary ĊĠĠĠĠĠĠĠ Ġworking Cover Ġ= Ġscale ( cover , Ġmessage Bits Size ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠThe Ġnumber Ġof Ġpixels Ġis Ġthe Ġimage Ġheight Ġ( in Ġpixels ) Ġtimes Ġthe Ġimage Ġwidth Ġ( in Ġpixels ) ĊĠĠĠĠĠĠĠ Ġval Ġnum Pixels Ġ= Ġworking Cover . height Ġ* Ġworking Cover . width ĊĊĠĠĠĠĠĠĠ Ġ// ĠDo Ġwe Ġhave Ġenough Ġpixels Ġfor Ġthe Ġbits Ġwe Ġneed Ġto Ġencode ? ĊĠĠĠĠĠĠĠ Ġval Ġmessage Patch Size Ġ= Ġnum Pixels Ġ/ Ġ( message Bits Size Ġ* Ġ 2 ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( message Patch Size Ġ< ĠSw atch . minimum Patch Size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġworking Cover . copy ( Bitmap . Config . ARGB _ 8 8 8 8 , Ġtrue ) ĊĠĠĠĠĠĠĠ Ġreturn Ġencode ( result , Ġmessage Bits ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠTakes Ġboth Ġmessages Ġ( length Ġmessage , Ġand Ġmessage Ġmessage ) Ġas Ġbits Ġand Ġthe Ġbitmap Ġwe Ġwant Ġto Ġput Ġthem Ġin ĊĠĠĠ Ġ@ Experimental Unsigned Types ĊĠĠĠ Ġfun Ġencode ( cover : ĠBitmap , Ġmessage : ĠInt Array ): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrules Ġ= Ġmake Rules ( cover , Ġmessage , Ġpayload Message Key ) ĊĠĠĠĠĠĠĠ Ġif Ġ( rules Ġ== Ġnull ) Ġ{ Ġreturn Ġnull Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsolver Ġ= ĠSolver ( cover , Ġrules ) ĊĠĠĠĠĠĠĠ Ġval Ġsuccess Ġ= Ġsolver . solve () ĊĠĠĠĠĠĠĠ Ġif Ġ(! success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġcover ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġscale ( bitmap : ĠBitmap , Ġbits : ĠInt ): ĠBitmap Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġp Ġ= Ġbits Ġ* Ġ 2 Ġ* ĠSw atch . minimum Patch Size ĊĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġbitmap . height Ġ* Ġbitmap . width ĊĠĠĠĠĠĠĠ Ġif Ġ( size Ġ== Ġp ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġbitmap ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoriginal Size Ġ= ĠImage Size ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap . height . toDouble (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap . width . toDouble (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 3 2 . 0 Ġ// ARGB _ 8 8 8 8 Ġ 8 Ġbits Ġfor Ġeach Ġin ĠAR GB Ġadded Ġtogether ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġscaled Size Ġ= Ġresize Pre serving AspectRatio ( original Size , Ġp ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew Height Ġ= Ġscaled Size . height . round ToInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew Width Ġ= Ġscaled Size . width . round ToInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew Num Pixels Ġ= Ġnew Height Ġ* Ġnew Width ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew Bits Ġ= Ġnew Num Pixels Ġ/ Ġ( Sw atch . minimum Patch Size Ġ* Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( new Bits Ġ< Ġbits ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprint (" Error Ġin Ġscaling Ġalgorithm .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscaled Size Ġ= Ġresize Pre serving AspectRatio ( original Size , Ġp ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Height Ġ= Ġscaled Size . height . round ToInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Width Ġ= Ġscaled Size . width . round ToInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Num Pixels Ġ= Ġnew Height Ġ* Ġnew Width ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Bits Ġ= Ġnew Num Pixels Ġ/ Ġ( Sw atch . minimum Patch Size Ġ* Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Bitmap Ġ= ĠBitmap . create Scaled Bitmap ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Height , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Width , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnew Bitmap ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġresize Pre serving AspectRatio ( original Size : ĠImage Size , Ġtarget Size Pixels : ĠInt ): ĠImage Size Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġaspect Ratio Ġ= Ġoriginal Size . height Ġ/ Ġoriginal Size . width ĊĠĠĠĠĠĠĠ Ġval Ġscaled Height Ġ= Ġsqrt ( target Size Pixels Ġ/ Ġaspect Ratio ) ĊĠĠĠĠĠĠĠ Ġval Ġscaled Width Ġ= Ġaspect Ratio Ġ* Ġscaled Height ĊĊĠĠĠĠĠĠĠ Ġreturn Ġ ĠImage Size ( scaled Height , Ġscaled Width , Ġoriginal Size . color Depth Bytes ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/// ĠGenerates Ġan Ġarray Ġof Ġrules . ĊĠĠĠ Ġ/// ĠEach Ġrule Ġreturns Ġ 2 Ġpatches Ġand Ġa Ġconstraint Ġ( w hether Ġor Ġnot Ġthey Ġare Ġlight er Ġor Ġdark er Ġthan Ġeach Ġother ) ĊĠĠĠ Ġ/// ĠG reater Ġis Ġa Ġ 1 ĊĠĠĠ Ġ/// ĠLess Ġis Ġa Ġ 0 ĊĠĠĠ Ġfun Ġmake Rules ( cover : ĠBitmap , Ġmessage : ĠInt Array , Ġkey : ĠInt ): ĠArray < Rule >? ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnum Pixels Ġ= Ġcover . height Ġ* Ġcover . width ĊĊĠĠĠĠĠĠĠ Ġ// ĠEach Ġbit Ġneeds Ġa Ġpair Ġof Ġpatches ĊĠĠĠĠĠĠĠ Ġval Ġpatch Size Ġ= Ġnum Pixels Ġ/ Ġ( message . size * 2 ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġmapped Ġ= ĠM apped Bitmap ( cover , Ġkey ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġrules : ĠArray < Rule > Ġ= ĠarrayOf () ĊĊĠĠĠĠĠĠĠ Ġ// ĠFor Ġeach Ġbit Ġin Ġthe Ġmessage Ġwe Ġget Ġa Ġrule ĊĠĠĠĠĠĠĠ Ġ// ĠA Ġrule Ġis Ġtwo Ġpatches Ġand Ġa Ġconstraint ĊĠĠĠĠĠĠĠ Ġfor Ġ( index Ġin Ġmessage . indices ) ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbit Ġ= Ġmessage [ index ] ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDoes Ġpatch A Ġneed Ġto Ġbe Ġlight er Ġthan Ġpatch B , Ġor Ġdark er ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠB rightness Ġis Ġbased Ġon Ġthe Ġaverage Ġbrightness Ġfor Ġthe Ġentire Ġpatch . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconstraint : ĠEncoder Constraint ? Ġ= Ġwhen Ġ( bit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 Ġ-> ĠEncoder Constraint . GRE ATER ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 Ġ-> ĠEncoder Constraint . LESS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( constraint Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrule Ġ= ĠRule ( index , Ġpatch Size , Ġconstraint , Ġmapped ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrules Ġ+= Ġrule ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġrules ĊĠĠĠ Ġ} Ċ }