003-jffs2_compression.patch 238 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096
  1. --- a/Documentation/Configure.help
  2. +++ b/Documentation/Configure.help
  3. @@ -17592,6 +17592,32 @@ CONFIG_JFFS2_FS_DEBUG
  4. If reporting bugs, please try to have available a full dump of the
  5. messages at debug level 1 while the misbehaviour was occurring.
  6. +ARMLIB compression support for BBC (EXPERIMENTAL)
  7. +CONFIG_JFFS2_BBC_ARMLIB
  8. + This enables ARMLIB support for BBC.
  9. +
  10. +LZO1X-* compression support for BBC (EXPERIMENTAL)
  11. +CONFIG_JFFS2_BBC_LZO
  12. + This enables LZO1X-1 and LZO1X-999 support for BBC. (fast & good
  13. + compressor, beats ZLIB in everything)
  14. +
  15. +LZARI compression support for BBC (EXPERIMENTAL)
  16. +CONFIG_JFFS2_BBC_LZARI
  17. + This enables LempelZiv-Storer-Szymanski compression for BBC with
  18. + additional arithmetic coding (damn slow, but best compresor).
  19. +
  20. +LZHD compression support for BBC (EXPERIMENTAL)
  21. +CONFIG_JFFS2_BBC_LZHD
  22. + This enables LempelZiv-Storer-Szymanski compression for BBC with
  23. + additional dynamic Huffman coding (a little faster than LZARI, and
  24. + it's compression ratio is a little worse than LZARI's)
  25. +
  26. +LZSS compression support for BBC (EXPERIMENTAL)
  27. +CONFIG_JFFS2_BBC_LZSS
  28. + This enables simple LempelZiv-Storer-Szymanski compression for BBC
  29. + (faster than LZHD, and, and has a not-so-good compression ratio,
  30. + was included just for testing)
  31. +
  32. JFFS stats available in /proc filesystem
  33. CONFIG_JFFS_PROC_FS
  34. Enabling this option will cause statistics from mounted JFFS file systems
  35. --- a/fs/Config.in
  36. +++ b/fs/Config.in
  37. @@ -50,6 +50,12 @@ dep_tristate 'Journalling Flash File Sys
  38. if [ "$CONFIG_JFFS2_FS" = "y" -o "$CONFIG_JFFS2_FS" = "m" ] ; then
  39. int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0
  40. fi
  41. +dep_mbool ' ARMLIB compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_ARMLIB $CONFIG_JFFS2_FS
  42. +dep_mbool ' LZO1X-* compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZO $CONFIG_JFFS2_FS
  43. +dep_mbool ' LZARI compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZARI $CONFIG_JFFS2_FS
  44. +dep_mbool ' LZHD compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZHD $CONFIG_JFFS2_FS
  45. +dep_mbool ' LZSS compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZSS $CONFIG_JFFS2_FS
  46. +
  47. tristate 'Compressed ROM file system support' CONFIG_CRAMFS
  48. tristate 'Squashed file system support' CONFIG_SQUASHFS
  49. if [ "$CONFIG_SQUASHFS" = "y" -o "$CONFIG_SQUASHFS" = "m" ] ; then
  50. --- /dev/null
  51. +++ b/fs/jffs2/Config.in.bbc.inc
  52. @@ -0,0 +1,5 @@
  53. +dep_mbool ' ARMLIB compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_ARMLIB $CONFIG_JFFS2_FS
  54. +dep_mbool ' LZO1X-* compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZO $CONFIG_JFFS2_FS
  55. +dep_mbool ' LZARI compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZARI $CONFIG_JFFS2_FS
  56. +dep_mbool ' LZHD compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZHD $CONFIG_JFFS2_FS
  57. +dep_mbool ' LZSS compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZSS $CONFIG_JFFS2_FS
  58. --- /dev/null
  59. +++ b/fs/jffs2/Configure.help.bbc.inc
  60. @@ -0,0 +1,25 @@
  61. +ARMLIB compression support for BBC (EXPERIMENTAL)
  62. +CONFIG_JFFS2_BBC_ARMLIB
  63. + This enables ARMLIB support for BBC.
  64. +
  65. +LZO1X-* compression support for BBC (EXPERIMENTAL)
  66. +CONFIG_JFFS2_BBC_LZO
  67. + This enables LZO1X-1 and LZO1X-999 support for BBC. (fast & good
  68. + compressor, beats ZLIB in everything)
  69. +
  70. +LZARI compression support for BBC (EXPERIMENTAL)
  71. +CONFIG_JFFS2_BBC_LZARI
  72. + This enables LempelZiv-Storer-Szymanski compression for BBC with
  73. + additional arithmetic coding (damn slow, but best compresor).
  74. +
  75. +LZHD compression support for BBC (EXPERIMENTAL)
  76. +CONFIG_JFFS2_BBC_LZHD
  77. + This enables LempelZiv-Storer-Szymanski compression for BBC with
  78. + additional dynamic Huffman coding (a little faster than LZARI, and
  79. + it's compression ratio is a little worse than LZARI's)
  80. +
  81. +LZSS compression support for BBC (EXPERIMENTAL)
  82. +CONFIG_JFFS2_BBC_LZSS
  83. + This enables simple LempelZiv-Storer-Szymanski compression for BBC
  84. + (faster than LZHD, and, and has a not-so-good compression ratio,
  85. + was included just for testing)
  86. --- /dev/null
  87. +++ b/fs/jffs2/Kconfig.bbc.inc
  88. @@ -0,0 +1,40 @@
  89. +config JFFS2_BBC_ARMLIB
  90. + bool "ARMLIB compression support for BBC (EXPERIMENTAL)"
  91. + depends on JFFS2_FS && EXPERIMENTAL
  92. + default y
  93. + help
  94. + This enables ARMLIB support for BBC.
  95. +
  96. +config JFFS2_BBC_LZO
  97. + bool "LZO1X-* compression support for BBC (EXPERIMENTAL)"
  98. + depends on JFFS2_FS && EXPERIMENTAL
  99. + default y
  100. + help
  101. + This enables LZO1X-1 and LZO1X-999 support for BBC. (fast & good
  102. + compressor)
  103. +
  104. +config JFFS2_BBC_LZARI
  105. + bool "LZARI compression support for BBC (EXPERIMENTAL)"
  106. + depends on JFFS2_FS && EXPERIMENTAL
  107. + default y
  108. + help
  109. + This enables LempelZiv-Storer-Szymanski compression for BBC with
  110. + additional arithmetic coding (damn slow, but best compresor).
  111. +
  112. +config JFFS2_BBC_LZHD
  113. + bool "LZHD compression support for BBC (EXPERIMENTAL)"
  114. + depends on JFFS2_FS && EXPERIMENTAL
  115. + default y
  116. + help
  117. + This enables LempelZiv-Storer-Szymanski compression for BBC with
  118. + additional dynamic Huffman coding (a little faster than LZARI, and
  119. + it's compression ratio is a little worse than LZARI's)
  120. +
  121. +config JFFS2_BBC_LZSS
  122. + bool "LZSS compression support for BBC (EXPERIMENTAL)"
  123. + depends on JFFS2_FS && EXPERIMENTAL
  124. + default y
  125. + help
  126. + This enables simple LempelZiv-Storer-Szymanski compression for BBC
  127. + (faster than LZHD, and, and has a not-so-good compression ratio,
  128. + was included just for testing)
  129. --- a/fs/jffs2/Makefile
  130. +++ b/fs/jffs2/Makefile
  131. @@ -10,9 +10,23 @@
  132. # Note 2! The CFLAGS definitions are now in the main makefile...
  133. +JFFS2_BBC_KERNEL_OBJS-y = jffs2_bbc_framework.o jffs2_bbc_fs.o
  134. +
  135. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_ARMLIB) += jffs2_bbc_armlib_comp.o
  136. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZO) += jffs2_bbc_lzo_comp.o
  137. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZSS) += jffs2_bbc_lzss_comp.o
  138. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZARI) += jffs2_bbc_lzari_comp.o
  139. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZHD) += jffs2_bbc_lzhd_comp.o
  140. +
  141. +JFFS2_BBC_KERNEL_OBJS := $(JFFS2_BBC_KERNEL_OBJS-y)
  142. +
  143. +JFFS2_BBC_MKFS_OBJS = jffs2_bbc_mkfs.o jffs2_bbc_framework.o jffs2_bbc_armlib_comp.o jffs2_bbc_lzo_comp.o\
  144. + jffs2_bbc_lzss_comp.o jffs2_bbc_lzari_comp.o jffs2_bbc_lzhd_comp.o
  145. +
  146. COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o pushpull.o \
  147. compr_zlib.o
  148. JFFS2_OBJS := dir.o file.o ioctl.o nodelist.o malloc.o \
  149. + $(JFFS2_BBC_KERNEL_OBJS) \
  150. read.o nodemgmt.o readinode.o super.o write.o scan.o gc.o \
  151. symlink.o build.o erase.o background.o
  152. --- /dev/null
  153. +++ b/fs/jffs2/Makefile.bbc.inc
  154. @@ -0,0 +1,12 @@
  155. +JFFS2_BBC_KERNEL_OBJS-y = jffs2_bbc_framework.o jffs2_bbc_fs.o
  156. +
  157. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_ARMLIB) += jffs2_bbc_armlib_comp.o
  158. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZO) += jffs2_bbc_lzo_comp.o
  159. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZSS) += jffs2_bbc_lzss_comp.o
  160. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZARI) += jffs2_bbc_lzari_comp.o
  161. +JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZHD) += jffs2_bbc_lzhd_comp.o
  162. +
  163. +JFFS2_BBC_KERNEL_OBJS := $(JFFS2_BBC_KERNEL_OBJS-y)
  164. +
  165. +JFFS2_BBC_MKFS_OBJS = jffs2_bbc_mkfs.o jffs2_bbc_framework.o jffs2_bbc_armlib_comp.o jffs2_bbc_lzo_comp.o\
  166. + jffs2_bbc_lzss_comp.o jffs2_bbc_lzari_comp.o jffs2_bbc_lzhd_comp.o
  167. --- a/fs/jffs2/compr_zlib.c
  168. +++ b/fs/jffs2/compr_zlib.c
  169. @@ -85,7 +85,7 @@ void jffs2_zlib_exit(void)
  170. vfree(inflate_workspace);
  171. }
  172. -int zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
  173. +int jffs2_zlib_compress2(unsigned char *data_in, unsigned char *cpage_out,
  174. __u32 *sourcelen, __u32 *dstlen)
  175. {
  176. z_stream strm;
  177. @@ -145,7 +145,7 @@ int zlib_compress(unsigned char *data_in
  178. return 0;
  179. }
  180. -void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
  181. +void jffs2_zlib_decompress2(unsigned char *data_in, unsigned char *cpage_out,
  182. __u32 srclen, __u32 destlen)
  183. {
  184. z_stream strm;
  185. @@ -175,3 +175,19 @@ void zlib_decompress(unsigned char *data
  186. zlib_inflateEnd(&strm);
  187. up(&inflate_sem);
  188. }
  189. +
  190. +extern int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 * sourcelen, __u32 * dstlen);
  191. +extern void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
  192. +
  193. +int zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
  194. + __u32 *sourcelen, __u32 *dstlen)
  195. +{
  196. + return jffs2_zlib_compress(data_in,cpage_out,sourcelen,dstlen);
  197. +}
  198. +
  199. +void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
  200. + __u32 srclen, __u32 destlen)
  201. +{
  202. + jffs2_zlib_decompress(data_in,cpage_out,srclen,destlen);
  203. +}
  204. +
  205. --- a/fs/jffs2/file.c
  206. +++ b/fs/jffs2/file.c
  207. @@ -35,6 +35,7 @@
  208. *
  209. */
  210. +#include "jffs2_bbc_framework.h" /**BBC**/
  211. #include <linux/kernel.h>
  212. #include <linux/mtd/compatmac.h> /* for min() */
  213. #include <linux/slab.h>
  214. @@ -459,6 +460,7 @@ int jffs2_commit_write (struct file *fil
  215. comprbuf = kmalloc(cdatalen, GFP_KERNEL);
  216. if (comprbuf) {
  217. + jffs2_bbc_model_set_act_sb(c); /**BBC**/
  218. comprtype = jffs2_compress(page_address(pg)+ (file_ofs & (PAGE_CACHE_SIZE-1)), comprbuf, &datalen, &cdatalen);
  219. }
  220. if (comprtype == JFFS2_COMPR_NONE) {
  221. --- a/fs/jffs2/gc.c
  222. +++ b/fs/jffs2/gc.c
  223. @@ -35,6 +35,7 @@
  224. *
  225. */
  226. +#include "jffs2_bbc_framework.h" /**BBC**/
  227. #include <linux/kernel.h>
  228. #include <linux/mtd/mtd.h>
  229. #include <linux/slab.h>
  230. @@ -651,6 +652,7 @@ static int jffs2_garbage_collect_dnode(s
  231. writebuf = pg_ptr + (offset & (PAGE_CACHE_SIZE -1));
  232. if (comprbuf) {
  233. + jffs2_bbc_model_set_act_sb(c); /**BBC**/
  234. comprtype = jffs2_compress(writebuf, comprbuf, &datalen, &cdatalen);
  235. }
  236. if (comprtype) {
  237. --- /dev/null
  238. +++ b/fs/jffs2/hpatch
  239. @@ -0,0 +1,191 @@
  240. +#!/usr/bin/perl
  241. +# A patch-like utility
  242. +# Designed for patching different version of jffs2 with the same hpatch file
  243. +#
  244. +# Copyright (C) 2004, Ferenc Havasi
  245. +#
  246. +# This program is free software; you can redistribute it and/or
  247. +# modify it under the terms of the GNU General Public License
  248. +# as published by the Free Software Foundation; either version 2
  249. +# of the License, or (at your option) any later version.
  250. +#
  251. +# This program is distributed in the hope that it will be useful,
  252. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  253. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  254. +# GNU General Public License for more details.
  255. +#
  256. +# You should have received a copy of the GNU General Public License
  257. +# along with this program; if not, write to the Free Software
  258. +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  259. +
  260. +$filename_tmp1="file1.tmp";
  261. +$filename_tmp2="file2.tmp";
  262. +
  263. +$filename_in="";
  264. +$filename_out=$filename_tmp1;
  265. +$filename_cnt=0;
  266. +
  267. +# Modes:
  268. +# 0: expecting =
  269. +# 1: normal_cmd
  270. +# 2: skip until =
  271. +# 3: expecting F (first state)
  272. +$mode=3;
  273. +
  274. +%rules = ();
  275. +
  276. +sub file_end {
  277. + if (($mode!=2)&&($modified==1)) {
  278. + while (<SRC>) {
  279. + print DST $_;
  280. + }
  281. + close(SRC);
  282. + close(DST);
  283. + if ($cmd_name ne "") { $rules{"$cmd_name"}=1; }
  284. + $filename_result=$filename_out;
  285. + if ($filename_result ne $filename_in_save) {
  286. + open(RES,"<$filename_result") or die "Cannot open $filename_result.\n";
  287. + open(DST,">$filename_in_save") or die "Cannot open $filename_in_save.\n";
  288. + while (<RES>) {
  289. + print DST $_;
  290. + }
  291. + close(DST);
  292. + close(RES);
  293. + }
  294. + unlink($filename_tmp1) && unlink($filename_tmp2);
  295. + }
  296. + else {
  297. + close(SRC);
  298. + close(DST);
  299. + $filename_result=$filename_in;
  300. + if ($filename_result ne $filename_in_save) {
  301. + open(RES,"<$filename_result") or die "Cannot open $filename_result.\n";
  302. + open(DST,">$filename_in_save") or die "Cannot open $filename_in_save.\n";
  303. + while (<RES>) {
  304. + print DST $_;
  305. + }
  306. + close(DST);
  307. + close(RES);
  308. + }
  309. + unlink($filename_tmp1);
  310. + }
  311. + $modified=0;
  312. + foreach $rulename (keys %rules) {
  313. + if ($rules{"$rulename"}==0) { print(STDERR "On $filename_in_save error applying rule $rulename.\n"); }
  314. + }
  315. + %rules = ();
  316. +}
  317. +
  318. +if ($#ARGV<0) {
  319. + print ("usage: hpatch hpatch_file\n");
  320. + exit;
  321. +}
  322. +
  323. +open(CMD,"<$ARGV[0]") or die "Cannot open $ARGV[0].\n";
  324. +$cmd_linenum=0;
  325. +
  326. +while (chomp($cmd_line=<CMD>)) {
  327. + $cmd_linenum++;
  328. + if ($cmd_line eq "") {next;}
  329. + #$cmd_line =~ s/\#.*//;
  330. + $cmd_line =~ s/\ *$//;
  331. + if ($cmd_line eq "") {next;}
  332. + if ($cmd_line =~ /^F(.*)/) {
  333. + $tmp_filename_in=$1;
  334. + if ($mode!=3) {
  335. + file_end();
  336. + }
  337. + $filename_in=$tmp_filename_in;
  338. + $filename_in_save=$filename_in;
  339. + open(SRC,"<$filename_in") or die "Cannot open $filename_in.\n";
  340. + open(DST,">$filename_out") or die "Cannot open $filename_out.\n";;
  341. + $modified=0;
  342. + $mode=0;
  343. + next;
  344. + }
  345. + if ($mode==3) {die "error: F expression expected in line $cmd_linenum\n";}
  346. + if ($cmd_line =~ /^=(.*)/) {
  347. + $tmp_cmd_name=$1;
  348. + if (($mode!=2)&&($modified==1)) {
  349. + while (<SRC>) {
  350. + print DST $_;
  351. + }
  352. + close(SRC);
  353. + close(DST);
  354. + if (($cmd_name ne "")) {$rules{"$cmd_name"}=1;};
  355. + $filename_cnt++;
  356. + if ($filename_cnt%2==1) {
  357. + $filename_in=$filename_tmp1;
  358. + $filename_out=$filename_tmp2;
  359. + }
  360. + else {
  361. + $filename_in=$filename_tmp2;
  362. + $filename_out=$filename_tmp1;
  363. + }
  364. + }
  365. + else {
  366. + close(SRC);
  367. + close(DST);
  368. + }
  369. + $mode=1;
  370. + $cmd_name=$tmp_cmd_name;
  371. + if (($cmd_name ne "")) {
  372. + if ($rules{"$cmd_name"}==1) {
  373. + $mode=2;
  374. + }
  375. + else {
  376. + $rules{"$cmd_name"}=0;
  377. + }
  378. + }
  379. + open(SRC,"<$filename_in") or die "Cannot open $filename_in.\n";
  380. + open(DST,">$filename_out") or die "Cannot open $filename_out.\n";
  381. + $modified=0;
  382. + next;
  383. + }
  384. + if ($mode == 0) {die "error: = expression expected in line $cmd_linenum\n";}
  385. + if ($mode == 2) {next;}
  386. + if ($cmd_line =~ /^!(.*)/) {
  387. + print "$1\n";
  388. + $modified=1;
  389. + next;
  390. + }
  391. + if ($cmd_line =~ /^\?(.*)/) {
  392. + $search_str=$1;
  393. + $found=0;
  394. + while (<SRC>) {
  395. + print DST $_;
  396. + if (index($_,$search_str)>=0) {$found=1; last;}
  397. + }
  398. + if ($found==0) { $mode=2; }
  399. + next;
  400. + }
  401. + if ($cmd_line =~ /^\+(.*)/) {
  402. + print DST "$1\n";
  403. + $modified=1;
  404. + next;
  405. + }
  406. + if ($cmd_line =~ /^\-(.*)/) {
  407. + $search_str=$1;
  408. + $found=0;
  409. + while (<SRC>) {
  410. + if (index($_,$search_str)>=0) {$saved_line=$_; $found=1; $modified=1; last;}
  411. + print DST $_;
  412. + }
  413. + if ($found==0) { $mode=2; }
  414. + next;
  415. + }
  416. + if ($cmd_line =~ /^i(.*)/) {
  417. + $filename_inc=$1;
  418. + open(INCSRC,"<$filename_inc") or die "Cannot open $filename_inc.\n";
  419. + while (<INCSRC>) {
  420. + print DST $_;
  421. + }
  422. + next;
  423. + }
  424. + if ($cmd_line =~ /^I/) {
  425. + print DST $saved_line;
  426. + next;
  427. + }
  428. +}
  429. +file_end();
  430. +close(CMD);
  431. --- /dev/null
  432. +++ b/fs/jffs2/jffs2_bbc_armlib_comp.c
  433. @@ -0,0 +1,2224 @@
  434. +/*
  435. + * JFFS2-BBC: armlib compressor plugin
  436. + *
  437. + * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  438. + *
  439. + * Copyright (C) 2004, Ferenc Havasi & Tamas Gergely
  440. + *
  441. + * This program is free software; you can redistribute it and/or
  442. + * modify it under the terms of the GNU General Public License
  443. + * as published by the Free Software Foundation; either version 2
  444. + * of the License, or (at your option) any later version.
  445. + *
  446. + * This program is distributed in the hope that it will be useful,
  447. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  448. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  449. + * GNU General Public License for more details.
  450. + *
  451. + * You should have received a copy of the GNU General Public License
  452. + * along with this program; if not, write to the Free Software
  453. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  454. + *
  455. + */
  456. +
  457. +#include "jffs2_bbc_framework.h"
  458. +
  459. +#ifdef __KERNEL__
  460. +#include <linux/string.h>
  461. +#else
  462. +#include <string.h>
  463. +#endif
  464. +
  465. +//ORIGIN: include/DataStructures/TypeDefs.h
  466. +
  467. +/*******************************************************************************
  468. +* FILE: TypeDefs.h
  469. +* AUTHOR: Tamás Gergely
  470. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  471. +*******************************************************************************/
  472. +
  473. +#ifndef TYPEDEFS_H
  474. +#define TYPEDEFS_H
  475. +
  476. +#pragma pack(4)
  477. +
  478. +#ifndef bool
  479. +#define bool char
  480. +#define true 1
  481. +#define false 0
  482. +#endif
  483. +
  484. +#ifndef u8
  485. +#define u8 unsigned char
  486. +#endif
  487. +#ifndef u16
  488. +#define u16 unsigned short
  489. +#endif
  490. +#ifndef u32
  491. +#define u32 unsigned long
  492. +#endif
  493. +#ifndef s8
  494. +#define s8 signed char
  495. +#endif
  496. +#ifndef s16
  497. +#define s16 signed short
  498. +#endif
  499. +#ifndef s32
  500. +#define s32 signed long
  501. +#endif
  502. +
  503. +typedef struct
  504. +{
  505. + u32 capacity;
  506. + u32 size;
  507. + u32 alloc_size;
  508. + void *ptr;
  509. +} vector;
  510. +
  511. +#define VECTOR_P_END(vct) ((void*)(((char*)((vct)->ptr)) + (vct)->size))
  512. +#define VECTOR_S_END(vct) ((void*)(((char*)((vct).ptr)) + (vct).size))
  513. +
  514. +static void vector_clear(vector *);
  515. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  516. +static void vector_reset(vector *);
  517. +static void vector_clr_ptr(vector *);
  518. +static void vector_add_u8(vector *, u8);
  519. +static void vector_add_u16(vector *, u16);
  520. +static void vector_add_u32(vector *, u32);
  521. +static void vector_add_s8(vector *, s8);
  522. +static void vector_add_s16(vector *, s16);
  523. +static void vector_add_s32(vector *, s32);
  524. +static void vector_add_ptr(vector *, void *);
  525. +static void vector_concat(vector *, vector *);
  526. +#endif
  527. +
  528. +#endif
  529. +
  530. +//ORIGIN: include/DataStructures/DataTypes.h
  531. +
  532. +/*******************************************************************************
  533. +* FILE: DataTypes.h
  534. +* AUTHOR: Tamás Gergely
  535. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  536. +*******************************************************************************/
  537. +
  538. +#ifndef DATATYPES_H
  539. +#define DATATYPES_H
  540. +
  541. +//#include "DataStructures/TypeDefs.h"
  542. +
  543. +typedef u16 THUMB_DataType;
  544. +typedef u32 ARM_DataType;
  545. +typedef u8 TokenType;
  546. +typedef u8 PredictorType;
  547. +typedef u8 *ProbDist;
  548. +
  549. +typedef vector RawData;
  550. +typedef vector RawBlocks;
  551. +typedef vector TokenStream;
  552. +typedef vector TokenBlocks;
  553. +typedef vector LatType;
  554. +
  555. +#define THUMB_DATA_LENGTH 16
  556. +#define ARM_DATA_LENGTH 32
  557. +#define TOKEN_LENGTH 8
  558. +#define TOKEN_MAXVALUE 0xff
  559. +#define PREDICTOR_LENGTH 8
  560. +#define PREDICTOR_MAXVALUE 0xff
  561. +
  562. +#endif
  563. +
  564. +//ORIGIN: include/DataStructures/BitVector.h
  565. +
  566. +/*******************************************************************************
  567. +* FILE: BitVector.h
  568. +* AUTHOR: Tamás Gergely
  569. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  570. +*******************************************************************************/
  571. +
  572. +#ifndef BITVECTOR_H
  573. +#define BITVECTOR_H
  574. +
  575. +//#include "DataStructures/TypeDefs.h"
  576. +
  577. +typedef vector BitBlocks;
  578. +
  579. +#pragma pack(4)
  580. +
  581. +typedef struct
  582. +{
  583. + u32 freebits;
  584. + u32 capacity;
  585. + u32 size;
  586. + u8 *base;
  587. + u8 *ptr;
  588. +} BitVector;
  589. +
  590. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  591. +static void bitblocks_clear(BitBlocks *);
  592. +static void bitvector_clear(BitVector *);
  593. +static void bitvector_W_reset(BitVector *);
  594. +static void bitvector_W_add0(BitVector *);
  595. +static void bitvector_W_add1(BitVector *);
  596. +static void bitvector_W_concat_b(BitVector *, BitVector *);
  597. +static void bitvector_W_concat_v(BitVector *, vector *);
  598. +static void bitvector_W_flush(BitVector *);
  599. +static void bitvector_R_reset(BitVector *);
  600. +static u8 bitvector_R_get1(BitVector *);
  601. +static u8 bitvector_R_get8(BitVector *);
  602. +#endif
  603. +
  604. +#define BITVECTOR_P_END(bv) ((void*)(((bv)->base)+((bv)->size)))
  605. +#define BITVECTOR_S_END(bv) ((void*)( ((bv).base)+ ((bv).size)))
  606. +#define BITVECTOR_SKIP(bv,num) ((bv)->ptr) += (num)
  607. +
  608. +#endif
  609. +
  610. +//ORIGIN: include/DataStructures/DecisionTree.h
  611. +
  612. +/*******************************************************************************
  613. +* FILE: DecisionTree.h
  614. +* AUTHOR: Tamás Gergely
  615. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  616. +*******************************************************************************/
  617. +
  618. +#ifndef DECISIONTREE_H
  619. +#define DECISIONTREE_H
  620. +
  621. +//#include "DataStructures/DataTypes.h"
  622. +
  623. +#pragma pack(4)
  624. +
  625. +#define TREENODETYPE_NULLNODE 0
  626. +#define TREENODETYPE_NODE_BINARY_EQ 1
  627. +#define TREENODETYPE_LEAF_P 2
  628. +#define TREENODETYPE_LEAF_C 3
  629. +#define TREENODETYPE_NODE_BINARY_LT 5
  630. +#define TREENODETYPE_IS_NODE(n) (((n) == TREENODETYPE_NODE_BINARY_EQ) || \
  631. + ((n) == TREENODETYPE_NODE_BINARY_LT))
  632. +#define TREENODETYPE_IS_NODE_BINARY(n) (((n) == TREENODETYPE_NODE_BINARY_EQ) || \
  633. + ((n) == TREENODETYPE_NODE_BINARY_LT))
  634. +
  635. +#define TREENODETYPE_IS_LEAF(n) (((n) == TREENODETYPE_LEAF_P) || \
  636. + ((n) == TREENODETYPE_LEAF_C))
  637. +
  638. +
  639. +#define TREE_SUBTREE_RELATION_LEFT_EQ !=
  640. +#define TREE_SUBTREE_RELATION_RIGHT_EQ ==
  641. +#define TREE_SUBTREE_RELATION_LEFT_LT <
  642. +#define TREE_SUBTREE_RELATION_RIGHT_LT >=
  643. +
  644. +#define GET_NODE_PTR_TYPE(n) (((TreeNodeDummy*)(n))->type)
  645. +
  646. +typedef struct
  647. +{
  648. + u8 type;
  649. +} TreeNodeDummy;
  650. +
  651. +typedef struct
  652. +{
  653. + u8 type; // [TREENODETYPE_NODE_BINARY]
  654. + u8 attribute;
  655. + PredictorType value;
  656. + void *left;
  657. + void *right;
  658. +} TreeNodeBinary;
  659. +
  660. +typedef struct
  661. +{
  662. + u8 type; // [TREENODETYPE_LEAF_P]
  663. + u16 pairs;
  664. + PredictorType *probabilities;
  665. +} TreeLeafP;
  666. +
  667. +typedef struct
  668. +{
  669. + u8 type; // [TREENODETYPE_LEAF_C]
  670. + PredictorType predicted_class;
  671. +} TreeLeafC;
  672. +
  673. +typedef struct
  674. +{
  675. + u32 high;
  676. + u32 low;
  677. + u32 max;
  678. +} ProbabilityType;
  679. +
  680. +
  681. +typedef struct
  682. +{
  683. + void *root;
  684. + u16 number_of_classes;
  685. + u16 number_of_predictors;
  686. + PredictorType *predictor_max_values;
  687. +} DecisionTree;
  688. +
  689. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  690. +static void decisiontree_delete(DecisionTree *);
  691. +static void decisiontree_get_probability_for_token(void *, PredictorType *, TokenType, ProbabilityType *);
  692. +static TokenType decisiontree_get_token_for_range(void *, PredictorType *, u32, u32, ProbabilityType *);
  693. +#endif
  694. +
  695. +#endif
  696. +
  697. +//ORIGIN: include/DataStructures/PredictorTable.h
  698. +
  699. +/*******************************************************************************
  700. +* FILE: PredictorTable.h
  701. +* AUTHOR: Tamás Gergely
  702. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  703. +*******************************************************************************/
  704. +
  705. +#ifndef PREDICTORTABLE_H
  706. +#define PREDICTORTABLE_H
  707. +
  708. +//#include "DataStructures/TypeDefs.h"
  709. +//#include "DataStructures/DataTypes.h"
  710. +////#include "DataStructures/Filter.h"
  711. +////#include "DataStructures/Converter.h"
  712. +////#include "DataStructures/Manipulator.h"
  713. +
  714. +#define NUMBER_OF_PREDICTORS_ARM 17
  715. +
  716. +#ifndef __KERNEL__
  717. +#define NUMBER_OF_PREDICTORS_TXT 2
  718. +#else
  719. +#undef TXT_TOKENS
  720. +#endif // __KERNEL__
  721. +
  722. +#ifdef TXT_TOKENS
  723. +#define NUMBER_OF_PREDICTORS NUMBER_OF_PREDICTORS_TXT
  724. +#define predictortable_reset predictortable_resetTXT
  725. +#define predictortable_update predictortable_updateTXT
  726. +#define predictortable_minvalue predictortable_minvalueTXT
  727. +#define predictortable_maxvalue predictortable_maxvalueTXT
  728. +#else
  729. +#define NUMBER_OF_PREDICTORS NUMBER_OF_PREDICTORS_ARM
  730. +#define predictortable_reset predictortable_resetARM
  731. +#define predictortable_update predictortable_updateARM
  732. +#define predictortable_minvalue predictortable_minvalueARM
  733. +#define predictortable_maxvalue predictortable_maxvalueARM
  734. +#endif
  735. +
  736. +
  737. +#pragma pack(4)
  738. +
  739. +typedef struct
  740. +{
  741. + PredictorType *predictors;
  742. +} PredictorTable;
  743. +
  744. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  745. +static void predictortable_clear(PredictorTable *);
  746. +static void predictortable_free(PredictorTable *);
  747. +static void predictortable_resetARM(PredictorTable *);
  748. +static void predictortable_updateARM(PredictorTable *, TokenType);
  749. +static PredictorType predictortable_minvalueARM(PredictorTable *, u32);
  750. +static PredictorType predictortable_maxvalueARM(PredictorTable *, u32);
  751. +#endif
  752. +
  753. +#ifndef __KERNEL__
  754. +/*
  755. +static void predictortable_resetTXT(PredictorTable *);
  756. +static void predictortable_updateTXT(PredictorTable *, TokenType);
  757. +static PredictorType predictortable_minvalueTXT(PredictorTable *, u32);
  758. +static PredictorType predictortable_maxvalueTXT(PredictorTable *, u32);
  759. +*/
  760. +#endif // __KERNEL__
  761. +
  762. +#endif
  763. +
  764. +//ORIGIN: include/DataStructures/ipack_model.h
  765. +
  766. +/*******************************************************************************
  767. +* FILE: ipack_model.h
  768. +* AUTHOR: Tamás Gergely
  769. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  770. +*******************************************************************************/
  771. +
  772. +#ifndef IPACK_MODEL_H
  773. +#define IPACK_MODEL_H
  774. +
  775. +//#include "DataStructures/DataTypes.h"
  776. +//#include "DataStructures/DecisionTree.h"
  777. +//#include "DataStructures/PredictorTable.h"
  778. +
  779. +#define PROBABILITY_SHIFT 12
  780. +#define PROBABILITY_MAX 0x00001000l
  781. +
  782. +#define NUMBER_OF_TOKENS_ARM 16
  783. +#define NUMBER_OF_TOKENS_PER_INSTRUCTION_ARM 8
  784. +
  785. +#ifndef __KERNEL__
  786. +#define NUMBER_OF_TOKENS_TXT 256
  787. +#define NUMBER_OF_TOKENS_PER_INSTRUCTION_TXT 4
  788. +#else
  789. +#undef TXT_TOKENS
  790. +#endif // __KERNEL__
  791. +
  792. +#ifdef TXT_TOKENS
  793. +#define NUMBER_OF_TOKENS NUMBER_OF_TOKENS_TXT
  794. +#define NUMBER_OF_TOKENS_PER_INSTRUCTION NUMBER_OF_TOKENS_PER_INSTRUCTION_TXT
  795. +#else
  796. +#define NUMBER_OF_TOKENS NUMBER_OF_TOKENS_ARM
  797. +#define NUMBER_OF_TOKENS_PER_INSTRUCTION NUMBER_OF_TOKENS_PER_INSTRUCTION_ARM
  798. +#endif
  799. +
  800. +#pragma pack(4)
  801. +
  802. +/*
  803. + Data structure of an internal node of the tree
  804. +*/
  805. +typedef struct
  806. +{
  807. + PredictorType *attribute_ptr;
  808. + u32 value; // PredictorType
  809. + void *right_child_ptr;
  810. +} ipack_treenodeBin;
  811. +/*
  812. + Data structure of a leaf with probabilities
  813. +*/
  814. +typedef struct
  815. +{
  816. + u16 probabilities[0]; // PredictorType[0]
  817. +} ipack_treeleafP;
  818. +/*
  819. + Data structure of a leaf with class prediction
  820. +*/
  821. +typedef struct
  822. +{
  823. + PredictorType predicted_class; // PredictorType
  824. +} ipack_treeleafC;
  825. +/*
  826. + Possible data structures of a tree node
  827. +*/
  828. +typedef union
  829. +{
  830. + ipack_treenodeBin nodeBin;
  831. + ipack_treeleafP leafP;
  832. + ipack_treeleafC leafC;
  833. +} ipack_node_data;
  834. +/*
  835. + Tree node
  836. +*/
  837. +typedef struct
  838. +{
  839. + u32 type; // u8
  840. + ipack_node_data data; // ipack_node_data
  841. +} ipack_nodetype;
  842. +/*
  843. + Nullnode
  844. +*/
  845. +typedef struct
  846. +{
  847. + u32 type;
  848. + u16 probabilities[NUMBER_OF_TOKENS];
  849. +} ipack_nullnode;
  850. +/*
  851. + Model for ipack project
  852. +*/
  853. +typedef struct
  854. +{
  855. + char ID[4]; // char[4]
  856. + char block_sign[4]; // only the first 2 are used!
  857. + void *tree_root_ptr; // void*
  858. + void *tree_code; // generated ARM code
  859. + PredictorType *predictors_ptr; // PredictorType*
  860. + ipack_nullnode nullnode;
  861. +} ipack_model_type;
  862. +
  863. +typedef struct
  864. +{
  865. + u32 high;
  866. + u32 low;
  867. +} ipack_probability_type;
  868. +
  869. +
  870. +static void ipack_model_get_probability_for_token(ipack_nodetype *, TokenType, ipack_probability_type *);
  871. +static TokenType ipack_model_get_token_for_range(ipack_nodetype *, u32, u32, ipack_probability_type *);
  872. +/*void ipack_model_predictortable_reset (PredictorType*);
  873. +void ipack_model_predictortable_update (PredictorType*, TokenType);*/
  874. +
  875. +#ifndef __KERNEL__
  876. +/*static void ipack_model_printinfo(ipack_model_type *);
  877. +static void ipack_dumpmodel(void *);*/
  878. +#endif
  879. +
  880. +#endif
  881. +
  882. +//ORIGIN: include/Builders/PredictorGenerator.h
  883. +
  884. +/*******************************************************************************
  885. +* FILE: PredictorGenerator.h
  886. +* AUTHOR: Tamás Gergely
  887. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  888. +*******************************************************************************/
  889. +
  890. +#ifndef PREDICTORGENERATOR_H
  891. +#define PREDICTORGENERATOR_H
  892. +
  893. +//#include "DataStructures.h"
  894. +
  895. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  896. +static PredictorTable *predictorgenerator_generate(void);
  897. +#endif
  898. +
  899. +#endif
  900. +
  901. +//ORIGIN: include/Builders/Coder.h
  902. +
  903. +/*******************************************************************************
  904. +* FILE: Coder.h
  905. +* AUTHOR: Tamás Gergely
  906. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  907. +*******************************************************************************/
  908. +
  909. +#ifndef CODER_H
  910. +#define CODER_H
  911. +
  912. +#define CODER_VALUEBITS 16
  913. +#define CODER_VALUEMAX 0x00010000l
  914. +#define CODER_VALUE3RD 0x0000c000l
  915. +#define CODER_VALUEHLF 0x00008000l
  916. +#define CODER_VALUE1ST 0x00004000l
  917. +
  918. +#endif
  919. +
  920. +//ORIGIN: DataStructures/src/TypeDefs.c
  921. +
  922. +/*******************************************************************************
  923. +* FILE: TypeDefs.c
  924. +* AUTHOR: Tamás Gergely
  925. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  926. +*******************************************************************************/
  927. +
  928. +//#include "ipack_common.h"
  929. +//#include "DataStructures/TypeDefs.h"
  930. +#ifndef __KERNEL__
  931. +#include <memory.h>
  932. +#endif
  933. +
  934. +#define VECTOR_ALLOC_SIZE 0x00001000
  935. +
  936. +static void vector_clear(vector * vct)
  937. +{
  938. + if (vct->ptr)
  939. + jffs2_bbc_free(vct->ptr);
  940. + vct->capacity = 0;
  941. + vct->size = 0;
  942. + vct->ptr = 0;
  943. +}
  944. +
  945. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  946. +static void vector_extend(vector * vct)
  947. +{
  948. + void *tmp;
  949. + vct->capacity += vct->alloc_size;
  950. + tmp = jffs2_bbc_malloc(vct->capacity);
  951. + if (vct->ptr) {
  952. + memcpy(tmp, vct->ptr, vct->size);
  953. + jffs2_bbc_free(vct->ptr);
  954. + }
  955. + vct->ptr = tmp;
  956. +}
  957. +
  958. +static void vector_reset(vector * vct)
  959. +{
  960. + vct->capacity = 0;
  961. + vct->size = 0;
  962. + vct->alloc_size = VECTOR_ALLOC_SIZE;
  963. + vct->ptr = 0;
  964. +}
  965. +
  966. +static void vector_clr_ptr(vector * vct)
  967. +{
  968. + void **it;
  969. + void *end_it;
  970. + for (it = vct->ptr, end_it = (((char *) (vct->ptr)) + vct->size); it != end_it; it++) {
  971. + vector_clear(*it);
  972. + jffs2_bbc_free(*it);
  973. + }
  974. + if (vct->ptr)
  975. + jffs2_bbc_free(vct->ptr);
  976. + vct->capacity = 0;
  977. + vct->size = 0;
  978. + vct->ptr = 0;
  979. +}
  980. +
  981. +static void vector_add_u8(vector * vct, u8 val)
  982. +{
  983. + if ((vct->size) + sizeof(u8) > (vct->capacity)) {
  984. + vector_extend(vct);
  985. + }
  986. + *(u8 *) ((char *) (vct->ptr) + (vct->size)) = val;
  987. + vct->size += sizeof(u8);
  988. +};
  989. +
  990. +static void vector_add_u16(vector * vct, u16 val)
  991. +{
  992. + if ((vct->size) + sizeof(u16) > (vct->capacity)) {
  993. + vector_extend(vct);
  994. + }
  995. + *(u16 *) ((char *) (vct->ptr) + (vct->size)) = val;
  996. + vct->size += sizeof(u16);
  997. +};
  998. +
  999. +static void vector_add_u32(vector * vct, u32 val)
  1000. +{
  1001. + if ((vct->size) + sizeof(u32) > (vct->capacity)) {
  1002. + vector_extend(vct);
  1003. + }
  1004. + *(u32 *) ((char *) (vct->ptr) + (vct->size)) = val;
  1005. + vct->size += sizeof(u32);
  1006. +};
  1007. +
  1008. +static void vector_add_s8(vector * vct, s8 val)
  1009. +{
  1010. + if ((vct->size) + sizeof(s8) > (vct->capacity)) {
  1011. + vector_extend(vct);
  1012. + }
  1013. + *(s8 *) ((char *) (vct->ptr) + (vct->size)) = val;
  1014. + vct->size += sizeof(s8);
  1015. +};
  1016. +
  1017. +static void vector_add_s16(vector * vct, s16 val)
  1018. +{
  1019. + if ((vct->size) + sizeof(s16) > (vct->capacity)) {
  1020. + vector_extend(vct);
  1021. + }
  1022. + *(s16 *) ((char *) (vct->ptr) + (vct->size)) = val;
  1023. + vct->size += sizeof(s16);
  1024. +};
  1025. +
  1026. +static void vector_add_s32(vector * vct, s32 val)
  1027. +{
  1028. + if ((vct->size) + sizeof(s32) > (vct->capacity)) {
  1029. + vector_extend(vct);
  1030. + }
  1031. + *(s32 *) ((char *) (vct->ptr) + (vct->size)) = val;
  1032. + vct->size += sizeof(s32);
  1033. +};
  1034. +
  1035. +static void vector_add_ptr(vector * vct, void *ptr)
  1036. +{
  1037. + if ((vct->size) + sizeof(void *) > (vct->capacity)) {
  1038. + vector_extend(vct);
  1039. + }
  1040. + *(void **) ((char *) (vct->ptr) + (vct->size)) = ptr;
  1041. + vct->size += sizeof(void *);
  1042. +}
  1043. +
  1044. +static void vector_concat(vector * lhs, vector * rhs)
  1045. +{
  1046. + void *tmp;
  1047. + if (!(rhs->size)) {
  1048. + return;
  1049. + }
  1050. + tmp = lhs->ptr;
  1051. + lhs->capacity = (lhs->size) + (rhs->size);
  1052. + lhs->ptr = jffs2_bbc_malloc(lhs->capacity);
  1053. + if (tmp) {
  1054. + memcpy(lhs->ptr, tmp, lhs->size);
  1055. + jffs2_bbc_free(tmp);
  1056. + }
  1057. + memcpy((((u8 *) lhs->ptr) + lhs->size), rhs->ptr, rhs->size);
  1058. + lhs->size += rhs->size;
  1059. +}
  1060. +
  1061. +#endif
  1062. +
  1063. +//ORIGIN: DataStructures/src/BitVector.c
  1064. +
  1065. +/*******************************************************************************
  1066. +* FILE: BitVector.c
  1067. +* AUTHOR: Tamás Gergely
  1068. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  1069. +*******************************************************************************/
  1070. +
  1071. +//#include "ipack_common.h"
  1072. +//#include "DataStructures/BitVector.h"
  1073. +#ifndef __KERNEL__
  1074. +#include <memory.h>
  1075. +#endif
  1076. +
  1077. +#define VECTOR_ALLOC_SIZE 0x00001000
  1078. +
  1079. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  1080. +
  1081. +static void bitblocks_clear(BitBlocks * this)
  1082. +{
  1083. + BitVector **it;
  1084. + void *end_it;
  1085. + for (it = this->ptr, end_it = VECTOR_P_END(this); it != end_it; it++) {
  1086. + bitvector_clear(*it);
  1087. + jffs2_bbc_free(*it);
  1088. + }
  1089. + jffs2_bbc_free(this->ptr);
  1090. + this->ptr = 0;
  1091. +}
  1092. +
  1093. +static void bitvector_clear(BitVector * this)
  1094. +{
  1095. + if (this->base) {
  1096. + jffs2_bbc_free(this->base);
  1097. + }
  1098. + this->freebits = 0;
  1099. + this->capacity = 0;
  1100. + this->size = 0;
  1101. + this->base = 0;
  1102. + this->ptr = 0;
  1103. +}
  1104. +
  1105. +static void bitvector_W_reset(BitVector * this)
  1106. +{
  1107. + this->freebits = 0;
  1108. + this->capacity = 0;
  1109. + this->size = 0;
  1110. + this->base = 0;
  1111. + this->ptr = 0;
  1112. +}
  1113. +
  1114. +static void bitvector_W_add0(BitVector * this)
  1115. +{
  1116. + if (!(this->freebits)) {
  1117. + if (this->size == this->capacity) {
  1118. + void *tmp = this->base;
  1119. + this->capacity += VECTOR_ALLOC_SIZE;
  1120. + this->base = jffs2_bbc_malloc(this->capacity);
  1121. + this->ptr = ((u8 *) (this->base)) + this->size;
  1122. + memcpy(this->base, tmp, this->size);
  1123. + jffs2_bbc_free(tmp);
  1124. + }
  1125. + else {
  1126. + this->ptr++;
  1127. + }
  1128. + this->size++;
  1129. + this->freebits = 7;
  1130. + *(this->ptr) = 0x00;
  1131. + }
  1132. + else {
  1133. + this->freebits--;
  1134. + (*(this->ptr)) <<= 1;
  1135. + }
  1136. +}
  1137. +
  1138. +static void bitvector_W_add1(BitVector * this)
  1139. +{
  1140. + if (!(this->freebits)) {
  1141. + if (this->size == this->capacity) {
  1142. + void *tmp = this->base;
  1143. + this->capacity += VECTOR_ALLOC_SIZE;
  1144. + this->base = jffs2_bbc_malloc(this->capacity);
  1145. + this->ptr = ((u8 *) (this->base)) + this->size;
  1146. + memcpy(this->base, tmp, this->size);
  1147. + jffs2_bbc_free(tmp);
  1148. + }
  1149. + else {
  1150. + this->ptr++;
  1151. + }
  1152. + this->size++;
  1153. + this->freebits = 7;
  1154. + *(this->ptr) = 0x01;
  1155. + }
  1156. + else {
  1157. + this->freebits--;
  1158. + (*(this->ptr)) <<= 1;
  1159. + (*(this->ptr)) |= 0x01;
  1160. + }
  1161. +}
  1162. +
  1163. +static void bitvector_W_concat_b(BitVector * lhs, BitVector * rhs)
  1164. +{
  1165. + void *tmp;
  1166. + if (!(rhs->size)) {
  1167. + return;
  1168. + }
  1169. + tmp = lhs->base;
  1170. + lhs->capacity = ((((lhs->size) + (rhs->size) - 1) / VECTOR_ALLOC_SIZE) + 1) * VECTOR_ALLOC_SIZE;
  1171. + lhs->base = jffs2_bbc_malloc(lhs->capacity);
  1172. + if (tmp) {
  1173. + memcpy(lhs->base, tmp, lhs->size);
  1174. + jffs2_bbc_free(tmp);
  1175. + }
  1176. + memcpy((((u8 *) (lhs->base)) + lhs->size), rhs->base, rhs->size);
  1177. + lhs->freebits = 0;
  1178. + lhs->size += rhs->size;
  1179. + lhs->ptr = ((u8 *) (lhs->base)) + lhs->size;
  1180. +}
  1181. +
  1182. +static void bitvector_W_concat_v(BitVector * lhs, vector * rhs)
  1183. +{
  1184. + void *tmp;
  1185. + if (!(rhs->size)) {
  1186. + return;
  1187. + }
  1188. + tmp = lhs->base;
  1189. + lhs->capacity = ((((lhs->size) + (rhs->size) - 1) / VECTOR_ALLOC_SIZE) + 1) * VECTOR_ALLOC_SIZE;
  1190. + lhs->base = jffs2_bbc_malloc(lhs->capacity);
  1191. + if (tmp) {
  1192. + memcpy(lhs->base, tmp, lhs->size);
  1193. + jffs2_bbc_free(tmp);
  1194. + }
  1195. + memcpy((((u8 *) (lhs->base)) + lhs->size), rhs->ptr, rhs->size);
  1196. + lhs->freebits = 0;
  1197. + lhs->size += rhs->size;
  1198. + lhs->ptr = ((u8 *) (lhs->base)) + lhs->size;
  1199. +}
  1200. +
  1201. +static void bitvector_W_flush(BitVector * this)
  1202. +{
  1203. + (*(this->ptr)) <<= this->freebits;
  1204. + this->freebits = 0;
  1205. +}
  1206. +
  1207. +static void bitvector_R_reset(BitVector * this)
  1208. +{
  1209. + this->freebits = 7;
  1210. + this->ptr = this->base;
  1211. +}
  1212. +
  1213. +static u8 bitvector_R_get1(BitVector * this)
  1214. +{
  1215. + u8 tmp = ((*(this->ptr)) >> this->freebits) & 0x01;
  1216. + if (!(this->freebits)) {
  1217. + this->freebits = 7;
  1218. + this->ptr++;
  1219. + }
  1220. + else {
  1221. + this->freebits--;
  1222. + }
  1223. + return tmp;
  1224. +}
  1225. +
  1226. +static u8 bitvector_R_get8(BitVector * this)
  1227. +{
  1228. + u8 tmp = (*(this->ptr));
  1229. + this->ptr++;
  1230. + return tmp;
  1231. +}
  1232. +
  1233. +#endif
  1234. +
  1235. +//ORIGIN: DataStructures/src/DecisionTree.c
  1236. +
  1237. +/*******************************************************************************
  1238. +* FILE: DecisionTree.c
  1239. +* AUTHOR: Tamás Gergely
  1240. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  1241. +*******************************************************************************/
  1242. +
  1243. +//#include "ipack_common.h"
  1244. +//#include "DataStructures/DecisionTree.h"
  1245. +
  1246. +static void decisiontree_delete_node(void *root)
  1247. +{
  1248. + u8 tmp = GET_NODE_PTR_TYPE(root);
  1249. + if (TREENODETYPE_IS_NODE_BINARY(tmp)) {
  1250. + decisiontree_delete_node(((TreeNodeBinary *) root)->left);
  1251. + decisiontree_delete_node(((TreeNodeBinary *) root)->right);
  1252. + }
  1253. + else if ((tmp) == TREENODETYPE_LEAF_P) {
  1254. + if (((TreeLeafP *) root)->probabilities) {
  1255. + jffs2_bbc_free(((TreeLeafP *) root)->probabilities);
  1256. + }
  1257. + }
  1258. + else if ((tmp) == TREENODETYPE_LEAF_C) {
  1259. + }
  1260. + jffs2_bbc_free(root);
  1261. +}
  1262. +
  1263. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  1264. +
  1265. +static void decisiontree_delete(DecisionTree * dt)
  1266. +{
  1267. + decisiontree_delete_node(dt->root);
  1268. + jffs2_bbc_free(dt->predictor_max_values);
  1269. +}
  1270. +
  1271. +static void decisiontree_get_probability_for_token(void *root, PredictorType * preds, TokenType token, ProbabilityType * prob)
  1272. +{
  1273. + void *tmp = root;
  1274. + while (TREENODETYPE_IS_NODE(((TreeNodeBinary *) tmp)->type)) {
  1275. + if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_NODE_BINARY_EQ) {
  1276. + if (preds[((TreeNodeBinary *) tmp)->attribute] TREE_SUBTREE_RELATION_LEFT_EQ((TreeNodeBinary *) tmp)->value) {
  1277. + tmp = ((TreeNodeBinary *) tmp)->left;
  1278. + }
  1279. + else {
  1280. + tmp = ((TreeNodeBinary *) tmp)->right;
  1281. + }
  1282. + }
  1283. + else if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_NODE_BINARY_LT) {
  1284. + if (preds[((TreeNodeBinary *) tmp)->attribute] TREE_SUBTREE_RELATION_LEFT_LT((TreeNodeBinary *) tmp)->value) {
  1285. + tmp = ((TreeNodeBinary *) tmp)->left;
  1286. + }
  1287. + else {
  1288. + tmp = ((TreeNodeBinary *) tmp)->right;
  1289. + }
  1290. + }
  1291. + }
  1292. + prob->high = 0;
  1293. + prob->low = 0;
  1294. + prob->max = 0;
  1295. + if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_LEAF_P) {
  1296. + u32 i;
  1297. + u32 lngth = ((TreeLeafP *) tmp)->pairs << 1;
  1298. + for (i = 0; i < lngth;) {
  1299. + TokenType at = ((TreeLeafP *) tmp)->probabilities[i++];
  1300. + TokenType av = ((TreeLeafP *) tmp)->probabilities[i++];
  1301. + if (token > at)
  1302. + prob->low += av;
  1303. + if (token >= at)
  1304. + prob->high += av;
  1305. + prob->max += av;
  1306. + }
  1307. + }
  1308. + else if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_LEAF_C) {
  1309. + if (((TreeLeafC *) tmp)->predicted_class == token) {
  1310. + prob->high = TOKEN_MAXVALUE;
  1311. + prob->max = TOKEN_MAXVALUE;
  1312. + }
  1313. + }
  1314. +}
  1315. +
  1316. +static TokenType decisiontree_get_token_for_range(void *root, PredictorType * preds, u32 value, u32 range, ProbabilityType * prob)
  1317. +{
  1318. + void *tmp = root;
  1319. + TokenType token = 0;
  1320. + while (TREENODETYPE_IS_NODE(((TreeNodeBinary *) tmp)->type)) {
  1321. + if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_NODE_BINARY_EQ) {
  1322. + if (preds[((TreeNodeBinary *) tmp)->attribute] TREE_SUBTREE_RELATION_LEFT_EQ((TreeNodeBinary *) tmp)->value) {
  1323. + tmp = ((TreeNodeBinary *) tmp)->left;
  1324. + }
  1325. + else {
  1326. + tmp = ((TreeNodeBinary *) tmp)->right;
  1327. + }
  1328. + }
  1329. + else if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_NODE_BINARY_LT) {
  1330. + if (preds[((TreeNodeBinary *) tmp)->attribute] TREE_SUBTREE_RELATION_LEFT_LT((TreeNodeBinary *) tmp)->value) {
  1331. + tmp = ((TreeNodeBinary *) tmp)->left;
  1332. + }
  1333. + else {
  1334. + tmp = ((TreeNodeBinary *) tmp)->right;
  1335. + }
  1336. + }
  1337. + }
  1338. + prob->high = 0;
  1339. + prob->low = 0;
  1340. + prob->max = 0;
  1341. + if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_LEAF_P) {
  1342. + u32 i;
  1343. + u32 norm;
  1344. + TokenType at = 0;
  1345. + TokenType av;
  1346. + u32 lngth = ((TreeLeafP *) tmp)->pairs << 1;
  1347. + for (i = 0; i < lngth;) {
  1348. + i++;
  1349. + prob->max += ((TreeLeafP *) tmp)->probabilities[i++];
  1350. + }
  1351. + norm = (value * prob->max - 1) / range;
  1352. + for (i = 0; prob->high <= norm;) {
  1353. + at = ((TreeLeafP *) tmp)->probabilities[i++];
  1354. + av = ((TreeLeafP *) tmp)->probabilities[i++];
  1355. + prob->high += av;
  1356. + if (prob->high <= norm)
  1357. + prob->low += av;
  1358. + }
  1359. + token = at;
  1360. + }
  1361. + else if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_LEAF_C) {
  1362. + token = ((TreeLeafC *) tmp)->predicted_class;
  1363. + prob->high = TOKEN_MAXVALUE;
  1364. + prob->max = TOKEN_MAXVALUE;
  1365. + }
  1366. + return token;
  1367. +}
  1368. +#endif
  1369. +
  1370. +//ORIGIN: DataStructures/src/PredictorTable.c
  1371. +
  1372. +/*******************************************************************************
  1373. +* FILE: PredictorTable.c
  1374. +* AUTHOR: Tamás Gergely
  1375. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  1376. +*******************************************************************************/
  1377. +
  1378. +//#include "ipack_common.h"
  1379. +//#include "DataStructures/PredictorTable.h"
  1380. +
  1381. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  1382. +
  1383. +static void predictortable_clear(PredictorTable * table)
  1384. +{
  1385. + table->predictors = 0;
  1386. +}
  1387. +
  1388. +static void predictortable_free(PredictorTable * table)
  1389. +{
  1390. + if (table->predictors) {
  1391. + jffs2_bbc_free(table->predictors);
  1392. + table->predictors = 0;
  1393. + }
  1394. +}
  1395. +
  1396. +static void predictortable_resetARM(PredictorTable * table)
  1397. +{
  1398. + register PredictorType *ptr = table->predictors;
  1399. + register PredictorType *end = ptr + NUMBER_OF_PREDICTORS_ARM;
  1400. + while (ptr < end) {
  1401. + *(ptr++) = 0;
  1402. + }
  1403. +}
  1404. +
  1405. +static void predictortable_updateARM(PredictorTable * table, TokenType token)
  1406. +{
  1407. + register PredictorType *ptr = table->predictors;
  1408. + register u32 ndx = ptr[0] + 1;
  1409. + ptr[ndx + 8] = ptr[ndx];
  1410. + ptr[ndx] = token;
  1411. + if (ndx == 8) {
  1412. + ptr[0] = 0;
  1413. + }
  1414. + else {
  1415. + ++ptr[0];
  1416. + }
  1417. +}
  1418. +
  1419. +static PredictorType predictortable_minvalueARM(PredictorTable * table, u32 index)
  1420. +{
  1421. + return 0;
  1422. +}
  1423. +
  1424. +static PredictorType predictortable_maxvalueARM(PredictorTable * table, u32 index)
  1425. +{
  1426. + if (index == 0) {
  1427. + return 7;
  1428. + }
  1429. + else {
  1430. + return 15;
  1431. + }
  1432. +}
  1433. +
  1434. +#endif
  1435. +
  1436. +#ifndef __KERNEL__
  1437. +
  1438. +/*static void predictortable_resetTXT(PredictorTable * table)
  1439. +{
  1440. + register PredictorType *ptr = table->predictors;
  1441. + register PredictorType *end = ptr + NUMBER_OF_PREDICTORS_TXT;
  1442. + while (ptr < end) {
  1443. + *(ptr++) = 0;
  1444. + }
  1445. +}
  1446. +
  1447. +static void predictortable_updateTXT(PredictorTable * table, TokenType token)
  1448. +{ //TODO: modify
  1449. + register PredictorType *ptr = table->predictors;
  1450. +// register u32 ndx;
  1451. + ptr[0] = token;
  1452. + if ((('a' <= token) && (token <= 'z')) || (('A' <= token) && (token <= 'Z'))) {
  1453. + ++(ptr[1]);
  1454. + }
  1455. + else {
  1456. + ptr[1] = 0;
  1457. + }
  1458. +}
  1459. +
  1460. +static PredictorType predictortable_minvalueTXT(PredictorTable * table, u32 index)
  1461. +{
  1462. + return 0;
  1463. +}
  1464. +
  1465. +static PredictorType predictortable_maxvalueTXT(PredictorTable * table, u32 index)
  1466. +{ //TODO: modify
  1467. + return 254;
  1468. +}*/
  1469. +
  1470. +#endif // __KERNEL__
  1471. +
  1472. +//ORIGIN: DataStructures/src/ipack_model.c
  1473. +
  1474. +/*******************************************************************************
  1475. +* FILE: ipack_model.c
  1476. +* AUTHOR: Tamás Gergely
  1477. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  1478. +*******************************************************************************/
  1479. +
  1480. +//#include "DataStructures/ipack_model.h"
  1481. +//#include "measuredef.h"
  1482. +//#include "ipack_common.h"
  1483. +
  1484. +#ifdef __MEASURE_TIME_MODEL_GETPROB
  1485. +#define __MT_P_MAX 256
  1486. +#define __MT_P_DIV 128
  1487. +#define __MT_P_MIN 0
  1488. +#endif
  1489. +
  1490. +static void ipack_model_get_probability_for_token(ipack_nodetype * tmp, TokenType token, ipack_probability_type * prob)
  1491. +{
  1492. +// register ipack_nodetype* tmp = model->tree_root_ptr;
  1493. +// register ipack_nodetype* tmp = root;
  1494. + while (TREENODETYPE_IS_NODE(tmp->type)) {
  1495. + if (tmp->type == TREENODETYPE_NODE_BINARY_EQ) {
  1496. + if (*(tmp->data.nodeBin.attribute_ptr) TREE_SUBTREE_RELATION_LEFT_EQ tmp->data.nodeBin.value) {
  1497. + ((char *) tmp) += sizeof(tmp->type) + sizeof(ipack_treenodeBin);
  1498. + }
  1499. + else {
  1500. + tmp = tmp->data.nodeBin.right_child_ptr;
  1501. + }
  1502. + }
  1503. + else if (tmp->type == TREENODETYPE_NODE_BINARY_LT) {
  1504. + if (*(tmp->data.nodeBin.attribute_ptr) TREE_SUBTREE_RELATION_LEFT_LT tmp->data.nodeBin.value) {
  1505. + ((char *) tmp) += sizeof(tmp->type) + sizeof(ipack_treenodeBin);
  1506. + }
  1507. + else {
  1508. + tmp = tmp->data.nodeBin.right_child_ptr;
  1509. + }
  1510. + }
  1511. + }
  1512. + prob->high = 0;
  1513. + prob->low = 0;
  1514. +// prob->max = 0;
  1515. + if (tmp->type == TREENODETYPE_LEAF_P) {
  1516. + if (token) {
  1517. + prob->low = tmp->data.leafP.probabilities[token - 1];
  1518. + }
  1519. + prob->high = tmp->data.leafP.probabilities[token];
  1520. +// prob->max = tmp->data.leafP.probabilities[15];
  1521. + }
  1522. + else if (tmp->type == TREENODETYPE_LEAF_C) {
  1523. + if (tmp->data.leafC.predicted_class == token) {
  1524. + prob->high = TOKEN_MAXVALUE;
  1525. +// prob->max = TOKEN_MAXVALUE;
  1526. + }
  1527. + }
  1528. +}
  1529. +
  1530. +#ifndef IPACK_ARM_ASM
  1531. +
  1532. +//return ipack_model_get_token_for_range2(tmp,value,range,prob);
  1533. +
  1534. +static TokenType ipack_model_get_token_for_range(ipack_nodetype * tmp, u32 value, u32 range, ipack_probability_type * prob)
  1535. +{
  1536. +// register ipack_nodetype* tmp = model->tree_root_ptr;
  1537. +// register ipack_nodetype* tmp = root;
  1538. + register TokenType token = 0;
  1539. + while (TREENODETYPE_IS_NODE(tmp->type)) {
  1540. + if (tmp->type == TREENODETYPE_NODE_BINARY_EQ) {
  1541. + if (*(tmp->data.nodeBin.attribute_ptr) TREE_SUBTREE_RELATION_LEFT_EQ tmp->data.nodeBin.value) {
  1542. + ((char *) tmp) += sizeof(tmp->type) + sizeof(ipack_treenodeBin);
  1543. + }
  1544. + else {
  1545. + tmp = tmp->data.nodeBin.right_child_ptr;
  1546. + }
  1547. + }
  1548. + else if (tmp->type == TREENODETYPE_NODE_BINARY_LT) {
  1549. + if (*(tmp->data.nodeBin.attribute_ptr) TREE_SUBTREE_RELATION_LEFT_LT tmp->data.nodeBin.value) {
  1550. + ((char *) tmp) += sizeof(tmp->type) + sizeof(ipack_treenodeBin);
  1551. + }
  1552. + else {
  1553. + tmp = tmp->data.nodeBin.right_child_ptr;
  1554. + }
  1555. + }
  1556. + }
  1557. + prob->high = 0;
  1558. + prob->low = 0;
  1559. +// prob->max = 0;
  1560. + if (tmp->type == TREENODETYPE_LEAF_P) {
  1561. + u32 i;
  1562. + u32 norm;
  1563. +// prob->max = tmp->data.leafP.probabilities[15];
  1564. +/* norm = (value * prob->max -1)/range;
  1565. + for(i = 0; i < 15; ++i) {
  1566. + if(tmp->data.leafP.probabilities[i] > norm) {
  1567. + break;
  1568. + }
  1569. + }*/
  1570. + norm = ((value << PROBABILITY_SHIFT) - 1);
  1571. + for (i = 0; i < NUMBER_OF_TOKENS; ++i) {
  1572. + if (range * tmp->data.leafP.probabilities[i] > norm) {
  1573. + break;
  1574. + }
  1575. + }
  1576. + token = (TokenType) i;
  1577. + prob->high = tmp->data.leafP.probabilities[i];
  1578. + if (token) {
  1579. + prob->low = tmp->data.leafP.probabilities[token - 1];
  1580. + }
  1581. + }
  1582. + else if (tmp->type == TREENODETYPE_LEAF_C) {
  1583. + token = tmp->data.leafC.predicted_class;
  1584. + prob->high = PROBABILITY_MAX;
  1585. +// prob->max = PROBABILITY_MAX;
  1586. + }
  1587. + return token;
  1588. +}
  1589. +#endif
  1590. +/*
  1591. +void ipack_model_predictortable_reset(PredictorType* ptr)
  1592. +{
  1593. +// register PredictorType* ptr = model->predictors_ptr;
  1594. +// register PredictorType* ptr = preds;
  1595. + register PredictorType* end = ptr + NUMBER_OF_PREDICTORS;
  1596. + while(ptr < end) {
  1597. + *(ptr++) = 0;
  1598. + }
  1599. +}
  1600. +
  1601. +void ipack_model_predictortable_update(PredictorType* ptr, TokenType token)
  1602. +{
  1603. +// register PredictorType* ptr = model->predictors_ptr;
  1604. +// register PredictorType* ptr = preds;
  1605. + register u32 ndx = ptr[0] + 1;
  1606. + ptr[ndx + 8] = ptr[ndx];
  1607. + ptr[ndx] = token;
  1608. + if(ndx == 8) {
  1609. + ptr[0] = 0;
  1610. + } else {
  1611. + ++ ptr[0];
  1612. + }
  1613. +}*/
  1614. +/****************************************************************************/
  1615. +
  1616. +#ifndef __KERNEL__
  1617. +static void ipack_model_countpreds(void *ptr, ipack_nodetype * node, double *table, double val)
  1618. +{
  1619. + if ((node->type == TREENODETYPE_NODE_BINARY_EQ) || (node->type == TREENODETYPE_NODE_BINARY_LT)) {
  1620. + table[(u32) (node->data.nodeBin.attribute_ptr) - (u32) (ptr)] += val;
  1621. + ipack_model_countpreds(ptr, (void *) (((u8 *) (node)) + sizeof(node->type) + sizeof(ipack_treenodeBin)), table, val / 2);
  1622. + ipack_model_countpreds(ptr, node->data.nodeBin.right_child_ptr, table, val / 2);
  1623. + }
  1624. + else {
  1625. + }
  1626. +}
  1627. +
  1628. +/*static void ipack_model_printinfo(ipack_model_type * model)
  1629. +{
  1630. + double *prcnt = jffs2_bbc_malloc(sizeof(double) * NUMBER_OF_PREDICTORS);
  1631. + u32 i;
  1632. + for (i = 0; i < NUMBER_OF_PREDICTORS; i++) {
  1633. + prcnt[i] = 0.0;
  1634. + }
  1635. + ipack_model_countpreds(model->predictors_ptr, model->tree_root_ptr, prcnt, 100);
  1636. + for (i = 0; i < NUMBER_OF_PREDICTORS; i++) {
  1637. + jffs2_bbc_print3(" p[%3d] = %10.6lf\n", (int) i, prcnt[i]);
  1638. + }
  1639. + jffs2_bbc_free(prcnt);
  1640. +}*/
  1641. +
  1642. +static void ipack_dumpnode(unsigned char **ptr, FILE * file, char *prefs)
  1643. +{
  1644. + switch (*((*ptr)++)) {
  1645. + u32 i;
  1646. + u32 j;
  1647. + u32 x;
  1648. + u32 y;
  1649. + case TREENODETYPE_NODE_BINARY_EQ:
  1650. + x = *((*ptr)++);
  1651. + y = *((*ptr)++);
  1652. + fprintf(file, "%s+->\tBinary node: P[%u] equals %u\n", prefs, (unsigned int)x, (unsigned int)y);
  1653. + for (j = 0; j < 4096 && prefs[j]; ++j);
  1654. + prefs[j] = '\t';
  1655. + prefs[++j] = '|';
  1656. + ipack_dumpnode(ptr, file, prefs);
  1657. + prefs[j--] = 0;
  1658. + ipack_dumpnode(ptr, file, prefs);
  1659. + prefs[j] = 0;
  1660. + break;
  1661. + case TREENODETYPE_NODE_BINARY_LT:
  1662. + x = *((*ptr)++);
  1663. + y = *((*ptr)++);
  1664. + fprintf(file, "%s+->\tBinary node: P[%u] greater than %u\n", prefs, (unsigned int)x, (unsigned int)y);
  1665. + for (j = 0; j < 4096 && prefs[j]; ++j);
  1666. + prefs[j] = '\t';
  1667. + prefs[++j] = '|';
  1668. + ipack_dumpnode(ptr, file, prefs);
  1669. + prefs[j--] = 0;
  1670. + ipack_dumpnode(ptr, file, prefs);
  1671. + prefs[j] = 0;
  1672. + break;
  1673. + case TREENODETYPE_LEAF_P:
  1674. + x = *((*ptr)++);
  1675. + fprintf(file, "%s+->\tLeaf: %u pairs\n", prefs, (unsigned int)x);
  1676. + (*ptr) += (x << 1);
  1677. + break;
  1678. + case TREENODETYPE_LEAF_C:
  1679. + x = *((*ptr)++);
  1680. + fprintf(file, "%s+->\tLeaf: class %u\n", prefs, (unsigned int)x);
  1681. + break;
  1682. + default:
  1683. + fprintf(file, "%s+->\tLeaf: nullnode\n", prefs);
  1684. + }
  1685. +}
  1686. +
  1687. +/*static void ipack_dumpmodel(void *model)
  1688. +{
  1689. + unsigned char *tmp_ptr = model;
  1690. + FILE *file;
  1691. + char C[4096];
  1692. + if ((file = fopen("DUMPED_MODEL", "wa"))) {
  1693. + int i;
  1694. + for (i = 0; i < 4096; C[i++] = 0);
  1695. + tmp_ptr += 8;
  1696. + tmp_ptr += sizeof(u32);
  1697. + ipack_dumpnode(&tmp_ptr, file, C);
  1698. + fclose(file);
  1699. + }
  1700. +}*/
  1701. +
  1702. +#endif
  1703. +
  1704. +//ORIGIN: Builders/src/PredictorGenerator.c
  1705. +
  1706. +/*******************************************************************************
  1707. +* FILE: PredictorGenerator.c
  1708. +* AUTHOR: Tamás Gergely
  1709. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  1710. +*******************************************************************************/
  1711. +
  1712. +//#include "ipack_common.h"
  1713. +//#include "Builders/PredictorGenerator.h"
  1714. +
  1715. +#ifdef JFFS2_BBC_ARMLIB_MODELGEN
  1716. +static PredictorTable *predictorgenerator_generate( /*PredictorGeneratorSettings* settings */ )
  1717. +{
  1718. + PredictorTable *ptr = jffs2_bbc_malloc(sizeof(PredictorTable));
  1719. + predictortable_clear(ptr);
  1720. + ptr->predictors = jffs2_bbc_malloc(NUMBER_OF_PREDICTORS * sizeof(PredictorType));
  1721. + return ptr;
  1722. +}
  1723. +#endif
  1724. +
  1725. +//ORIGIN: Builders/src/ipack_armlib_compressor.c
  1726. +
  1727. +/*******************************************************************************
  1728. +* FILE: ipack_armlim_compressor.c
  1729. +* AUTHOR: Tamás Gergely
  1730. +* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  1731. +*******************************************************************************/
  1732. +
  1733. +//#include "ipack_common.h"
  1734. +//#include "DataStructures.h"
  1735. +//#include "Builders/PredictorGenerator.h"
  1736. +//#include "Builders/Tokenizer.h"
  1737. +//#include "Builders/Coder.h"
  1738. +
  1739. +#define EC_NO_ERROR 0
  1740. +#define EC_NOT_IPMF_FILE -1
  1741. +#define EC_NOT_IPMF_MODEL -2
  1742. +#define EC_NOT_HG_BLOCK -3
  1743. +#define EC_WRONG_INPUT_LENGTH -501
  1744. +#define EC_CODER_WRONG_PROBABILITY 1
  1745. +#define EC_CODER_WRONG_RANGE 2
  1746. +#define EC_BUFFER_OVERFLOW 501
  1747. +#define EC_BUFFER_UNDERFLOW 502
  1748. +#define EC_UNKNOWN_TOKEN_TYPE 1001
  1749. +#define EC_UNKNOWN_FILTER 1002
  1750. +#define EC_UNKNOWN_CONVERTER 1003
  1751. +#define EC_UNKNOWN_MANIPULATOR 1004
  1752. +
  1753. +/*******************************************************************************
  1754. +
  1755. + COMPRESSOR INIT FUNCTIONS
  1756. +
  1757. +*******************************************************************************/
  1758. +
  1759. +#define ROUND_UP_TO_DWORD(val) ( ( (val) + 3 ) & 0xfffffffc )
  1760. +
  1761. +#ifndef __KERNEL__
  1762. +int ipack_glb_endian_X;
  1763. +#endif
  1764. +
  1765. +static int ipack_compressor_init_tree(unsigned char **ptr, ipack_model_type * model, ipack_nodetype * node, void *nullnode)
  1766. +{
  1767. + int retval = 0;
  1768. + node->type = *((*ptr)++);
  1769. + switch (node->type) {
  1770. + u32 i;
  1771. + u32 j;
  1772. + u32 lngth;
  1773. + u32 tmpret;
  1774. + TokenType at;
  1775. + u16 av;
  1776. + case TREENODETYPE_NODE_BINARY_EQ:
  1777. + case TREENODETYPE_NODE_BINARY_LT:
  1778. + node->data.nodeBin.attribute_ptr = (model->predictors_ptr) + (*((*ptr)++));
  1779. + node->data.nodeBin.value = *((*ptr)++);
  1780. + retval = sizeof(node->data.nodeBin);
  1781. + retval += ipack_compressor_init_tree(ptr, model, (void *) ROUND_UP_TO_DWORD(((u32) node) + sizeof(node->type) + sizeof(node->data.nodeBin)), nullnode);
  1782. + node->data.nodeBin.right_child_ptr = (void *) ROUND_UP_TO_DWORD(((u32) node) + retval + sizeof(node->type));
  1783. + retval += ipack_compressor_init_tree(ptr, model, node->data.nodeBin.right_child_ptr, nullnode);
  1784. + break;
  1785. + case TREENODETYPE_LEAF_P:
  1786. + lngth = *((*ptr)++);
  1787. + av = 0;
  1788. + for (i = 0, j = 0; i < lngth; ++i) {
  1789. + at = *((*ptr)++);
  1790. + while (j < at) {
  1791. + node->data.leafP.probabilities[j++] = av;
  1792. + }
  1793. + av += *((*ptr)++);
  1794. + }
  1795. + while (j < NUMBER_OF_TOKENS) {
  1796. + node->data.leafP.probabilities[j++] = av;
  1797. + }
  1798. + for (i = 0; i < NUMBER_OF_TOKENS; ++i) {
  1799. + node->data.leafP.probabilities[i] = ((node->data.leafP.probabilities[i] << PROBABILITY_SHIFT) / node->data.leafP.probabilities[NUMBER_OF_TOKENS - 1]);
  1800. + }
  1801. + retval = ROUND_UP_TO_DWORD(NUMBER_OF_TOKENS * sizeof(u16));
  1802. + break;
  1803. + case TREENODETYPE_LEAF_C:
  1804. + node->data.leafC.predicted_class = *((*ptr)++);
  1805. + retval = sizeof(node->data.leafC);
  1806. + retval = ROUND_UP_TO_DWORD(retval);
  1807. + break;
  1808. + default:
  1809. + return 0;
  1810. + }
  1811. + return retval + sizeof(node->type);
  1812. +}
  1813. +
  1814. +#define IPACK_TREE_CONVERT_REPLACE 0
  1815. +#define IPACK_TREE_CONVERT_KEEP 1
  1816. +
  1817. +static void *ipack_tree_to_code(ipack_model_type * model, int *code_size);
  1818. +
  1819. +static int ipack_armlib_convert_tree_to_code(ipack_model_type * model_img, int mode)
  1820. +{
  1821. +#ifdef IPACK_TREE_TO_CODE
  1822. + int tree_size;
  1823. +
  1824. + model_img->tree_code = ipack_tree_to_code(model_img, &tree_size);
  1825. + jffs2_bbc_print2("Convertation done. Code size=%d\n", tree_size);
  1826. + if (mode == IPACK_TREE_CONVERT_REPLACE) {
  1827. + jffs2_bbc_print1("Freeing original tree.\n");
  1828. + jffs2_bbc_free(model_img->tree_root_ptr);
  1829. + model_img->tree_root_ptr = NULL;
  1830. + }
  1831. +#endif
  1832. + return 0;
  1833. +}
  1834. +
  1835. +
  1836. +static int ipack_armlib_compressor_init(void **model)
  1837. +{
  1838. + int retval = EC_NO_ERROR;
  1839. + unsigned char *tmp_ptr = *model;
  1840. + u32 i;
  1841. + ipack_model_type *model_img;
  1842. + char tmp_c[2];
  1843. +
  1844. + if (*(tmp_ptr++) != 'i') {
  1845. + return EC_NOT_IPMF_FILE;
  1846. + }
  1847. + else if (*(tmp_ptr++) != 'P') {
  1848. + return EC_NOT_IPMF_FILE;
  1849. + }
  1850. + else if (*(tmp_ptr++) != 'M') {
  1851. + return EC_NOT_IPMF_FILE;
  1852. + }
  1853. + else if (*(tmp_ptr++) != 'F') {
  1854. + return EC_NOT_IPMF_FILE;
  1855. + }
  1856. + tmp_c[0] = *(tmp_ptr++);
  1857. + tmp_c[1] = *(tmp_ptr++);
  1858. + tmp_ptr += 2;
  1859. +
  1860. + //model_img = jffs2_bbc_malloc(*((u32*)tmp_ptr));
  1861. + model_img = jffs2_bbc_malloc(sizeof(ipack_model_type) + ROUND_UP_TO_DWORD(NUMBER_OF_PREDICTORS));
  1862. + model_img->tree_root_ptr = jffs2_bbc_malloc(*((u32 *) tmp_ptr)); //it is smaller a little but, but...
  1863. +
  1864. + tmp_ptr += sizeof(u32);
  1865. +
  1866. + model_img->ID[0] = 'i';
  1867. + model_img->ID[1] = 'P';
  1868. + model_img->ID[2] = 'M';
  1869. + model_img->ID[3] = 'F';
  1870. +
  1871. + model_img->block_sign[0] = tmp_c[0];
  1872. + model_img->block_sign[1] = tmp_c[1];
  1873. +
  1874. + model_img->nullnode.type = TREENODETYPE_LEAF_P;
  1875. + for (i = 0; i < NUMBER_OF_TOKENS; ++i) {
  1876. + model_img->nullnode.probabilities[i] = 0;
  1877. + }
  1878. + model_img->predictors_ptr = (void *) (((u32) model_img) + sizeof(ipack_model_type));
  1879. + //model_img->tree_root_ptr = (void*)ROUND_UP_TO_DWORD(((u32)(model_img->predictors_ptr)) + NUMBER_OF_PREDICTORS);//ALIGN
  1880. +
  1881. + ipack_compressor_init_tree(&tmp_ptr, model_img, model_img->tree_root_ptr, &(model_img->nullnode));
  1882. +
  1883. +#ifdef IPACK_TREE_TO_CODE
  1884. +#ifdef IPACK_AUTO_TREE_TO_CODE
  1885. + jffs2_bbc_print1("Automatically converting tree to ARM code...\n");
  1886. + ipack_armlib_convert_tree_to_code(model_img, IPACK_TREE_CONVERT_REPLACE);
  1887. +#else
  1888. + model_img->tree_code = NULL;
  1889. +#endif
  1890. +#else
  1891. + model_img->tree_code = NULL;
  1892. +#endif
  1893. +
  1894. + jffs2_bbc_free(*model);
  1895. + *model = model_img;
  1896. + return retval;
  1897. +}
  1898. +
  1899. +/*******************************************************************************
  1900. +
  1901. + COMPRESSOR DEINIT FUNCTIONS
  1902. +
  1903. +*******************************************************************************/
  1904. +
  1905. +
  1906. +/* Descructor of compressor (model will be freed with jffs2_bbc_free() after it)*/
  1907. +static void ipack_armlib_compressor_deinit(void)
  1908. +{
  1909. +}
  1910. +
  1911. +/*******************************************************************************
  1912. +
  1913. + COMPRESS FUNCTIONS
  1914. +
  1915. +*******************************************************************************/
  1916. +
  1917. +static int writebits0(unsigned char **dest, u8 * freebits, u32 * opposite, unsigned char *end)
  1918. +{
  1919. + if (!(*freebits)) {
  1920. + ++(*dest);
  1921. + *freebits = 7;
  1922. + **dest = 0x00;
  1923. + }
  1924. + else {
  1925. + --(*freebits);
  1926. + (**dest) <<= 1;
  1927. + }
  1928. + if ((*dest == end) && !(*freebits)) {
  1929. + return EC_BUFFER_OVERFLOW;
  1930. + }
  1931. + while (*opposite) {
  1932. + --(*opposite);
  1933. + if (!(*freebits)) {
  1934. + ++(*dest);
  1935. + *freebits = 7;
  1936. + **dest = 0x01;
  1937. + }
  1938. + else {
  1939. + --(*freebits);
  1940. + (**dest) <<= 1;
  1941. + (**dest) |= 0x01;
  1942. + }
  1943. + if ((*dest == end) && !(*freebits)) {
  1944. + return EC_BUFFER_OVERFLOW;
  1945. + }
  1946. + }
  1947. + return 0;
  1948. +}
  1949. +
  1950. +static int writebits1(unsigned char **dest, u8 * freebits, u32 * opposite, unsigned char *end)
  1951. +{
  1952. + if (!(*freebits)) {
  1953. + ++(*dest);
  1954. + *freebits = 7;
  1955. + **dest = 0x01;
  1956. + }
  1957. + else {
  1958. + --(*freebits);
  1959. + (**dest) <<= 1;
  1960. + (**dest) |= 0x01;
  1961. + }
  1962. + if ((*dest == end) && !(*freebits)) {
  1963. + return EC_BUFFER_OVERFLOW;
  1964. + }
  1965. + while (*opposite) {
  1966. + --(*opposite);
  1967. + if (!(*freebits)) {
  1968. + ++(*dest);
  1969. + *freebits = 7;
  1970. + **dest = 0x00;
  1971. + }
  1972. + else {
  1973. + --(*freebits);
  1974. + (**dest) <<= 1;
  1975. + }
  1976. + if ((*dest == end) && !(*freebits)) {
  1977. + return EC_BUFFER_OVERFLOW;
  1978. + }
  1979. + }
  1980. + return 0;
  1981. +}
  1982. +
  1983. +
  1984. +
  1985. +
  1986. +/* Compress block
  1987. + * *dstlen bytes are allocated.
  1988. + * if it is not enough write *sourcelen over to the processed amount of data
  1989. + * returns non zero if fails
  1990. + */
  1991. +static int ipack_armlib_compress(void *model, unsigned char *input, unsigned char *output, unsigned long *sourcelen, unsigned long *dstlen)
  1992. +{
  1993. + register u32 coder_high = CODER_VALUEMAX - 1;
  1994. + register u32 coder_low = 0;
  1995. + u32 coder_opbits = 0;
  1996. + u8 bitvector_freebits = 8;
  1997. + unsigned char *bitvector_ptr = output;
  1998. + unsigned char *bitvector_end = output + (*dstlen - 1);
  1999. + ARM_DataType *tmpp;
  2000. + TokenStream tmpv;
  2001. + TokenType *it;
  2002. + void *end_it;
  2003. +
  2004. + ipack_nodetype *treeroot = ((ipack_model_type *) model)->tree_root_ptr;
  2005. + PredictorType *predctrs = ((ipack_model_type *) model)->predictors_ptr;
  2006. +
  2007. +#ifdef IPACK_TREE_TO_CODE
  2008. + void (*treefunc) (ipack_nodetype *, TokenType, ipack_probability_type *);
  2009. +
  2010. + treefunc = ((ipack_model_type *) model)->tree_code;
  2011. + if (treefunc != NULL)
  2012. + treefunc += 4;
  2013. +#endif
  2014. +
  2015. + if ((*sourcelen % 4) != 0) {
  2016. + return EC_WRONG_INPUT_LENGTH;
  2017. + }
  2018. + if (*dstlen <= 4) {
  2019. + return EC_BUFFER_OVERFLOW;
  2020. + }
  2021. +
  2022. + if (((ipack_model_type *) model)->ID[0] != 'i') {
  2023. + return EC_NOT_IPMF_MODEL;
  2024. + }
  2025. + else if (((ipack_model_type *) model)->ID[1] != 'P') {
  2026. + return EC_NOT_IPMF_MODEL;
  2027. + }
  2028. + else if (((ipack_model_type *) model)->ID[2] != 'M') {
  2029. + return EC_NOT_IPMF_MODEL;
  2030. + }
  2031. + else if (((ipack_model_type *) model)->ID[3] != 'F') {
  2032. + return EC_NOT_IPMF_MODEL;
  2033. + }
  2034. +#ifdef TXT_TOKENS
  2035. + tmpv.capacity = (*sourcelen);
  2036. +#else
  2037. + tmpv.capacity = (*sourcelen) << 1;
  2038. +#endif
  2039. + tmpv.size = tmpv.capacity;
  2040. + tmpv.ptr = jffs2_bbc_malloc(tmpv.size);
  2041. + it = tmpv.ptr;
  2042. +
  2043. +#ifndef __KERNEL__
  2044. + if (ipack_glb_endian_X) {
  2045. + for (tmpp = (void *) input; (u32) tmpp < (u32) (input + *sourcelen); ++tmpp) {
  2046. +#ifdef TXT_TOKENS
  2047. + *(it++) = (u8) ((*tmpp & 0xff000000) >> 24);
  2048. + *(it++) = (u8) ((*tmpp & 0x00ff0000) >> 16);
  2049. + *(it++) = (u8) ((*tmpp & 0x0000ff00) >> 8);
  2050. + *(it++) = (u8) ((*tmpp & 0x000000ff));
  2051. +#else
  2052. + *(it++) = (u8) ((*tmpp & 0x0000f000) >> 12);
  2053. + *(it++) = (u8) ((*tmpp & 0x0000000f));
  2054. + *(it++) = (u8) ((*tmpp & 0xf0000000) >> 28);
  2055. + *(it++) = (u8) ((*tmpp & 0x000f0000) >> 16);
  2056. + *(it++) = (u8) ((*tmpp & 0x00000f00) >> 8);
  2057. + *(it++) = (u8) ((*tmpp & 0x00f00000) >> 20);
  2058. + *(it++) = (u8) ((*tmpp & 0x0f000000) >> 24);
  2059. + *(it++) = (u8) ((*tmpp & 0x000000f0) >> 4);
  2060. +#endif //TXT_TOKENS
  2061. + }
  2062. + }
  2063. + else {
  2064. +#endif
  2065. + for (tmpp = (void *) input; (u32) tmpp < (u32) (input + *sourcelen); ++tmpp) {
  2066. +#ifdef TXT_TOKENS
  2067. + *(it++) = (u8) ((*tmpp & 0x000000ff));
  2068. + *(it++) = (u8) ((*tmpp & 0x0000ff00) >> 8);
  2069. + *(it++) = (u8) ((*tmpp & 0x00ff0000) >> 16);
  2070. + *(it++) = (u8) ((*tmpp & 0xff000000) >> 24);
  2071. +#else
  2072. + *(it++) = (u8) ((*tmpp & 0x00f00000) >> 20);
  2073. + *(it++) = (u8) ((*tmpp & 0x0f000000) >> 24);
  2074. + *(it++) = (u8) ((*tmpp & 0x000000f0) >> 4);
  2075. + *(it++) = (u8) ((*tmpp & 0x00000f00) >> 8);
  2076. + *(it++) = (u8) ((*tmpp & 0x000f0000) >> 16);
  2077. + *(it++) = (u8) ((*tmpp & 0x0000f000) >> 12);
  2078. + *(it++) = (u8) ((*tmpp & 0x0000000f));
  2079. + *(it++) = (u8) ((*tmpp & 0xf0000000) >> 28);
  2080. +#endif //TXT_TOKENS
  2081. + }
  2082. +#ifndef __KERNEL__
  2083. + }
  2084. +#endif
  2085. +/*
  2086. + ENCODE
  2087. +*/
  2088. + { //predictor reset
  2089. + register PredictorType *ptr = predctrs;
  2090. + register PredictorType *end = ptr + NUMBER_OF_PREDICTORS;
  2091. + while (ptr < end) {
  2092. + *(ptr++) = 0;
  2093. + }
  2094. + }
  2095. +
  2096. + //*(bitvector_ptr++) = 'H';
  2097. + //*(bitvector_ptr++) = 'G';
  2098. + *(bitvector_ptr++) = ((ipack_model_type *) model)->block_sign[0];
  2099. + *(bitvector_ptr++) = ((ipack_model_type *) model)->block_sign[1];
  2100. +
  2101. + *(bitvector_ptr++) = (unsigned char) (((*sourcelen) >> 8) & 0xff);
  2102. + *(bitvector_ptr++) = (unsigned char) ((*sourcelen) & 0xff);
  2103. + for (it = tmpv.ptr, end_it = VECTOR_S_END(tmpv); it != end_it; ++it) {
  2104. + ipack_probability_type prob;
  2105. + u32 range;
  2106. +
  2107. +#ifdef IPACK_TREE_TO_CODE
  2108. + if (treefunc != NULL)
  2109. + (*treefunc) (treeroot, *it, &prob);
  2110. + else
  2111. + ipack_model_get_probability_for_token(treeroot, *it, &prob);
  2112. +#else
  2113. + ipack_model_get_probability_for_token(treeroot, *it, &prob);
  2114. +#endif
  2115. +
  2116. + if (prob.high == prob.low) {
  2117. + vector_clear(&tmpv);
  2118. + return EC_CODER_WRONG_PROBABILITY;
  2119. + }
  2120. + range = coder_high - coder_low + 1;
  2121. + coder_high = coder_low + ((range * prob.high) >> PROBABILITY_SHIFT) - 1;
  2122. + coder_low += ((range * prob.low) >> PROBABILITY_SHIFT);
  2123. + for (;;) {
  2124. + if (coder_high < CODER_VALUEHLF) {
  2125. + if (writebits0(&bitvector_ptr, &bitvector_freebits, &coder_opbits, bitvector_end)) {
  2126. + vector_clear(&tmpv);
  2127. + return EC_BUFFER_OVERFLOW;
  2128. + }
  2129. + }
  2130. + else if (coder_low >= CODER_VALUEHLF) {
  2131. + if (writebits1(&bitvector_ptr, &bitvector_freebits, &coder_opbits, bitvector_end)) {
  2132. + vector_clear(&tmpv);
  2133. + return EC_BUFFER_OVERFLOW;
  2134. + }
  2135. + coder_high -= CODER_VALUEHLF;
  2136. + coder_low -= CODER_VALUEHLF;
  2137. + }
  2138. + else if ((CODER_VALUE1ST <= coder_low) && (coder_high < CODER_VALUE3RD)) {
  2139. + ++coder_opbits;
  2140. + coder_high -= CODER_VALUE1ST;
  2141. + coder_low -= CODER_VALUE1ST;
  2142. + }
  2143. + else {
  2144. + break;
  2145. + }
  2146. + coder_high <<= 1;
  2147. + ++coder_high;
  2148. + coder_low <<= 1;
  2149. + if (coder_high < coder_low) {
  2150. + vector_clear(&tmpv);
  2151. + return EC_CODER_WRONG_RANGE;
  2152. + }
  2153. + }
  2154. + {
  2155. +#ifdef TXT_TOKENS
  2156. +// register u32 ndx;
  2157. + predctrs[0] = *it;
  2158. + if ((('a' <= *it) && (*it <= 'z')) || (('A' <= *it) && (*it <= 'Z'))) {
  2159. + ++(predctrs[1]);
  2160. + }
  2161. + else {
  2162. + predctrs[1] = 0;
  2163. + }
  2164. +#else
  2165. + register u32 ndx = predctrs[0] + 1;
  2166. + predctrs[ndx + 8] = predctrs[ndx];
  2167. + predctrs[ndx] = *it;
  2168. + if (ndx == 8) {
  2169. + predctrs[0] = 0;
  2170. + }
  2171. + else {
  2172. + ++predctrs[0];
  2173. + }
  2174. +#endif
  2175. + }
  2176. +
  2177. + }
  2178. + vector_clear(&tmpv);
  2179. + ++coder_opbits;
  2180. + if (coder_low < CODER_VALUE1ST) {
  2181. + if (writebits0(&bitvector_ptr, &bitvector_freebits, &coder_opbits, bitvector_end)) {
  2182. + return EC_BUFFER_OVERFLOW;
  2183. + }
  2184. + }
  2185. + else {
  2186. + if (writebits1(&bitvector_ptr, &bitvector_freebits, &coder_opbits, bitvector_end)) {
  2187. + return EC_BUFFER_OVERFLOW;
  2188. + }
  2189. + }
  2190. + (*(bitvector_ptr)) <<= bitvector_freebits;
  2191. + *dstlen = ((u32) bitvector_ptr - (u32) output + 1);
  2192. + return EC_NO_ERROR;
  2193. +}
  2194. +
  2195. +/*******************************************************************************
  2196. +
  2197. + DECOMPRESS FUNCTIONS
  2198. +
  2199. +*******************************************************************************/
  2200. +
  2201. +typedef struct
  2202. +{
  2203. + u32 high;
  2204. + u32 low;
  2205. + u32 value;
  2206. + u32 overread;
  2207. +} ipack_decompressor_values;
  2208. +
  2209. +typedef struct
  2210. +{
  2211. + u8 freebits;
  2212. + unsigned char *ptr;
  2213. + unsigned char *end;
  2214. +} ipack_decompressor_bitvector;
  2215. +
  2216. +static u8 ipack_bitvector_R_get1(ipack_decompressor_bitvector * bv)
  2217. +{
  2218. + u8 tmp;
  2219. + if (bv->ptr == bv->end) {
  2220. + bv->freebits = 0;
  2221. + return 0;
  2222. + }
  2223. + tmp = (*(bv->ptr) >> bv->freebits) & 0x01;
  2224. + if (!(bv->freebits)) {
  2225. + bv->freebits = 7;
  2226. + ++(bv->ptr);
  2227. + }
  2228. + else {
  2229. + --(bv->freebits);
  2230. + }
  2231. + return tmp;
  2232. +}
  2233. +
  2234. +/* Decompress block
  2235. + * returns non zero if fails
  2236. + */
  2237. +static int ipack_armlib_decompress(void *model, unsigned char *input, unsigned char *output, unsigned long sourcelen, unsigned long dstlen)
  2238. +{
  2239. + ARM_DataType *data;
  2240. + register u32 coder_high = CODER_VALUEMAX - 1;
  2241. + register u32 coder_low = 0;
  2242. + register u32 coder_value = 0;
  2243. + u32 coder_overread = 0;
  2244. + ipack_decompressor_bitvector bitvector;
  2245. + u32 lngth;
  2246. + u32 i;
  2247. + u32 cntbytes;
  2248. + TokenType tkns[8];
  2249. + TokenType *tptr;
  2250. +
  2251. + ipack_nodetype *treeroot = ((ipack_model_type *) model)->tree_root_ptr;
  2252. + PredictorType *predctrs = ((ipack_model_type *) model)->predictors_ptr;
  2253. +
  2254. +#ifdef IPACK_TREE_TO_CODE
  2255. + TokenType(*treefunc) (ipack_nodetype *, u32, u32, ipack_probability_type *);
  2256. +
  2257. + treefunc = ((ipack_model_type *) model)->tree_code;
  2258. +#endif
  2259. +
  2260. +
  2261. + if (((ipack_model_type *) model)->ID[0] != 'i') {
  2262. + return EC_NOT_IPMF_MODEL;
  2263. + }
  2264. + else if (((ipack_model_type *) model)->ID[1] != 'P') {
  2265. + return EC_NOT_IPMF_MODEL;
  2266. + }
  2267. + else if (((ipack_model_type *) model)->ID[2] != 'M') {
  2268. + return EC_NOT_IPMF_MODEL;
  2269. + }
  2270. + else if (((ipack_model_type *) model)->ID[3] != 'F') {
  2271. + return EC_NOT_IPMF_MODEL;
  2272. + }
  2273. +
  2274. + bitvector.freebits = 7;
  2275. + bitvector.ptr = input;
  2276. + bitvector.end = input + sourcelen;
  2277. +
  2278. + /*if(*(bitvector.ptr++) != 'H') {
  2279. + return EC_NOT_HG_BLOCK;
  2280. + } else if(*(bitvector.ptr++) != 'G') {
  2281. + return EC_NOT_HG_BLOCK;
  2282. + } */
  2283. + bitvector.ptr++;
  2284. + bitvector.ptr++;
  2285. +
  2286. + data = (void *) output;
  2287. + cntbytes = *(bitvector.ptr++);
  2288. + cntbytes <<= 8;
  2289. + cntbytes += *(bitvector.ptr++);
  2290. +
  2291. + { //predictor reset
  2292. + register PredictorType *ptr = predctrs;
  2293. + register PredictorType *end = ptr + NUMBER_OF_PREDICTORS;
  2294. + while (ptr < end) {
  2295. + *(ptr++) = 0;
  2296. + }
  2297. + }
  2298. + for (i = 0; i < CODER_VALUEBITS; ++i) {
  2299. + coder_value <<= 1;
  2300. + coder_value += ipack_bitvector_R_get1(&bitvector);
  2301. + }
  2302. + lngth = dstlen >> 2;
  2303. + if (lngth > (cntbytes >> 2)) {
  2304. + lngth = cntbytes >> 2;
  2305. + }
  2306. + for (i = 0; (i < lngth); ++i) {
  2307. + TokenType itoken;
  2308. + u32 j;
  2309. + tptr = tkns;
  2310. + for (j = 0; j < NUMBER_OF_TOKENS_PER_INSTRUCTION; ++j) {
  2311. + ipack_probability_type prob;
  2312. + u32 range = coder_high - coder_low + 1;
  2313. +
  2314. +#ifdef IPACK_TREE_TO_CODE
  2315. + if (treefunc != NULL)
  2316. + itoken = (*treefunc) (treeroot, coder_value - coder_low + 1, range, &prob);
  2317. + else
  2318. +#endif
  2319. + itoken = ipack_model_get_token_for_range(treeroot, coder_value - coder_low + 1, range, &prob);
  2320. +
  2321. +
  2322. + if (prob.high == prob.low) {
  2323. + return EC_CODER_WRONG_PROBABILITY;
  2324. + }
  2325. + coder_high = coder_low + ((range * prob.high) >> PROBABILITY_SHIFT) - 1;
  2326. + coder_low += ((range * prob.low) >> PROBABILITY_SHIFT);
  2327. + for (;;) {
  2328. + if (coder_high < CODER_VALUEHLF) {
  2329. + }
  2330. + else if (CODER_VALUEHLF <= coder_low) {
  2331. + coder_value -= CODER_VALUEHLF;
  2332. + coder_high -= CODER_VALUEHLF;
  2333. + coder_low -= CODER_VALUEHLF;
  2334. + }
  2335. + else if ((CODER_VALUE1ST <= coder_low) && (coder_high < CODER_VALUE3RD)) {
  2336. + coder_value -= CODER_VALUE1ST;
  2337. + coder_high -= CODER_VALUE1ST;
  2338. + coder_low -= CODER_VALUE1ST;
  2339. + }
  2340. + else {
  2341. + break;
  2342. + }
  2343. + coder_low <<= 1;
  2344. + coder_high <<= 1;
  2345. + ++(coder_high);
  2346. + coder_value <<= 1;
  2347. + if (bitvector.ptr == bitvector.end) {
  2348. + bitvector.freebits = 0;
  2349. + }
  2350. + coder_value += ((*(bitvector.ptr) >> bitvector.freebits) & 0x01);
  2351. + if (bitvector.freebits) {
  2352. + --bitvector.freebits;
  2353. + }
  2354. + else {
  2355. + bitvector.freebits = 7;
  2356. + ++bitvector.ptr;
  2357. + }
  2358. + if (coder_high < coder_low) {
  2359. + return EC_CODER_WRONG_RANGE;
  2360. + }
  2361. + if ((bitvector.ptr == bitvector.end) && !(bitvector.freebits)) {
  2362. + if ((coder_overread++) > CODER_VALUEBITS) {
  2363. + return EC_BUFFER_UNDERFLOW;
  2364. + }
  2365. + }
  2366. + }
  2367. + {
  2368. +#ifdef TXT_TOKENS
  2369. +// register u32 ndx;
  2370. + predctrs[0] = itoken;
  2371. + if ((('a' <= itoken) && (itoken <= 'z')) || (('A' <= itoken) && (itoken <= 'Z'))) {
  2372. + ++(predctrs[1]);
  2373. + }
  2374. + else {
  2375. + predctrs[1] = 0;
  2376. + }
  2377. +
  2378. +#else
  2379. + register u32 ndx = predctrs[0] + 1;
  2380. + predctrs[ndx + 8] = predctrs[ndx];
  2381. + predctrs[ndx] = itoken;
  2382. + if (ndx == 8) {
  2383. + predctrs[0] = 0;
  2384. + }
  2385. + else {
  2386. + ++predctrs[0];
  2387. + }
  2388. +#endif
  2389. + }
  2390. +
  2391. + (*(tptr++)) = itoken;
  2392. + }
  2393. + tptr = tkns;
  2394. +#ifndef __KERNEL__
  2395. + if (ipack_glb_endian_X) {
  2396. +#ifdef TXT_TOKENS
  2397. + (*data) = ((*tptr) << 24);
  2398. + ++tptr;
  2399. + (*data) |= ((*tptr) << 16);
  2400. + ++tptr;
  2401. + (*data) |= ((*tptr) << 8);
  2402. + ++tptr;
  2403. + (*data) |= (*tptr);
  2404. + ++data;
  2405. +#else
  2406. + (*data) = (((*tptr) & 0xf) << 12);
  2407. + ++tptr;
  2408. + (*data) |= ((*tptr) & 0xf);
  2409. + ++tptr;
  2410. + (*data) |= (((*tptr) & 0xf) << 28);
  2411. + ++tptr;
  2412. + (*data) |= (((*tptr) & 0xf) << 16);
  2413. + ++tptr;
  2414. + (*data) |= (((*tptr) & 0xf) << 8);
  2415. + ++tptr;
  2416. + (*data) |= (((*tptr) & 0xf) << 20);
  2417. + ++tptr;
  2418. + (*data) |= (((*tptr) & 0xf) << 24);
  2419. + ++tptr;
  2420. + (*data) |= (((*tptr) & 0xf) << 4);
  2421. + ++data;
  2422. +#endif
  2423. + }
  2424. + else {
  2425. +#endif
  2426. +#ifdef TXT_TOKENS
  2427. + (*data) = (*tptr);
  2428. + ++tptr;
  2429. + (*data) |= ((*tptr) << 8);
  2430. + ++tptr;
  2431. + (*data) |= ((*tptr) << 16);
  2432. + ++tptr;
  2433. + (*data) |= ((*tptr) << 24);
  2434. + ++data;
  2435. +#else
  2436. + (*data) = (((*tptr) & 0xf) << 20);
  2437. + ++tptr;
  2438. + (*data) |= (((*tptr) & 0xf) << 24);
  2439. + ++tptr;
  2440. + (*data) |= (((*tptr) & 0xf) << 4);
  2441. + ++tptr;
  2442. + (*data) |= (((*tptr) & 0xf) << 8);
  2443. + ++tptr;
  2444. + (*data) |= (((*tptr) & 0xf) << 16);
  2445. + ++tptr;
  2446. + (*data) |= (((*tptr) & 0xf) << 12);
  2447. + ++tptr;
  2448. + (*data) |= ((*tptr) & 0xf);
  2449. + ++tptr;
  2450. + (*data) |= (((*tptr) & 0xf) << 28);
  2451. + ++data;
  2452. +#endif
  2453. +#ifndef __KERNEL__
  2454. + }
  2455. +#endif
  2456. + }
  2457. + return EC_NO_ERROR;
  2458. +}
  2459. +
  2460. +static int ipack_armlib_estimate(void *model, unsigned char *input, unsigned long sourcelen, unsigned long *dstlen, unsigned long *readtime, unsigned long *writetime)
  2461. +{
  2462. + int i, tmp, tmp2, max, maxi;
  2463. + int cnt_cond[] = { 0, 0, 0, 0 };
  2464. + int cnt_inst[] = { 0, 0, 0, 0 };
  2465. +
  2466. + // TODO: make a more precise estimation!!!
  2467. + *readtime = JFFS2_BBC_ZLIB_READ_TIME * 6;
  2468. + *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 2;
  2469. +
  2470. + if (sourcelen % 4 != 0) {
  2471. + *dstlen = sourcelen;
  2472. + return 0;
  2473. + }
  2474. + for (i = 0; i < sourcelen; i++, input++) {
  2475. + tmp2 = tmp = *input;
  2476. + tmp = ((tmp) & 0xf0) >> 4;
  2477. + tmp2 = tmp2 & 0xf;
  2478. + if (tmp == 14)
  2479. + cnt_cond[i % 4]++;
  2480. + if ((tmp2 == 2) || (tmp2 == 3))
  2481. + cnt_inst[i % 4]++;
  2482. + }
  2483. + maxi = -1;
  2484. + max = -1;
  2485. + for (i = 0; i < 4; i++)
  2486. + if (max < cnt_cond[i]) {
  2487. + max = cnt_cond[i];
  2488. + maxi = i;
  2489. + }
  2490. + /*jffs2_bbc_print("armlib_EST: %d/%d : %d/%d %d/%d %d/%d %d/%d",
  2491. + cnt_cond[maxi],cnt_inst[maxi],
  2492. + cnt_cond[0],cnt_inst[0],
  2493. + cnt_cond[1],cnt_inst[1],
  2494. + cnt_cond[2],cnt_inst[2],
  2495. + cnt_cond[3],cnt_inst[3]); */
  2496. +
  2497. + if (cnt_cond[maxi] < (sourcelen >> 4)) {
  2498. + *dstlen = sourcelen;
  2499. + }
  2500. + else {
  2501. + *dstlen = sourcelen / 3;
  2502. + }
  2503. +
  2504. + return 0;
  2505. +}
  2506. +
  2507. +static char *ipack_armlib_proc_info(void);
  2508. +static int ipack_armlib_proc_command(char *command);
  2509. +static void ipack_armlib_destroy_model(void **model);
  2510. +
  2511. +struct jffs2_bbc_compressor_type jffs2_bbc_armlib = {
  2512. + "armlib",
  2513. + 0x464d5069,
  2514. + {0, 0, 0, 0},
  2515. + NULL, // init
  2516. + ipack_armlib_compressor_init, // init_model
  2517. + ipack_armlib_destroy_model, // destroy_model
  2518. + ipack_armlib_compressor_deinit, // deinit
  2519. + ipack_armlib_compress,
  2520. + ipack_armlib_estimate,
  2521. + ipack_armlib_decompress,
  2522. + ipack_armlib_proc_info,
  2523. + ipack_armlib_proc_command
  2524. +};
  2525. +
  2526. +
  2527. +static char *ipack_armlib_proc_info()
  2528. +{
  2529. +#ifdef IPACK_TREE_TO_CODE
  2530. +#ifdef IPACK_AUTO_TREE_TO_CODE
  2531. + return "automatic tree to code conversion";
  2532. +#else
  2533. + return "manual tree to code conversion possibility";
  2534. +#endif
  2535. +#else
  2536. + return "tree in memory version";
  2537. +#endif
  2538. +}
  2539. +
  2540. +static int ipack_armlib_proc_command(char *command)
  2541. +{
  2542. + struct jffs2_bbc_model_list_node *model;
  2543. + ipack_model_type *armlib_model;
  2544. +
  2545. + if ((*command == 'g') || (*command == 'G')) {
  2546. + jffs2_bbc_print1("Converting tree(s) to ARM code... (keeping original)\n");
  2547. + model = jffs2_bbc_armlib.models;
  2548. + if (model == NULL)
  2549. + jffs2_bbc_print1("no model found!\n");
  2550. + while (model != NULL) {
  2551. + armlib_model = model->model;
  2552. + if (armlib_model == NULL) {
  2553. + jffs2_bbc_print1("Error: NULL model!\n");
  2554. + }
  2555. + else {
  2556. + ipack_armlib_convert_tree_to_code(armlib_model, IPACK_TREE_CONVERT_KEEP);
  2557. + }
  2558. + model = model->next_compr_model;
  2559. + }
  2560. + }
  2561. + else if ((*command == 'r') || (*command == 'R')) {
  2562. + jffs2_bbc_print1("Converting tree(s) to ARM code... (deleting original)\n");
  2563. + model = jffs2_bbc_armlib.models;
  2564. + if (model == NULL)
  2565. + jffs2_bbc_print1("no model found!\n");
  2566. + while (model != NULL) {
  2567. + armlib_model = model->model;
  2568. + if (armlib_model == NULL) {
  2569. + jffs2_bbc_print1("Error: NULL model!\n");
  2570. + }
  2571. + else {
  2572. + //armlib_model->tree_code = ipack_tree_to_code(armlib_model, &tree_size);
  2573. + //jffs2_bbc_print("Convertation done. Code size=%d\n",tree_size);
  2574. + ipack_armlib_convert_tree_to_code(armlib_model, IPACK_TREE_CONVERT_REPLACE);
  2575. + }
  2576. + model = model->next_compr_model;
  2577. + }
  2578. + }
  2579. + else if ((*command == 'c') || (*command == 'C')) {
  2580. + jffs2_bbc_print1("Deleting ARM representation of the tree(s)...\n");
  2581. + model = jffs2_bbc_armlib.models;
  2582. + if (model == NULL)
  2583. + jffs2_bbc_print1("no model found!\n");
  2584. + while (model != NULL) {
  2585. + armlib_model = model->model;
  2586. + if (armlib_model == NULL) {
  2587. + jffs2_bbc_print1("Error: NULL model!\n");
  2588. + }
  2589. + else {
  2590. + if (armlib_model->tree_code == NULL) {
  2591. + jffs2_bbc_print1("already deleted.\n");
  2592. + }
  2593. + else {
  2594. + if (armlib_model->tree_root_ptr == NULL) {
  2595. + jffs2_bbc_print1("cannot delete this ARM tree - original tree has deleted\n");
  2596. + }
  2597. + else {
  2598. + jffs2_bbc_print1("deleting...");
  2599. + jffs2_bbc_free(armlib_model->tree_code);
  2600. + armlib_model->tree_code = NULL;
  2601. + jffs2_bbc_print1("done.\n");
  2602. + }
  2603. + }
  2604. + }
  2605. + model = model->next_compr_model;
  2606. + }
  2607. + }
  2608. + else if (*command == '?') {
  2609. + jffs2_bbc_print1("ARMLIB commands:\n");
  2610. + jffs2_bbc_print1(" g: convert TREEs to ARM code and keep the original\n");
  2611. + jffs2_bbc_print1(" r: convert TREEs to ARM code and remove the original\n");
  2612. + jffs2_bbc_print1(" c: delete the original TREEs - if there is any\n");
  2613. + }
  2614. + else {
  2615. + jffs2_bbc_print1("Unknown command.\n");
  2616. + }
  2617. + return 0;
  2618. +}
  2619. +
  2620. +static void ipack_armlib_destroy_model(void **model)
  2621. +{
  2622. + ipack_model_type *model_img;
  2623. +
  2624. + model_img = *model;
  2625. + if (model_img == NULL) {
  2626. + jffs2_bbc_print1("jffs2.bbc: armlib: NULL model at destoying model!\n");
  2627. + return;
  2628. + }
  2629. + if (model_img->tree_code != NULL) {
  2630. + //jffs2_bbc_print1("jffs2.bbc: armlib: debug: freeing code...\n");
  2631. + jffs2_bbc_free(model_img->tree_code);
  2632. + model_img->tree_code = NULL;
  2633. + }
  2634. + if (model_img->tree_root_ptr != NULL) {
  2635. + //jffs2_bbc_print1("jffs2.bbc: armlib: debug: freeing tree...\n");
  2636. + jffs2_bbc_free(model_img->tree_root_ptr);
  2637. + model_img->tree_root_ptr = NULL;
  2638. + }
  2639. +
  2640. + jffs2_bbc_free(model_img);
  2641. + *model = NULL;
  2642. +}
  2643. +
  2644. +struct jffs2_bbc_compressor_type *jffs2_bbc_armlib_init(int mode)
  2645. +{
  2646. + if (jffs2_bbc_register_compressor(&jffs2_bbc_armlib) == 0)
  2647. + return &jffs2_bbc_armlib;
  2648. + else
  2649. + return NULL;
  2650. +}
  2651. +
  2652. +void jffs2_bbc_armlib_deinit(void)
  2653. +{
  2654. + jffs2_bbc_unregister_compressor(&jffs2_bbc_armlib);
  2655. +}
  2656. +
  2657. +/*END OF ARMLIB*/
  2658. --- /dev/null
  2659. +++ b/fs/jffs2/jffs2_bbc_framework.c
  2660. @@ -0,0 +1,1324 @@
  2661. +/*
  2662. + * JFFS2-BBC: Compression Framework
  2663. + *
  2664. + * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  2665. + *
  2666. + * Copyright (C) 2004, Ferenc Havasi
  2667. + *
  2668. + * This program is free software; you can redistribute it and/or
  2669. + * modify it under the terms of the GNU General Public License
  2670. + * as published by the Free Software Foundation; either version 2
  2671. + * of the License, or (at your option) any later version.
  2672. + *
  2673. + * This program is distributed in the hope that it will be useful,
  2674. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2675. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2676. + * GNU General Public License for more details.
  2677. + *
  2678. + * You should have received a copy of the GNU General Public License
  2679. + * along with this program; if not, write to the Free Software
  2680. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  2681. + *
  2682. + */
  2683. +
  2684. +/* USE JFFS2_BBC_STANDALONE define if you don't want to compile without JFFS2 */
  2685. +
  2686. +//#define DEBUG_COMPRESSORS
  2687. +//#define DEBUG_SHOW_BLOCK_SIZES
  2688. +
  2689. +#define JFFS2_BBC_STAT_BUFF_SIZE 8000
  2690. +
  2691. +#ifndef __KERNEL__
  2692. +
  2693. +#include <stdio.h>
  2694. +#include <malloc.h>
  2695. +typedef unsigned long uint32_t;
  2696. +
  2697. +#else
  2698. +
  2699. +#include <linux/kernel.h>
  2700. +#include <linux/slab.h>
  2701. +#include <linux/vmalloc.h>
  2702. +
  2703. +#endif
  2704. +
  2705. +#define JFFS2_BBC_ZLIB_BLOCK_SIGN_0 (120)
  2706. +#define JFFS2_BBC_ZLIB_BLOCK_SIGN_1 (94)
  2707. +
  2708. +#define JFFS2_BBC_DUMMY_BLOCKSIGN_0 (0x54)
  2709. +#define JFFS2_BBC_DUMMY_BLOCKSIGN_1 (0x01)
  2710. +
  2711. +#ifndef NULL
  2712. +#define NULL ((void*)(0))
  2713. +#endif
  2714. +
  2715. +#include "jffs2_bbc_framework.h"
  2716. +
  2717. +/*********************************************************************
  2718. + * Global data *
  2719. + *********************************************************************/
  2720. +
  2721. +static int jffs2_bbc_compression_mode = JFFS2_BBC_ZLIB_MODE;
  2722. +static struct jffs2_bbc_compressor_type *jffs2_bbc_manual_compressor = NULL;
  2723. +static struct jffs2_bbc_compressor_type *jffs2_bbc_compressors = NULL;
  2724. +static struct jffs2_bbc_model_list_node *jffs2_bbc_model_list = NULL;
  2725. +static void *last_sb = NULL; /* previously activated sb */
  2726. +
  2727. +/*********************************************************************
  2728. + * Compressor initialization *
  2729. + *********************************************************************/
  2730. +
  2731. +#ifndef JFFS2_BBC_STANDALONE
  2732. +
  2733. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_ARMLIB)
  2734. +struct jffs2_bbc_compressor_type *jffs2_bbc_armlib_init(void);
  2735. +void jffs2_bbc_armlib_deinit(void);
  2736. +#endif
  2737. +
  2738. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZO)
  2739. +struct jffs2_bbc_compressor_type *jffs2_bbc_lzo_init(void);
  2740. +void jffs2_bbc_lzo_deinit(void);
  2741. +#endif
  2742. +
  2743. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZSS)
  2744. +struct jffs2_bbc_compressor_type *jffs2_bbc_lzss_init(void);
  2745. +void jffs2_bbc_lzss_deinit(void);
  2746. +#endif
  2747. +
  2748. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZARI)
  2749. +struct jffs2_bbc_compressor_type *jffs2_bbc_lzari_init(void);
  2750. +void jffs2_bbc_lzari_deinit(void);
  2751. +#endif
  2752. +
  2753. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZHD)
  2754. +struct jffs2_bbc_compressor_type *jffs2_bbc_lzhd_init(void);
  2755. +void jffs2_bbc_lzhd_deinit(void);
  2756. +#endif
  2757. +
  2758. +void jffs2_bbc_compressor_init()
  2759. +{
  2760. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_ARMLIB)
  2761. + jffs2_bbc_armlib_init();
  2762. +#endif
  2763. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZO)
  2764. + jffs2_bbc_lzo_init();
  2765. +#endif
  2766. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZSS)
  2767. + jffs2_bbc_lzss_init();
  2768. +#endif
  2769. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZARI)
  2770. + jffs2_bbc_lzari_init();
  2771. +#endif
  2772. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZHD)
  2773. + jffs2_bbc_lzhd_init();
  2774. +#endif
  2775. +}
  2776. +
  2777. +void jffs2_bbc_compressor_deinit()
  2778. +{
  2779. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZHD)
  2780. + jffs2_bbc_lzhd_deinit();
  2781. +#endif
  2782. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZARI)
  2783. + jffs2_bbc_lzari_deinit();
  2784. +#endif
  2785. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZSS)
  2786. + jffs2_bbc_lzss_deinit();
  2787. +#endif
  2788. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZO)
  2789. + jffs2_bbc_lzo_deinit();
  2790. +#endif
  2791. +#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_ARMLIB)
  2792. + jffs2_bbc_armlib_deinit();
  2793. +#endif
  2794. +}
  2795. +
  2796. +#endif
  2797. +
  2798. +#ifndef JFFS2_BBC_STANDALONE
  2799. +
  2800. +/*********************************************************************
  2801. + * ZLIB COMPRESSOR *
  2802. + *********************************************************************/
  2803. +
  2804. +extern int jffs2_zlib_compress2(unsigned char *data_in, unsigned char *cpage_out, uint32_t * sourcelen, uint32_t * dstlen);
  2805. +extern void jffs2_zlib_decompress2(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
  2806. +
  2807. +static int jffs2_bbc_zlib_compress(void *model, unsigned char *input, unsigned char *output, unsigned long *sourcelen, unsigned long *dstlen)
  2808. +{
  2809. + return jffs2_zlib_compress2(input, output, sourcelen, dstlen);
  2810. +}
  2811. +
  2812. +static int jffs2_bbc_zlib_decompress(void *model, unsigned char *input, unsigned char *output, unsigned long sourcelen, unsigned long dstlen)
  2813. +{
  2814. + jffs2_zlib_decompress2(input, output, sourcelen, dstlen);
  2815. + return 0;
  2816. +}
  2817. +
  2818. +static int jffs2_bbc_zlib_estimate(void *model, unsigned char *input, unsigned long sourcelen, unsigned long *dstlen, unsigned long *readtime, unsigned long *writetime)
  2819. +{
  2820. + *dstlen = sourcelen * 65 / 100;
  2821. + *readtime = JFFS2_BBC_ZLIB_READ_TIME;
  2822. + *writetime = JFFS2_BBC_ZLIB_WRITE_TIME;
  2823. + return 0;
  2824. +}
  2825. +
  2826. +static struct jffs2_bbc_compressor_type jffs2_bbc_zlib = {
  2827. + "zlib",
  2828. + 0,
  2829. + {JFFS2_BBC_ZLIB_BLOCK_SIGN_0, JFFS2_BBC_ZLIB_BLOCK_SIGN_1, 0, 0},
  2830. + NULL,
  2831. + NULL,
  2832. + NULL,
  2833. + NULL,
  2834. + jffs2_bbc_zlib_compress,
  2835. + jffs2_bbc_zlib_estimate,
  2836. + jffs2_bbc_zlib_decompress,
  2837. + NULL,
  2838. + NULL,
  2839. + 1
  2840. +};
  2841. +
  2842. +static struct jffs2_bbc_compressor_type *jffs2_bbc_original_compressor = &jffs2_bbc_zlib;
  2843. +
  2844. +#endif
  2845. +
  2846. +/*********************************************************************
  2847. + * Compression mode handling *
  2848. + *********************************************************************/
  2849. +
  2850. +int jffs2_bbc_get_compression_mode(void)
  2851. +{
  2852. + return jffs2_bbc_compression_mode;
  2853. +}
  2854. +
  2855. +void jffs2_bbc_set_compression_mode(int mode)
  2856. +{
  2857. + jffs2_bbc_compression_mode = mode;
  2858. +}
  2859. +
  2860. +void jffs2_bbc_set_manual_compressor(struct jffs2_bbc_compressor_type *c)
  2861. +{
  2862. + jffs2_bbc_manual_compressor = c;
  2863. + jffs2_bbc_set_compression_mode(JFFS2_BBC_MANUAL_MODE);
  2864. +}
  2865. +
  2866. +int jffs2_bbc_set_manual_compressor_by_name(char *name)
  2867. +{
  2868. + struct jffs2_bbc_compressor_type *l;
  2869. + int i;
  2870. +
  2871. + l = jffs2_bbc_compressors;
  2872. + while (l != NULL) {
  2873. + for (i = 0; i < 1000; i++) {
  2874. + if (l->name[i] == 0) {
  2875. + jffs2_bbc_set_manual_compressor(l);
  2876. + return 0;
  2877. + }
  2878. + else if (name[i] == 0)
  2879. + i = 1000;
  2880. + else if (name[i] != l->name[i])
  2881. + i = 1000;
  2882. + }
  2883. + l = l->next;
  2884. + }
  2885. + jffs2_bbc_set_manual_compressor(NULL);
  2886. + return 1;
  2887. +}
  2888. +
  2889. +static struct jffs2_bbc_compressor_type *jffs2_bbc_get_compressor_by_name(char *name)
  2890. +{
  2891. + struct jffs2_bbc_compressor_type *l;
  2892. + int i;
  2893. +
  2894. +#ifndef JFFS2_BBC_STANDALONE
  2895. + l = jffs2_bbc_original_compressor;
  2896. + for (i = 0; i < 1000; i++) {
  2897. + if (l->name[i] == 0) {
  2898. + return l;
  2899. + }
  2900. + else if (name[i] == 0)
  2901. + i = 1000;
  2902. + else if (name[i] != l->name[i])
  2903. + i = 1000;
  2904. + }
  2905. +#endif
  2906. +
  2907. + l = jffs2_bbc_compressors;
  2908. + while (l != NULL) {
  2909. + for (i = 0; i < 1000; i++) {
  2910. + if (l->name[i] == 0) {
  2911. + return l;
  2912. + }
  2913. + else if (name[i] == 0)
  2914. + i = 1000;
  2915. + else if (name[i] != l->name[i])
  2916. + i = 1000;
  2917. + }
  2918. + l = l->next;
  2919. + }
  2920. +
  2921. + return NULL;
  2922. +}
  2923. +
  2924. +int jffs2_bbc_disable_compressor_by_name(char *name)
  2925. +{
  2926. + struct jffs2_bbc_compressor_type *l;
  2927. +
  2928. + l = jffs2_bbc_get_compressor_by_name(name);
  2929. + if (l == NULL) return 1;
  2930. + l->enabled = 0;
  2931. + return 0;
  2932. +}
  2933. +
  2934. +int jffs2_bbc_enable_compressor_by_name(char *name)
  2935. +{
  2936. + struct jffs2_bbc_compressor_type *l;
  2937. +
  2938. + l = jffs2_bbc_get_compressor_by_name(name);
  2939. + if (l == NULL) return 1;
  2940. + l->enabled = 1;
  2941. + return 0;
  2942. +}
  2943. +
  2944. +void jffs2_bbc_compressor_command_by_name(char *name_and_command)
  2945. +{
  2946. + struct jffs2_bbc_compressor_type *l;
  2947. + int i;
  2948. +
  2949. + l = jffs2_bbc_compressors;
  2950. + while (l != NULL) {
  2951. + for (i = 0; i < 1000; i++) {
  2952. + if (l->name[i] == 0) {
  2953. + if (name_and_command[i] != ':') {
  2954. + jffs2_bbc_print1("jffs2.bbc: ':' missing after compressor name\n");
  2955. + }
  2956. + else {
  2957. + if (l->proc_command != NULL)
  2958. + l->proc_command(name_and_command + i + 1);
  2959. + }
  2960. + i = 1000;
  2961. + return;
  2962. + }
  2963. + else if (name_and_command[i] == 0) {
  2964. + i = 1000;
  2965. + }
  2966. + else if (name_and_command[i] != l->name[i]) {
  2967. + i = 1000;
  2968. + }
  2969. + }
  2970. + l = l->next;
  2971. + }
  2972. +}
  2973. +
  2974. +struct jffs2_bbc_compressor_type *jffs2_bbc_get_manual_compressor(void)
  2975. +{
  2976. + if (jffs2_bbc_get_compression_mode() != JFFS2_BBC_MANUAL_MODE) {
  2977. + jffs2_bbc_manual_compressor = NULL;
  2978. + }
  2979. + return jffs2_bbc_manual_compressor;
  2980. +}
  2981. +
  2982. +/*********************************************************************
  2983. + * Compressor handling *
  2984. + *********************************************************************/
  2985. +
  2986. +struct jffs2_bbc_compressor_type *jffs2_bbc_get_compressor_list(void)
  2987. +{
  2988. + return jffs2_bbc_compressors;
  2989. +}
  2990. +
  2991. +struct jffs2_bbc_model_list_node *jffs2_bbc_get_model_list(void)
  2992. +{
  2993. + return jffs2_bbc_model_list;
  2994. +}
  2995. +
  2996. +int jffs2_bbc_register_compressor(struct jffs2_bbc_compressor_type *c)
  2997. +{
  2998. + struct jffs2_bbc_compressor_type *l;
  2999. + struct jffs2_bbc_model_list_node *l2;
  3000. + int model_found = 0;
  3001. +
  3002. + l = jffs2_bbc_compressors;
  3003. + /* Check for confilcts */
  3004. + while (l != NULL) {
  3005. + c->name[15] = 0;
  3006. + /*if (strcmp(c->name,l->name)==0) {
  3007. + jffs2_bbc_print1("jffs2.bbc: compressor is already loaded.");
  3008. + return -1;
  3009. + } */
  3010. + if ((l->model_file_sign == c->model_file_sign) && (c->model_file_sign != 0)) {
  3011. + jffs2_bbc_print1("jffs2.bbc: already used model file sign. fail.");
  3012. + return -1;
  3013. + }
  3014. + l = l->next;
  3015. + }
  3016. + /* Search and initialize model */
  3017. + c->models = NULL;
  3018. + c->mounted = 0;
  3019. + if (c->init != NULL) {
  3020. + if (c->init() != 0) {
  3021. + jffs2_bbc_print2("jffs2.bbc: cannot initialize compressor %s.\n", c->name);
  3022. + return -1;
  3023. + }
  3024. + }
  3025. + if (c->model_file_sign != 0) {
  3026. + l2 = jffs2_bbc_model_list;
  3027. + while (1) {
  3028. + if (l2 == NULL)
  3029. + break;
  3030. + if (c->model_file_sign == l2->sign) {
  3031. + if (l2->compressor != NULL) {
  3032. + jffs2_bbc_print2("jffs2.bbc: register for %s: BUG, model file already reserved!!!!\n", c->name);
  3033. + }
  3034. + else {
  3035. + if (c->init_model(&(l2->model)) != 0) {
  3036. + jffs2_bbc_print2("jffs2.bbc: cannot initialize compressor %s for a model", c->name);
  3037. + }
  3038. + else {
  3039. + l2->compressor = c;
  3040. + l2->next_compr_model = c->models;
  3041. + c->models = l2;
  3042. + c->mounted++;
  3043. + model_found++;
  3044. + }
  3045. + }
  3046. + }
  3047. + l2 = l2->next_model;
  3048. + }
  3049. + /*if (model_found==0) {
  3050. + jffs2_bbc_print2("jffs2.bbc: no macthing model file found for %s at this time (maybe later)\n",c->name);
  3051. + } */
  3052. + }
  3053. + /* Insert to the end of the compressor list */
  3054. + c->enabled = 1;
  3055. + c->buffer = NULL;
  3056. + c->buffer_size = 0;
  3057. + c->stat_compr_orig = c->stat_compr_new = c->stat_decompr = 0;
  3058. + c->next = NULL;
  3059. + if (jffs2_bbc_compressors == NULL) {
  3060. + jffs2_bbc_compressors = c;
  3061. + }
  3062. + else {
  3063. + l = jffs2_bbc_compressors;
  3064. + while (l->next != NULL)
  3065. + l = l->next;
  3066. + l->next = c;
  3067. + }
  3068. + return 0;
  3069. +}
  3070. +
  3071. +int jffs2_bbc_unregister_compressor(struct jffs2_bbc_compressor_type *c)
  3072. +{
  3073. + struct jffs2_bbc_compressor_type *l;
  3074. + struct jffs2_bbc_model_list_node *l2;
  3075. +
  3076. + if (c->mounted != 0) {
  3077. + jffs2_bbc_print1("jffs2.bbc: Compressor is in use. Sorry.");
  3078. + return -1;
  3079. + }
  3080. + if (jffs2_bbc_compressors == NULL) {
  3081. + jffs2_bbc_print1("jffs2.bbc: unregister: empty list.");
  3082. + return -1;
  3083. + }
  3084. + else if (jffs2_bbc_compressors == c) {
  3085. + if (c->deinit != NULL)
  3086. + c->deinit();
  3087. + jffs2_bbc_compressors = c->next;
  3088. + }
  3089. + else {
  3090. + l = jffs2_bbc_compressors;
  3091. + while (l->next != c) {
  3092. + if (l->next == NULL) {
  3093. + jffs2_bbc_print2("jffs2.bbc: unregister: cannot find compressor %s in the list.", c->name);
  3094. + return -1;
  3095. + }
  3096. + l = l->next;
  3097. + }
  3098. + if (c->deinit != NULL)
  3099. + c->deinit();
  3100. + l->next = c->next;
  3101. + }
  3102. + if (c->buffer != NULL) {
  3103. + jffs2_bbc_free(c->buffer);
  3104. + c->buffer = NULL;
  3105. + c->buffer_size = 0;
  3106. + }
  3107. +
  3108. + l2 = jffs2_bbc_model_list;
  3109. + while (l2 != NULL) {
  3110. + if (l2->compressor == c) {
  3111. + jffs2_bbc_print1("jffs2.bbc: unregister: BUG: model found!!!");
  3112. + l2->compressor = NULL;
  3113. + l2->next_compr_model = NULL;
  3114. + }
  3115. + l2 = l2->next_model;
  3116. + }
  3117. +
  3118. + return 0;
  3119. +}
  3120. +
  3121. +int jffs2_bbc_model_new(void *sb, int i_num, void *model)
  3122. +{
  3123. + struct jffs2_bbc_model_list_node *node;
  3124. + struct jffs2_bbc_compressor_type *l;
  3125. + char block_sign[2];
  3126. +
  3127. + int sign;
  3128. +
  3129. + /* check for conflicts... */
  3130. + sign = *((int *) model);
  3131. + block_sign[0] = *(((char *) model) + 4);
  3132. + block_sign[1] = *(((char *) model) + 5);
  3133. + node = jffs2_bbc_model_list;
  3134. + while (node != NULL) {
  3135. + if ((node->block_sign[0] == block_sign[0]) && (node->block_sign[1] == block_sign[1]) && (node->sb == sb)) {
  3136. + //jffs2_bbc_print2("jffs2.bbc: model_new: model conflict (inode=%d)!\n",i_num);
  3137. + return -1;
  3138. + }
  3139. + node = node->next_model;
  3140. + }
  3141. +
  3142. + /* insertion */
  3143. + node = jffs2_bbc_malloc_small((long)sizeof(struct jffs2_bbc_model_list_node));
  3144. + node->sb = sb;
  3145. + node->model = model;
  3146. + node->sign = *((int *) model);
  3147. + node->block_sign[0] = *(((char *) model) + 4);
  3148. + node->block_sign[1] = *(((char *) model) + 5);
  3149. + node->inode = i_num;
  3150. + node->next_model = jffs2_bbc_model_list;
  3151. + node->compressor = NULL;
  3152. + node->stat_decompr = 0;
  3153. + node->next_compr_model = NULL;
  3154. + jffs2_bbc_model_list = node;
  3155. +
  3156. + /* search for matching compressor */
  3157. + l = jffs2_bbc_compressors;
  3158. + while (l != NULL) {
  3159. + if (l->model_file_sign == sign) {
  3160. + //jffs2_bbc_print2("jffs2.bbc: compressor for model found: %s ",l->name);
  3161. + if (l->init_model(&(node->model)) != 0) {
  3162. + jffs2_bbc_print1("jffs2.bbc: cannot initialize compressor for a model");
  3163. + }
  3164. + else {
  3165. + l->mounted++;
  3166. + node->compressor = l;
  3167. + node->next_compr_model = l->models;
  3168. + l->models = node;
  3169. + }
  3170. + break;
  3171. + }
  3172. + l = l->next;
  3173. + }
  3174. + return 0;
  3175. +}
  3176. +
  3177. +static void jffs2_bbc_model_del_from_compressor(struct jffs2_bbc_model_list_node *node)
  3178. +{
  3179. + struct jffs2_bbc_model_list_node *l;
  3180. +
  3181. + if (node->model != NULL) {
  3182. + if (node->compressor != NULL) {
  3183. + if (node->compressor->destroy_model == NULL) {
  3184. + jffs2_bbc_free(node->model);
  3185. + node->model = NULL;
  3186. + }
  3187. + else {
  3188. + node->compressor->destroy_model(&(node->model));
  3189. + if (node->model != NULL)
  3190. + jffs2_bbc_print1("jffs2.bbc: warning: not NULL model after destroying!\n");
  3191. + }
  3192. + }
  3193. + }
  3194. +
  3195. + if (node->compressor == NULL) {
  3196. + jffs2_bbc_print1("jffs2.bbc: jffs2_bbc_model_del_from_compressor: no compressor!\n");
  3197. + return;
  3198. + }
  3199. + l = node->compressor->models;
  3200. + if (l == NULL) {
  3201. + jffs2_bbc_print1("jffs2.bbc: jffs2_bbc_model_del_from_compressor error, models=NULL!\n");
  3202. + return;
  3203. + }
  3204. + if (l == node) {
  3205. + node->compressor->models = node->next_compr_model;
  3206. + node->compressor->mounted--;
  3207. + return;
  3208. + }
  3209. + while (1) {
  3210. + if (l->next_compr_model == node) {
  3211. + l->next_compr_model = node->next_compr_model;
  3212. + node->compressor->mounted--;
  3213. + return;
  3214. + }
  3215. + l = l->next_compr_model;
  3216. + if (l == NULL) {
  3217. + jffs2_bbc_print1("jffs2.bbc: jffs2_bbc_model_del_from_compressor: not found\n");
  3218. + return;
  3219. + }
  3220. + }
  3221. +}
  3222. +
  3223. +void jffs2_bbc_model_del(void *sb)
  3224. +{
  3225. + struct jffs2_bbc_model_list_node *l, *l2;
  3226. +
  3227. + l = jffs2_bbc_model_list;
  3228. + if (l == NULL)
  3229. + return;
  3230. + if (l->sb == sb) {
  3231. + jffs2_bbc_model_list = l->next_model;
  3232. + jffs2_bbc_model_del_from_compressor(l);
  3233. + jffs2_bbc_free_small(l);
  3234. + jffs2_bbc_model_del(sb);
  3235. + return;
  3236. + }
  3237. + while (1) {
  3238. + if (l->next_model == NULL) {
  3239. + break;
  3240. + }
  3241. + if (l->next_model->sb == sb) {
  3242. + l2 = l->next_model;
  3243. + l->next_model = l->next_model->next_model;
  3244. + jffs2_bbc_model_del_from_compressor(l2);
  3245. + jffs2_bbc_free_small(l2);
  3246. + jffs2_bbc_model_del(sb);
  3247. + return;
  3248. + }
  3249. + l = l->next_model;
  3250. + }
  3251. + last_sb = NULL;
  3252. +}
  3253. +
  3254. +void jffs2_bbc_model_set_act_sb(void *sb)
  3255. +{
  3256. + last_sb = sb;
  3257. +}
  3258. +
  3259. +void *jffs2_bbc_model_get_act_sb(void)
  3260. +{
  3261. + return last_sb;
  3262. +}
  3263. +
  3264. +void *jffs2_bbc_model_get_newest(struct jffs2_bbc_compressor_type *compressor)
  3265. +{
  3266. + struct jffs2_bbc_model_list_node *m, *best_m;
  3267. + int max_sign, sign;
  3268. +
  3269. + if (compressor == NULL) {
  3270. + jffs2_bbc_print1("jffs2.bbc: jffs2_bbc_model_get: NULL!!\n");
  3271. + return NULL;
  3272. + }
  3273. +
  3274. + best_m = NULL;
  3275. + max_sign = -1;
  3276. + m = compressor->models;
  3277. + while (m != NULL) {
  3278. + if (m->sb == last_sb) {
  3279. + sign = (int) (m->block_sign[0]) * 256 + (int) (m->block_sign[1]);
  3280. + if (sign > max_sign) {
  3281. + max_sign = sign;
  3282. + best_m = m;
  3283. + }
  3284. + }
  3285. + m = m->next_compr_model;
  3286. + }
  3287. + if (best_m != NULL)
  3288. + return best_m->model;
  3289. + else
  3290. + return NULL;
  3291. +}
  3292. +
  3293. +/*********************************************************************
  3294. + * Statistics *
  3295. + *********************************************************************/
  3296. +
  3297. +static char *jffs2_bbc_stat_buff = NULL;
  3298. +
  3299. +char *jffs2_bbc_get_model_stats(void)
  3300. +{
  3301. + char *b;
  3302. + struct jffs2_bbc_model_list_node *m;
  3303. + struct jffs2_bbc_compressor_type *c;
  3304. +
  3305. + if (jffs2_bbc_stat_buff == NULL)
  3306. + jffs2_bbc_stat_buff = jffs2_bbc_malloc(8000);
  3307. +
  3308. + b = jffs2_bbc_stat_buff;
  3309. +
  3310. + b += sprintf(b, "Loaded compressors:");
  3311. + c = jffs2_bbc_compressors;
  3312. + while (c != NULL) {
  3313. + b += sprintf(b, "\n %s (%d) ", c->name, c->enabled);
  3314. + if (c->model_file_sign != 0) {
  3315. + b += sprintf(b, "m_sign=%d ", c->model_file_sign);
  3316. + b += sprintf(b, "models=");
  3317. + m = c->models;
  3318. + while (m != NULL) {
  3319. + b += sprintf(b, "(inode=%d)", m->inode);
  3320. + m = m->next_compr_model;
  3321. + }
  3322. + }
  3323. + else {
  3324. + b += sprintf(b, "b_sign=(%d,%d) nomodel", (int) (c->block_sign[0]), (int) (c->block_sign[1]));
  3325. + }
  3326. + if (c->proc_info != NULL) {
  3327. + b += sprintf(b, "\n %s", c->proc_info());
  3328. + }
  3329. + c = c->next;
  3330. + }
  3331. +
  3332. + m = jffs2_bbc_model_list;
  3333. +
  3334. + if (m == NULL) {
  3335. + b += sprintf(b, "\nPresent models: NONE\n");
  3336. + }
  3337. + else {
  3338. + b += sprintf(b, "\nPresent models:\n");
  3339. + while (m != NULL) {
  3340. + b += sprintf(b, " b_sign=(%d,%d),inode=%d,decompr=%d", (int) (m->block_sign[0]), (int) (m->block_sign[1]), m->inode, m->stat_decompr);
  3341. + if (m->compressor == NULL)
  3342. + b += sprintf(b, ",compressor=NULL\n");
  3343. + else
  3344. + b += sprintf(b, ",compressor=%s\n", m->compressor->name);
  3345. + m = m->next_model;
  3346. + }
  3347. + }
  3348. +
  3349. + return jffs2_bbc_stat_buff;
  3350. +}
  3351. +
  3352. +/*********************************************************************
  3353. + * Memory handling, debug *
  3354. + *********************************************************************/
  3355. +
  3356. +static int jffs2_bbc_mem_counter = 0;
  3357. +
  3358. +#ifdef __KERNEL__
  3359. +
  3360. +void *jffs2_bbc_malloc(long size)
  3361. +{
  3362. + void *addr = vmalloc(size);
  3363. + if (addr != NULL)
  3364. + jffs2_bbc_mem_counter++;
  3365. + else {
  3366. + jffs2_bbc_print2("DEBUG: not enough memory (%ld)\n", size);
  3367. + }
  3368. + return addr;
  3369. +}
  3370. +
  3371. +void jffs2_bbc_free(void *addr)
  3372. +{
  3373. + jffs2_bbc_mem_counter--;
  3374. + vfree(addr);
  3375. +}
  3376. +
  3377. +void *jffs2_bbc_malloc_small(long size)
  3378. +{
  3379. + void *addr;
  3380. + addr = kmalloc(size, 0);
  3381. + if (addr != NULL)
  3382. + jffs2_bbc_mem_counter++;
  3383. + return addr;
  3384. +}
  3385. +
  3386. +void jffs2_bbc_free_small(void *addr)
  3387. +{
  3388. + jffs2_bbc_mem_counter--;
  3389. + kfree(addr);
  3390. +}
  3391. +
  3392. +#else
  3393. +
  3394. +void *jffs2_bbc_malloc(long size)
  3395. +{
  3396. + void *addr = malloc(size);
  3397. + if (addr != NULL)
  3398. + jffs2_bbc_mem_counter++;
  3399. + return addr;
  3400. +}
  3401. +
  3402. +void jffs2_bbc_free(void *addr)
  3403. +{
  3404. + jffs2_bbc_mem_counter--;
  3405. + free(addr);
  3406. +}
  3407. +
  3408. +void *jffs2_bbc_malloc_small(long size)
  3409. +{
  3410. + return jffs2_bbc_malloc(size);
  3411. +}
  3412. +
  3413. +void jffs2_bbc_free_small(void *addr)
  3414. +{
  3415. + jffs2_bbc_free(addr);
  3416. +}
  3417. +
  3418. +#endif
  3419. +
  3420. +int jffs2_bbc_test_memory_counter(int verbose)
  3421. +{
  3422. + if (verbose > 0) {
  3423. + jffs2_bbc_print2("jffs2.bbc: mem_counter=%d!\n", jffs2_bbc_mem_counter);
  3424. + }
  3425. + return jffs2_bbc_mem_counter;
  3426. +}
  3427. +
  3428. +int jffs2_bbc_get_memory_counter(void)
  3429. +{
  3430. + return jffs2_bbc_mem_counter;
  3431. +}
  3432. +
  3433. +static char mem_stat[200];
  3434. +
  3435. +char *jffs2_bbc_get_mem_stats(void)
  3436. +{
  3437. + sprintf(mem_stat, "Memcounter=%d\n", jffs2_bbc_mem_counter);
  3438. + return mem_stat;
  3439. +}
  3440. +
  3441. +void jffs2_bbc_print_flush(void)
  3442. +{
  3443. +#ifdef __KERNEL__
  3444. + return;
  3445. +#else
  3446. + fflush(stdout);
  3447. + fflush(stderr);
  3448. +#endif
  3449. +}
  3450. +
  3451. +/*********************************************************************
  3452. + * FRAMEWORK - ZLIB REPLACEMENT *
  3453. + *********************************************************************/
  3454. +
  3455. +#ifndef JFFS2_BBC_STANDALONE
  3456. +
  3457. +/* Temorary buffers */
  3458. +static char stat_str[JFFS2_BBC_STAT_BUFF_SIZE];
  3459. +static int tmp_buffer_size = 0;
  3460. +static char *tmp_buffer = NULL;
  3461. +
  3462. +/* Statistic - used by /proc/jffs2_bbc and mkfs.jffs2 */
  3463. +char *jffs2_bbc_get_compr_stats(void)
  3464. +{
  3465. + struct jffs2_bbc_compressor_type *l;
  3466. + char *s = stat_str;
  3467. +
  3468. + s += sprintf(s, "Compression statistics:\n");
  3469. + l = jffs2_bbc_original_compressor;
  3470. + //s += sprintf(s, " zlib: compr=%d/%d decompr=%d\n", stat_zlib_compr_new, stat_zlib_compr_orig, stat_zlib_decompr);
  3471. + s += sprintf(s, " %s: compr=%d/%d decompr=%d\n", l->name, l->stat_compr_new, l->stat_compr_orig, l->stat_decompr);
  3472. + l = jffs2_bbc_get_compressor_list();
  3473. + while (l != NULL) {
  3474. + s += sprintf(s, " %s: compr=%d/%d decompr=%d\n", l->name, l->stat_compr_new, l->stat_compr_orig, l->stat_decompr);
  3475. + l = l->next;
  3476. + }
  3477. + return stat_str;
  3478. +}
  3479. +
  3480. +static void jffs2_bbc_buffer_fill(unsigned char *buff, int size)
  3481. +{
  3482. + for (; size > 0; size--, buff++)
  3483. + *buff = 255;
  3484. +}
  3485. +
  3486. +
  3487. +static int jffs2_bbc_update_compr_buf(unsigned long size)
  3488. +{
  3489. + struct jffs2_bbc_compressor_type *l;
  3490. +
  3491. + if (size < 5000)
  3492. + size = 5000;
  3493. + if (tmp_buffer == NULL) {
  3494. + tmp_buffer = jffs2_bbc_malloc(size);
  3495. + jffs2_bbc_buffer_fill(tmp_buffer, size);
  3496. + tmp_buffer_size = size;
  3497. + }
  3498. + else if (tmp_buffer_size < size) {
  3499. + jffs2_bbc_free(tmp_buffer);
  3500. + tmp_buffer = jffs2_bbc_malloc(size);
  3501. + jffs2_bbc_buffer_fill(tmp_buffer, size);
  3502. + tmp_buffer_size = size;
  3503. + }
  3504. + l = jffs2_bbc_get_compressor_list();
  3505. + while (l != NULL) {
  3506. + if (l->buffer == NULL) {
  3507. + l->buffer_size = size;
  3508. + l->buffer = jffs2_bbc_malloc(size);
  3509. + jffs2_bbc_buffer_fill(l->buffer, size);
  3510. + }
  3511. + else if (l->buffer_size < size) {
  3512. + jffs2_bbc_free(l->buffer);
  3513. + l->buffer_size = size;
  3514. + l->buffer = jffs2_bbc_malloc(size);
  3515. + jffs2_bbc_buffer_fill(l->buffer, size);
  3516. + }
  3517. + l = l->next;
  3518. + }
  3519. + return 0;
  3520. +}
  3521. +
  3522. +#ifdef DEBUG_COMPRESSORS
  3523. +
  3524. +static unsigned char *debug_tmp_buff = NULL;
  3525. +static long debug_orig_srclen = -1;
  3526. +static long debug_orig_dstlen = -1;
  3527. +static int debug_mem_counter = -1;
  3528. +
  3529. +
  3530. +void debug_before_compress(struct jffs2_bbc_compressor_type *c, void *model, unsigned char *input, unsigned char *output, long *sourcelen, long *dstlen)
  3531. +{
  3532. +
  3533. + debug_orig_srclen = *sourcelen; // for buffer overflow test
  3534. + debug_orig_dstlen = *dstlen; // for buffer overflow test
  3535. + output[debug_orig_dstlen + 1] = 255;
  3536. +
  3537. + debug_mem_counter = jffs2_bbc_get_memory_counter(); // for memory guard
  3538. +}
  3539. +
  3540. +void debug_after_compress(struct jffs2_bbc_compressor_type *c, int back, void *model, unsigned char *input, unsigned char *output, long *sourcelen, long *dstlen)
  3541. +{
  3542. + long dst_len = *dstlen;
  3543. + long src_len = *sourcelen;
  3544. + int i;
  3545. +
  3546. + // Memory guard
  3547. + if (debug_mem_counter != jffs2_bbc_get_memory_counter()) {
  3548. + jffs2_bbc_print4("!!!!!!!! %s error: possible COMPRESSOR MEMORY LEAK: %d->%d\n", c->name, debug_mem_counter, jffs2_bbc_get_memory_counter());
  3549. + debug_mem_counter = jffs2_bbc_get_memory_counter();
  3550. + }
  3551. +
  3552. + // Buffer overflow test
  3553. + if (output[debug_orig_dstlen + 1] != 255) {
  3554. + jffs2_bbc_print7("!!!!!!!! %s error: BUFFER OVERFLOW !!!!!!!!!!!! b[%d]=%d (srclen=%d dstlen=%d, back=%d)\n", c->name, (int) (debug_orig_dstlen + 1), (int) (output[debug_orig_dstlen + 1]), (int) (debug_orig_srclen), (int) (*dstlen), back);
  3555. + }
  3556. +
  3557. + // Decompression check
  3558. + if (back == 0) {
  3559. + if (debug_tmp_buff == NULL)
  3560. + debug_tmp_buff = jffs2_bbc_malloc(17000);
  3561. + for (i = 0; i < src_len; i++) debug_tmp_buff[i] = 0xf6;
  3562. + c->decompress(model, output, debug_tmp_buff, dst_len, src_len);
  3563. + // Memory guard for decompressor
  3564. + if (debug_mem_counter != jffs2_bbc_get_memory_counter()) {
  3565. + jffs2_bbc_print4("!!!!!!!! %s error: possible DECOMPRESSOR MEMORY LEAK: %d->%d\n", c->name, debug_mem_counter, jffs2_bbc_get_memory_counter());
  3566. + debug_mem_counter = jffs2_bbc_get_memory_counter();
  3567. + }
  3568. +
  3569. + for (i = 0; i < src_len; i++)
  3570. + if (input[i] != debug_tmp_buff[i]) {
  3571. + jffs2_bbc_print7("!!!!!!!! %s error: BLOCK DECOMPRESSED BADLY (first bad: %d in %d: %d!=%d (compressed size=%d)) !!!!!!!!!!!!\n", c->name, i, src_len, (int)input[i], (int)debug_tmp_buff[i], dst_len);
  3572. + break;
  3573. + }
  3574. + return;
  3575. + }
  3576. +
  3577. + // Return value test
  3578. + //jffs2_bbc_print3("!!!!!!!! %s error: %d !!!!!!!!!!!!\n", c->name, back);
  3579. +}
  3580. +
  3581. +#endif
  3582. +
  3583. +int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t * sourcelen, uint32_t * dstlen)
  3584. +{
  3585. + struct jffs2_bbc_compressor_type *c;
  3586. + int back, back_zlib, mode, min, i, i2;
  3587. + long tmp = 0, tmp_read_time = 1000, tmp_write_time = 1000, orig_src, orig_dest, src, dest;
  3588. + struct jffs2_bbc_model_list_node *m;
  3589. + void *sb;
  3590. + unsigned char *tmp_p = NULL;
  3591. +
  3592. + sb = jffs2_bbc_model_get_act_sb();
  3593. +
  3594. + orig_src = *sourcelen;
  3595. + orig_dest = *dstlen;
  3596. +
  3597. + mode = jffs2_bbc_get_compression_mode();
  3598. +
  3599. + if (mode == JFFS2_BBC_DUMMY_MODE) {
  3600. + i=0; i2=0;
  3601. + if (*dstlen>2) {
  3602. + cpage_out[i++]=JFFS2_BBC_DUMMY_BLOCKSIGN_0;
  3603. + cpage_out[i++]=JFFS2_BBC_DUMMY_BLOCKSIGN_1;
  3604. + i2=i;
  3605. + }
  3606. + for (;((i < *dstlen) && (i < (*sourcelen)+i2));i++) {
  3607. + cpage_out[i] = data_in[i-i2];
  3608. + }
  3609. + *sourcelen=i-i2;
  3610. + *dstlen=i;
  3611. + return 0;
  3612. + }
  3613. +
  3614. + if (mode == JFFS2_BBC_ZLIB_MODE) {
  3615. + /*if (!jffs2_bbc_original_compressor->enabled) {
  3616. + jffs2_bbc_print2("jffs2.bbc: WARNING: ZLIB mode but %s disabled! Enabling for this procedure...\n",jffs2_bbc_original_compressor->name);
  3617. + }*/
  3618. + back = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen);
  3619. + jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen;
  3620. + jffs2_bbc_original_compressor->stat_compr_new += *dstlen;
  3621. + return back;
  3622. + }
  3623. +
  3624. + jffs2_bbc_update_compr_buf(orig_dest);
  3625. +
  3626. + if (mode == JFFS2_BBC_SIZE_MODE) {
  3627. + // Testing all compressors
  3628. + if (!jffs2_bbc_original_compressor->enabled) {
  3629. + min = -1;
  3630. + }
  3631. + else {
  3632. + back_zlib = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen);
  3633. + min = *dstlen;
  3634. + }
  3635. + c = jffs2_bbc_get_compressor_list();
  3636. + while (c != NULL) {
  3637. + c->buffer_cnt = -1;
  3638. + if (c->enabled == 0) {
  3639. + c = c->next;
  3640. + continue;
  3641. + }
  3642. + if (c->model_file_sign == 0) {
  3643. + src = orig_src;
  3644. + dest = orig_dest;
  3645. +#ifdef DEBUG_COMPRESSORS
  3646. + debug_before_compress(c, NULL, data_in, c->buffer, &src, &dest);
  3647. +#endif
  3648. + back = c->compress(NULL, data_in, c->buffer, &src, &dest);
  3649. +#ifdef DEBUG_COMPRESSORS
  3650. + debug_after_compress(c, back, NULL, data_in, c->buffer, &src, &dest);
  3651. +#endif
  3652. + if (back == 0) {
  3653. + c->buffer_cnt = dest;
  3654. + if ((min < 0) || (min > dest))
  3655. + min = dest;
  3656. + }
  3657. + }
  3658. + else {
  3659. + m = c->models;
  3660. + while (m != NULL) {
  3661. + src = orig_src;
  3662. + dest = orig_dest;
  3663. + if (m->sb == sb) {
  3664. + if (c->buffer_cnt == -1) {
  3665. +#ifdef DEBUG_COMPRESSORS
  3666. + debug_before_compress(c, m->model, data_in, c->buffer, (long *) (&src), (long *) (&dest));
  3667. +#endif
  3668. + back = c->compress(m->model, data_in, c->buffer, (long *) (&src), (long *) (&dest));
  3669. +#ifdef DEBUG_COMPRESSORS
  3670. + debug_after_compress(c, back, m->model, data_in, c->buffer, (long *) (&src), (long *) (&dest));
  3671. +#endif
  3672. + if (back == 0) {
  3673. + c->buffer_cnt = dest;
  3674. + if ((min < 0) || (min > dest))
  3675. + min = dest;
  3676. + }
  3677. + }
  3678. + else {
  3679. +#ifdef DEBUG_COMPRESSORS
  3680. + debug_before_compress(c, m->model, data_in, tmp_buffer, &src, &dest);
  3681. +#endif
  3682. + back = c->compress(m->model, data_in, tmp_buffer, &src, &dest);
  3683. +#ifdef DEBUG_COMPRESSORS
  3684. + debug_after_compress(c, back, m->model, data_in, tmp_buffer, &src, &dest);
  3685. +#endif
  3686. + if (back == 0) {
  3687. + if (c->buffer_cnt > dest) {
  3688. + c->buffer_cnt = dest;
  3689. + tmp_p = c->buffer;
  3690. + c->buffer = tmp_buffer;
  3691. + tmp_buffer = tmp_p;
  3692. + if ((min < 0) || (min > dest))
  3693. + min = dest;
  3694. + }
  3695. + }
  3696. + }
  3697. + }
  3698. + m = m->next_compr_model;
  3699. + }
  3700. + }
  3701. + c = c->next;
  3702. + }
  3703. + //Finding the best and copy its result
  3704. +
  3705. +#ifdef DEBUG_SHOW_BLOCK_SIZES
  3706. + jffs2_bbc_print1("\n");
  3707. + if (jffs2_bbc_original_compressor->enabled) {
  3708. + if (min == *dstlen) {
  3709. + jffs2_bbc_print3("%s:%d* ", jffs2_bbc_original_compressor->name, (int) (*dstlen));
  3710. + }
  3711. + else {
  3712. + jffs2_bbc_print3("%s:%d ", jffs2_bbc_original_compressor->name, (int) (*dstlen));
  3713. + }
  3714. + }
  3715. + c = jffs2_bbc_get_compressor_list();
  3716. + while (c != NULL) {
  3717. + if (c->enabled == 0) {
  3718. + c = c->next;
  3719. + continue;
  3720. + }
  3721. + if (c->buffer_cnt == min)
  3722. + jffs2_bbc_print3("%s:%d* ", c->name, c->buffer_cnt);
  3723. + else
  3724. + jffs2_bbc_print3("%s:%d ", c->name, c->buffer_cnt);
  3725. + c = c->next;
  3726. + }
  3727. +#endif
  3728. +
  3729. + if (min == -1) {
  3730. + return -1; // none of compressors work (maybe too short output buffer)
  3731. + }
  3732. +
  3733. + if (jffs2_bbc_original_compressor->enabled) {
  3734. + if (min == *dstlen) {
  3735. + jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen;
  3736. + jffs2_bbc_original_compressor->stat_compr_new += *dstlen;
  3737. + return back_zlib;
  3738. + }
  3739. + }
  3740. +
  3741. + c = jffs2_bbc_get_compressor_list();
  3742. + while (c != NULL) {
  3743. + if (c->enabled == 0) {
  3744. + c = c->next;
  3745. + continue;
  3746. + }
  3747. + if (c->buffer_cnt == min) {
  3748. + *dstlen = c->buffer_cnt;
  3749. + *sourcelen = orig_src;
  3750. + for (i = 0; i < *dstlen; i++) {
  3751. + cpage_out[i] = c->buffer[i];
  3752. + }
  3753. + c->stat_compr_orig += *sourcelen;
  3754. + c->stat_compr_new += *dstlen;
  3755. + return 0;
  3756. + }
  3757. + c = c->next;
  3758. + }
  3759. + jffs2_bbc_print1("jffs2.bbc: compr (full): BUG!!!\n");
  3760. + return 0;
  3761. + }
  3762. +
  3763. + if ((mode == JFFS2_BBC_FASTR_MODE)||(mode == JFFS2_BBC_FASTW_MODE)||(mode == JFFS2_BBC_FASTS_MODE)) {
  3764. + // Estimating all compressors
  3765. + if (jffs2_bbc_original_compressor->enabled) {
  3766. + back = jffs2_bbc_original_compressor->estimate(NULL, data_in, *sourcelen, &tmp, &tmp_read_time, &tmp_write_time);
  3767. + }
  3768. + else {
  3769. + tmp = -1;
  3770. + tmp_read_time = -1;
  3771. + tmp_write_time = -1;
  3772. + }
  3773. + if (mode == JFFS2_BBC_FASTR_MODE) tmp = tmp_read_time;
  3774. + if (mode == JFFS2_BBC_FASTW_MODE) tmp = tmp_write_time;
  3775. + min = tmp;
  3776. + c = jffs2_bbc_get_compressor_list();
  3777. + while (c != NULL) {
  3778. + src = orig_src;
  3779. + dest = orig_dest;
  3780. + c->buffer_cnt = -1;
  3781. + if (c->enabled == 0) {
  3782. + c = c->next;
  3783. + continue;
  3784. + }
  3785. + if ((c->model_file_sign == 0) || (jffs2_bbc_model_get_newest(c) != NULL)) {
  3786. + back = c->estimate(jffs2_bbc_model_get_newest(c), data_in, src, &dest, &tmp_read_time, &tmp_write_time);
  3787. + if (mode == JFFS2_BBC_FASTR_MODE) dest = tmp_read_time;
  3788. + if (mode == JFFS2_BBC_FASTW_MODE) dest = tmp_write_time;
  3789. + if (back == 0) {
  3790. + c->buffer_cnt = dest;
  3791. + if ((min < 0) || (min > dest))
  3792. + min = dest;
  3793. + }
  3794. + else {
  3795. + c->buffer_cnt = -1;
  3796. + }
  3797. + }
  3798. + c = c->next;
  3799. + }
  3800. + // Finding the best and compress with it
  3801. + if (min == -1) {
  3802. + return -1;
  3803. + }
  3804. + if (jffs2_bbc_original_compressor->enabled) {
  3805. + if (min == tmp) {
  3806. + back = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen);
  3807. + jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen;
  3808. + jffs2_bbc_original_compressor->stat_compr_new += *dstlen;
  3809. + return back;
  3810. + }
  3811. + }
  3812. + c = jffs2_bbc_get_compressor_list();
  3813. + while (c != NULL) {
  3814. + if (c->enabled == 0) {
  3815. + c = c->next;
  3816. + continue;
  3817. + }
  3818. + if (c->buffer_cnt == min) {
  3819. + back = c->compress(jffs2_bbc_model_get_newest(c), data_in, cpage_out, (unsigned long*)sourcelen, (unsigned long*)dstlen);
  3820. + if ((back == 0) && (*dstlen < orig_dest) && (*dstlen > 4)) {
  3821. + c->stat_compr_orig += *sourcelen;
  3822. + c->stat_compr_new += *dstlen;
  3823. + }
  3824. + else { // fallback will always be available
  3825. + *sourcelen = orig_src;
  3826. + *dstlen = orig_dest;
  3827. + back = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen);
  3828. + jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen;
  3829. + jffs2_bbc_original_compressor->stat_compr_new += *dstlen;
  3830. + return back;
  3831. + }
  3832. + return 0;
  3833. + }
  3834. + c = c->next;
  3835. + }
  3836. + jffs2_bbc_print1("jffs2.bbc: compress (fastX mode): BUG!!!\n");
  3837. + return 0;
  3838. + }
  3839. +
  3840. + if (mode == JFFS2_BBC_MANUAL_MODE) {
  3841. + c = jffs2_bbc_get_manual_compressor();
  3842. + if (c != NULL) {
  3843. + if (c->model_file_sign == 0) {
  3844. + src = orig_src;
  3845. + dest = orig_dest;
  3846. + back = c->compress(NULL, data_in, cpage_out, &src, &dest);
  3847. + if (back == 0) {
  3848. + *dstlen = dest;
  3849. + *sourcelen = src;
  3850. + c->stat_compr_orig += *sourcelen;
  3851. + c->stat_compr_new += *dstlen;
  3852. + return 0;
  3853. + }
  3854. + }
  3855. + else {
  3856. + c->buffer_cnt = -1;
  3857. + m = c->models;
  3858. + min = -1;
  3859. + while (m != NULL) {
  3860. + src = orig_src;
  3861. + dest = orig_dest;
  3862. + if (m->sb == sb) {
  3863. + if (min == -1) {
  3864. + back = c->compress(m->model, data_in, cpage_out, (unsigned long*)sourcelen, (unsigned long*)dstlen);
  3865. + if ((back == 0) && (*dstlen < orig_dest) && (*dstlen > 4)) {
  3866. + min = dest;
  3867. + tmp_p = cpage_out;
  3868. + }
  3869. + }
  3870. + else {
  3871. + back = c->compress(m->model, data_in, tmp_buffer, &src, &dest);
  3872. + if ((back == 0) && (dest < orig_dest) && (dest > 4)) {
  3873. + if (c->buffer_cnt > dest) {
  3874. + if (min > dest) {
  3875. + min = dest;
  3876. + tmp_p = tmp_buffer;
  3877. + }
  3878. + }
  3879. + }
  3880. + }
  3881. + }
  3882. + m = m->next_compr_model;
  3883. + }
  3884. + if (min != -1) {
  3885. + if (tmp_p != cpage_out) {
  3886. + for (i = 0; i < min; i++)
  3887. + cpage_out[i] = tmp_p[i];
  3888. + *sourcelen = orig_src;
  3889. + *dstlen = min;
  3890. + }
  3891. + c->stat_compr_orig += *sourcelen;
  3892. + c->stat_compr_new += *dstlen;
  3893. + return 0;
  3894. + }
  3895. + }
  3896. + }
  3897. + /*else {
  3898. + jffs2_bbc_print1("iPack: manual mode without selected compressor!\n");
  3899. + } */
  3900. +
  3901. + /*if (!jffs2_bbc_original_compressor->enabled) {
  3902. + jffs2_bbc_print2("jffs2.bbc: WARNING: %s must be enabled! Enabling for this procedure...\n",jffs2_bbc_original_compressor->name);
  3903. + }*/
  3904. + back = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen);
  3905. + jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen;
  3906. + jffs2_bbc_original_compressor->stat_compr_new += *dstlen;
  3907. + return back;
  3908. +
  3909. +
  3910. + }
  3911. +
  3912. + jffs2_bbc_print1("jffs2.bbc: compress: unimlemented compress mode!!!\n");
  3913. + return 0;
  3914. +}
  3915. +
  3916. +void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen)
  3917. +{
  3918. + struct jffs2_bbc_model_list_node *m;
  3919. + struct jffs2_bbc_compressor_type *c;
  3920. + char d[2];
  3921. + void *sb;
  3922. + int i;
  3923. +
  3924. + /* If the input too small... */
  3925. + if (destlen<=2) {
  3926. + cpage_out[0]=data_in[0];
  3927. + if (destlen==2) cpage_out[1]=data_in[1];
  3928. + return;
  3929. + }
  3930. +
  3931. + sb = jffs2_bbc_model_get_act_sb();
  3932. + d[0] = *(data_in);
  3933. + d[1] = *(data_in + 1);
  3934. +
  3935. + d[0] &= 0x7f; // Variants support...
  3936. +
  3937. + /* Search for model based decompressors... */
  3938. + m = jffs2_bbc_get_model_list();
  3939. + while (m != NULL) {
  3940. + if ((d[0] == m->block_sign[0]) && (d[1] == m->block_sign[1]) && (sb == m->sb)) {
  3941. + if (m->compressor == NULL) {
  3942. + jffs2_bbc_print3("jffs2.bbc: decompressor for block_sign (%d,%d) not loaded!\n", (int) (d[0]), (int) (d[1]));
  3943. + }
  3944. + else {
  3945. + m->compressor->decompress(m->model, data_in, cpage_out, srclen, destlen);
  3946. + m->compressor->stat_decompr++;
  3947. + m->stat_decompr++;
  3948. + }
  3949. + return;
  3950. + }
  3951. + m = m->next_model;
  3952. + }
  3953. + /* Is it ZLIB? */
  3954. + if ((((int) d[0]) == (int)(jffs2_bbc_original_compressor->block_sign[0])) && (((int) d[1]) == (int)(jffs2_bbc_original_compressor->block_sign[1]))) {
  3955. + jffs2_bbc_original_compressor->decompress(NULL, data_in, cpage_out, srclen, destlen);
  3956. + jffs2_bbc_original_compressor->stat_decompr++;
  3957. + return;
  3958. + }
  3959. + /* Search for non model based decompressors... */
  3960. + c = jffs2_bbc_get_compressor_list();
  3961. + while (c != NULL) {
  3962. + if (c->model_file_sign == 0) {
  3963. + if (((int) (d[0]) == (int) (c->block_sign[0])) && ((int) (d[1]) == (int) (c->block_sign[1]))) {
  3964. + c->decompress(NULL, data_in, cpage_out, srclen, destlen);
  3965. + c->stat_decompr++;
  3966. + return;
  3967. + }
  3968. + }
  3969. + c = c->next;
  3970. + }
  3971. + /* Is it DUMMY? */
  3972. + if ((((int) d[0]) == JFFS2_BBC_DUMMY_BLOCKSIGN_0) && (((int) d[1]) == JFFS2_BBC_DUMMY_BLOCKSIGN_1)) {
  3973. + for (i=0;i<destlen;i++) {
  3974. + cpage_out[i]=data_in[i+2];
  3975. + }
  3976. + return;
  3977. + }
  3978. + /* No matching decompressor found... */
  3979. + jffs2_bbc_print4("jffs2.bbc: cannot find model for decompress: bsign=(%d,%d),sb=%d. Using zlib.\n", (int) d[0], (int) d[1], (int) sb);
  3980. + jffs2_bbc_original_compressor->decompress(NULL, data_in, cpage_out, srclen, destlen);
  3981. + jffs2_bbc_original_compressor->stat_decompr++;
  3982. +}
  3983. +
  3984. +#endif
  3985. --- /dev/null
  3986. +++ b/fs/jffs2/jffs2_bbc_framework.h
  3987. @@ -0,0 +1,202 @@
  3988. +/*
  3989. + * JFFS2-BBC: Compression Framework - headers
  3990. + *
  3991. + * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  3992. + *
  3993. + * Copyright (C) 2004, Ferenc Havasi
  3994. + *
  3995. + * This program is free software; you can redistribute it and/or
  3996. + * modify it under the terms of the GNU General Public License
  3997. + * as published by the Free Software Foundation; either version 2
  3998. + * of the License, or (at your option) any later version.
  3999. + *
  4000. + * This program is distributed in the hope that it will be useful,
  4001. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4002. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4003. + * GNU General Public License for more details.
  4004. + *
  4005. + * You should have received a copy of the GNU General Public License
  4006. + * along with this program; if not, write to the Free Software
  4007. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  4008. + *
  4009. + */
  4010. +
  4011. +#ifndef __JFFS2_BBC_FRAMEWORK_H__
  4012. +
  4013. +#define __JFFS2_BBC_FRAMEWORK_H__
  4014. +
  4015. +#define JFFS2_BBC_VERSION "0.54.3"
  4016. +
  4017. +#define JFFS2_BBC_CONFIG_FILE "bbc.conf"
  4018. +
  4019. +/*********************************************************************
  4020. + * Compression mode handling *
  4021. + *********************************************************************/
  4022. +
  4023. +#define JFFS2_BBC_ZLIB_MODE 1
  4024. +#define JFFS2_BBC_SIZE_MODE 2
  4025. +#define JFFS2_BBC_FASTR_MODE 3
  4026. +#define JFFS2_BBC_FASTW_MODE 4
  4027. +#define JFFS2_BBC_FASTS_MODE 5
  4028. +#define JFFS2_BBC_MANUAL_MODE 6
  4029. +#define JFFS2_BBC_DUMMY_MODE 7
  4030. +
  4031. +int jffs2_bbc_get_compression_mode(void);
  4032. +void jffs2_bbc_set_compression_mode(int mode);
  4033. +
  4034. +/*********************************************************************
  4035. + * Read/write speed unit *
  4036. + * everything is relative to the speed of zlib *
  4037. + * bigger number means slower speed! *
  4038. + *********************************************************************/
  4039. +
  4040. +#define JFFS2_BBC_ZLIB_READ_TIME 10000
  4041. +#define JFFS2_BBC_ZLIB_WRITE_TIME 10000
  4042. +
  4043. +/*********************************************************************
  4044. + * Compressor handling *
  4045. + *********************************************************************/
  4046. +
  4047. +struct jffs2_bbc_compressor_type
  4048. +{
  4049. + char name[16];
  4050. + int model_file_sign; /* 0 for no model file needed */
  4051. + char block_sign[4]; /* only nomodel compressors, and only the first 2 _bytes are used! */
  4052. + int (*init)(void);
  4053. + int (*init_model)(void **model);
  4054. + void (*destroy_model)(void **model);
  4055. + void (*deinit)(void);
  4056. + /* Compress block
  4057. + * *dstlen bytes are allocated.
  4058. + * if it is not enough write *sourcelen over to the processed amount of data
  4059. + * returns non zero if fails
  4060. + */
  4061. + int (*compress)(void *model, unsigned char *input, unsigned char *output, unsigned long *sourcelen, unsigned long *dstlen);
  4062. + int (*estimate)(void *model, unsigned char *input, unsigned long sourcelen,
  4063. + unsigned long *dstlen, unsigned long *readtime, unsigned long *writetime);
  4064. + /* Decompress block
  4065. + * returns non zero if fails
  4066. + */
  4067. + int (*decompress)(void *model, unsigned char *input, unsigned char *output, unsigned long sourcelen, unsigned long dstlen);
  4068. + char *(*proc_info)(void);
  4069. + int (*proc_command)(char *command);
  4070. + int enabled; /* filled by BBC */
  4071. + int mounted; /* filled by BBC */
  4072. + void *models; /* filled by BBC */
  4073. + char *buffer; /* filled by BBC */
  4074. + int buffer_size; /* filled by BBC */
  4075. + int buffer_cnt; /* filled by BBC */
  4076. + int buffer_tmp; /* filled by BBC */
  4077. + int stat_compr_orig; /* filled by BBC */
  4078. + int stat_compr_new; /* filled by BBC */
  4079. + int stat_decompr; /* filled by BBC */
  4080. + struct jffs2_bbc_compressor_type *next; /* filled by BBC */
  4081. +};
  4082. +
  4083. +/* It sets the compression mode to JFFS2_BBC_MANUAL_MODE */
  4084. +
  4085. +void jffs2_bbc_set_manual_compressor(struct jffs2_bbc_compressor_type *c); /* NULL = ZLIB */
  4086. +int jffs2_bbc_set_manual_compressor_by_name(char *name);
  4087. +int jffs2_bbc_disable_compressor_by_name(char *name);
  4088. +int jffs2_bbc_enable_compressor_by_name(char *name);
  4089. +void jffs2_bbc_compressor_command_by_name(char *name_and_command);
  4090. +
  4091. +/* If the compression mode is JFFS2_BCC_MANUAL_MODE the manually setted
  4092. + compressor can be get using it. Otherwise it returns with NULL. */
  4093. +
  4094. +struct jffs2_bbc_compressor_type *jffs2_bbc_get_manual_compressor(void);
  4095. +
  4096. +struct jffs2_bbc_model_list_node
  4097. +{
  4098. + void *sb; /* FS idendifier (JFFS2_SB_INFO(sb) at this moment) */
  4099. + void *model; /* model data */
  4100. + int sign; /* sign of the model (first 4 bytes) */
  4101. + char block_sign[4]; /* block sign - only the first 2 bytes are used! */
  4102. + int inode; /* inode number of the model file */
  4103. + int stat_decompr;
  4104. + struct jffs2_bbc_compressor_type *compressor;
  4105. + struct jffs2_bbc_model_list_node *next_model;
  4106. + struct jffs2_bbc_model_list_node *next_compr_model;
  4107. +};
  4108. +
  4109. +struct jffs2_bbc_compressor_type *jffs2_bbc_get_compressor_list(void);
  4110. +struct jffs2_bbc_model_list_node *jffs2_bbc_get_model_list(void);
  4111. +
  4112. +int jffs2_bbc_register_compressor(struct jffs2_bbc_compressor_type *c);
  4113. +int jffs2_bbc_unregister_compressor(struct jffs2_bbc_compressor_type *c);
  4114. +
  4115. +int jffs2_bbc_model_new(void *sb, int i_num, void *model);
  4116. +void jffs2_bbc_model_del(void *sb);
  4117. +void jffs2_bbc_model_set_act_sb(void *sb);
  4118. +void *jffs2_bbc_model_get_act_sb(void);
  4119. +void *jffs2_bbc_model_get_newest(struct jffs2_bbc_compressor_type *compressor);
  4120. +
  4121. +/*********************************************************************
  4122. + * Compressor init function *
  4123. + *********************************************************************/
  4124. +
  4125. +void jffs2_bbc_compressor_init(void);
  4126. +void jffs2_bbc_compressor_deinit(void);
  4127. +
  4128. +/*********************************************************************
  4129. + * Statistics *
  4130. + *********************************************************************/
  4131. +
  4132. +char *jffs2_bbc_get_compr_stats(void);
  4133. +char *jffs2_bbc_get_model_stats(void);
  4134. +
  4135. +/*********************************************************************
  4136. + * Other *
  4137. + *********************************************************************/
  4138. +
  4139. +
  4140. +void jffs2_bbc_print_flush(void);
  4141. +
  4142. +#ifdef __KERNEL__
  4143. +#include <linux/kernel.h>
  4144. +#define jffs2_bbc_print1(a) printk(a)
  4145. +#define jffs2_bbc_print2(a,b) printk(a,b)
  4146. +#define jffs2_bbc_print3(a,b,c) printk(a,b,c)
  4147. +#define jffs2_bbc_print4(a,b,c,d) printk(a,b,c,d)
  4148. +#define jffs2_bbc_print5(a,b,c,d,e) printk(a,b,c,d,e)
  4149. +#define jffs2_bbc_print6(a,b,c,d,e,f) printk(a,b,c,d,e,f)
  4150. +#define jffs2_bbc_print7(a,b,c,d,e,f,g) printk(a,b,c,d,e,f,g)
  4151. +#define jffs2_bbc_print8(a,b,c,d,e,f,g,h) printk(a,b,c,d,e,f,g,h)
  4152. +#define jffs2_bbc_print9(a,b,c,d,e,f,g,h,i) printk(a,b,c,d,e,f,g,h,i)
  4153. +#else
  4154. +#include <stdio.h>
  4155. +#define jffs2_bbc_print1(a) fprintf(stderr,a)
  4156. +#define jffs2_bbc_print2(a,b) fprintf(stderr,a,b)
  4157. +#define jffs2_bbc_print3(a,b,c) fprintf(stderr,a,b,c)
  4158. +#define jffs2_bbc_print4(a,b,c,d) fprintf(stderr,a,b,c,d)
  4159. +#define jffs2_bbc_print5(a,b,c,d,e) fprintf(stderr,a,b,c,d,e)
  4160. +#define jffs2_bbc_print6(a,b,c,d,e,f) fprintf(stderr,a,b,c,d,e,f)
  4161. +#define jffs2_bbc_print7(a,b,c,d,e,f,g) fprintf(stderr,a,b,c,d,e,f,g)
  4162. +#define jffs2_bbc_print8(a,b,c,d,e,f,g,h) fprintf(stderr,a,b,c,d,e,f,g,h)
  4163. +#define jffs2_bbc_print9(a,b,c,d,e,f,g,h,i) fprintf(stderr,a,b,c,d,e,f,g,h,i)
  4164. +#endif
  4165. +
  4166. +/* Handle endianness */
  4167. +#ifndef __KERNEL__
  4168. +
  4169. +#define ENDIAN_HOST_AND_TARGET_SAME 0
  4170. +#define ENDIAN_HOST_AND_TARGET_DIFFERENT 1
  4171. +
  4172. +extern int jffs2_bbc_glb_endian_X;
  4173. +
  4174. +#endif
  4175. +
  4176. +/* Allocating more than one page (tip. 4096 byte) */
  4177. +void *jffs2_bbc_malloc(long size);
  4178. +void jffs2_bbc_free(void *addr);
  4179. +
  4180. +/* Allocating less than one page (tip. 4096 byte) */
  4181. +void *jffs2_bbc_malloc_small(long size);
  4182. +void jffs2_bbc_free_small(void *addr);
  4183. +
  4184. +/* Memory guarding */
  4185. +int jffs2_bbc_test_memory_counter(int verbose);
  4186. +char *jffs2_bbc_get_mem_stats(void);
  4187. +int jffs2_bbc_get_memory_counter(void);
  4188. +
  4189. +#endif
  4190. --- /dev/null
  4191. +++ b/fs/jffs2/jffs2_bbc_fs.c
  4192. @@ -0,0 +1,331 @@
  4193. +/*
  4194. + * JFFS2-BBC: File System Extension for Linux Kernel
  4195. + *
  4196. + * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  4197. + *
  4198. + * Copyright (C) 2004, Ferenc Havasi
  4199. + *
  4200. + * This program is free software; you can redistribute it and/or
  4201. + * modify it under the terms of the GNU General Public License
  4202. + * as published by the Free Software Foundation; either version 2
  4203. + * of the License, or (at your option) any later version.
  4204. + *
  4205. + * This program is distributed in the hope that it will be useful,
  4206. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4207. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4208. + * GNU General Public License for more details.
  4209. + *
  4210. + * You should have received a copy of the GNU General Public License
  4211. + * along with this program; if not, write to the Free Software
  4212. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  4213. + *
  4214. + */
  4215. +
  4216. +#include <linux/kernel.h>
  4217. +#include <linux/fs.h>
  4218. +#include <linux/jffs2.h>
  4219. +#include <linux/proc_fs.h>
  4220. +#include <linux/version.h>
  4221. +
  4222. +#include "nodelist.h"
  4223. +
  4224. +#include "jffs2_bbc_framework.h"
  4225. +
  4226. +struct jffs2_bbc_fs_sb_list {
  4227. + struct super_block *sb;
  4228. + struct jffs2_bbc_fs_sb_list *next;
  4229. +};
  4230. +
  4231. +static struct jffs2_bbc_fs_sb_list *sb_list = NULL;
  4232. +
  4233. +void jffs2_bbc_proc_init(void);
  4234. +void jffs2_bbc_proc_deinit(void);
  4235. +
  4236. +void jffs2_bbc_load_model(void *sb_par) {
  4237. + struct jffs2_sb_info *c;
  4238. + //struct jffs2_inode_info *f;
  4239. + struct dentry *config_dentry,*model_dentry;
  4240. + struct qstr config_name,model_name;
  4241. + struct file *config_file,*model_file;
  4242. + char *buff=NULL,*model_buff;
  4243. + int config_size,model_size;
  4244. + int i,prev_i;
  4245. + struct super_block *sb;
  4246. + struct jffs2_bbc_fs_sb_list *sb_l;
  4247. +
  4248. + sb = sb_par;
  4249. + sb_l = jffs2_bbc_malloc_small(sizeof(struct jffs2_bbc_fs_sb_list));
  4250. + sb_l->sb = sb;
  4251. + sb_l->next = sb_list;
  4252. + sb_list = sb_l;
  4253. + config_name.name = JFFS2_BBC_CONFIG_FILE;
  4254. + config_name.len = strlen(config_name.name);
  4255. + config_name.hash = full_name_hash(config_name.name,config_name.len);
  4256. + config_dentry = d_alloc(sb->s_root,&config_name);
  4257. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  4258. + sb->s_root->d_inode->i_op->lookup(sb->s_root->d_inode,config_dentry);
  4259. +#else
  4260. + sb->s_root->d_inode->i_op->lookup(sb->s_root->d_inode,config_dentry,NULL);
  4261. +#endif
  4262. +
  4263. + if (config_dentry->d_inode != NULL) {
  4264. + config_size = config_dentry->d_inode->i_size;
  4265. + //printk("config_file_size=%d\n",config_size);
  4266. + if (config_size > 0) {
  4267. + buff = jffs2_bbc_malloc(config_size+1);
  4268. + config_file = dentry_open(config_dentry,NULL,O_RDONLY);
  4269. + kernel_read(config_file,0,buff,config_size);
  4270. + buff[config_size] = 0;
  4271. + for (prev_i = i = 0 ; i < config_size+1 ; i++) {
  4272. + if (buff[i] == '\n') buff[i]=0;
  4273. + if (buff[i] == 0) {
  4274. + if (prev_i != i) {
  4275. + if ((buff[prev_i] == '-') && (buff[prev_i+1] == 0)) break;
  4276. + printk("reading model file %s... ",buff+prev_i);
  4277. + model_name.name = buff+prev_i;
  4278. + model_name.len = strlen(buff+prev_i);
  4279. + model_name.hash = full_name_hash(model_name.name,model_name.len);
  4280. + model_dentry = d_alloc(sb->s_root,&model_name);
  4281. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  4282. + sb->s_root->d_inode->i_op->lookup(sb->s_root->d_inode,model_dentry);
  4283. +#else
  4284. + sb->s_root->d_inode->i_op->lookup(sb->s_root->d_inode,model_dentry,NULL);
  4285. +#endif
  4286. + if (model_dentry->d_inode != NULL) {
  4287. + c = JFFS2_SB_INFO(model_dentry->d_inode->i_sb);
  4288. + //f = JFFS2_INODE_INFO(model_dentry->d_inode);
  4289. + model_size = model_dentry->d_inode->i_size;
  4290. + model_buff = jffs2_bbc_malloc(model_size);
  4291. + model_file = dentry_open(model_dentry,NULL,O_RDONLY);
  4292. + kernel_read(model_file,0,model_buff,model_size);
  4293. + if (jffs2_bbc_model_new(c,model_dentry->d_inode->i_ino,model_buff) != 0) {
  4294. + printk("already loaded.\n");
  4295. + jffs2_bbc_free(model_buff);
  4296. + }
  4297. + else {
  4298. + printk("done (%d bytes readed from inode %d).\n",model_size,(int)(model_dentry->d_inode->i_ino));
  4299. + }
  4300. + }
  4301. + else {
  4302. + printk("not found.\n");
  4303. + }
  4304. + dput(model_dentry);
  4305. + }
  4306. + prev_i = i+1;
  4307. + }
  4308. + }
  4309. + }
  4310. + }
  4311. + dput(config_dentry);
  4312. + if (buff != NULL) jffs2_bbc_free(buff);
  4313. +}
  4314. +
  4315. +void jffs2_bbc_unload_model(void *sb_par)
  4316. +{
  4317. + struct jffs2_sb_info *c;
  4318. + struct super_block *sb = sb_par;
  4319. + struct jffs2_bbc_fs_sb_list *sb_l,*sb_l2;
  4320. + int done = 0;
  4321. +
  4322. + c = JFFS2_SB_INFO(sb);
  4323. + jffs2_bbc_model_del(c);
  4324. + if (sb_list == NULL) printk("jffs2.bbc: error! NULL sb list!\n");
  4325. + else {
  4326. + if (sb_list->sb == sb) {
  4327. + jffs2_bbc_free_small(sb_list);
  4328. + sb_list = NULL;
  4329. + done = 1;
  4330. + }
  4331. + else {
  4332. + sb_l = sb_list;
  4333. + while (sb_l->next != NULL) {
  4334. + if (sb_l->next->sb == sb) {
  4335. + sb_l2 = sb_l->next->next;
  4336. + jffs2_bbc_free_small(sb_l->next);
  4337. + sb_l->next = sb_l2;
  4338. + done = 1;
  4339. + }
  4340. + sb_l = sb_l->next;
  4341. + }
  4342. +
  4343. + }
  4344. + if (done == 0) {
  4345. + printk("jffs2.bbc: cannot delete sb from sblist!\n");
  4346. + }
  4347. + }
  4348. +}
  4349. +
  4350. +static int jffs2_bbc_get_mounted(void) {
  4351. + struct jffs2_bbc_fs_sb_list *sb_l;
  4352. + int num = 0;
  4353. +
  4354. + sb_l = sb_list;
  4355. + while (sb_l != NULL) {
  4356. + num++;
  4357. + sb_l = sb_l->next;
  4358. + }
  4359. + return num;
  4360. +
  4361. +}
  4362. +
  4363. +int jffs2_bbc_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data)
  4364. +{
  4365. + int len = 0, mode;
  4366. +
  4367. + mode = jffs2_bbc_get_compression_mode();
  4368. + len += sprintf(buf + len, "BBC version: %s\n", JFFS2_BBC_VERSION);
  4369. + len += sprintf(buf+len,"Mounted jffs2 filesystems: %d\n",jffs2_bbc_get_mounted());
  4370. + //len += sprintf(buf+len,"actual model file inode: %d\n",jffs2_bbc_model_get_inum());
  4371. + len += sprintf(buf + len, "Compression mode: ");
  4372. + if (mode == JFFS2_BBC_ZLIB_MODE)
  4373. + len += sprintf(buf + len, "ZLIB mode");
  4374. + else if (mode == JFFS2_BBC_SIZE_MODE)
  4375. + len += sprintf(buf + len, "SIZE mode");
  4376. + else if (mode == JFFS2_BBC_FASTR_MODE)
  4377. + len += sprintf(buf + len, "FASTR mode");
  4378. + else if (mode == JFFS2_BBC_FASTW_MODE)
  4379. + len += sprintf(buf + len, "FASTW mode");
  4380. + else if (mode == JFFS2_BBC_FASTS_MODE)
  4381. + len += sprintf(buf + len, "FASTS mode");
  4382. + else if (mode == JFFS2_BBC_DUMMY_MODE)
  4383. + len += sprintf(buf + len, "DUMMY mode");
  4384. + else if (mode == JFFS2_BBC_MANUAL_MODE) {
  4385. + len += sprintf(buf + len, "MANUAL mode (");
  4386. + if (jffs2_bbc_get_manual_compressor() != NULL)
  4387. + len += sprintf(buf + len, "%s)", jffs2_bbc_get_manual_compressor()->name);
  4388. + else
  4389. + len += sprintf(buf + len, "ZLIB)");
  4390. + }
  4391. + else
  4392. + len += sprintf(buf + len, "unknown mode");
  4393. + len += sprintf(buf + len, "\n");
  4394. + len += sprintf(buf + len, "%s", jffs2_bbc_get_compr_stats());
  4395. + len += sprintf(buf + len, "%s", jffs2_bbc_get_model_stats());
  4396. + len += sprintf(buf + len, "%s", jffs2_bbc_get_mem_stats());
  4397. + *eof = 1;
  4398. + return len;
  4399. +}
  4400. +
  4401. +int jffs2_bbc_proc_write(struct file *file, const char *buffer_orig, unsigned long count, void *data)
  4402. +{
  4403. + char *buffer;
  4404. + int i;
  4405. + struct jffs2_bbc_fs_sb_list *sb_l;
  4406. +
  4407. + if (buffer_orig == NULL) return 0;
  4408. +
  4409. + buffer = jffs2_bbc_malloc(count+2);
  4410. + for (i=0;i<count;i++) buffer[i]=buffer_orig[i];
  4411. + buffer[count] = 0;
  4412. + if ((*buffer == 'z') || (*buffer == 'Z')) {
  4413. + jffs2_bbc_set_compression_mode(JFFS2_BBC_ZLIB_MODE);
  4414. + jffs2_bbc_print1("jffs2.bbc: ZLIB compression mode activated.\n");
  4415. + jffs2_bbc_free(buffer);
  4416. + return count;
  4417. + }
  4418. + else if ((*buffer == 's') || (*buffer == 'S')) {
  4419. + jffs2_bbc_set_compression_mode(JFFS2_BBC_SIZE_MODE);
  4420. + jffs2_bbc_print1("jffs2.bbc: SIZE compression mode activated.\n");
  4421. + jffs2_bbc_free(buffer);
  4422. + return count;
  4423. + }
  4424. + else if ((*buffer == 'd') || (*buffer == 'D')) {
  4425. + jffs2_bbc_set_compression_mode(JFFS2_BBC_DUMMY_MODE);
  4426. + jffs2_bbc_print1("jffs2.bbc: DUMMY compression mode activated.\n");
  4427. + jffs2_bbc_free(buffer);
  4428. + return count;
  4429. + }
  4430. + else if (((*buffer == 'm') || (*buffer == 'M')) && (count >= 3) && (buffer[1] == ':')) {
  4431. + jffs2_bbc_print1("jffs2.bbc: activating MANUAL mode.\n");
  4432. + jffs2_bbc_set_manual_compressor_by_name(buffer + 2);
  4433. + jffs2_bbc_free(buffer);
  4434. + return count;
  4435. + }
  4436. + else if (((*buffer == '0')) && (count >= 3) && (buffer[1] == ':')) {
  4437. + jffs2_bbc_print1("jffs2.bbc: disabling a compressor... ");
  4438. + if (jffs2_bbc_disable_compressor_by_name(buffer + 2) == 0) {
  4439. + jffs2_bbc_print1("done.\n");
  4440. + }
  4441. + else {
  4442. + jffs2_bbc_print1("not found.\n");
  4443. + }
  4444. + jffs2_bbc_free(buffer);
  4445. + return count;
  4446. + }
  4447. + else if (((*buffer == '1')) && (count >= 3) && (buffer[1] == ':')) {
  4448. + jffs2_bbc_print1("jffs2.bbc: enabling a compressor... ");
  4449. + if (jffs2_bbc_enable_compressor_by_name(buffer + 2) == 0) {
  4450. + jffs2_bbc_print1("done.\n");
  4451. + }
  4452. + else {
  4453. + jffs2_bbc_print1("not found.\n");
  4454. + }
  4455. + jffs2_bbc_free(buffer);
  4456. + return count;
  4457. + }
  4458. + else if (((*buffer == 'c') || (*buffer == 'C')) && (count >= 3) && (buffer[1] == ':')) {
  4459. + jffs2_bbc_compressor_command_by_name(buffer + 2);
  4460. + jffs2_bbc_free(buffer);
  4461. + return count;
  4462. + }
  4463. + else if ((*buffer == 'r') || (*buffer == 'R')) {
  4464. + jffs2_bbc_print1("jffs2.bbc: reloading model files:\n");
  4465. + sb_l = sb_list;
  4466. + while (sb_l != NULL) {
  4467. + jffs2_bbc_unload_model(sb_l->sb);
  4468. + jffs2_bbc_load_model(sb_l->sb);
  4469. + sb_l = sb_l->next;
  4470. + }
  4471. + jffs2_bbc_free(buffer);
  4472. + return count;
  4473. + }
  4474. + else if (((buffer[0] == 'f') || (buffer[0] == 'F'))&&((buffer[1] == 'r') || (buffer[1] == 'R'))) {
  4475. + jffs2_bbc_set_compression_mode(JFFS2_BBC_FASTR_MODE);
  4476. + jffs2_bbc_print1("jffs2.bbc: FASTR compression mode activated.\n");
  4477. + jffs2_bbc_free(buffer);
  4478. + return count;
  4479. + }
  4480. + else if (((buffer[0] == 'f') || (buffer[0] == 'F'))&&((buffer[1] == 'w') || (buffer[1] == 'W'))) {
  4481. + jffs2_bbc_set_compression_mode(JFFS2_BBC_FASTW_MODE);
  4482. + jffs2_bbc_print1("jffs2.bbc: FASTW compression mode activated.\n");
  4483. + jffs2_bbc_free(buffer);
  4484. + return count;
  4485. + }
  4486. + else if (((buffer[0] == 'f') || (buffer[0] == 'F'))&&((buffer[1] == 's') || (buffer[1] == 'S'))) {
  4487. + jffs2_bbc_set_compression_mode(JFFS2_BBC_FASTS_MODE);
  4488. + jffs2_bbc_print1("jffs2.bbc: FASTS compression mode activated.\n");
  4489. + jffs2_bbc_free(buffer);
  4490. + return count;
  4491. + }
  4492. +
  4493. + jffs2_bbc_print1("jffs2.bbc: unkown command. Valid commands are:\n"
  4494. + " z = switch to ZLIB compression mode\n"
  4495. + " s = switch to SIZE compression mode\n"
  4496. + " d = switch to DUMMY compression mode\n"
  4497. + " fr = switch to FASTR compression mode\n"
  4498. + " fw = switch to FASTW compression mode\n"
  4499. + " fs = switch to FASTS compression mode\n"
  4500. + " r = reread model files from actual file system\n"
  4501. + " m:compressor_name = switch to MANUAL compression mode\n"
  4502. + " 0:compressor_name = disable a compressor\n"
  4503. + " 1:compressor_name = enable a compressor\n"
  4504. + " c:compressor_name:command = enable a compressor\n");
  4505. + jffs2_bbc_free(buffer);
  4506. + return count;
  4507. +}
  4508. +
  4509. +void jffs2_bbc_proc_init()
  4510. +{
  4511. + struct proc_dir_entry *res = create_proc_entry("jffs2_bbc", 0, NULL);
  4512. + jffs2_bbc_compressor_init();
  4513. + if (res) {
  4514. + res->read_proc = jffs2_bbc_proc_read;
  4515. + res->write_proc = jffs2_bbc_proc_write;
  4516. + }
  4517. +}
  4518. +
  4519. +void jffs2_bbc_proc_deinit()
  4520. +{
  4521. + jffs2_bbc_compressor_deinit();
  4522. + remove_proc_entry("jffs2_bbc", NULL);
  4523. +}
  4524. --- /dev/null
  4525. +++ b/fs/jffs2/jffs2_bbc_fs.h
  4526. @@ -0,0 +1,30 @@
  4527. +/*
  4528. + * JFFS2 BBC: File System Extension for Linux Kernel - headers
  4529. + *
  4530. + * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  4531. + *
  4532. + * Copyright (C) 2004, Ferenc Havasi
  4533. + *
  4534. + * This program is free software; you can redistribute it and/or
  4535. + * modify it under the terms of the GNU General Public License
  4536. + * as published by the Free Software Foundation; either version 2
  4537. + * of the License, or (at your option) any later version.
  4538. + *
  4539. + * This program is distributed in the hope that it will be useful,
  4540. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4541. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4542. + * GNU General Public License for more details.
  4543. + *
  4544. + * You should have received a copy of the GNU General Public License
  4545. + * along with this program; if not, write to the Free Software
  4546. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  4547. + *
  4548. + */
  4549. +
  4550. +extern int jffs2_bbc_inode_not_found;
  4551. +
  4552. +void jffs2_bbc_load_model(void *sb);
  4553. +void jffs2_bbc_unload_model(void *sb);
  4554. +
  4555. +void jffs2_bbc_proc_init(void);
  4556. +void jffs2_bbc_proc_deinit(void);
  4557. --- /dev/null
  4558. +++ b/fs/jffs2/jffs2_bbc_lzari_comp.c
  4559. @@ -0,0 +1,788 @@
  4560. +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
  4561. +
  4562. +/*
  4563. + jffs2_bbc_lzari_comp.c -- Lempel-Ziv-Arithmetic coding compression module for jffs2
  4564. + Copyright (C) 2004 Patrik Kluba
  4565. + Based on the LZARI source included in LDS (lossless datacompression sources)
  4566. + Block-compression and bitstream modifications by Patrik Kluba
  4567. + $Header: /openwrt/openwrt/package/linux/kernel-patches/301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  4568. +*/
  4569. +
  4570. +/*
  4571. +Original copyright follows:
  4572. +
  4573. +**************************************************************
  4574. + LZARI.C -- A Data Compression Program
  4575. + (tab = 4 spaces)
  4576. +**************************************************************
  4577. + 4/7/1989 Haruhiko Okumura
  4578. + Use, distribute, and modify this program freely.
  4579. + Please send me your improved versions.
  4580. + PC-VAN SCIENCE
  4581. + NIFTY-Serve PAF01022
  4582. + CompuServe 74050,1022
  4583. +**************************************************************
  4584. +
  4585. +LZARI.C (c)1989 by Haruyasu Yoshizaki, Haruhiko Okumura, and Kenji Rikitake.
  4586. +All rights reserved. Permission granted for non-commercial use.
  4587. +
  4588. +*/
  4589. +
  4590. +/*
  4591. +
  4592. + 2004-02-18 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu>
  4593. + Removed unused variables and fixed no return value
  4594. +
  4595. + 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu>
  4596. + Initial release
  4597. +
  4598. +*/
  4599. +
  4600. +/* lzari.c */
  4601. +
  4602. +#define N 4096 /* size of ring buffer */
  4603. +#define F 60 /* upper limit for match_length */
  4604. +#define THRESHOLD 2 /* encode string into position and length
  4605. + if match_length is greater than this */
  4606. +#define NIL N /* index for root of binary search trees */
  4607. +
  4608. +static unsigned char
  4609. + text_buf[N + F - 1]; /* ring buffer of size N,
  4610. + with extra F-1 bytes to facilitate string comparison */
  4611. +static unsigned long match_position, match_length, /* of longest match. These are
  4612. + set by the InsertNode() procedure. */
  4613. + lson[N + 1], rson[N + 257], dad[N + 1]; /* left & right children &
  4614. + parents -- These constitute binary search trees. */
  4615. +
  4616. +static void InitTree(void) /* Initialize trees */
  4617. +{
  4618. + unsigned long i;
  4619. +
  4620. + /* For i = 0 to N - 1, rson[i] and lson[i] will be the right and
  4621. + left children of node i. These nodes need not be initialized.
  4622. + Also, dad[i] is the parent of node i. These are initialized to
  4623. + NIL (= N), which stands for 'not used.'
  4624. + For i = 0 to 255, rson[N + i + 1] is the root of the tree
  4625. + for strings that begin with character i. These are initialized
  4626. + to NIL. Note there are 256 trees. */
  4627. +
  4628. + for (i = N + 1; i <= N + 256; i++) rson[i] = NIL; /* root */
  4629. + for (i = 0; i < N; i++) dad[i] = NIL; /* node */
  4630. +}
  4631. +
  4632. +static void InsertNode(unsigned long r)
  4633. + /* Inserts string of length F, text_buf[r..r+F-1], into one of the
  4634. + trees (text_buf[r]'th tree) and returns the longest-match position
  4635. + and length via the global variables match_position and match_length.
  4636. + If match_length = F, then removes the old node in favor of the new
  4637. + one, because the old one will be deleted sooner.
  4638. + Note r plays double role, as tree node and position in buffer. */
  4639. +{
  4640. + unsigned long i, p, temp;
  4641. + unsigned char *key;
  4642. + signed long cmp;
  4643. +
  4644. + cmp = 1; key = &text_buf[r]; p = N + 1 + key[0];
  4645. + rson[r] = lson[r] = NIL; match_length = 0;
  4646. + for ( ; ; ) {
  4647. + if (cmp >= 0) {
  4648. + if (rson[p] != NIL) p = rson[p];
  4649. + else { rson[p] = r; dad[r] = p; return; }
  4650. + } else {
  4651. + if (lson[p] != NIL) p = lson[p];
  4652. + else { lson[p] = r; dad[r] = p; return; }
  4653. + }
  4654. + for (i = 1; i < F; i++)
  4655. + if ((cmp = key[i] - text_buf[p + i]) != 0) break;
  4656. + if (i > THRESHOLD) {
  4657. + if (i > match_length) {
  4658. + match_position = (r - p) & (N - 1);
  4659. + if ((match_length = i) >= F) break;
  4660. + } else if (i == match_length) {
  4661. + if ((temp = (r - p) & (N - 1)) < match_position)
  4662. + match_position = temp;
  4663. + }
  4664. + }
  4665. + }
  4666. + dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p];
  4667. + dad[lson[p]] = r; dad[rson[p]] = r;
  4668. + if (rson[dad[p]] == p) rson[dad[p]] = r;
  4669. + else lson[dad[p]] = r;
  4670. + dad[p] = NIL; /* remove p */
  4671. +}
  4672. +
  4673. +static void DeleteNode(unsigned long p) /* Delete node p from tree */
  4674. +{
  4675. + unsigned long q;
  4676. +
  4677. + if (dad[p] == NIL) return; /* not in tree */
  4678. + if (rson[p] == NIL) q = lson[p];
  4679. + else if (lson[p] == NIL) q = rson[p];
  4680. + else {
  4681. + q = lson[p];
  4682. + if (rson[q] != NIL) {
  4683. + do { q = rson[q]; } while (rson[q] != NIL);
  4684. + rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q];
  4685. + lson[q] = lson[p]; dad[lson[p]] = q;
  4686. + }
  4687. + rson[q] = rson[p]; dad[rson[p]] = q;
  4688. + }
  4689. + dad[q] = dad[p];
  4690. + if (rson[dad[p]] == p) rson[dad[p]] = q;
  4691. + else lson[dad[p]] = q;
  4692. + dad[p] = NIL;
  4693. +}
  4694. +
  4695. +/********** Arithmetic Compression **********/
  4696. +
  4697. +/* If you are not familiar with arithmetic compression, you should read
  4698. + I. E. Witten, R. M. Neal, and J. G. Cleary,
  4699. + Communications of the ACM, Vol. 30, pp. 520-540 (1987),
  4700. + from which much have been borrowed. */
  4701. +
  4702. +#define M 15
  4703. +
  4704. +/* Q1 (= 2 to the M) must be sufficiently large, but not so
  4705. + large as the unsigned long 4 * Q1 * (Q1 - 1) overflows. */
  4706. +
  4707. +#define Q1 (1UL << M)
  4708. +#define Q2 (2 * Q1)
  4709. +#define Q3 (3 * Q1)
  4710. +#define Q4 (4 * Q1)
  4711. +#define MAX_CUM (Q1 - 1)
  4712. +
  4713. +#define N_CHAR (256 - THRESHOLD + F)
  4714. + /* character code = 0, 1, ..., N_CHAR - 1 */
  4715. +
  4716. +static unsigned long char_to_sym[N_CHAR], sym_to_char[N_CHAR + 1];
  4717. +static unsigned long
  4718. + sym_freq[N_CHAR + 1], /* frequency for symbols */
  4719. + sym_cum[N_CHAR + 1], /* cumulative freq for symbols */
  4720. + position_cum[N + 1]; /* cumulative freq for positions */
  4721. +
  4722. +static void StartModel(void) /* Initialize model */
  4723. +{
  4724. + unsigned long ch, sym, i;
  4725. +
  4726. + sym_cum[N_CHAR] = 0;
  4727. + for (sym = N_CHAR; sym >= 1; sym--) {
  4728. + ch = sym - 1;
  4729. + char_to_sym[ch] = sym; sym_to_char[sym] = ch;
  4730. + sym_freq[sym] = 1;
  4731. + sym_cum[sym - 1] = sym_cum[sym] + sym_freq[sym];
  4732. + }
  4733. + sym_freq[0] = 0; /* sentinel (!= sym_freq[1]) */
  4734. + position_cum[N] = 0;
  4735. + for (i = N; i >= 1; i--)
  4736. + position_cum[i - 1] = position_cum[i] + 10000 / (i + 200);
  4737. + /* empirical distribution function (quite tentative) */
  4738. + /* Please devise a better mechanism! */
  4739. +}
  4740. +
  4741. +static void UpdateModel(unsigned long sym)
  4742. +{
  4743. + unsigned long c, ch_i, ch_sym;
  4744. + unsigned long i;
  4745. + if (sym_cum[0] >= MAX_CUM) {
  4746. + c = 0;
  4747. + for (i = N_CHAR; i > 0; i--) {
  4748. + sym_cum[i] = c;
  4749. + c += (sym_freq[i] = (sym_freq[i] + 1) >> 1);
  4750. + }
  4751. + sym_cum[0] = c;
  4752. + }
  4753. + for (i = sym; sym_freq[i] == sym_freq[i - 1]; i--) ;
  4754. + if (i < sym) {
  4755. + ch_i = sym_to_char[i]; ch_sym = sym_to_char[sym];
  4756. + sym_to_char[i] = ch_sym; sym_to_char[sym] = ch_i;
  4757. + char_to_sym[ch_i] = sym; char_to_sym[ch_sym] = i;
  4758. + }
  4759. + sym_freq[i]++;
  4760. + while (--i > 0) sym_cum[i]++;
  4761. + sym_cum[0]++;
  4762. +}
  4763. +
  4764. +static unsigned long BinarySearchSym(unsigned long x)
  4765. + /* 1 if x >= sym_cum[1],
  4766. + N_CHAR if sym_cum[N_CHAR] > x,
  4767. + i such that sym_cum[i - 1] > x >= sym_cum[i] otherwise */
  4768. +{
  4769. + unsigned long i, j, k;
  4770. +
  4771. + i = 1; j = N_CHAR;
  4772. + while (i < j) {
  4773. + k = (i + j) / 2;
  4774. + if (sym_cum[k] > x) i = k + 1; else j = k;
  4775. + }
  4776. + return i;
  4777. +}
  4778. +
  4779. +unsigned long BinarySearchPos(unsigned long x)
  4780. + /* 0 if x >= position_cum[1],
  4781. + N - 1 if position_cum[N] > x,
  4782. + i such that position_cum[i] > x >= position_cum[i + 1] otherwise */
  4783. +{
  4784. + unsigned long i, j, k;
  4785. +
  4786. + i = 1; j = N;
  4787. + while (i < j) {
  4788. + k = (i + j) / 2;
  4789. + if (position_cum[k] > x) i = k + 1; else j = k;
  4790. + }
  4791. + return i - 1;
  4792. +}
  4793. +
  4794. +/* modified for block compression */
  4795. +/* on return, srclen will contain the number of successfully compressed bytes
  4796. + and dstlen will contain completed compressed bytes */
  4797. +
  4798. +static int Encode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long *srclen,
  4799. + unsigned long *dstlen)
  4800. +{
  4801. + unsigned long c, i, len, r, s, last_match_length, sym, range;
  4802. + unsigned long low = 0;
  4803. + unsigned long high = Q4;
  4804. + unsigned long shifts = 0; /* counts for magnifying low and high around Q2 */
  4805. + unsigned char *ip, *op;
  4806. + unsigned long written = 0;
  4807. + unsigned long read = 0;
  4808. + unsigned char buffer = 0;
  4809. + unsigned char mask = 128;
  4810. + unsigned char *srcend = srcbuf + *srclen;
  4811. + unsigned char *dstend = dstbuf + *dstlen;
  4812. + ip = srcbuf;
  4813. + op = dstbuf;
  4814. + StartModel();
  4815. + InitTree(); /* initialize trees */
  4816. + s = 0; r = N - F;
  4817. + for (i = s; i < r; i++) text_buf[i] = ' '; /* Clear the buffer with
  4818. + any character that will appear often. */
  4819. + for (len = 0; (len < F) && (ip < srcend); len++)
  4820. + text_buf[r + len] = *(ip++); /* Read F bytes into the last F bytes of
  4821. + the buffer */
  4822. + read = len;
  4823. + for (i = 1; i <= F; i++) InsertNode(r - i); /* Insert the F strings,
  4824. + each of which begins with one or more 'space' characters. Note
  4825. + the order in which these strings are inserted. This way,
  4826. + degenerate trees will be less likely to occur. */
  4827. + InsertNode(r); /* Finally, insert the whole string just read. The
  4828. + global variables match_length and match_position are set. */
  4829. + do {
  4830. + if (match_length > len) match_length = len; /* match_length
  4831. + may be spuriously long near the end of text. */
  4832. + if (match_length <= THRESHOLD) {
  4833. + match_length = 1; /* Not long enough match. Send one byte. */
  4834. + sym = char_to_sym[text_buf[r]];
  4835. + range = high - low;
  4836. + high = low + (range * sym_cum[sym - 1]) / sym_cum[0];
  4837. + low += (range * sym_cum[sym ]) / sym_cum[0];
  4838. + for ( ; ; ) {
  4839. + if (high <= Q2) {
  4840. + if ((mask >>= 1) == 0) {
  4841. + if (op >= dstend) {
  4842. + *dstlen = written;
  4843. + return -1;
  4844. + }
  4845. + *(op++) = buffer;
  4846. + buffer = 0;
  4847. + mask = 128;
  4848. + written++;
  4849. + *srclen = read;
  4850. + }
  4851. + for ( ; shifts > 0; shifts--) {
  4852. + buffer |= mask;
  4853. + if ((mask >>= 1) == 0) {
  4854. + if (op >= dstend) {
  4855. + *dstlen = written;
  4856. + return -1;
  4857. + }
  4858. + *(op++) = buffer;
  4859. + buffer = 0;
  4860. + mask = 128;
  4861. + written++;
  4862. + *srclen = read;
  4863. + }
  4864. + }
  4865. + } else if (low >= Q2) {
  4866. + buffer |= mask;
  4867. + if ((mask >>= 1) == 0) {
  4868. + if (op >= dstend) {
  4869. + *dstlen = written;
  4870. + return -1;
  4871. + }
  4872. + *(op++) = buffer;
  4873. + buffer = 0;
  4874. + mask = 128;
  4875. + written++;
  4876. + *srclen = read;
  4877. + }
  4878. + for ( ; shifts > 0; shifts--) {
  4879. + if ((mask >>= 1) == 0) {
  4880. + if (op >= dstend) {
  4881. + *dstlen = written;
  4882. + return -1;
  4883. + }
  4884. + *(op++) = buffer;
  4885. + buffer = 0;
  4886. + mask = 128;
  4887. + written++;
  4888. + *srclen = read;
  4889. + }
  4890. + }
  4891. + low -= Q2;
  4892. + high -= Q2;
  4893. + } else if (low >= Q1 && high <= Q3) {
  4894. + shifts++;
  4895. + low -= Q1;
  4896. + high -= Q1;
  4897. + } else break;
  4898. + low += low; high += high;
  4899. + }
  4900. + UpdateModel(sym);
  4901. + } else {
  4902. + sym = char_to_sym[255 - THRESHOLD + match_length];
  4903. + range = high - low;
  4904. + high = low + (range * sym_cum[sym - 1]) / sym_cum[0];
  4905. + low += (range * sym_cum[sym ]) / sym_cum[0];
  4906. + for ( ; ; ) {
  4907. + if (high <= Q2) {
  4908. + if ((mask >>= 1) == 0) {
  4909. + if (op >= dstend) {
  4910. + *dstlen = written;
  4911. + return -1;
  4912. + }
  4913. + *(op++) = buffer;
  4914. + buffer = 0;
  4915. + mask = 128;
  4916. + written++;
  4917. + *srclen = read;
  4918. + }
  4919. + for ( ; shifts > 0; shifts--) {
  4920. + buffer |= mask;
  4921. + if ((mask >>= 1) == 0) {
  4922. + if (op >= dstend) {
  4923. + *dstlen = written;
  4924. + return -1;
  4925. + }
  4926. + *(op++) = buffer;
  4927. + buffer = 0;
  4928. + mask = 128;
  4929. + written++;
  4930. + *srclen = read;
  4931. + }
  4932. + }
  4933. + } else if (low >= Q2) {
  4934. + buffer |= mask;
  4935. + if ((mask >>= 1) == 0) {
  4936. + if (op >= dstend) {
  4937. + *dstlen = written;
  4938. + return -1;
  4939. + }
  4940. + *(op++) = buffer;
  4941. + buffer = 0;
  4942. + mask = 128;
  4943. + written++;
  4944. + *srclen = read;
  4945. + }
  4946. + for ( ; shifts > 0; shifts--) {
  4947. + if ((mask >>= 1) == 0) {
  4948. + if (op >= dstend) {
  4949. + *dstlen = written;
  4950. + return -1;
  4951. + }
  4952. + *(op++) = buffer;
  4953. + buffer = 0;
  4954. + mask = 128;
  4955. + written++;
  4956. + *srclen = read;
  4957. + }
  4958. + }
  4959. + low -= Q2;
  4960. + high -= Q2;
  4961. + } else if (low >= Q1 && high <= Q3) {
  4962. + shifts++;
  4963. + low -= Q1;
  4964. + high -= Q1;
  4965. + } else break;
  4966. + low += low; high += high;
  4967. + }
  4968. + UpdateModel(sym);
  4969. + range = high - low;
  4970. + high = low + (range * position_cum[match_position - 1]) / position_cum[0];
  4971. + low += (range * position_cum[match_position ]) / position_cum[0];
  4972. + for ( ; ; ) {
  4973. + if (high <= Q2) {
  4974. + if ((mask >>= 1) == 0) {
  4975. + if (op >= dstend) {
  4976. + *dstlen = written;
  4977. + return -1;
  4978. + }
  4979. + *(op++) = buffer;
  4980. + buffer = 0;
  4981. + mask = 128;
  4982. + written++;
  4983. + *srclen = read;
  4984. + }
  4985. + for ( ; shifts > 0; shifts--) {
  4986. + buffer |= mask;
  4987. + if ((mask >>= 1) == 0) {
  4988. + if (op >= dstend) {
  4989. + *dstlen = written;
  4990. + return -1;
  4991. + }
  4992. + *(op++) = buffer;
  4993. + buffer = 0;
  4994. + mask = 128;
  4995. + written++;
  4996. + *srclen = read;
  4997. + }
  4998. + }
  4999. + } else {
  5000. + if (low >= Q2) {
  5001. + buffer |= mask;
  5002. + if ((mask >>= 1) == 0) {
  5003. + if (op >= dstend) {
  5004. + *dstlen = written;
  5005. + return -1;
  5006. + }
  5007. + *(op++) = buffer;
  5008. + buffer = 0;
  5009. + mask = 128;
  5010. + written++;
  5011. + *srclen = read;
  5012. + }
  5013. + for ( ; shifts > 0; shifts--) {
  5014. + if ((mask >>= 1) == 0) {
  5015. + if (op >= dstend) {
  5016. + *dstlen = written;
  5017. + return -1;
  5018. + }
  5019. + *(op++) = buffer;
  5020. + buffer = 0;
  5021. + mask = 128;
  5022. + written++;
  5023. + *srclen = read;
  5024. + }
  5025. + }
  5026. + low -= Q2;
  5027. + high -= Q2;
  5028. + } else {
  5029. + if ((low >= Q1) && (high <= Q3)) {
  5030. + shifts++;
  5031. + low -= Q1;
  5032. + high -= Q1;
  5033. + } else {
  5034. + break;
  5035. + }
  5036. + }
  5037. + }
  5038. + low += low;
  5039. + high += high;
  5040. + }
  5041. + }
  5042. + last_match_length = match_length;
  5043. + for (i = 0; (i < last_match_length) && (ip < srcend); i++) {
  5044. + c = *(ip++);
  5045. + DeleteNode(s);
  5046. + text_buf[s] = c;
  5047. + if (s < F - 1)
  5048. + text_buf[s + N] = c;
  5049. + s = (s + 1) & (N - 1);
  5050. + r = (r + 1) & (N - 1);
  5051. + InsertNode(r);
  5052. + }
  5053. + read += i;
  5054. + while (i++ < last_match_length) {
  5055. + DeleteNode(s);
  5056. + s = (s + 1) & (N - 1);
  5057. + r = (r + 1) & (N - 1);
  5058. + if (--len) InsertNode(r);
  5059. + }
  5060. + } while (len > 0);
  5061. + shifts++;
  5062. + if (low < Q1) {
  5063. + if ((mask >>= 1) == 0) {
  5064. + if (op >= dstend) {
  5065. + *dstlen = written;
  5066. + return -1;
  5067. + }
  5068. + *(op++) = buffer;
  5069. + buffer = 0;
  5070. + mask = 128;
  5071. + written++;
  5072. + *srclen = read;
  5073. + }
  5074. + for ( ; shifts > 0; shifts--) {
  5075. + buffer |= mask;
  5076. + if ((mask >>= 1) == 0) {
  5077. + if (op >= dstend) {
  5078. + *dstlen = written;
  5079. + return -1;
  5080. + }
  5081. + *(op++) = buffer;
  5082. + buffer = 0;
  5083. + mask = 128;
  5084. + written++;
  5085. + *srclen = read;
  5086. + }
  5087. + }
  5088. + } else {
  5089. + buffer |= mask;
  5090. + if ((mask >>= 1) == 0) {
  5091. + if (op >= dstend) {
  5092. + *dstlen = written;
  5093. + return -1;
  5094. + }
  5095. + *(op++) = buffer;
  5096. + buffer = 0;
  5097. + mask = 128;
  5098. + written++;
  5099. + *srclen = read;
  5100. + }
  5101. + for ( ; shifts > 0; shifts--) {
  5102. + if ((mask >>= 1) == 0) {
  5103. + if (op >= dstend) {
  5104. + *dstlen = written;
  5105. + return -1;
  5106. + }
  5107. + *(op++) = buffer;
  5108. + buffer = 0;
  5109. + mask = 128;
  5110. + written++;
  5111. + *srclen = read;
  5112. + }
  5113. + }
  5114. + }
  5115. + for (i = 0; i < 7; i++) {
  5116. + if ((mask >>= 1) == 0) {
  5117. + if (op >= dstend) {
  5118. + *dstlen = written;
  5119. + return -1;
  5120. + }
  5121. + *(op++) = buffer;
  5122. + buffer = 0;
  5123. + mask = 128;
  5124. + written++;
  5125. + *srclen = read;
  5126. + }
  5127. + }
  5128. + *dstlen = written;
  5129. + return 0;
  5130. +}
  5131. +
  5132. +static int Decode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long srclen,
  5133. + unsigned long dstlen) /* Just the reverse of Encode(). */
  5134. +{
  5135. + unsigned long i, r, j, k, c, range, sym;
  5136. + unsigned char *ip, *op;
  5137. + unsigned char *srcend = srcbuf + srclen;
  5138. + unsigned char *dstend = dstbuf + dstlen;
  5139. + unsigned char buffer = 0;
  5140. + unsigned char mask = 0;
  5141. + unsigned long low = 0;
  5142. + unsigned long high = Q4;
  5143. + unsigned long value = 0;
  5144. + ip = srcbuf;
  5145. + op = dstbuf;
  5146. + for (i = 0; i < M + 2; i++) {
  5147. + value *= 2;
  5148. + if ((mask >>= 1) == 0) {
  5149. + buffer = (ip >= srcend) ? 0 : *(ip++);
  5150. + mask = 128;
  5151. + }
  5152. + value += ((buffer & mask) != 0);
  5153. + }
  5154. + StartModel();
  5155. + for (i = 0; i < N - F; i++) text_buf[i] = ' ';
  5156. + r = N - F;
  5157. + while (op < dstend) {
  5158. + range = high - low;
  5159. + sym = BinarySearchSym((unsigned long)
  5160. + (((value - low + 1) * sym_cum[0] - 1) / range));
  5161. + high = low + (range * sym_cum[sym - 1]) / sym_cum[0];
  5162. + low += (range * sym_cum[sym ]) / sym_cum[0];
  5163. + for ( ; ; ) {
  5164. + if (low >= Q2) {
  5165. + value -= Q2; low -= Q2; high -= Q2;
  5166. + } else if (low >= Q1 && high <= Q3) {
  5167. + value -= Q1; low -= Q1; high -= Q1;
  5168. + } else if (high > Q2) break;
  5169. + low += low; high += high;
  5170. + value *= 2;
  5171. + if ((mask >>= 1) == 0) {
  5172. + buffer = (ip >= srcend) ? 0 : *(ip++);
  5173. + mask = 128;
  5174. + }
  5175. + value += ((buffer & mask) != 0);
  5176. + }
  5177. + c = sym_to_char[sym];
  5178. + UpdateModel(sym);
  5179. + if (c < 256) {
  5180. + if (op >= dstend) return -1;
  5181. + *(op++) = c;
  5182. + text_buf[r++] = c;
  5183. + r &= (N - 1);
  5184. + } else {
  5185. + j = c - 255 + THRESHOLD;
  5186. + range = high - low;
  5187. + i = BinarySearchPos((unsigned long)
  5188. + (((value - low + 1) * position_cum[0] - 1) / range));
  5189. + high = low + (range * position_cum[i ]) / position_cum[0];
  5190. + low += (range * position_cum[i + 1]) / position_cum[0];
  5191. + for ( ; ; ) {
  5192. + if (low >= Q2) {
  5193. + value -= Q2; low -= Q2; high -= Q2;
  5194. + } else if (low >= Q1 && high <= Q3) {
  5195. + value -= Q1; low -= Q1; high -= Q1;
  5196. + } else if (high > Q2) break;
  5197. + low += low; high += high;
  5198. + value *= 2;
  5199. + if ((mask >>= 1) == 0) {
  5200. + buffer = (ip >= srcend) ? 0 : *(ip++);
  5201. + mask = 128;
  5202. + }
  5203. + value += ((buffer & mask) != 0);
  5204. + }
  5205. + i = (r - i - 1) & (N - 1);
  5206. + for (k = 0; k < j; k++) {
  5207. + c = text_buf[(i + k) & (N - 1)];
  5208. + if (op >= dstend) return -1;
  5209. + *(op++) = c;
  5210. + text_buf[r++] = c;
  5211. + r &= (N - 1);
  5212. + }
  5213. + }
  5214. + }
  5215. + return 0;
  5216. +}
  5217. +
  5218. +/* interface to jffs2 bbc follows */
  5219. +
  5220. +#include "jffs2_bbc_framework.h"
  5221. +
  5222. +#define JFFS2_BBC_LZARI_BLOCK_SIGN {0x73, 0x9a, 0x1c, 0x4d}
  5223. +
  5224. +static int
  5225. +jffs2_bbc_lzari_compressor_init (void);
  5226. +
  5227. +static void
  5228. +jffs2_bbc_lzari_compressor_deinit (void);
  5229. +
  5230. +static int
  5231. +jffs2_bbc_lzari_compress (void *model, unsigned char *input,
  5232. + unsigned char *output, unsigned long *sourcelen,
  5233. + unsigned long *dstlen);
  5234. +
  5235. +static int
  5236. +jffs2_bbc_lzari_estimate (void *model, unsigned char *input,
  5237. + unsigned long sourcelen, unsigned long *dstlen,
  5238. + unsigned long *readtime, unsigned long *writetime);
  5239. +
  5240. +static int
  5241. +jffs2_bbc_lzari_decompress (void *model, unsigned char *input,
  5242. + unsigned char *output, unsigned long sourcelen,
  5243. + unsigned long dstlen);
  5244. +
  5245. +static char *
  5246. +jffs2_bbc_lzari_proc_info (void);
  5247. +
  5248. +static int
  5249. +jffs2_bbc_lzari_proc_command (char *command);
  5250. +
  5251. +struct jffs2_bbc_compressor_type jffs2_bbc_lzari = {
  5252. + "lzari",
  5253. + 0,
  5254. + JFFS2_BBC_LZARI_BLOCK_SIGN,
  5255. + jffs2_bbc_lzari_compressor_init,
  5256. + NULL,
  5257. + NULL,
  5258. + jffs2_bbc_lzari_compressor_deinit,
  5259. + jffs2_bbc_lzari_compress,
  5260. + jffs2_bbc_lzari_estimate,
  5261. + jffs2_bbc_lzari_decompress,
  5262. + jffs2_bbc_lzari_proc_info,
  5263. + jffs2_bbc_lzari_proc_command
  5264. +};
  5265. +
  5266. +static int
  5267. +jffs2_bbc_lzari_compressor_init (void)
  5268. +{
  5269. + return 0;
  5270. +}
  5271. +
  5272. +static void
  5273. +jffs2_bbc_lzari_compressor_deinit (void)
  5274. +{
  5275. +}
  5276. +
  5277. +static int
  5278. +jffs2_bbc_lzari_compress (void *model, unsigned char *input,
  5279. + unsigned char *output, unsigned long *sourcelen,
  5280. + unsigned long *dstlen)
  5281. +{
  5282. + int retval;
  5283. + unsigned long dst = *dstlen;
  5284. + *(output++) = jffs2_bbc_lzari.block_sign[0];
  5285. + *(output++) = jffs2_bbc_lzari.block_sign[1];
  5286. + dst -= 2;
  5287. + retval = Encode(input, output, sourcelen, &dst);
  5288. + dst += 2;
  5289. + *dstlen = dst;
  5290. + return retval;
  5291. +}
  5292. +
  5293. +static int
  5294. +jffs2_bbc_lzari_estimate (void *model, unsigned char *input,
  5295. + unsigned long sourcelen, unsigned long *dstlen,
  5296. + unsigned long *readtime, unsigned long *writetime)
  5297. +{
  5298. + *dstlen = sourcelen / 2;
  5299. + *readtime = JFFS2_BBC_ZLIB_READ_TIME * 15;
  5300. + *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 7;
  5301. + return 0;
  5302. +}
  5303. +
  5304. +static int
  5305. +jffs2_bbc_lzari_decompress (void *model, unsigned char *input,
  5306. + unsigned char *output, unsigned long sourcelen,
  5307. + unsigned long dstlen)
  5308. +{
  5309. + if ( ( *(input++) != (unsigned char)jffs2_bbc_lzari.block_sign[0] ) ||
  5310. + ( *(input++) != (unsigned char)jffs2_bbc_lzari.block_sign[1] )
  5311. + ) {
  5312. + return -1;
  5313. + } else {
  5314. + return Decode(input, output, sourcelen - 2, dstlen);
  5315. + }
  5316. +}
  5317. +
  5318. +static char *
  5319. +jffs2_bbc_lzari_proc_info (void)
  5320. +{
  5321. + return "Lempel-Ziv-Arithmetic coding compression module";
  5322. +}
  5323. +
  5324. +static int
  5325. +jffs2_bbc_lzari_proc_command (char *command)
  5326. +{
  5327. + return 0;
  5328. +}
  5329. +
  5330. +struct jffs2_bbc_compressor_type *
  5331. +jffs2_bbc_lzari_init (int mode)
  5332. +{
  5333. + if (jffs2_bbc_register_compressor (&jffs2_bbc_lzari) == 0)
  5334. + {
  5335. + return &jffs2_bbc_lzari;
  5336. + }
  5337. + else
  5338. + {
  5339. + return NULL;
  5340. + }
  5341. +}
  5342. +
  5343. +void
  5344. +jffs2_bbc_lzari_deinit (void)
  5345. +{
  5346. + jffs2_bbc_unregister_compressor (&jffs2_bbc_lzari);
  5347. +}
  5348. --- /dev/null
  5349. +++ b/fs/jffs2/jffs2_bbc_lzhd_comp.c
  5350. @@ -0,0 +1,747 @@
  5351. +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
  5352. +
  5353. +/*
  5354. + jffs2_bbc_lzhd_comp.c -- Lempel-Ziv-(dynamic) Huffman compression module for jffs2
  5355. + Copyright (C) 2004 Patrik Kluba
  5356. + Based on the LZHUF source included in LDS (lossless datacompression sources)
  5357. + Block-compression and bitstream modifications by Patrik Kluba
  5358. + $Header: /openwrt/openwrt/package/linux/kernel-patches/301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  5359. +*/
  5360. +
  5361. +/*
  5362. +Original copyright follows:
  5363. +
  5364. +**************************************************************
  5365. + lzhuf.c
  5366. + written by Haruyasu Yoshizaki 11/20/1988
  5367. + some minor changes 4/6/1989
  5368. + comments translated by Haruhiko Okumura 4/7/1989
  5369. +**************************************************************
  5370. +
  5371. +LZHUF.C (c)1989 by Haruyasu Yoshizaki, Haruhiko Okumura, and Kenji Rikitake.
  5372. +All rights reserved. Permission granted for non-commercial use.
  5373. +
  5374. +*/
  5375. +
  5376. +/*
  5377. +
  5378. + 2004-02-18 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu>
  5379. + Replaced name lzh-d with lzhd
  5380. + Fixed no return value
  5381. +
  5382. + 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu>
  5383. + Initial release
  5384. +
  5385. +*/
  5386. +
  5387. +/* required because of memmove */
  5388. +#ifndef __KERNEL__
  5389. + #include <string.h>
  5390. +#else
  5391. + #include <linux/string.h>
  5392. +#endif
  5393. +
  5394. +/* lzhuf.c */
  5395. +
  5396. +#define N 4096 /* size of ring buffer */
  5397. +#define F 60 /* upper limit for match_length */
  5398. +#define THRESHOLD 2 /* encode string into position and length
  5399. + if match_length is greater than this */
  5400. +#define NIL N /* index for root of binary search trees */
  5401. +
  5402. +static unsigned char
  5403. + text_buf[N + F - 1]; /* ring buffer of size N,
  5404. + with extra F-1 bytes to facilitate string comparison */
  5405. +static unsigned long match_position, match_length, /* of longest match. These are
  5406. + set by the InsertNode() procedure. */
  5407. + lson[N + 1], rson[N + 257], dad[N + 1]; /* left & right children &
  5408. + parents -- These constitute binary search trees. */
  5409. +
  5410. +static void InitTree(void) /* initialize trees */
  5411. +{
  5412. + unsigned long i;
  5413. +
  5414. + /* For i = 0 to N - 1, rson[i] and lson[i] will be the right and
  5415. + left children of node i. These nodes need not be initialized.
  5416. + Also, dad[i] is the parent of node i. These are initialized to
  5417. + NIL (= N), which stands for 'not used.'
  5418. + For i = 0 to 255, rson[N + i + 1] is the root of the tree
  5419. + for strings that begin with character i. These are initialized
  5420. + to NIL. Note there are 256 trees. */
  5421. +
  5422. + for (i = N + 1; i <= N + 256; i++) rson[i] = NIL;
  5423. + for (i = 0; i < N; i++) dad[i] = NIL;
  5424. +}
  5425. +
  5426. +static void InsertNode(unsigned long r)
  5427. + /* Inserts string of length F, text_buf[r..r+F-1], into one of the
  5428. + trees (text_buf[r]'th tree) and returns the longest-match position
  5429. + and length via the global variables match_position and match_length.
  5430. + If match_length = F, then removes the old node in favor of the new
  5431. + one, because the old one will be deleted sooner.
  5432. + Note r plays double role, as tree node and position in buffer. */
  5433. +{
  5434. + unsigned long i, p, c;
  5435. + signed long cmp;
  5436. + unsigned char *key;
  5437. +
  5438. + cmp = 1; key = &text_buf[r]; p = N + 1 + key[0];
  5439. + rson[r] = lson[r] = NIL; match_length = 0;
  5440. + for ( ; ; ) {
  5441. + if (cmp >= 0) {
  5442. + if (rson[p] != NIL) p = rson[p];
  5443. + else { rson[p] = r; dad[r] = p; return; }
  5444. + } else {
  5445. + if (lson[p] != NIL) p = lson[p];
  5446. + else { lson[p] = r; dad[r] = p; return; }
  5447. + }
  5448. + for (i = 1; i < F; i++)
  5449. + if ((cmp = key[i] - text_buf[p + i]) != 0) break;
  5450. + if (i > THRESHOLD) {
  5451. + if (i > match_length) {
  5452. + match_position = ((r - p) & (N - 1)) - 1;
  5453. + if ((match_length = i) >= F) break;
  5454. + }
  5455. + if (i == match_length) {
  5456. + if ((c = ((r - p) & (N - 1)) - 1) < match_position) {
  5457. + match_position = c;
  5458. + }
  5459. + }
  5460. + }
  5461. + }
  5462. + dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p];
  5463. + dad[lson[p]] = r; dad[rson[p]] = r;
  5464. + if (rson[dad[p]] == p) rson[dad[p]] = r;
  5465. + else lson[dad[p]] = r;
  5466. + dad[p] = NIL; /* remove p */
  5467. +}
  5468. +
  5469. +static void DeleteNode(unsigned long p) /* deletes node p from tree */
  5470. +{
  5471. + unsigned long q;
  5472. +
  5473. + if (dad[p] == NIL) return; /* not in tree */
  5474. + if (rson[p] == NIL) q = lson[p];
  5475. + else if (lson[p] == NIL) q = rson[p];
  5476. + else {
  5477. + q = lson[p];
  5478. + if (rson[q] != NIL) {
  5479. + do { q = rson[q]; } while (rson[q] != NIL);
  5480. + rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q];
  5481. + lson[q] = lson[p]; dad[lson[p]] = q;
  5482. + }
  5483. + rson[q] = rson[p]; dad[rson[p]] = q;
  5484. + }
  5485. + dad[q] = dad[p];
  5486. + if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q;
  5487. + dad[p] = NIL;
  5488. +}
  5489. +
  5490. +/* Huffman coding */
  5491. +
  5492. +#define N_CHAR (256 - THRESHOLD + F)
  5493. + /* kinds of characters (character code = 0..N_CHAR-1) */
  5494. +#define T (N_CHAR * 2 - 1) /* size of table */
  5495. +#define R (T - 1) /* position of root */
  5496. +#define MAX_FREQ 0x8000 /* updates tree when the */
  5497. + /* root frequency comes to this value. */
  5498. +
  5499. +typedef unsigned long uchar; // much-much faster
  5500. +
  5501. +/* table for encoding and decoding the upper 6 bits of position */
  5502. +
  5503. +/* for encoding */
  5504. +static uchar p_len[64] = {
  5505. + 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
  5506. + 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
  5507. + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  5508. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5509. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5510. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5511. + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  5512. + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
  5513. +};
  5514. +
  5515. +static uchar p_code[64] = {
  5516. + 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
  5517. + 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
  5518. + 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
  5519. + 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
  5520. + 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
  5521. + 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
  5522. + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
  5523. + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  5524. +};
  5525. +
  5526. +/* for decoding */
  5527. +static uchar d_code[256] = {
  5528. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  5529. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  5530. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  5531. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  5532. + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  5533. + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  5534. + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  5535. + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  5536. + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  5537. + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  5538. + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  5539. + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  5540. + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  5541. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5542. + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  5543. + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
  5544. + 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
  5545. + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
  5546. + 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
  5547. + 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
  5548. + 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
  5549. + 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
  5550. + 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
  5551. + 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
  5552. + 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
  5553. + 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
  5554. + 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
  5555. + 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
  5556. + 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
  5557. + 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
  5558. + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  5559. + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  5560. +};
  5561. +
  5562. +static uchar d_len[256] = {
  5563. + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  5564. + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  5565. + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  5566. + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  5567. + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  5568. + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  5569. + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  5570. + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  5571. + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  5572. + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  5573. + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  5574. + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  5575. + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  5576. + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  5577. + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  5578. + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  5579. + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  5580. + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  5581. + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  5582. + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  5583. + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  5584. + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  5585. + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  5586. + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  5587. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5588. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5589. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5590. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5591. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5592. + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  5593. + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  5594. + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  5595. +};
  5596. +
  5597. +static unsigned long freq[T + 1]; /* frequency table */
  5598. +
  5599. +static unsigned long prnt[T + N_CHAR]; /* pointers to parent nodes, except for the */
  5600. + /* elements [T..T + N_CHAR - 1] which are used to get */
  5601. + /* the positions of leaves corresponding to the codes. */
  5602. +
  5603. +static unsigned long son[T]; /* pointers to child nodes (son[], son[] + 1) */
  5604. +
  5605. +/* initialization of tree */
  5606. +
  5607. +static void StartHuff(void)
  5608. +{
  5609. + unsigned long i, j;
  5610. +
  5611. + for (i = 0; i < N_CHAR; i++) {
  5612. + freq[i] = 1;
  5613. + son[i] = i + T;
  5614. + prnt[i + T] = i;
  5615. + }
  5616. + i = 0; j = N_CHAR;
  5617. + while (j <= R) {
  5618. + freq[j] = freq[i] + freq[i + 1];
  5619. + son[j] = i;
  5620. + prnt[i] = prnt[i + 1] = j;
  5621. + i += 2; j++;
  5622. + }
  5623. + freq[T] = 0xffff;
  5624. + prnt[R] = 0;
  5625. +}
  5626. +
  5627. +/* reconstruction of tree */
  5628. +
  5629. +static void reconst(void)
  5630. +{
  5631. + unsigned long f, l, i, j, k;
  5632. +
  5633. + /* collect leaf nodes in the first half of the table */
  5634. + /* and replace the freq by (freq + 1) / 2. */
  5635. + j = 0;
  5636. + for (i = 0; i < T; i++) {
  5637. + if (son[i] >= T) {
  5638. + freq[j] = (freq[i] + 1) / 2;
  5639. + son[j] = son[i];
  5640. + j++;
  5641. + }
  5642. + }
  5643. + /* begin constructing tree by connecting sons */
  5644. + for (i = 0, j = N_CHAR; j < T; i += 2, j++) {
  5645. + k = i + 1;
  5646. + f = freq[j] = freq[i] + freq[k];
  5647. + for (k = j - 1; f < freq[k]; k--);
  5648. + k++;
  5649. + l = (j - k) * 2;
  5650. + memmove(&freq[k + 1], &freq[k], l*sizeof(unsigned long));
  5651. + freq[k] = f;
  5652. + memmove(&son[k + 1], &son[k], l*sizeof(unsigned long));
  5653. + son[k] = i;
  5654. + }
  5655. + /* connect prnt */
  5656. + for (i = 0; i < T; i++) {
  5657. + if ((k = son[i]) >= T) {
  5658. + prnt[k] = i;
  5659. + } else {
  5660. + prnt[k] = prnt[k + 1] = i;
  5661. + }
  5662. + }
  5663. +}
  5664. +
  5665. +/* increment frequency of given code by one, and update tree */
  5666. +
  5667. +static void update(unsigned long c)
  5668. +{
  5669. + unsigned long i, j, k, l;
  5670. +
  5671. + if (freq[R] == MAX_FREQ) {
  5672. + reconst();
  5673. + }
  5674. + c = prnt[c + T];
  5675. + do {
  5676. + k = ++freq[c];
  5677. +
  5678. + /* if the order is disturbed, exchange nodes */
  5679. + if (k > freq[l = c + 1]) {
  5680. + while (k > freq[++l]);
  5681. + l--;
  5682. + freq[c] = freq[l];
  5683. + freq[l] = k;
  5684. +
  5685. + i = son[c];
  5686. + prnt[i] = l;
  5687. + if (i < T) prnt[i + 1] = l;
  5688. +
  5689. + j = son[l];
  5690. + son[l] = i;
  5691. +
  5692. + prnt[j] = c;
  5693. + if (j < T) prnt[j + 1] = c;
  5694. + son[c] = j;
  5695. +
  5696. + c = l;
  5697. + }
  5698. + } while (c = prnt[c]); /* repeat up to root */
  5699. +}
  5700. +
  5701. +/* modified for block compression */
  5702. +/* on return, srclen will contain the number of successfully compressed bytes
  5703. + and dstlen will contain completed compressed bytes */
  5704. +
  5705. +static int Encode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long *srclen,
  5706. + unsigned long *dstlen)
  5707. +{
  5708. + unsigned long c, i, j, k, len, r, s, last_match_length, code_buf_ptr;
  5709. + unsigned char code_buf[17], mask;
  5710. + unsigned char *ip, *op;
  5711. + unsigned long written = 0;
  5712. + unsigned long read = 0;
  5713. + unsigned short putbuf = 0;
  5714. + uchar putlen = 0;
  5715. + unsigned char *srcend = srcbuf + *srclen;
  5716. + unsigned char *dstend = dstbuf + *dstlen;
  5717. + ip = srcbuf;
  5718. + op = dstbuf;
  5719. + StartHuff();
  5720. + InitTree(); /* initialize trees */
  5721. + code_buf[0] = 0; /* code_buf[1..16] saves eight units of code, and
  5722. + code_buf[0] works as eight flags, "1" representing that the unit
  5723. + is an unencoded letter (1 byte), "0" a position-and-length pair
  5724. + (2 bytes). Thus, eight units require at most 16 bytes of code. */
  5725. + code_buf_ptr = mask = 1;
  5726. + s = 0; r = N - F;
  5727. + for (i = s; i < r; i++) text_buf[i] = ' '; /* Clear the buffer with
  5728. + any character that will appear often. */
  5729. + for (len = 0; (len < F) && (ip < srcend); len++)
  5730. + text_buf[r + len] = *(ip++); /* Read F bytes into the last F bytes of
  5731. + the buffer */
  5732. + read = len;
  5733. + for (i = 1; i <= F; i++) InsertNode(r - i); /* Insert the F strings,
  5734. + each of which begins with one or more 'space' characters. Note
  5735. + the order in which these strings are inserted. This way,
  5736. + degenerate trees will be less likely to occur. */
  5737. + InsertNode(r); /* Finally, insert the whole string just read. The
  5738. + global variables match_length and match_position are set. */
  5739. + do {
  5740. + if (match_length > len) match_length = len; /* match_length
  5741. + may be spuriously long near the end of text. */
  5742. + if (match_length <= THRESHOLD) {
  5743. + match_length = 1; /* Not long enough match. Send one byte. */
  5744. + c = text_buf[r];
  5745. + i = 0; j = 0; k = prnt[c + T];
  5746. + do {
  5747. + i >>= 1;
  5748. + /* if node's address is odd-numbered, choose bigger brother node */
  5749. + if (k & 1) i |= 0x8000;
  5750. + j++;
  5751. + } while ((k = prnt[k]) != R);
  5752. + putbuf |= i >> putlen;
  5753. + if ((putlen += j) >= 8) {
  5754. + if (op >= dstend) {
  5755. + *dstlen = written;
  5756. + return -1;
  5757. + }
  5758. + *(op++) = putbuf >> 8;
  5759. + if ((putlen -= 8) >= 8) {
  5760. + if (op >= dstend) {
  5761. + *dstlen = written;
  5762. + return -1;
  5763. + }
  5764. + *(op++) = putbuf;
  5765. + written += 2;
  5766. + putlen -= 8;
  5767. + putbuf = i << (j - putlen); /**warm**/
  5768. + } else {
  5769. + putbuf <<= 8;
  5770. + written++;
  5771. + }
  5772. + *srclen = read;
  5773. + }
  5774. + update(c);
  5775. + } else {
  5776. + c = 255 - THRESHOLD + match_length;
  5777. + i = 0; j = 0; k = prnt[c + T];
  5778. + do {
  5779. + i >>= 1;
  5780. + /* if node's address is odd-numbered, choose bigger brother node */
  5781. + if (k & 1) i |= 0x8000;
  5782. + j++;
  5783. + } while ((k = prnt[k]) != R);
  5784. + putbuf |= i >> putlen;
  5785. + if ((putlen += j) >= 8) {
  5786. + if (op >= dstend) {
  5787. + *dstlen = written;
  5788. + return -1;
  5789. + }
  5790. + *(op++) = putbuf >> 8;
  5791. + if ((putlen -= 8) >= 8) {
  5792. + if (op >= dstend) {
  5793. + *dstlen = written;
  5794. + return -1;
  5795. + }
  5796. + *(op++) = putbuf;
  5797. + written += 2;
  5798. + putlen -= 8;
  5799. + putbuf = i << (j - putlen); /**warm**/
  5800. + } else {
  5801. + putbuf <<= 8;
  5802. + written++;
  5803. + }
  5804. + *srclen = read;
  5805. + }
  5806. + update(c);
  5807. + j = p_len[match_position >> 6];
  5808. + i = p_code[match_position >> 6] << 8;
  5809. + putbuf |= i >> putlen;
  5810. + if ((putlen += j) >= 8) {
  5811. + if (op >= dstend) {
  5812. + *dstlen = written;
  5813. + return -1;
  5814. + }
  5815. + *(op++) = putbuf >> 8;
  5816. + if ((putlen -= 8) >= 8) {
  5817. + if (op >= dstend) {
  5818. + *dstlen = written;
  5819. + return -1;
  5820. + }
  5821. + *(op++) = putbuf;
  5822. + written += 2;
  5823. + putlen -= 8;
  5824. + putbuf = i << (j - putlen); /**hot**/
  5825. + } else {
  5826. + putbuf <<= 8;
  5827. + written++;
  5828. + }
  5829. + *srclen = read;
  5830. + }
  5831. + j = 6;
  5832. + i = (match_position & 0x3f) << 10;
  5833. + putbuf |= i >> putlen;
  5834. + if ((putlen += j) >= 8) {
  5835. + if (op >= dstend) {
  5836. + *dstlen = written;
  5837. + return -1;
  5838. + }
  5839. + *(op++) = putbuf >> 8;
  5840. + if ((putlen -= 8) >= 8) {
  5841. + if (op >= dstend) {
  5842. + *dstlen = written;
  5843. + return -1;
  5844. + }
  5845. + *(op++) = putbuf;
  5846. + written += 2;
  5847. + putlen -= 8;
  5848. + putbuf = i << (j - putlen); /**hot**/
  5849. + } else {
  5850. + putbuf <<= 8;
  5851. + written++;
  5852. + }
  5853. + *srclen = read;
  5854. + }
  5855. + }
  5856. + last_match_length = match_length;
  5857. + for (i = 0; (i < last_match_length) && (ip < srcend); i++) {
  5858. + c = *(ip++);
  5859. + DeleteNode(s);
  5860. + text_buf[s] = c;
  5861. + if (s < F - 1)
  5862. + text_buf[s + N] = c;
  5863. + s = (s + 1) & (N - 1);
  5864. + r = (r + 1) & (N - 1);
  5865. + InsertNode(r);
  5866. + }
  5867. + read += i;
  5868. + while (i++ < last_match_length) {
  5869. + DeleteNode(s);
  5870. + s = (s + 1) & (N - 1);
  5871. + r = (r + 1) & (N - 1);
  5872. + if (--len) InsertNode(r);
  5873. + }
  5874. + } while (len > 0);
  5875. + if (putlen) {
  5876. + if (op >= dstend) {
  5877. + *dstlen = written;
  5878. + return -1;
  5879. + }
  5880. + *(op++) = putbuf >> 8;
  5881. + written++;
  5882. + *srclen = read;
  5883. + }
  5884. + *dstlen = written;
  5885. + return 0;
  5886. +}
  5887. +
  5888. +static int Decode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long srclen,
  5889. + unsigned long dstlen) /* Just the reverse of Encode(). */
  5890. +{
  5891. + unsigned long i, r, j, k, c;
  5892. + unsigned char *ip, *op;
  5893. + unsigned char *srcend = srcbuf + srclen;
  5894. + unsigned char *dstend = dstbuf + dstlen;
  5895. + unsigned short getbuf = 0;
  5896. + uchar getlen = 0;
  5897. + ip = srcbuf;
  5898. + op = dstbuf;
  5899. + StartHuff();
  5900. + for (i = 0; i < N - F; i++) text_buf[i] = ' ';
  5901. + r = N - F;
  5902. + while (op < dstend) {
  5903. + c = son[R];
  5904. + /* travel from root to leaf, */
  5905. + /* choosing the smaller child node (son[]) if the read bit is 0, */
  5906. + /* the bigger (son[]+1} if 1 */
  5907. + while (c < T) {
  5908. + while (getlen <= 8) {
  5909. + unsigned short t;
  5910. + t = (ip >= srcend) ? 0 : *(ip++);
  5911. + getbuf |= t << (8 - getlen);
  5912. + getlen += 8;
  5913. + }
  5914. + c += ((signed short)getbuf < 0);
  5915. + getbuf <<= 1;
  5916. + getlen--;
  5917. + c = son[c];
  5918. + }
  5919. + c -= T;
  5920. + update(c);
  5921. + if (c < 256) {
  5922. + if (op >= dstend) return -1;
  5923. + *(op++) = c;
  5924. + text_buf[r++] = c;
  5925. + r &= (N - 1);
  5926. + } else {
  5927. + j = c - 255 + THRESHOLD;
  5928. + while (getlen <= 8) {
  5929. + unsigned short t;
  5930. + t = (ip >= srcend) ? 0 : *(ip++);
  5931. + getbuf |= t << (8 - getlen);
  5932. + getlen += 8;
  5933. + }
  5934. + i = getbuf >> 8;
  5935. + getbuf <<= 8;
  5936. + getlen -= 8;
  5937. + c = d_code[i] << 6;
  5938. + k = d_len[i];
  5939. + /* read lower 6 bits verbatim */
  5940. + k -= 2;
  5941. + while (k--) {
  5942. + while (getlen <= 8) {
  5943. + unsigned short t;
  5944. + t = (ip >= srcend) ? 0 : *(ip++);
  5945. + getbuf |= t << (8 - getlen);
  5946. + getlen += 8;
  5947. + }
  5948. + i = (i << 1) + ((signed short)getbuf < 0);
  5949. + getbuf <<= 1;
  5950. + getlen--;
  5951. + }
  5952. + i = c | (i & 0x3F);
  5953. + i = r - i - 1;
  5954. + i &= (N - 1);
  5955. + for (k = 0; k < j; k++) {
  5956. + c = text_buf[(i + k) & (N - 1)];
  5957. + if (op >= dstend) return -1;
  5958. + *(op++) = c;
  5959. + text_buf[r++] = c;
  5960. + r &= (N - 1);
  5961. + }
  5962. + }
  5963. + }
  5964. + return 0;
  5965. +}
  5966. +
  5967. +/* interface to jffs2 bbc follows */
  5968. +
  5969. +#include "jffs2_bbc_framework.h"
  5970. +
  5971. +
  5972. +#define JFFS2_BBC_LZHD_BLOCK_SIGN {0x3a, 0x98, 0xf7, 0xda}
  5973. +
  5974. +static int
  5975. +jffs2_bbc_lzhd_compressor_init (void);
  5976. +
  5977. +static void
  5978. +jffs2_bbc_lzhd_compressor_deinit (void);
  5979. +
  5980. +static int
  5981. +jffs2_bbc_lzhd_compress (void *model, unsigned char *input,
  5982. + unsigned char *output, unsigned long *sourcelen,
  5983. + unsigned long *dstlen);
  5984. +
  5985. +static int
  5986. +jffs2_bbc_lzhd_estimate (void *model, unsigned char *input,
  5987. + unsigned long sourcelen, unsigned long *dstlen,
  5988. + unsigned long *readtime, unsigned long *writetime);
  5989. +
  5990. +static int
  5991. +jffs2_bbc_lzhd_decompress (void *model, unsigned char *input,
  5992. + unsigned char *output, unsigned long sourcelen,
  5993. + unsigned long dstlen);
  5994. +
  5995. +static char *
  5996. +jffs2_bbc_lzhd_proc_info (void);
  5997. +
  5998. +static int
  5999. +jffs2_bbc_lzhd_proc_command (char *command);
  6000. +
  6001. +struct jffs2_bbc_compressor_type jffs2_bbc_lzhd = {
  6002. + "lzhd",
  6003. + 0,
  6004. + JFFS2_BBC_LZHD_BLOCK_SIGN,
  6005. + jffs2_bbc_lzhd_compressor_init,
  6006. + NULL,
  6007. + NULL,
  6008. + jffs2_bbc_lzhd_compressor_deinit,
  6009. + jffs2_bbc_lzhd_compress,
  6010. + jffs2_bbc_lzhd_estimate,
  6011. + jffs2_bbc_lzhd_decompress,
  6012. + jffs2_bbc_lzhd_proc_info,
  6013. + jffs2_bbc_lzhd_proc_command
  6014. +};
  6015. +
  6016. +static int
  6017. +jffs2_bbc_lzhd_compressor_init (void)
  6018. +{
  6019. + return 0;
  6020. +}
  6021. +
  6022. +static void
  6023. +jffs2_bbc_lzhd_compressor_deinit (void)
  6024. +{
  6025. +}
  6026. +
  6027. +static int
  6028. +jffs2_bbc_lzhd_compress (void *model, unsigned char *input,
  6029. + unsigned char *output, unsigned long *sourcelen,
  6030. + unsigned long *dstlen)
  6031. +{
  6032. + int retval;
  6033. + unsigned long dst = *dstlen;
  6034. + *(output++) = jffs2_bbc_lzhd.block_sign[0];
  6035. + *(output++) = jffs2_bbc_lzhd.block_sign[1];
  6036. + dst -= 2;
  6037. + retval = Encode(input, output, sourcelen, &dst);
  6038. + dst += 2;
  6039. + *dstlen = dst;
  6040. + return retval;
  6041. +}
  6042. +
  6043. +static int
  6044. +jffs2_bbc_lzhd_estimate (void *model, unsigned char *input,
  6045. + unsigned long sourcelen, unsigned long *dstlen,
  6046. + unsigned long *readtime, unsigned long *writetime)
  6047. +{
  6048. + *dstlen = sourcelen * 55 / 100;
  6049. + *readtime = JFFS2_BBC_ZLIB_READ_TIME * 8;
  6050. + *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 65 / 10;
  6051. + return 0;
  6052. +}
  6053. +
  6054. +static int
  6055. +jffs2_bbc_lzhd_decompress (void *model, unsigned char *input,
  6056. + unsigned char *output, unsigned long sourcelen,
  6057. + unsigned long dstlen)
  6058. +{
  6059. + if ( ( *(input++) != (unsigned char)jffs2_bbc_lzhd.block_sign[0] ) ||
  6060. + ( *(input++) != (unsigned char)jffs2_bbc_lzhd.block_sign[1] )
  6061. + ) {
  6062. + return -1;
  6063. + } else {
  6064. + return Decode(input, output, sourcelen - 2, dstlen);
  6065. + }
  6066. +}
  6067. +
  6068. +static char *
  6069. +jffs2_bbc_lzhd_proc_info (void)
  6070. +{
  6071. + return "Lempel-Ziv-(dynamic) Huffman compression module";
  6072. +}
  6073. +
  6074. +static int
  6075. +jffs2_bbc_lzhd_proc_command (char *command)
  6076. +{
  6077. + return 0;
  6078. +}
  6079. +
  6080. +struct jffs2_bbc_compressor_type *
  6081. +jffs2_bbc_lzhd_init (int mode)
  6082. +{
  6083. + if (jffs2_bbc_register_compressor (&jffs2_bbc_lzhd) == 0)
  6084. + {
  6085. + return &jffs2_bbc_lzhd;
  6086. + }
  6087. + else
  6088. + {
  6089. + return NULL;
  6090. + }
  6091. +}
  6092. +
  6093. +void
  6094. +jffs2_bbc_lzhd_deinit (void)
  6095. +{
  6096. + jffs2_bbc_unregister_compressor (&jffs2_bbc_lzhd);
  6097. +}
  6098. --- /dev/null
  6099. +++ b/fs/jffs2/jffs2_bbc_lzo_comp.c
  6100. @@ -0,0 +1,2435 @@
  6101. +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
  6102. +
  6103. +/*
  6104. + jffs2_bbc_lzo_comp.c -- LZO1X-1 (and -999) compression module for jffs2
  6105. + Copyright (C) 2004 Patrik Kluba
  6106. + Based on the original LZO sources
  6107. + $Header: /openwrt/openwrt/package/linux/kernel-patches/301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  6108. +*/
  6109. +
  6110. +/*
  6111. + Original copyright notice follows:
  6112. +
  6113. + lzo1x_9x.c -- implementation of the LZO1X-999 compression algorithm
  6114. + lzo_ptr.h -- low-level pointer constructs
  6115. + lzo_swd.ch -- sliding window dictionary
  6116. + lzoconf.h -- configuration for the LZO real-time data compression library
  6117. + lzo_mchw.ch -- matching functions using a window
  6118. + minilzo.c -- mini subset of the LZO real-time data compression library
  6119. + config1x.h -- configuration for the LZO1X algorithm
  6120. + lzo1x.h -- public interface of the LZO1X compression algorithm
  6121. +
  6122. + These files are part of the LZO real-time data compression library.
  6123. +
  6124. + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
  6125. + All Rights Reserved.
  6126. +
  6127. + The LZO library is free software; you can redistribute it and/or
  6128. + modify it under the terms of the GNU General Public License as
  6129. + published by the Free Software Foundation; either version 2 of
  6130. + the License, or (at your option) any later version.
  6131. +
  6132. + The LZO library is distributed in the hope that it will be useful,
  6133. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  6134. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  6135. + GNU General Public License for more details.
  6136. +
  6137. + You should have received a copy of the GNU General Public License
  6138. + along with the LZO library; see the file COPYING.
  6139. + If not, write to the Free Software Foundation, Inc.,
  6140. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  6141. +
  6142. + Markus F.X.J. Oberhumer
  6143. + <[email protected]>
  6144. +*/
  6145. +
  6146. +/*
  6147. +
  6148. + 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu>
  6149. + Initial release
  6150. + -removed all 16 bit code
  6151. + -all sensitive data will be on 4 byte boundary
  6152. + -removed check parts for library use
  6153. + -removed all but LZO1X-* compression
  6154. +
  6155. +*/
  6156. +
  6157. +#ifndef __KERNEL__
  6158. + #include <sys/types.h>
  6159. + #include <stddef.h>
  6160. + #include <string.h>
  6161. + #include <limits.h>
  6162. +#else
  6163. + #include <linux/kernel.h>
  6164. + #include <linux/types.h>
  6165. + #include <linux/stddef.h>
  6166. + #include <linux/string.h>
  6167. + #define USHRT_MAX 65535
  6168. + /* #define UINT_MAX 4294967295U */
  6169. +#endif
  6170. +
  6171. +/* data type definitions */
  6172. +#define U32 unsigned long
  6173. +#define S32 signed long
  6174. +#define I32 long
  6175. +#define U16 unsigned short
  6176. +#define S16 signed short
  6177. +#define I16 short
  6178. +#define U8 unsigned char
  6179. +#define S8 signed char
  6180. +#define I8 char
  6181. +
  6182. +/*************************************/
  6183. +
  6184. +/* lzo_swd.ch */
  6185. +
  6186. +#define SWD_N N
  6187. +#define SWD_F F
  6188. +#define SWD_THRESHOLD THRESHOLD
  6189. +
  6190. +/* shortest unsigned int that 2 * SWD_F + SWD_N (currently 53248) fits in */
  6191. +typedef unsigned short swd_uint;
  6192. +/* upper limit of that data type */
  6193. +#define SWD_UINT_MAX USHRT_MAX
  6194. +
  6195. +/* minilzo.c */
  6196. +
  6197. +#define LZO_VERSION_DATE "Jul 12 2002"
  6198. +#define LZO_VERSION_STRING "1.08"
  6199. +#define LZO_VERSION 0x1080
  6200. +
  6201. +/* lzo_ptr.h */
  6202. +
  6203. +/* Integral types that have *exactly* the same number of bits as a lzo_voidp */
  6204. +typedef unsigned long lzo_ptr_t;
  6205. +typedef long lzo_sptr_t;
  6206. +
  6207. +
  6208. +/*************************************/
  6209. +
  6210. +/* config1x.h */
  6211. +
  6212. +#define M1_MAX_OFFSET 0x0400
  6213. +#define M2_MAX_OFFSET 0x0800
  6214. +#define M3_MAX_OFFSET 0x4000
  6215. +#define M4_MAX_OFFSET 0xbfff
  6216. +
  6217. +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET)
  6218. +
  6219. +#define M1_MIN_LEN 2
  6220. +#define M1_MAX_LEN 2
  6221. +#define M2_MIN_LEN 3
  6222. +#define M2_MAX_LEN 8
  6223. +#define M3_MIN_LEN 3
  6224. +#define M3_MAX_LEN 33
  6225. +#define M4_MIN_LEN 3
  6226. +#define M4_MAX_LEN 9
  6227. +
  6228. +#define M1_MARKER 0
  6229. +#define M2_MARKER 64
  6230. +#define M3_MARKER 32
  6231. +#define M4_MARKER 16
  6232. +
  6233. +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1)
  6234. +
  6235. +/* minilzo.c */
  6236. +
  6237. +#define LZO_BYTE(x) ((unsigned char) ((x) & 0xff))
  6238. +
  6239. +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b))
  6240. +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b))
  6241. +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c))
  6242. +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c))
  6243. +
  6244. +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type)))
  6245. +
  6246. +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array))))
  6247. +
  6248. +#define LZO_SIZE(bits) (1u << (bits))
  6249. +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1)
  6250. +
  6251. +#define LZO_LSIZE(bits) (1ul << (bits))
  6252. +#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1)
  6253. +
  6254. +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits))
  6255. +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1)
  6256. +
  6257. +#define LZO_STYPE_MAX(b) (((1l << (8*(b)-2)) - 1l) + (1l << (8*(b)-2)))
  6258. +#define LZO_UTYPE_MAX(b) (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1)))
  6259. +
  6260. +#define _LZO_STRINGIZE(x) #x
  6261. +#define _LZO_MEXPAND(x) _LZO_STRINGIZE(x)
  6262. +
  6263. +#define _LZO_CONCAT2(a,b) a ## b
  6264. +#define _LZO_CONCAT3(a,b,c) a ## b ## c
  6265. +#define _LZO_CONCAT4(a,b,c,d) a ## b ## c ## d
  6266. +#define _LZO_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
  6267. +
  6268. +#define _LZO_ECONCAT2(a,b) _LZO_CONCAT2(a,b)
  6269. +#define _LZO_ECONCAT3(a,b,c) _LZO_CONCAT3(a,b,c)
  6270. +#define _LZO_ECONCAT4(a,b,c,d) _LZO_CONCAT4(a,b,c,d)
  6271. +#define _LZO_ECONCAT5(a,b,c,d,e) _LZO_CONCAT5(a,b,c,d,e)
  6272. +
  6273. +#define lzo_dict_t const lzo_bytep
  6274. +#define lzo_dict_p lzo_dict_t *
  6275. +#define lzo_moff_t lzo_uint
  6276. +
  6277. +#define MEMCPY8_DS(dest,src,len) \
  6278. + memcpy(dest,src,len); \
  6279. + dest += len; \
  6280. + src += len
  6281. +
  6282. +#define MEMCPY_DS(dest,src,len) \
  6283. + do *dest++ = *src++; \
  6284. + while (--len > 0)
  6285. +
  6286. +#define MEMMOVE_DS(dest,src,len) \
  6287. + do *dest++ = *src++; \
  6288. + while (--len > 0)
  6289. +
  6290. +#define BZERO8_PTR(s,l,n) memset((s),0,(lzo_uint)(l)*(n))
  6291. +
  6292. +#define LZO_BASE 65521u
  6293. +#define LZO_NMAX 5552
  6294. +
  6295. +#define LZO_DO1(buf,i) {s1 += buf[i]; s2 += s1;}
  6296. +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1);
  6297. +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2);
  6298. +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4);
  6299. +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8);
  6300. +
  6301. +#define IS_SIGNED(type) (((type) (-1)) < ((type) 0))
  6302. +#define IS_UNSIGNED(type) (((type) (-1)) > ((type) 0))
  6303. +
  6304. +#define IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0)
  6305. +
  6306. +#define D_BITS 14
  6307. +#define D_INDEX1(d,p) d = DM((0x21*DX3(p,5,5,6)) >> 5)
  6308. +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
  6309. +
  6310. +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B
  6311. +
  6312. +#define DL_MIN_LEN M2_MIN_LEN
  6313. +
  6314. +#define D_SIZE LZO_SIZE(D_BITS)
  6315. +#define D_MASK LZO_MASK(D_BITS)
  6316. +
  6317. +#define D_HIGH ((D_MASK >> 1) + 1)
  6318. +
  6319. +#define DINDEX1 D_INDEX1
  6320. +#define DINDEX2 D_INDEX2
  6321. +
  6322. +#define DX2(p,s1,s2) \
  6323. + (((((lzo_uint32)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0])
  6324. +
  6325. +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0])
  6326. +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s)))
  6327. +#define DM(v) DMS(v,0)
  6328. +
  6329. +#define DENTRY(p,in) (p)
  6330. +#define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex]
  6331. +
  6332. +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
  6333. + (m_pos == NULL || (m_off = (lzo_moff_t) (ip - m_pos)) > max_offset)
  6334. +
  6335. +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
  6336. + (BOUNDS_CHECKING_OFF_IN_EXPR( \
  6337. + (PTR_LT(m_pos,in) || \
  6338. + (m_off = (lzo_moff_t) PTR_DIFF(ip,m_pos)) <= 0 || \
  6339. + m_off > max_offset) ))
  6340. +
  6341. +#define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr)
  6342. +
  6343. +#define DD_BITS 0
  6344. +#define DD_SIZE LZO_SIZE(DD_BITS)
  6345. +#define DD_MASK LZO_MASK(DD_BITS)
  6346. +
  6347. +#define DL_BITS (D_BITS - DD_BITS)
  6348. +#define DL_SIZE LZO_SIZE(DL_BITS)
  6349. +#define DL_MASK LZO_MASK(DL_BITS)
  6350. +
  6351. +#define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in)
  6352. +#define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in)
  6353. +#define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in)
  6354. +
  6355. +#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
  6356. +#define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
  6357. +
  6358. +#define TEST_IP (ip < ip_end)
  6359. +#define TEST_OP (op <= op_end)
  6360. +
  6361. +#define NEED_IP(x) \
  6362. + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
  6363. +#define NEED_OP(x) \
  6364. + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
  6365. +#define TEST_LOOKBEHIND(m_pos,out) if (m_pos < out) goto lookbehind_overrun
  6366. +
  6367. +/* lzo1x_9x.c */
  6368. +
  6369. +#define LZO_UINT_MAX UINT_MAX
  6370. +#define N M4_MAX_OFFSET
  6371. +#define THRESHOLD 1
  6372. +#define F 2048
  6373. +
  6374. +#define SWD_BEST_OFF (LZO_MAX3( M2_MAX_LEN, M3_MAX_LEN, M4_MAX_LEN ) + 1)
  6375. +
  6376. +/* ../include/lzoconf.h */
  6377. +
  6378. +typedef U32 lzo_uint32;
  6379. +typedef I32 lzo_int32;
  6380. +typedef U32 lzo_uint;
  6381. +typedef I32 lzo_int;
  6382. +typedef int lzo_bool;
  6383. +
  6384. +#define lzo_byte U8
  6385. +#define lzo_bytep U8 *
  6386. +#define lzo_charp char *
  6387. +#define lzo_voidp void *
  6388. +#define lzo_shortp short *
  6389. +#define lzo_ushortp unsigned short *
  6390. +#define lzo_uint32p lzo_uint32 *
  6391. +#define lzo_int32p lzo_int32 *
  6392. +#define lzo_uintp lzo_uint *
  6393. +#define lzo_intp lzo_int *
  6394. +#define lzo_voidpp lzo_voidp *
  6395. +#define lzo_bytepp lzo_bytep *
  6396. +#define lzo_sizeof_dict_t sizeof(lzo_bytep)
  6397. +
  6398. +#define LZO_E_OK 0
  6399. +#define LZO_E_ERROR (-1)
  6400. +#define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */
  6401. +#define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */
  6402. +#define LZO_E_INPUT_OVERRUN (-4)
  6403. +#define LZO_E_OUTPUT_OVERRUN (-5)
  6404. +#define LZO_E_LOOKBEHIND_OVERRUN (-6)
  6405. +#define LZO_E_EOF_NOT_FOUND (-7)
  6406. +#define LZO_E_INPUT_NOT_CONSUMED (-8)
  6407. +
  6408. +#define LZO_PTR_ALIGN_UP(_ptr,_size) \
  6409. + ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size)))
  6410. +#define LZO_ALIGN(_ptr,_size) LZO_PTR_ALIGN_UP(_ptr,_size)
  6411. +
  6412. +typedef int
  6413. + (*lzo_compress_t) (const lzo_byte * src, lzo_uint src_len,
  6414. + lzo_byte * dst, lzo_uintp dst_len,
  6415. + lzo_voidp wrkmem);
  6416. +
  6417. +typedef int
  6418. + (*lzo_decompress_t) (const lzo_byte * src, lzo_uint src_len,
  6419. + lzo_byte * dst, lzo_uintp dst_len,
  6420. + lzo_voidp wrkmem);
  6421. +
  6422. +typedef int
  6423. + (*lzo_optimize_t) (lzo_byte * src, lzo_uint src_len,
  6424. + lzo_byte * dst, lzo_uintp dst_len,
  6425. + lzo_voidp wrkmem);
  6426. +
  6427. +typedef int
  6428. + (*lzo_compress_dict_t) (const lzo_byte * src, lzo_uint src_len,
  6429. + lzo_byte * dst, lzo_uintp dst_len,
  6430. + lzo_voidp wrkmem,
  6431. + const lzo_byte * dict, lzo_uint dict_len);
  6432. +
  6433. +typedef int
  6434. + (*lzo_decompress_dict_t) (const lzo_byte * src, lzo_uint src_len,
  6435. + lzo_byte * dst, lzo_uintp dst_len,
  6436. + lzo_voidp wrkmem,
  6437. + const lzo_byte * dict, lzo_uint dict_len);
  6438. +
  6439. +typedef int
  6440. + (*lzo_compress_asm_t) (const lzo_byte * src, lzo_uint src_len,
  6441. + lzo_byte * dst, lzo_uintp dst_len,
  6442. + lzo_voidp wrkmem);
  6443. +
  6444. +typedef int
  6445. + (*lzo_decompress_asm_t) (const lzo_byte * src, lzo_uint src_len,
  6446. + lzo_byte * dst, lzo_uintp dst_len,
  6447. + lzo_voidp wrkmem);
  6448. +
  6449. +typedef void (*lzo_progress_callback_t) (lzo_uint, lzo_uint);
  6450. +
  6451. +typedef union
  6452. +{
  6453. + lzo_bytep p;
  6454. + lzo_uint u;
  6455. +} __lzo_pu_u;
  6456. +typedef union
  6457. +{
  6458. + lzo_bytep p;
  6459. + lzo_uint32 u32;
  6460. +} __lzo_pu32_u;
  6461. +typedef union
  6462. +{
  6463. + void *vp;
  6464. + lzo_bytep bp;
  6465. + lzo_uint32 u32;
  6466. + long l;
  6467. +} lzo_align_t;
  6468. +
  6469. +/* lzo1x.h */
  6470. +
  6471. +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
  6472. +#define LZO1X_999_MEM_COMPRESS ((lzo_uint32) (14 * 16384L * sizeof(short)))
  6473. +
  6474. +/* lzo_ptr.h */
  6475. +
  6476. +#define PTR(a) ((lzo_ptr_t) (a))
  6477. +#define PTR_LINEAR(a) PTR(a)
  6478. +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0)
  6479. +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0)
  6480. +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0)
  6481. +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0)
  6482. +#define PTR_LT(a,b) (PTR(a) < PTR(b))
  6483. +#define PTR_GE(a,b) (PTR(a) >= PTR(b))
  6484. +#define PTR_DIFF(a,b) ((lzo_ptrdiff_t) (PTR(a) - PTR(b)))
  6485. +#define pd(a,b) ((lzo_uint) ((a)-(b)))
  6486. +
  6487. +typedef ptrdiff_t lzo_ptrdiff_t;
  6488. +
  6489. +typedef union
  6490. +{
  6491. + char a_char;
  6492. + unsigned char a_uchar;
  6493. + short a_short;
  6494. + unsigned short a_ushort;
  6495. + int a_int;
  6496. + unsigned int a_uint;
  6497. + long a_long;
  6498. + unsigned long a_ulong;
  6499. + lzo_int a_lzo_int;
  6500. + lzo_uint a_lzo_uint;
  6501. + lzo_int32 a_lzo_int32;
  6502. + lzo_uint32 a_lzo_uint32;
  6503. + ptrdiff_t a_ptrdiff_t;
  6504. + lzo_ptrdiff_t a_lzo_ptrdiff_t;
  6505. + lzo_ptr_t a_lzo_ptr_t;
  6506. + lzo_voidp a_lzo_voidp;
  6507. + void *a_void_p;
  6508. + lzo_bytep a_lzo_bytep;
  6509. + lzo_bytepp a_lzo_bytepp;
  6510. + lzo_uintp a_lzo_uintp;
  6511. + lzo_uint *a_lzo_uint_p;
  6512. + lzo_uint32p a_lzo_uint32p;
  6513. + lzo_uint32 *a_lzo_uint32_p;
  6514. + unsigned char *a_uchar_p;
  6515. + char *a_char_p;
  6516. +}
  6517. +lzo_full_align_t;
  6518. +
  6519. +/* lzo_mchw.ch */
  6520. +
  6521. +typedef struct
  6522. +{
  6523. + int init;
  6524. +
  6525. + lzo_uint look;
  6526. +
  6527. + lzo_uint m_len;
  6528. + lzo_uint m_off;
  6529. +
  6530. + lzo_uint last_m_len;
  6531. + lzo_uint last_m_off;
  6532. +
  6533. + const lzo_byte *bp;
  6534. + const lzo_byte *ip;
  6535. + const lzo_byte *in;
  6536. + const lzo_byte *in_end;
  6537. + lzo_byte *out;
  6538. +
  6539. + lzo_progress_callback_t cb;
  6540. +
  6541. + lzo_uint textsize;
  6542. + lzo_uint codesize;
  6543. + lzo_uint printcount;
  6544. +
  6545. + unsigned long lit_bytes;
  6546. + unsigned long match_bytes;
  6547. + unsigned long rep_bytes;
  6548. + unsigned long lazy;
  6549. +
  6550. + lzo_uint r1_lit;
  6551. + lzo_uint r1_m_len;
  6552. +
  6553. + unsigned long m1a_m, m1b_m, m2_m, m3_m, m4_m;
  6554. + unsigned long lit1_r, lit2_r, lit3_r;
  6555. +}
  6556. +lzo1x_999_t;
  6557. +
  6558. +#define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1))
  6559. +
  6560. +/* lzo_swd.ch */
  6561. +
  6562. +#define SWD_UINT(x) ((swd_uint)(x))
  6563. +#define SWD_HSIZE 16384
  6564. +#define SWD_MAX_CHAIN 2048
  6565. +#define HEAD3(b,p) \
  6566. + (((0x9f5f*(((((lzo_uint32)b[p]<<5)^b[p+1])<<5)^b[p+2]))>>5) & (SWD_HSIZE-1))
  6567. +#define HEAD2(b,p) (b[p] ^ ((unsigned)b[p+1]<<8))
  6568. +#define NIL2 SWD_UINT_MAX
  6569. +
  6570. +typedef struct
  6571. +{
  6572. + lzo_uint n;
  6573. + lzo_uint f;
  6574. + lzo_uint threshold;
  6575. +
  6576. + lzo_uint max_chain;
  6577. + lzo_uint nice_length;
  6578. + lzo_bool use_best_off;
  6579. + lzo_uint lazy_insert;
  6580. +
  6581. + lzo_uint m_len;
  6582. + lzo_uint m_off;
  6583. + lzo_uint look;
  6584. + int b_char;
  6585. +
  6586. + lzo_uint best_off[SWD_BEST_OFF];
  6587. +
  6588. + lzo1x_999_t *c;
  6589. + lzo_uint m_pos;
  6590. +
  6591. + lzo_uint best_pos[SWD_BEST_OFF];
  6592. +
  6593. + const lzo_byte *dict;
  6594. + const lzo_byte *dict_end;
  6595. + lzo_uint dict_len;
  6596. +
  6597. + lzo_uint ip;
  6598. + lzo_uint bp;
  6599. + lzo_uint rp;
  6600. + lzo_uint b_size;
  6601. +
  6602. + unsigned char *b_wrap;
  6603. +
  6604. + lzo_uint node_count;
  6605. + lzo_uint first_rp;
  6606. +
  6607. + unsigned char b[SWD_N + SWD_F + SWD_F];
  6608. + swd_uint head3[SWD_HSIZE];
  6609. + swd_uint succ3[SWD_N + SWD_F];
  6610. + swd_uint best3[SWD_N + SWD_F];
  6611. + swd_uint llen3[SWD_HSIZE];
  6612. +
  6613. + swd_uint head2[65536L];
  6614. +}
  6615. +lzo1x_999_swd_t;
  6616. +
  6617. +#define s_head3(s,key) s->head3[key]
  6618. +#define swd_pos2off(s,pos) \
  6619. + (s->bp > (pos) ? s->bp - (pos) : s->b_size - ((pos) - s->bp))
  6620. +
  6621. +static __inline__ void
  6622. +swd_getbyte (lzo1x_999_swd_t * s)
  6623. +{
  6624. + int c;
  6625. +
  6626. + if ((c = getbyte (*(s->c))) < 0)
  6627. + {
  6628. + if (s->look > 0)
  6629. + --s->look;
  6630. + }
  6631. + else
  6632. + {
  6633. + s->b[s->ip] = LZO_BYTE (c);
  6634. + if (s->ip < s->f)
  6635. + s->b_wrap[s->ip] = LZO_BYTE (c);
  6636. + }
  6637. + if (++s->ip == s->b_size)
  6638. + s->ip = 0;
  6639. + if (++s->bp == s->b_size)
  6640. + s->bp = 0;
  6641. + if (++s->rp == s->b_size)
  6642. + s->rp = 0;
  6643. +}
  6644. +
  6645. +static void
  6646. +swd_initdict (lzo1x_999_swd_t * s, const lzo_byte * dict, lzo_uint dict_len)
  6647. +{
  6648. + s->dict = s->dict_end = NULL;
  6649. + s->dict_len = 0;
  6650. +
  6651. + if (!dict || dict_len <= 0)
  6652. + return;
  6653. + if (dict_len > s->n)
  6654. + {
  6655. + dict += dict_len - s->n;
  6656. + dict_len = s->n;
  6657. + }
  6658. +
  6659. + s->dict = dict;
  6660. + s->dict_len = dict_len;
  6661. + s->dict_end = dict + dict_len;
  6662. + memcpy (s->b, dict, dict_len);
  6663. + s->ip = dict_len;
  6664. +}
  6665. +
  6666. +static void
  6667. +swd_insertdict (lzo1x_999_swd_t * s, lzo_uint node, lzo_uint len)
  6668. +{
  6669. + lzo_uint key;
  6670. +
  6671. + s->node_count = s->n - len;
  6672. + s->first_rp = node;
  6673. +
  6674. + while (len-- > 0)
  6675. + {
  6676. + key = HEAD3 (s->b, node);
  6677. + s->succ3[node] = s_head3 (s, key);
  6678. + s->head3[key] = SWD_UINT (node);
  6679. + s->best3[node] = SWD_UINT (s->f + 1);
  6680. + s->llen3[key]++;
  6681. +
  6682. + key = HEAD2 (s->b, node);
  6683. + s->head2[key] = SWD_UINT (node);
  6684. +
  6685. + node++;
  6686. + }
  6687. +}
  6688. +
  6689. +static int
  6690. +swd_init (lzo1x_999_swd_t * s, const lzo_byte * dict, lzo_uint dict_len)
  6691. +{
  6692. +
  6693. + s->n = SWD_N;
  6694. + s->f = SWD_F;
  6695. + s->threshold = SWD_THRESHOLD;
  6696. +
  6697. +
  6698. +
  6699. + s->max_chain = SWD_MAX_CHAIN;
  6700. + s->nice_length = SWD_F;
  6701. + s->use_best_off = 0;
  6702. + s->lazy_insert = 0;
  6703. +
  6704. + s->b_size = s->n + s->f;
  6705. + if (2 * s->f >= s->n || s->b_size + s->f >= NIL2)
  6706. + return LZO_E_ERROR;
  6707. + s->b_wrap = s->b + s->b_size;
  6708. + s->node_count = s->n;
  6709. +
  6710. + memset (s->llen3, 0, sizeof (s->llen3[0]) * SWD_HSIZE);
  6711. + memset (s->head2, 0xff, sizeof (s->head2[0]) * 65536L);
  6712. +
  6713. + s->ip = 0;
  6714. + swd_initdict (s, dict, dict_len);
  6715. + s->bp = s->ip;
  6716. + s->first_rp = s->ip;
  6717. +
  6718. + s->look = (lzo_uint) (s->c->in_end - s->c->ip);
  6719. + if (s->look > 0)
  6720. + {
  6721. + if (s->look > s->f)
  6722. + s->look = s->f;
  6723. + memcpy (&s->b[s->ip], s->c->ip, s->look);
  6724. + s->c->ip += s->look;
  6725. + s->ip += s->look;
  6726. + }
  6727. +
  6728. + if (s->ip == s->b_size)
  6729. + s->ip = 0;
  6730. +
  6731. + if (s->look >= 2 && s->dict_len > 0)
  6732. + swd_insertdict (s, 0, s->dict_len);
  6733. +
  6734. + s->rp = s->first_rp;
  6735. + if (s->rp >= s->node_count)
  6736. + s->rp -= s->node_count;
  6737. + else
  6738. + s->rp += s->b_size - s->node_count;
  6739. +
  6740. + return LZO_E_OK;
  6741. +}
  6742. +
  6743. +static __inline__ void
  6744. +swd_remove_node (lzo1x_999_swd_t * s, lzo_uint node)
  6745. +{
  6746. + if (s->node_count == 0)
  6747. + {
  6748. + lzo_uint key;
  6749. +
  6750. + key = HEAD3 (s->b, node);
  6751. +
  6752. + --s->llen3[key];
  6753. +
  6754. + key = HEAD2 (s->b, node);
  6755. +
  6756. + if ((lzo_uint) s->head2[key] == node)
  6757. + s->head2[key] = NIL2;
  6758. + }
  6759. + else
  6760. + --s->node_count;
  6761. +}
  6762. +
  6763. +static void
  6764. +swd_accept (lzo1x_999_swd_t * s, lzo_uint n)
  6765. +{
  6766. +
  6767. + while (n--)
  6768. + {
  6769. + lzo_uint key;
  6770. +
  6771. + swd_remove_node (s, s->rp);
  6772. +
  6773. + key = HEAD3 (s->b, s->bp);
  6774. + s->succ3[s->bp] = s_head3 (s, key);
  6775. + s->head3[key] = SWD_UINT (s->bp);
  6776. + s->best3[s->bp] = SWD_UINT (s->f + 1);
  6777. + s->llen3[key]++;
  6778. +
  6779. + key = HEAD2 (s->b, s->bp);
  6780. + s->head2[key] = SWD_UINT (s->bp);;
  6781. +
  6782. + swd_getbyte (s);
  6783. + }
  6784. +}
  6785. +
  6786. +static void
  6787. +swd_search (lzo1x_999_swd_t * s, lzo_uint node, lzo_uint cnt)
  6788. +{
  6789. + const unsigned char *p1;
  6790. + const unsigned char *p2;
  6791. + const unsigned char *px;
  6792. +
  6793. + lzo_uint m_len = s->m_len;
  6794. + const unsigned char *b = s->b;
  6795. + const unsigned char *bp = s->b + s->bp;
  6796. + const unsigned char *bx = s->b + s->bp + s->look;
  6797. + unsigned char scan_end1;
  6798. +
  6799. + scan_end1 = bp[m_len - 1];
  6800. + for (; cnt-- > 0; node = s->succ3[node])
  6801. + {
  6802. + p1 = bp;
  6803. + p2 = b + node;
  6804. + px = bx;
  6805. +
  6806. + if (p2[m_len - 1] == scan_end1 &&
  6807. + p2[m_len] == p1[m_len] &&
  6808. + p2[0] == p1[0] && p2[1] == p1[1])
  6809. + {
  6810. + lzo_uint i;
  6811. +
  6812. + p1 += 2;
  6813. + p2 += 2;
  6814. + do
  6815. + {
  6816. + }
  6817. + while (++p1 < px && *p1 == *++p2);
  6818. +
  6819. + i = p1 - bp;
  6820. +
  6821. + if (i < SWD_BEST_OFF)
  6822. + {
  6823. + if (s->best_pos[i] == 0)
  6824. + s->best_pos[i] = node + 1;
  6825. + }
  6826. +
  6827. + if (i > m_len)
  6828. + {
  6829. + s->m_len = m_len = i;
  6830. + s->m_pos = node;
  6831. + if (m_len == s->look)
  6832. + return;
  6833. + if (m_len >= s->nice_length)
  6834. + return;
  6835. + if (m_len > (lzo_uint) s->best3[node])
  6836. + return;
  6837. + scan_end1 = bp[m_len - 1];
  6838. + }
  6839. + }
  6840. + }
  6841. +}
  6842. +
  6843. +static lzo_bool
  6844. +swd_search2 (lzo1x_999_swd_t * s)
  6845. +{
  6846. + lzo_uint key;
  6847. +
  6848. + key = s->head2[HEAD2 (s->b, s->bp)];
  6849. + if (key == NIL2)
  6850. + return 0;
  6851. +
  6852. + if (s->best_pos[2] == 0)
  6853. + s->best_pos[2] = key + 1;
  6854. +
  6855. + if (s->m_len < 2)
  6856. + {
  6857. + s->m_len = 2;
  6858. + s->m_pos = key;
  6859. + }
  6860. + return 1;
  6861. +}
  6862. +
  6863. +static void
  6864. +swd_findbest (lzo1x_999_swd_t * s)
  6865. +{
  6866. + lzo_uint key;
  6867. + lzo_uint cnt, node;
  6868. + lzo_uint len;
  6869. +
  6870. + key = HEAD3 (s->b, s->bp);
  6871. + node = s->succ3[s->bp] = s_head3 (s, key);
  6872. + cnt = s->llen3[key]++;
  6873. +
  6874. + if (cnt > s->max_chain && s->max_chain > 0)
  6875. + cnt = s->max_chain;
  6876. + s->head3[key] = SWD_UINT (s->bp);
  6877. +
  6878. + s->b_char = s->b[s->bp];
  6879. + len = s->m_len;
  6880. + if (s->m_len >= s->look)
  6881. + {
  6882. + if (s->look == 0)
  6883. + s->b_char = -1;
  6884. + s->m_off = 0;
  6885. + s->best3[s->bp] = SWD_UINT (s->f + 1);
  6886. + }
  6887. + else
  6888. + {
  6889. +
  6890. + if (swd_search2 (s))
  6891. +
  6892. + if (s->look >= 3)
  6893. + swd_search (s, node, cnt);
  6894. + if (s->m_len > len)
  6895. + s->m_off = swd_pos2off (s, s->m_pos);
  6896. + s->best3[s->bp] = SWD_UINT (s->m_len);
  6897. +
  6898. + if (s->use_best_off)
  6899. + {
  6900. + int i;
  6901. + for (i = 2; i < SWD_BEST_OFF; i++)
  6902. + if (s->best_pos[i] > 0)
  6903. + s->best_off[i] =
  6904. + swd_pos2off (s,
  6905. + s->best_pos[i] -
  6906. + 1);
  6907. + else
  6908. + s->best_off[i] = 0;
  6909. + }
  6910. +
  6911. + }
  6912. +
  6913. + swd_remove_node (s, s->rp);
  6914. +
  6915. + key = HEAD2 (s->b, s->bp);
  6916. + s->head2[key] = SWD_UINT (s->bp);
  6917. +
  6918. +}
  6919. +
  6920. +/* lzo_mchw.ch */
  6921. +
  6922. +static int
  6923. +init_match (lzo1x_999_t * c, lzo1x_999_swd_t * s,
  6924. + const lzo_byte * dict, lzo_uint dict_len, lzo_uint32 flags)
  6925. +{
  6926. + int r;
  6927. +
  6928. + c->init = 1;
  6929. +
  6930. + s->c = c;
  6931. +
  6932. + c->last_m_len = c->last_m_off = 0;
  6933. +
  6934. + c->textsize = c->codesize = c->printcount = 0;
  6935. + c->lit_bytes = c->match_bytes = c->rep_bytes = 0;
  6936. + c->lazy = 0;
  6937. +
  6938. + r = swd_init (s, dict, dict_len);
  6939. + if (r != 0)
  6940. + return r;
  6941. +
  6942. + s->use_best_off = (flags & 1) ? 1 : 0;
  6943. + return r;
  6944. +}
  6945. +
  6946. +static int
  6947. +find_match (lzo1x_999_t * c, lzo1x_999_swd_t * s,
  6948. + lzo_uint this_len, lzo_uint skip)
  6949. +{
  6950. + if (skip > 0)
  6951. + {
  6952. + swd_accept (s, this_len - skip);
  6953. + c->textsize += this_len - skip + 1;
  6954. + }
  6955. + else
  6956. + {
  6957. + c->textsize += this_len - skip;
  6958. + }
  6959. +
  6960. + s->m_len = 1;
  6961. + s->m_len = 1;
  6962. +
  6963. + if (s->use_best_off)
  6964. + memset (s->best_pos, 0, sizeof (s->best_pos));
  6965. +
  6966. + swd_findbest (s);
  6967. + c->m_len = s->m_len;
  6968. + c->m_off = s->m_off;
  6969. +
  6970. + swd_getbyte (s);
  6971. +
  6972. + if (s->b_char < 0)
  6973. + {
  6974. + c->look = 0;
  6975. + c->m_len = 0;
  6976. + }
  6977. + else
  6978. + {
  6979. + c->look = s->look + 1;
  6980. + }
  6981. + c->bp = c->ip - c->look;
  6982. +
  6983. + if (c->cb && c->textsize > c->printcount)
  6984. + {
  6985. + (*c->cb) (c->textsize, c->codesize);
  6986. + c->printcount += 1024;
  6987. + }
  6988. +
  6989. + return LZO_E_OK;
  6990. +}
  6991. +
  6992. +/* lzo1x_9x.c */
  6993. +
  6994. +static lzo_byte *
  6995. +code_match (lzo1x_999_t * c, lzo_byte * op, lzo_uint m_len, lzo_uint m_off)
  6996. +{
  6997. + lzo_uint x_len = m_len;
  6998. + lzo_uint x_off = m_off;
  6999. +
  7000. + c->match_bytes += m_len;
  7001. +
  7002. + if (m_len == 2)
  7003. + {
  7004. + m_off -= 1;
  7005. +
  7006. + *op++ = LZO_BYTE (M1_MARKER | ((m_off & 3) << 2));
  7007. + *op++ = LZO_BYTE (m_off >> 2);
  7008. +
  7009. + c->m1a_m++;
  7010. + }
  7011. +
  7012. + else if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET)
  7013. +
  7014. + {
  7015. +
  7016. + m_off -= 1;
  7017. + *op++ = LZO_BYTE (((m_len - 1) << 5) | ((m_off & 7) << 2));
  7018. + *op++ = LZO_BYTE (m_off >> 3);
  7019. + c->m2_m++;
  7020. + }
  7021. + else if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET
  7022. + && c->r1_lit >= 4)
  7023. + {
  7024. + m_off -= 1 + M2_MAX_OFFSET;
  7025. +
  7026. + *op++ = LZO_BYTE (M1_MARKER | ((m_off & 3) << 2));
  7027. + *op++ = LZO_BYTE (m_off >> 2);
  7028. +
  7029. + c->m1b_m++;
  7030. + }
  7031. + else if (m_off <= M3_MAX_OFFSET)
  7032. + {
  7033. + m_off -= 1;
  7034. + if (m_len <= M3_MAX_LEN)
  7035. + *op++ = LZO_BYTE (M3_MARKER | (m_len - 2));
  7036. + else
  7037. + {
  7038. + m_len -= M3_MAX_LEN;
  7039. + *op++ = M3_MARKER | 0;
  7040. + while (m_len > 255)
  7041. + {
  7042. + m_len -= 255;
  7043. + *op++ = 0;
  7044. + }
  7045. + *op++ = LZO_BYTE (m_len);
  7046. + }
  7047. +
  7048. + *op++ = LZO_BYTE (m_off << 2);
  7049. + *op++ = LZO_BYTE (m_off >> 6);
  7050. +
  7051. + c->m3_m++;
  7052. + }
  7053. + else
  7054. + {
  7055. + lzo_uint k;
  7056. +
  7057. + m_off -= 0x4000;
  7058. + k = (m_off & 0x4000) >> 11;
  7059. + if (m_len <= M4_MAX_LEN)
  7060. + *op++ = LZO_BYTE (M4_MARKER | k | (m_len - 2));
  7061. + else
  7062. + {
  7063. + m_len -= M4_MAX_LEN;
  7064. + *op++ = LZO_BYTE (M4_MARKER | k | 0);
  7065. + while (m_len > 255)
  7066. + {
  7067. + m_len -= 255;
  7068. + *op++ = 0;
  7069. + }
  7070. + *op++ = LZO_BYTE (m_len);
  7071. + }
  7072. +
  7073. + *op++ = LZO_BYTE (m_off << 2);
  7074. + *op++ = LZO_BYTE (m_off >> 6);
  7075. +
  7076. + c->m4_m++;
  7077. + }
  7078. +
  7079. + c->last_m_len = x_len;
  7080. + c->last_m_off = x_off;
  7081. + return op;
  7082. +}
  7083. +
  7084. +static lzo_byte *
  7085. +STORE_RUN (lzo1x_999_t * c, lzo_byte * op, const lzo_byte * ii, lzo_uint t)
  7086. +{
  7087. + c->lit_bytes += t;
  7088. +
  7089. + if (op == c->out && t <= 238)
  7090. + {
  7091. + *op++ = LZO_BYTE (17 + t);
  7092. + }
  7093. + else if (t <= 3)
  7094. + {
  7095. + op[-2] |= LZO_BYTE (t);
  7096. +
  7097. + c->lit1_r++;
  7098. + }
  7099. + else if (t <= 18)
  7100. + {
  7101. + *op++ = LZO_BYTE (t - 3);
  7102. + c->lit2_r++;
  7103. + }
  7104. + else
  7105. + {
  7106. + lzo_uint tt = t - 18;
  7107. +
  7108. + *op++ = 0;
  7109. + while (tt > 255)
  7110. + {
  7111. + tt -= 255;
  7112. + *op++ = 0;
  7113. + }
  7114. + *op++ = LZO_BYTE (tt);
  7115. + c->lit3_r++;
  7116. + }
  7117. + do
  7118. + *op++ = *ii++;
  7119. + while (--t > 0);
  7120. +
  7121. + return op;
  7122. +}
  7123. +
  7124. +static lzo_byte *
  7125. +code_run (lzo1x_999_t * c, lzo_byte * op, const lzo_byte * ii,
  7126. + lzo_uint lit, lzo_uint m_len)
  7127. +{
  7128. + if (lit > 0)
  7129. + {
  7130. + op = STORE_RUN (c, op, ii, lit);
  7131. + c->r1_m_len = m_len;
  7132. + c->r1_lit = lit;
  7133. + }
  7134. + else
  7135. + {
  7136. + c->r1_m_len = 0;
  7137. + c->r1_lit = 0;
  7138. + }
  7139. +
  7140. + return op;
  7141. +}
  7142. +
  7143. +static int
  7144. +len_of_coded_match (lzo_uint m_len, lzo_uint m_off, lzo_uint lit)
  7145. +{
  7146. + int n = 4;
  7147. +
  7148. + if (m_len < 2)
  7149. + return -1;
  7150. + if (m_len == 2)
  7151. + return (m_off <= M1_MAX_OFFSET && lit > 0
  7152. + && lit < 4) ? 2 : -1;
  7153. + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET)
  7154. + return 2;
  7155. + if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && lit >= 4)
  7156. + return 2;
  7157. + if (m_off <= M3_MAX_OFFSET)
  7158. + {
  7159. + if (m_len <= M3_MAX_LEN)
  7160. + return 3;
  7161. + m_len -= M3_MAX_LEN;
  7162. + while (m_len > 255)
  7163. + {
  7164. + m_len -= 255;
  7165. + n++;
  7166. + }
  7167. + return n;
  7168. + }
  7169. + if (m_off <= M4_MAX_OFFSET)
  7170. + {
  7171. + if (m_len <= M4_MAX_LEN)
  7172. + return 3;
  7173. + m_len -= M4_MAX_LEN;
  7174. + while (m_len > 255)
  7175. + {
  7176. + m_len -= 255;
  7177. + n++;
  7178. + }
  7179. + return n;
  7180. + }
  7181. + return -1;
  7182. +}
  7183. +
  7184. +static lzo_int
  7185. +min_gain (lzo_uint ahead, lzo_uint lit1, lzo_uint lit2, int l1, int l2,
  7186. + int l3)
  7187. +{
  7188. + lzo_int lazy_match_min_gain = 0;
  7189. +
  7190. + lazy_match_min_gain += ahead;
  7191. +
  7192. + if (lit1 <= 3)
  7193. + lazy_match_min_gain += (lit2 <= 3) ? 0 : 2;
  7194. + else if (lit1 <= 18)
  7195. + lazy_match_min_gain += (lit2 <= 18) ? 0 : 1;
  7196. +
  7197. + lazy_match_min_gain += (l2 - l1) * 2;
  7198. + if (l3 > 0)
  7199. + lazy_match_min_gain -= (ahead - l3) * 2;
  7200. +
  7201. + if (lazy_match_min_gain < 0)
  7202. + lazy_match_min_gain = 0;
  7203. +
  7204. + return lazy_match_min_gain;
  7205. +}
  7206. +
  7207. +static void
  7208. +better_match (const lzo1x_999_swd_t * swd, lzo_uint * m_len, lzo_uint * m_off)
  7209. +{
  7210. + if (*m_len <= M2_MIN_LEN)
  7211. + return;
  7212. +
  7213. + if (*m_off <= M2_MAX_OFFSET)
  7214. + return;
  7215. +
  7216. + if (*m_off > M2_MAX_OFFSET &&
  7217. + *m_len >= M2_MIN_LEN + 1 && *m_len <= M2_MAX_LEN + 1 &&
  7218. + swd->best_off[*m_len - 1]
  7219. + && swd->best_off[*m_len - 1] <= M2_MAX_OFFSET)
  7220. + {
  7221. + *m_len = *m_len - 1;
  7222. + *m_off = swd->best_off[*m_len];
  7223. + return;
  7224. + }
  7225. +
  7226. + if (*m_off > M3_MAX_OFFSET &&
  7227. + *m_len >= M4_MAX_LEN + 1 && *m_len <= M2_MAX_LEN + 2 &&
  7228. + swd->best_off[*m_len - 2]
  7229. + && swd->best_off[*m_len - 2] <= M2_MAX_OFFSET)
  7230. + {
  7231. + *m_len = *m_len - 2;
  7232. + *m_off = swd->best_off[*m_len];
  7233. + return;
  7234. + }
  7235. +
  7236. + if (*m_off > M3_MAX_OFFSET &&
  7237. + *m_len >= M4_MAX_LEN + 1 && *m_len <= M3_MAX_LEN + 1 &&
  7238. + swd->best_off[*m_len - 1]
  7239. + && swd->best_off[*m_len - 1] <= M3_MAX_OFFSET)
  7240. + {
  7241. + *m_len = *m_len - 1;
  7242. + *m_off = swd->best_off[*m_len];
  7243. + }
  7244. +
  7245. +}
  7246. +
  7247. +/* minilzo.c */
  7248. +
  7249. +static lzo_bool
  7250. +lzo_assert (int expr)
  7251. +{
  7252. + return (expr) ? 1 : 0;
  7253. +}
  7254. +
  7255. +/* lzo1x_9x.c */
  7256. +
  7257. +static int
  7258. +lzo1x_999_compress_internal (const lzo_byte * in, lzo_uint in_len,
  7259. + lzo_byte * out, lzo_uintp out_len,
  7260. + lzo_voidp wrkmem,
  7261. + const lzo_byte * dict, lzo_uint dict_len,
  7262. + lzo_progress_callback_t cb,
  7263. + int try_lazy,
  7264. + lzo_uint good_length,
  7265. + lzo_uint max_lazy,
  7266. + lzo_uint nice_length,
  7267. + lzo_uint max_chain, lzo_uint32 flags)
  7268. +{
  7269. + lzo_byte *op;
  7270. + const lzo_byte *ii;
  7271. + lzo_uint lit;
  7272. + lzo_uint m_len, m_off;
  7273. + lzo1x_999_t cc;
  7274. + lzo1x_999_t *const c = &cc;
  7275. + lzo1x_999_swd_t *const swd = (lzo1x_999_swd_t *) wrkmem;
  7276. + int r;
  7277. +
  7278. + if (!lzo_assert
  7279. + (LZO1X_999_MEM_COMPRESS >= lzo_sizeof (lzo1x_999_swd_t)))
  7280. + return LZO_E_ERROR;
  7281. +
  7282. + if (try_lazy < 0)
  7283. + try_lazy = 1;
  7284. +
  7285. + if (good_length <= 0)
  7286. + good_length = 32;
  7287. +
  7288. + if (max_lazy <= 0)
  7289. + max_lazy = 32;
  7290. +
  7291. + if (nice_length <= 0)
  7292. + nice_length = 0;
  7293. +
  7294. + if (max_chain <= 0)
  7295. + max_chain = SWD_MAX_CHAIN;
  7296. +
  7297. + c->init = 0;
  7298. + c->ip = c->in = in;
  7299. + c->in_end = in + in_len;
  7300. + c->out = out;
  7301. + c->cb = cb;
  7302. + c->m1a_m = c->m1b_m = c->m2_m = c->m3_m = c->m4_m = 0;
  7303. + c->lit1_r = c->lit2_r = c->lit3_r = 0;
  7304. +
  7305. + op = out;
  7306. + ii = c->ip;
  7307. + lit = 0;
  7308. + c->r1_lit = c->r1_m_len = 0;
  7309. +
  7310. + r = init_match (c, swd, dict, dict_len, flags);
  7311. + if (r != 0)
  7312. + return r;
  7313. + if (max_chain > 0)
  7314. + swd->max_chain = max_chain;
  7315. + if (nice_length > 0)
  7316. + swd->nice_length = nice_length;
  7317. +
  7318. + r = find_match (c, swd, 0, 0);
  7319. + if (r != 0)
  7320. + return r;
  7321. + while (c->look > 0)
  7322. + {
  7323. + lzo_uint ahead;
  7324. + lzo_uint max_ahead;
  7325. + int l1, l2, l3;
  7326. +
  7327. + c->codesize = op - out;
  7328. +
  7329. + m_len = c->m_len;
  7330. + m_off = c->m_off;
  7331. +
  7332. + if (lit == 0)
  7333. + ii = c->bp;
  7334. +
  7335. + if (m_len < 2 ||
  7336. + (m_len == 2
  7337. + && (m_off > M1_MAX_OFFSET || lit == 0 || lit >= 4))
  7338. + || (m_len == 2 && op == out) || (op == out && lit == 0))
  7339. + {
  7340. +
  7341. + m_len = 0;
  7342. + }
  7343. + else if (m_len == M2_MIN_LEN)
  7344. + {
  7345. +
  7346. + if (m_off > MX_MAX_OFFSET && lit >= 4)
  7347. + m_len = 0;
  7348. + }
  7349. +
  7350. + if (m_len == 0)
  7351. + {
  7352. +
  7353. + lit++;
  7354. + swd->max_chain = max_chain;
  7355. + r = find_match (c, swd, 1, 0);
  7356. + continue;
  7357. + }
  7358. +
  7359. + if (swd->use_best_off)
  7360. + better_match (swd, &m_len, &m_off);
  7361. +
  7362. + ahead = 0;
  7363. + if (try_lazy <= 0 || m_len >= max_lazy)
  7364. + {
  7365. +
  7366. + l1 = 0;
  7367. + max_ahead = 0;
  7368. + }
  7369. + else
  7370. + {
  7371. +
  7372. + l1 = len_of_coded_match (m_len, m_off, lit);
  7373. +
  7374. + max_ahead = LZO_MIN (try_lazy, l1 - 1);
  7375. +
  7376. + }
  7377. +
  7378. + while (ahead < max_ahead && c->look > m_len)
  7379. + {
  7380. + lzo_int lazy_match_min_gain;
  7381. +
  7382. + if (m_len >= good_length)
  7383. + swd->max_chain = max_chain >> 2;
  7384. + else
  7385. + swd->max_chain = max_chain;
  7386. + r = find_match (c, swd, 1, 0);
  7387. + ahead++;
  7388. +
  7389. + if (c->m_len < m_len)
  7390. + continue;
  7391. +
  7392. + if (c->m_len == m_len && c->m_off >= m_off)
  7393. + continue;
  7394. +
  7395. + if (swd->use_best_off)
  7396. + better_match (swd, &c->m_len, &c->m_off);
  7397. +
  7398. + l2 = len_of_coded_match (c->m_len, c->m_off,
  7399. + lit + ahead);
  7400. + if (l2 < 0)
  7401. + continue;
  7402. +
  7403. + l3 = (op == out) ? -1 : len_of_coded_match (ahead,
  7404. + m_off,
  7405. + lit);
  7406. +
  7407. + lazy_match_min_gain =
  7408. + min_gain (ahead, lit, lit + ahead, l1, l2,
  7409. + l3);
  7410. + if (c->m_len >= m_len + lazy_match_min_gain)
  7411. + {
  7412. + c->lazy++;
  7413. +
  7414. + if (l3 > 0)
  7415. + {
  7416. +
  7417. + op = code_run (c, op, ii, lit, ahead);
  7418. + lit = 0;
  7419. +
  7420. + op = code_match (c, op, ahead, m_off);
  7421. + }
  7422. + else
  7423. + {
  7424. + lit += ahead;
  7425. + }
  7426. + goto lazy_match_done;
  7427. + }
  7428. + }
  7429. +
  7430. + op = code_run (c, op, ii, lit, m_len);
  7431. + lit = 0;
  7432. +
  7433. + op = code_match (c, op, m_len, m_off);
  7434. + swd->max_chain = max_chain;
  7435. + r = find_match (c, swd, m_len, 1 + ahead);
  7436. +
  7437. + lazy_match_done:;
  7438. + }
  7439. +
  7440. + if (lit > 0)
  7441. + op = STORE_RUN (c, op, ii, lit);
  7442. +
  7443. + *op++ = M4_MARKER | 1;
  7444. + *op++ = 0;
  7445. + *op++ = 0;
  7446. +
  7447. + c->codesize = op - out;
  7448. +
  7449. + *out_len = op - out;
  7450. +
  7451. + if (c->cb)
  7452. + (*c->cb) (c->textsize, c->codesize);
  7453. +
  7454. + return LZO_E_OK;
  7455. +}
  7456. +
  7457. +static int
  7458. +lzo1x_999_compress_level (const lzo_byte * in, lzo_uint in_len,
  7459. + lzo_byte * out, lzo_uintp out_len,
  7460. + lzo_voidp wrkmem,
  7461. + const lzo_byte * dict, lzo_uint dict_len,
  7462. + lzo_progress_callback_t cb, int compression_level)
  7463. +{
  7464. + static const struct
  7465. + {
  7466. + int try_lazy;
  7467. + lzo_uint good_length;
  7468. + lzo_uint max_lazy;
  7469. + lzo_uint nice_length;
  7470. + lzo_uint max_chain;
  7471. + lzo_uint32 flags;
  7472. + } c[9] =
  7473. + {
  7474. + {
  7475. + 0, 0, 0, 8, 4, 0},
  7476. + {
  7477. + 0, 0, 0, 16, 8, 0},
  7478. + {
  7479. + 0, 0, 0, 32, 16, 0},
  7480. + {
  7481. + 1, 4, 4, 16, 16, 0},
  7482. + {
  7483. + 1, 8, 16, 32, 32, 0},
  7484. + {
  7485. + 1, 8, 16, 128, 128, 0},
  7486. + {
  7487. + 2, 8, 32, 128, 256, 0},
  7488. + {
  7489. + 2, 32, 128, F, 2048, 1},
  7490. + {
  7491. + 2, F, F, F, 4096, 1}
  7492. + };
  7493. +
  7494. + if (compression_level < 1 || compression_level > 9)
  7495. + return LZO_E_ERROR;
  7496. +
  7497. + compression_level -= 1;
  7498. + return lzo1x_999_compress_internal (in, in_len, out, out_len, wrkmem,
  7499. + dict, dict_len, cb,
  7500. + c[compression_level].try_lazy,
  7501. + c[compression_level].good_length,
  7502. + c[compression_level].max_lazy,
  7503. + 0,
  7504. + c[compression_level].max_chain,
  7505. + c[compression_level].flags);
  7506. +}
  7507. +
  7508. +static int
  7509. +lzo1x_999_compress (const lzo_byte * in, lzo_uint in_len,
  7510. + lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem)
  7511. +{
  7512. + return lzo1x_999_compress_level (in, in_len, out, out_len, wrkmem,
  7513. + NULL, 0, 0, 8);
  7514. +}
  7515. +
  7516. +/* minilzo.c */
  7517. +
  7518. +static const lzo_byte __lzo_copyright[] = LZO_VERSION_STRING;
  7519. +
  7520. +static lzo_uint
  7521. +_lzo1x_1_do_compress (const lzo_byte * in, lzo_uint in_len,
  7522. + lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem)
  7523. +{
  7524. +
  7525. + register const lzo_byte *ip;
  7526. +
  7527. + lzo_byte *op;
  7528. + const lzo_byte *const in_end = in + in_len;
  7529. + const lzo_byte *const ip_end = in + in_len - 8 - 5;
  7530. + const lzo_byte *ii;
  7531. + lzo_dict_p const dict = (lzo_dict_p) wrkmem;
  7532. +
  7533. + op = out;
  7534. + ip = in;
  7535. + ii = ip;
  7536. +
  7537. + ip += 4;
  7538. + for (;;)
  7539. + {
  7540. + register const lzo_byte *m_pos;
  7541. +
  7542. + lzo_uint m_off;
  7543. + lzo_uint m_len;
  7544. + lzo_uint dindex;
  7545. +
  7546. + DINDEX1 (dindex, ip);
  7547. + GINDEX (m_pos, m_off, dict, dindex, in);
  7548. + if (LZO_CHECK_MPOS_NON_DET
  7549. + (m_pos, m_off, in, ip, M4_MAX_OFFSET))
  7550. + goto literal;
  7551. +
  7552. + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
  7553. + goto try_match;
  7554. + DINDEX2 (dindex, ip);
  7555. + GINDEX (m_pos, m_off, dict, dindex, in);
  7556. +
  7557. + if (LZO_CHECK_MPOS_NON_DET
  7558. + (m_pos, m_off, in, ip, M4_MAX_OFFSET))
  7559. + goto literal;
  7560. + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
  7561. + goto try_match;
  7562. + goto literal;
  7563. +
  7564. + try_match:
  7565. + if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
  7566. + {
  7567. + }
  7568. + else
  7569. + {
  7570. + if (m_pos[2] == ip[2])
  7571. + {
  7572. + goto match;
  7573. + }
  7574. + else
  7575. + {
  7576. + }
  7577. + }
  7578. +
  7579. + literal:
  7580. + UPDATE_I (dict, 0, dindex, ip, in);
  7581. + ++ip;
  7582. + if (ip >= ip_end)
  7583. + break;
  7584. + continue;
  7585. +
  7586. + match:
  7587. + UPDATE_I (dict, 0, dindex, ip, in);
  7588. +
  7589. + if (pd (ip, ii) > 0)
  7590. + {
  7591. + register lzo_uint t = pd (ip, ii);
  7592. +
  7593. + if (t <= 3)
  7594. + {
  7595. + op[-2] |= LZO_BYTE (t);
  7596. + }
  7597. + else if (t <= 18)
  7598. + *op++ = LZO_BYTE (t - 3);
  7599. + else
  7600. + {
  7601. + register lzo_uint tt = t - 18;
  7602. +
  7603. + *op++ = 0;
  7604. + while (tt > 255)
  7605. + {
  7606. + tt -= 255;
  7607. + *op++ = 0;
  7608. + }
  7609. + *op++ = LZO_BYTE (tt);;
  7610. + }
  7611. + do
  7612. + *op++ = *ii++;
  7613. + while (--t > 0);
  7614. + }
  7615. +
  7616. + ip += 3;
  7617. + if (m_pos[3] != *ip++ || m_pos[4] != *ip++
  7618. + || m_pos[5] != *ip++ || m_pos[6] != *ip++
  7619. + || m_pos[7] != *ip++ || m_pos[8] != *ip++)
  7620. + {
  7621. + --ip;
  7622. + m_len = ip - ii;
  7623. +
  7624. + if (m_off <= M2_MAX_OFFSET)
  7625. + {
  7626. + m_off -= 1;
  7627. +
  7628. + *op++ = LZO_BYTE (((m_len -
  7629. + 1) << 5) | ((m_off & 7) <<
  7630. + 2));
  7631. + *op++ = LZO_BYTE (m_off >> 3);
  7632. + }
  7633. + else if (m_off <= M3_MAX_OFFSET)
  7634. + {
  7635. + m_off -= 1;
  7636. + *op++ = LZO_BYTE (M3_MARKER | (m_len - 2));
  7637. + goto m3_m4_offset;
  7638. + }
  7639. + else
  7640. +
  7641. + {
  7642. + m_off -= 0x4000;
  7643. +
  7644. + *op++ = LZO_BYTE (M4_MARKER |
  7645. + ((m_off & 0x4000) >> 11) |
  7646. + (m_len - 2));
  7647. + goto m3_m4_offset;
  7648. + }
  7649. + }
  7650. + else
  7651. + {
  7652. + {
  7653. + const lzo_byte *end = in_end;
  7654. + const lzo_byte *m = m_pos + M2_MAX_LEN + 1;
  7655. + while (ip < end && *m == *ip)
  7656. + m++, ip++;
  7657. + m_len = (ip - ii);
  7658. + }
  7659. +
  7660. +
  7661. + if (m_off <= M3_MAX_OFFSET)
  7662. + {
  7663. + m_off -= 1;
  7664. + if (m_len <= 33)
  7665. + *op++ = LZO_BYTE (M3_MARKER |
  7666. + (m_len - 2));
  7667. + else
  7668. + {
  7669. + m_len -= 33;
  7670. + *op++ = M3_MARKER | 0;
  7671. + goto m3_m4_len;
  7672. + }
  7673. + }
  7674. + else
  7675. + {
  7676. + m_off -= 0x4000;
  7677. +
  7678. + if (m_len <= M4_MAX_LEN)
  7679. + *op++ = LZO_BYTE (M4_MARKER |
  7680. + ((m_off & 0x4000) >>
  7681. + 11) | (m_len - 2));
  7682. +
  7683. + else
  7684. + {
  7685. + m_len -= M4_MAX_LEN;
  7686. + *op++ = LZO_BYTE (M4_MARKER |
  7687. + ((m_off & 0x4000) >>
  7688. + 11));
  7689. + m3_m4_len:
  7690. + while (m_len > 255)
  7691. + {
  7692. + m_len -= 255;
  7693. + *op++ = 0;
  7694. + }
  7695. +
  7696. + *op++ = LZO_BYTE (m_len);
  7697. + }
  7698. + }
  7699. +
  7700. + m3_m4_offset:
  7701. + *op++ = LZO_BYTE ((m_off & 63) << 2);
  7702. + *op++ = LZO_BYTE (m_off >> 6);
  7703. + }
  7704. + ii = ip;
  7705. + if (ip >= ip_end)
  7706. + break;
  7707. + }
  7708. +
  7709. + *out_len = op - out;
  7710. + return pd (in_end, ii);
  7711. +}
  7712. +
  7713. +static int
  7714. +lzo1x_1_compress (const lzo_byte * in, lzo_uint in_len,
  7715. + lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem)
  7716. +{
  7717. + lzo_byte *op = out;
  7718. + lzo_uint t;
  7719. +
  7720. + if (in_len <= M2_MAX_LEN + 5)
  7721. + t = in_len;
  7722. + else
  7723. + {
  7724. + t = _lzo1x_1_do_compress (in, in_len, op, out_len, wrkmem);
  7725. + op += *out_len;
  7726. + }
  7727. +
  7728. + if (t > 0)
  7729. + {
  7730. + const lzo_byte *ii = in + in_len - t;
  7731. +
  7732. + if (op == out && t <= 238)
  7733. + *op++ = LZO_BYTE (17 + t);
  7734. + else if (t <= 3)
  7735. + op[-2] |= LZO_BYTE (t);
  7736. + else if (t <= 18)
  7737. + *op++ = LZO_BYTE (t - 3);
  7738. + else
  7739. + {
  7740. + lzo_uint tt = t - 18;
  7741. +
  7742. + *op++ = 0;
  7743. + while (tt > 255)
  7744. + {
  7745. + tt -= 255;
  7746. + *op++ = 0;
  7747. + }
  7748. +
  7749. + *op++ = LZO_BYTE (tt);
  7750. + }
  7751. + do
  7752. + *op++ = *ii++;
  7753. + while (--t > 0);
  7754. + }
  7755. +
  7756. + *op++ = M4_MARKER | 1;
  7757. + *op++ = 0;
  7758. + *op++ = 0;
  7759. +
  7760. + *out_len = op - out;
  7761. + return 0;
  7762. +}
  7763. +
  7764. +static int
  7765. +lzo1x_decompress (const lzo_byte * in, lzo_uint in_len,
  7766. + lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem)
  7767. +{
  7768. + register lzo_byte *op;
  7769. + register const lzo_byte *ip;
  7770. + register lzo_uint t;
  7771. +
  7772. + register const lzo_byte *m_pos;
  7773. +
  7774. + const lzo_byte *const ip_end = in + in_len;
  7775. + lzo_byte *const op_end = out + *out_len;
  7776. +
  7777. + *out_len = 0;
  7778. +
  7779. + op = out;
  7780. + ip = in;
  7781. +
  7782. + if (*ip > 17)
  7783. + {
  7784. + t = *ip++ - 17;
  7785. + if (t < 4)
  7786. + goto match_next;
  7787. + NEED_OP (t);
  7788. + NEED_IP (t + 1);
  7789. + do
  7790. + *op++ = *ip++;
  7791. + while (--t > 0);
  7792. + goto first_literal_run;
  7793. + }
  7794. +
  7795. + while (TEST_IP && TEST_OP)
  7796. + {
  7797. + t = *ip++;
  7798. + if (t >= 16)
  7799. + goto match;
  7800. + if (t == 0)
  7801. + {
  7802. + NEED_IP (1);
  7803. + while (*ip == 0)
  7804. + {
  7805. + t += 255;
  7806. + ip++;
  7807. + NEED_IP (1);
  7808. + }
  7809. + t += 15 + *ip++;
  7810. + }
  7811. + NEED_OP (t + 3);
  7812. + NEED_IP (t + 4);
  7813. + if (PTR_ALIGNED2_4 (op, ip))
  7814. + {
  7815. + COPY4 (op, ip);
  7816. +
  7817. + op += 4;
  7818. + ip += 4;
  7819. + if (--t > 0)
  7820. + {
  7821. + if (t >= 4)
  7822. + {
  7823. + do
  7824. + {
  7825. + COPY4 (op, ip);
  7826. + op += 4;
  7827. + ip += 4;
  7828. + t -= 4;
  7829. + }
  7830. + while (t >= 4);
  7831. + if (t > 0)
  7832. + do
  7833. + *op++ = *ip++;
  7834. + while (--t > 0);
  7835. + }
  7836. + else
  7837. + do
  7838. + *op++ = *ip++;
  7839. + while (--t > 0);
  7840. + }
  7841. + }
  7842. + else
  7843. + {
  7844. + *op++ = *ip++;
  7845. + *op++ = *ip++;
  7846. + *op++ = *ip++;
  7847. + do
  7848. + *op++ = *ip++;
  7849. + while (--t > 0);
  7850. + }
  7851. + first_literal_run:
  7852. +
  7853. + t = *ip++;
  7854. + if (t >= 16)
  7855. + goto match;
  7856. +
  7857. + m_pos = op - (1 + M2_MAX_OFFSET);
  7858. + m_pos -= t >> 2;
  7859. + m_pos -= *ip++ << 2;
  7860. + TEST_LOOKBEHIND (m_pos, out);
  7861. + NEED_OP (3);
  7862. + *op++ = *m_pos++;
  7863. + *op++ = *m_pos++;
  7864. + *op++ = *m_pos;
  7865. +
  7866. + goto match_done;
  7867. +
  7868. + while (TEST_IP && TEST_OP)
  7869. + {
  7870. + match:
  7871. + if (t >= 64)
  7872. + {
  7873. + m_pos = op - 1;
  7874. + m_pos -= (t >> 2) & 7;
  7875. + m_pos -= *ip++ << 3;
  7876. + t = (t >> 5) - 1;
  7877. + TEST_LOOKBEHIND (m_pos, out);
  7878. + NEED_OP (t + 3 - 1);
  7879. + goto copy_match;
  7880. +
  7881. + }
  7882. + else if (t >= 32)
  7883. + {
  7884. + t &= 31;
  7885. + if (t == 0)
  7886. + {
  7887. + NEED_IP (1);
  7888. + while (*ip == 0)
  7889. + {
  7890. + t += 255;
  7891. + ip++;
  7892. + NEED_IP (1);
  7893. + }
  7894. + t += 31 + *ip++;
  7895. + }
  7896. +
  7897. + m_pos = op - 1;
  7898. + m_pos -= (ip[0] >> 2) + (ip[1] << 6);
  7899. +
  7900. + ip += 2;
  7901. + }
  7902. + else if (t >= 16)
  7903. + {
  7904. + m_pos = op;
  7905. + m_pos -= (t & 8) << 11;
  7906. +
  7907. + t &= 7;
  7908. + if (t == 0)
  7909. + {
  7910. + NEED_IP (1);
  7911. + while (*ip == 0)
  7912. + {
  7913. + t += 255;
  7914. + ip++;
  7915. + NEED_IP (1);
  7916. + }
  7917. + t += 7 + *ip++;
  7918. + }
  7919. +
  7920. + m_pos -= (ip[0] >> 2) + (ip[1] << 6);
  7921. +
  7922. + ip += 2;
  7923. + if (m_pos == op)
  7924. + goto eof_found;
  7925. + m_pos -= 0x4000;
  7926. + }
  7927. + else
  7928. + {
  7929. +
  7930. + m_pos = op - 1;
  7931. + m_pos -= t >> 2;
  7932. + m_pos -= *ip++ << 2;
  7933. + TEST_LOOKBEHIND (m_pos, out);
  7934. + NEED_OP (2);
  7935. + *op++ = *m_pos++;
  7936. + *op++ = *m_pos;
  7937. +
  7938. + goto match_done;
  7939. + }
  7940. +
  7941. + TEST_LOOKBEHIND (m_pos, out);
  7942. + NEED_OP (t + 3 - 1);
  7943. + if (t >= 2 * 4 - (3 - 1)
  7944. + && PTR_ALIGNED2_4 (op, m_pos))
  7945. + {
  7946. + COPY4 (op, m_pos);
  7947. + op += 4;
  7948. + m_pos += 4;
  7949. + t -= 4 - (3 - 1);
  7950. + do
  7951. + {
  7952. + COPY4 (op, m_pos);
  7953. + op += 4;
  7954. + m_pos += 4;
  7955. + t -= 4;
  7956. + }
  7957. + while (t >= 4);
  7958. + if (t > 0)
  7959. + do
  7960. + *op++ = *m_pos++;
  7961. + while (--t > 0);
  7962. + }
  7963. + else
  7964. +
  7965. + {
  7966. + copy_match:
  7967. + *op++ = *m_pos++;
  7968. + *op++ = *m_pos++;
  7969. + do
  7970. + *op++ = *m_pos++;
  7971. + while (--t > 0);
  7972. + }
  7973. +
  7974. + match_done:
  7975. + t = ip[-2] & 3;
  7976. +
  7977. + if (t == 0)
  7978. + break;
  7979. +
  7980. + match_next:
  7981. + NEED_OP (t);
  7982. + NEED_IP (t + 1);
  7983. + do
  7984. + *op++ = *ip++;
  7985. + while (--t > 0);
  7986. + t = *ip++;
  7987. + }
  7988. + }
  7989. + *out_len = op - out;
  7990. + return LZO_E_EOF_NOT_FOUND;
  7991. +
  7992. + eof_found:
  7993. + *out_len = op - out;
  7994. + return (ip == ip_end ? LZO_E_OK :
  7995. + (ip <
  7996. + ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
  7997. +
  7998. + input_overrun:
  7999. + *out_len = op - out;
  8000. + return LZO_E_INPUT_OVERRUN;
  8001. +
  8002. + output_overrun:
  8003. + *out_len = op - out;
  8004. + return LZO_E_OUTPUT_OVERRUN;
  8005. +
  8006. + lookbehind_overrun:
  8007. + *out_len = op - out;
  8008. + return LZO_E_LOOKBEHIND_OVERRUN;
  8009. +}
  8010. +
  8011. +/* lzo1x_oo.ch */
  8012. +
  8013. +#define NO_LIT LZO_UINT_MAX
  8014. +
  8015. +static void
  8016. +copy2 (lzo_byte * ip, const lzo_byte * m_pos, lzo_ptrdiff_t off)
  8017. +{
  8018. + ip[0] = m_pos[0];
  8019. + if (off == 1)
  8020. + ip[1] = m_pos[0];
  8021. + else
  8022. + ip[1] = m_pos[1];
  8023. +}
  8024. +
  8025. +static void
  8026. +copy3 (lzo_byte * ip, const lzo_byte * m_pos, lzo_ptrdiff_t off)
  8027. +{
  8028. + ip[0] = m_pos[0];
  8029. + if (off == 1)
  8030. + {
  8031. + ip[2] = ip[1] = m_pos[0];
  8032. + }
  8033. + else if (off == 2)
  8034. + {
  8035. + ip[1] = m_pos[1];
  8036. + ip[2] = m_pos[0];
  8037. + }
  8038. + else
  8039. + {
  8040. + ip[1] = m_pos[1];
  8041. + ip[2] = m_pos[2];
  8042. + }
  8043. +}
  8044. +
  8045. +static int
  8046. +lzo1x_optimize (lzo_byte * in, lzo_uint in_len,
  8047. + lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem)
  8048. +{
  8049. + register lzo_byte *op;
  8050. + register lzo_byte *ip;
  8051. + register lzo_uint t;
  8052. + register lzo_byte *m_pos;
  8053. + lzo_uint nl;
  8054. + const lzo_byte *const ip_end = in + in_len;
  8055. + const lzo_byte *const op_end = out + *out_len;
  8056. + lzo_byte *litp = NULL;
  8057. + lzo_uint lit = 0;
  8058. + lzo_uint next_lit = NO_LIT;
  8059. + long o_m1_a = 0, o_m1_b = 0, o_m2 = 0, o_m3_a = 0, o_m3_b = 0;
  8060. +
  8061. + *out_len = 0;
  8062. +
  8063. + op = out;
  8064. + ip = in;
  8065. +
  8066. + if (*ip > 17)
  8067. + {
  8068. + t = *ip++ - 17;
  8069. + if (t < 4)
  8070. + goto match_next;
  8071. + goto first_literal_run;
  8072. + }
  8073. +
  8074. + while (TEST_IP && TEST_OP)
  8075. + {
  8076. + t = *ip++;
  8077. + if (t >= 16)
  8078. + goto match;
  8079. + litp = ip - 1;
  8080. + if (t == 0)
  8081. + {
  8082. + t = 15;
  8083. + while (*ip == 0)
  8084. + t += 255, ip++;
  8085. + t += *ip++;
  8086. + }
  8087. + lit = t + 3;
  8088. + copy_literal_run:
  8089. + *op++ = *ip++;
  8090. + *op++ = *ip++;
  8091. + *op++ = *ip++;
  8092. + first_literal_run:
  8093. + do
  8094. + *op++ = *ip++;
  8095. + while (--t > 0);
  8096. +
  8097. + t = *ip++;
  8098. +
  8099. + if (t >= 16)
  8100. + goto match;
  8101. + m_pos = op - 1 - 0x800;
  8102. + m_pos -= t >> 2;
  8103. + m_pos -= *ip++ << 2;
  8104. + *op++ = *m_pos++;
  8105. + *op++ = *m_pos++;
  8106. + *op++ = *m_pos++;
  8107. + lit = 0;
  8108. + goto match_done;
  8109. +
  8110. + while (TEST_IP && TEST_OP)
  8111. + {
  8112. + if (t < 16)
  8113. + {
  8114. + m_pos = op - 1;
  8115. + m_pos -= t >> 2;
  8116. + m_pos -= *ip++ << 2;
  8117. +
  8118. + if (litp == NULL)
  8119. + goto copy_m1;
  8120. +
  8121. + nl = ip[-2] & 3;
  8122. + if (nl == 0 && lit == 1 && ip[0] >= 16)
  8123. + {
  8124. + next_lit = nl;
  8125. + lit += 2;
  8126. + *litp = LZO_BYTE ((*litp & ~3) | lit);
  8127. + copy2 (ip - 2, m_pos, op - m_pos);
  8128. + o_m1_a++;
  8129. + }
  8130. + else if (nl == 0 && ip[0] < 16 && ip[0] != 0
  8131. + && (lit + 2 + ip[0] < 16))
  8132. + {
  8133. + t = *ip++;
  8134. + *litp &= ~3;
  8135. + copy2 (ip - 3 + 1, m_pos, op - m_pos);
  8136. + litp += 2;
  8137. + if (lit > 0)
  8138. + memmove (litp + 1, litp, lit);
  8139. + lit += 2 + t + 3;
  8140. + *litp = LZO_BYTE (lit - 3);
  8141. +
  8142. + o_m1_b++;
  8143. + *op++ = *m_pos++;
  8144. + *op++ = *m_pos++;
  8145. + goto copy_literal_run;
  8146. + }
  8147. + copy_m1:
  8148. + *op++ = *m_pos++;
  8149. + *op++ = *m_pos++;
  8150. + }
  8151. + else
  8152. + {
  8153. + match:
  8154. + if (t >= 64)
  8155. + {
  8156. + m_pos = op - 1;
  8157. + m_pos -= (t >> 2) & 7;
  8158. + m_pos -= *ip++ << 3;
  8159. + t = (t >> 5) - 1;
  8160. + if (litp == NULL)
  8161. + goto copy_m;
  8162. +
  8163. + nl = ip[-2] & 3;
  8164. + if (t == 1 && lit > 3 && nl == 0 &&
  8165. + ip[0] < 16 && ip[0] != 0
  8166. + && (lit + 3 + ip[0] < 16))
  8167. + {
  8168. + t = *ip++;
  8169. + copy3 (ip - 1 - 2, m_pos,
  8170. + op - m_pos);
  8171. + lit += 3 + t + 3;
  8172. + *litp = LZO_BYTE (lit - 3);
  8173. + o_m2++;
  8174. + *op++ = *m_pos++;
  8175. + *op++ = *m_pos++;
  8176. + *op++ = *m_pos++;
  8177. + goto copy_literal_run;
  8178. + }
  8179. + }
  8180. + else
  8181. + {
  8182. + if (t >= 32)
  8183. + {
  8184. + t &= 31;
  8185. + if (t == 0)
  8186. + {
  8187. + t = 31;
  8188. + while (*ip == 0)
  8189. + t += 255,
  8190. + ip++;
  8191. + t += *ip++;
  8192. + }
  8193. + m_pos = op - 1;
  8194. + m_pos -= *ip++ >> 2;
  8195. + m_pos -= *ip++ << 6;
  8196. + }
  8197. + else
  8198. + {
  8199. + m_pos = op;
  8200. + m_pos -= (t & 8) << 11;
  8201. + t &= 7;
  8202. + if (t == 0)
  8203. + {
  8204. + t = 7;
  8205. + while (*ip == 0)
  8206. + t += 255,
  8207. + ip++;
  8208. + t += *ip++;
  8209. + }
  8210. + m_pos -= *ip++ >> 2;
  8211. + m_pos -= *ip++ << 6;
  8212. + if (m_pos == op)
  8213. + goto eof_found;
  8214. + m_pos -= 0x4000;
  8215. + }
  8216. + if (litp == NULL)
  8217. + goto copy_m;
  8218. +
  8219. + nl = ip[-2] & 3;
  8220. + if (t == 1 && lit == 0 && nl == 0
  8221. + && ip[0] >= 16)
  8222. + {
  8223. + next_lit = nl;
  8224. + lit += 3;
  8225. + *litp = LZO_BYTE ((*litp & ~3)
  8226. + | lit);
  8227. + copy3 (ip - 3, m_pos,
  8228. + op - m_pos);
  8229. + o_m3_a++;
  8230. + }
  8231. + else if (t == 1 && lit <= 3 && nl == 0
  8232. + && ip[0] < 16 && ip[0] != 0
  8233. + && (lit + 3 + ip[0] < 16))
  8234. + {
  8235. + t = *ip++;
  8236. + *litp &= ~3;
  8237. + copy3 (ip - 4 + 1, m_pos,
  8238. + op - m_pos);
  8239. + litp += 2;
  8240. + if (lit > 0)
  8241. + memmove (litp + 1,
  8242. + litp, lit);
  8243. + lit += 3 + t + 3;
  8244. + *litp = LZO_BYTE (lit - 3);
  8245. +
  8246. + o_m3_b++;
  8247. + *op++ = *m_pos++;
  8248. + *op++ = *m_pos++;
  8249. + *op++ = *m_pos++;
  8250. + goto copy_literal_run;
  8251. + }
  8252. + }
  8253. + copy_m:
  8254. + *op++ = *m_pos++;
  8255. + *op++ = *m_pos++;
  8256. + do
  8257. + *op++ = *m_pos++;
  8258. + while (--t > 0);
  8259. + }
  8260. +
  8261. + match_done:
  8262. + if (next_lit == NO_LIT)
  8263. + {
  8264. + t = ip[-2] & 3;
  8265. + lit = t;
  8266. + litp = ip - 2;
  8267. + }
  8268. + else
  8269. + t = next_lit;
  8270. + next_lit = NO_LIT;
  8271. + if (t == 0)
  8272. + break;
  8273. + match_next:
  8274. + do
  8275. + *op++ = *ip++;
  8276. + while (--t > 0);
  8277. + t = *ip++;
  8278. + }
  8279. + }
  8280. +
  8281. + *out_len = op - out;
  8282. + return LZO_E_EOF_NOT_FOUND;
  8283. +
  8284. + eof_found:
  8285. + *out_len = op - out;
  8286. + return (ip == ip_end ? LZO_E_OK :
  8287. + (ip <
  8288. + ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
  8289. +}
  8290. +
  8291. +/* interface to jffs2 bbc follows */
  8292. +
  8293. +#include "jffs2_bbc_framework.h"
  8294. +
  8295. +#define BLOCKSIZE 4096
  8296. +#define OUTBLOCKSIZE (BLOCKSIZE + BLOCKSIZE / 64 + 16 + 3)
  8297. +
  8298. +#define JFFS2_BBC_LZO_BLOCK_SIGN {0x3f, 0x47, 0x5a, 0x18}
  8299. +
  8300. +static int
  8301. +jffs2_bbc_lzo_compressor_init (void);
  8302. +
  8303. +static void
  8304. +jffs2_bbc_lzo_compressor_deinit (void);
  8305. +
  8306. +static int
  8307. +jffs2_bbc_lzo_compress (void *model, unsigned char *input,
  8308. + unsigned char *output, unsigned long *sourcelen,
  8309. + unsigned long *dstlen);
  8310. +
  8311. +static int
  8312. +jffs2_bbc_lzo_estimate (void *model, unsigned char *input,
  8313. + unsigned long sourcelen, unsigned long *dstlen,
  8314. + unsigned long *readtime, unsigned long *writetime);
  8315. +
  8316. +static int
  8317. +jffs2_bbc_lzo_decompress (void *model, unsigned char *input,
  8318. + unsigned char *output, unsigned long sourcelen,
  8319. + unsigned long dstlen);
  8320. +
  8321. +static char *
  8322. +jffs2_bbc_lzo_proc_info (void);
  8323. +
  8324. +static int
  8325. +jffs2_bbc_lzo_proc_command (char *command);
  8326. +
  8327. +struct jffs2_bbc_compressor_type jffs2_bbc_lzo = {
  8328. + "lzo",
  8329. + 0,
  8330. + JFFS2_BBC_LZO_BLOCK_SIGN,
  8331. + jffs2_bbc_lzo_compressor_init,
  8332. + NULL,
  8333. + NULL,
  8334. + jffs2_bbc_lzo_compressor_deinit,
  8335. + jffs2_bbc_lzo_compress,
  8336. + jffs2_bbc_lzo_estimate,
  8337. + jffs2_bbc_lzo_decompress,
  8338. + jffs2_bbc_lzo_proc_info,
  8339. + jffs2_bbc_lzo_proc_command
  8340. +};
  8341. +
  8342. +static int
  8343. +no_lzo1x_optimize (lzo_byte * src, lzo_uint src_len,
  8344. + lzo_byte * dst, lzo_uintp dst_len, lzo_voidp wrkmem)
  8345. +{
  8346. + return 0;
  8347. +}
  8348. +
  8349. +#ifdef __KERNEL__
  8350. +static lzo_compress_t lzo1x_compressor = lzo1x_1_compress;
  8351. +static lzo_optimize_t lzo1x_optimizer = no_lzo1x_optimize;
  8352. +static int lzo1x_compressor_type = 1;
  8353. +static int lzo1x_optimize_type = 0;
  8354. +static unsigned long lzo1x_compressor_memsize = LZO1X_1_MEM_COMPRESS;
  8355. +#else
  8356. +static lzo_compress_t lzo1x_compressor = lzo1x_999_compress;
  8357. +static lzo_optimize_t lzo1x_optimizer = lzo1x_optimize;
  8358. +static int lzo1x_compressor_type = 999;
  8359. +static int lzo1x_optimize_type = 1;
  8360. +static unsigned long lzo1x_compressor_memsize = LZO1X_999_MEM_COMPRESS;
  8361. +#endif
  8362. +
  8363. +static lzo_bytep wrkmem = NULL; /* temporary buffer for compression, used by lzo */
  8364. +static lzo_bytep cmprssmem = NULL; /* temporary buffer for compression, used by interface */
  8365. +
  8366. +static int
  8367. +jffs2_bbc_lzo_compressor_init (void)
  8368. +{
  8369. + wrkmem = (lzo_bytep) jffs2_bbc_malloc (lzo1x_compressor_memsize);
  8370. + cmprssmem = (lzo_bytep) jffs2_bbc_malloc (OUTBLOCKSIZE);
  8371. + return !(wrkmem && cmprssmem);
  8372. +}
  8373. +
  8374. +static void
  8375. +jffs2_bbc_lzo_compressor_deinit (void)
  8376. +{
  8377. + jffs2_bbc_free (wrkmem);
  8378. + jffs2_bbc_free (cmprssmem);
  8379. +}
  8380. +
  8381. +static int
  8382. +jffs2_bbc_lzo_compress (void *model, unsigned char *input,
  8383. + unsigned char *output, unsigned long *sourcelen,
  8384. + unsigned long *dstlen)
  8385. +{
  8386. + lzo_uint csize = OUTBLOCKSIZE;
  8387. + lzo_uint isize = *sourcelen;
  8388. + int retval;
  8389. + if ((retval =
  8390. + lzo1x_compressor (input, *sourcelen, cmprssmem, &csize,
  8391. + wrkmem)) != LZO_E_OK)
  8392. + {
  8393. + *sourcelen = *dstlen = 0;
  8394. + return retval;
  8395. + }
  8396. + else
  8397. + {
  8398. + retval = lzo1x_optimizer (cmprssmem, csize, input, &isize,
  8399. + NULL);
  8400. + csize += 2;
  8401. + if (csize <= *dstlen) {
  8402. + *dstlen = csize;
  8403. + *(output++) = jffs2_bbc_lzo.block_sign[0];
  8404. + *(output++) = jffs2_bbc_lzo.block_sign[1];
  8405. + memcpy (output, cmprssmem, csize - 2);
  8406. + return retval;
  8407. + } else {
  8408. + *sourcelen = *dstlen = 0;
  8409. + return -1;
  8410. + }
  8411. + }
  8412. +}
  8413. +
  8414. +static int
  8415. +jffs2_bbc_lzo_estimate (void *model, unsigned char *input,
  8416. + unsigned long sourcelen, unsigned long *dstlen,
  8417. + unsigned long *readtime, unsigned long *writetime)
  8418. +{
  8419. + *dstlen = sourcelen * 55 / 100;
  8420. + *readtime = JFFS2_BBC_ZLIB_READ_TIME / 2;
  8421. + *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 8 / 10; /* LZO1X-1 is much-much faster,
  8422. + but LZO1X-999 is slow. The default mode for inside kernel compression is LZO1X-1
  8423. + This should be *0.4 really */
  8424. + return 0;
  8425. +}
  8426. +
  8427. +static int
  8428. +jffs2_bbc_lzo_decompress (void *model, unsigned char *input,
  8429. + unsigned char *output, unsigned long sourcelen,
  8430. + unsigned long dstlen)
  8431. +{
  8432. + lzo_uint outlen = dstlen;
  8433. + if ( ( *(input++) != (unsigned char)jffs2_bbc_lzo.block_sign[0] ) ||
  8434. + ( *(input++) != (unsigned char)jffs2_bbc_lzo.block_sign[1] )
  8435. + ) {
  8436. + return -1;
  8437. + } else {
  8438. + return lzo1x_decompress (input, sourcelen - 2, output, &outlen, NULL);
  8439. + }
  8440. +}
  8441. +
  8442. +static char *
  8443. +jffs2_bbc_lzo_proc_info (void)
  8444. +{
  8445. + if (lzo1x_compressor_type == 1)
  8446. + {
  8447. + if (lzo1x_optimize_type == 1)
  8448. + {
  8449. + return "LZO1X-1 compression with optimization";
  8450. + }
  8451. + else
  8452. + {
  8453. + return "LZO1X-1 compression without optimization";
  8454. + }
  8455. + }
  8456. + else if (lzo1x_compressor_type == 999)
  8457. + {
  8458. + if (lzo1x_optimize_type == 1)
  8459. + {
  8460. + return "LZO1X-999 compression with optimization";
  8461. + }
  8462. + else
  8463. + {
  8464. + return "LZO1X-999 compression without optimization";
  8465. + }
  8466. + }
  8467. + else
  8468. + {
  8469. + return "Unknown configuration!";
  8470. + }
  8471. +}
  8472. +
  8473. +static int
  8474. +jffs2_bbc_lzo_proc_command (char *command)
  8475. +{
  8476. + switch (*command)
  8477. + {
  8478. + case 'o':
  8479. + /* switch optimization off */
  8480. + lzo1x_optimizer = no_lzo1x_optimize;
  8481. + lzo1x_optimize_type = 0;
  8482. + jffs2_bbc_print1 ("Compression optimization switched off.\n");
  8483. + return 0;
  8484. + case 'O':
  8485. + /* switch optimization on */
  8486. + lzo1x_optimizer = lzo1x_optimize;
  8487. + lzo1x_optimize_type = 1;
  8488. + jffs2_bbc_print1 ("Compression optimization switched on.\n");
  8489. + return 0;
  8490. + case '1':
  8491. + /* switch compression to LZO1X-1 */
  8492. + jffs2_bbc_free (wrkmem);
  8493. + lzo1x_compressor_type = 1;
  8494. + lzo1x_compressor = lzo1x_1_compress;
  8495. + lzo1x_compressor_memsize = LZO1X_1_MEM_COMPRESS;
  8496. + wrkmem = (lzo_bytep)
  8497. + jffs2_bbc_malloc (lzo1x_compressor_memsize);
  8498. + jffs2_bbc_print1 ("Compression type switched to LZO1X-1.\n");
  8499. + return 0;
  8500. + case '9':
  8501. + /* switch compression to LZO1X-999 */
  8502. + jffs2_bbc_free (wrkmem);
  8503. + lzo1x_compressor_type = 999;
  8504. + lzo1x_compressor = lzo1x_999_compress;
  8505. + lzo1x_compressor_memsize = LZO1X_999_MEM_COMPRESS;
  8506. + wrkmem = (lzo_bytep)
  8507. + jffs2_bbc_malloc (lzo1x_compressor_memsize);
  8508. + jffs2_bbc_print1
  8509. + ("Compression type switched to LZO1X-999.\n");
  8510. + return 0;
  8511. + default:
  8512. + jffs2_bbc_print1 ("Unknown command!\n");
  8513. + return 0;
  8514. + }
  8515. +}
  8516. +
  8517. +
  8518. +struct jffs2_bbc_compressor_type *
  8519. +jffs2_bbc_lzo_init (int mode)
  8520. +{
  8521. + if (jffs2_bbc_register_compressor (&jffs2_bbc_lzo) == 0)
  8522. + {
  8523. + return &jffs2_bbc_lzo;
  8524. + }
  8525. + else
  8526. + {
  8527. + return NULL;
  8528. + }
  8529. +}
  8530. +
  8531. +void
  8532. +jffs2_bbc_lzo_deinit (void)
  8533. +{
  8534. + jffs2_bbc_unregister_compressor (&jffs2_bbc_lzo);
  8535. +}
  8536. --- /dev/null
  8537. +++ b/fs/jffs2/jffs2_bbc_lzss_comp.c
  8538. @@ -0,0 +1,385 @@
  8539. +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
  8540. +
  8541. +/*
  8542. + jffs2_bbc_lzss_comp.c -- Lempel-Ziv-Storer-Szymanski compression module for jffs2
  8543. + Copyright (C) 2004 Patrik Kluba
  8544. + Based on the LZSS source included in LDS (lossless datacompression sources)
  8545. + Block-compression modifications by Patrik Kluba
  8546. + $Header: /openwrt/openwrt/package/linux/kernel-patches/301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $
  8547. +*/
  8548. +
  8549. +/*
  8550. +Original copyright follows:
  8551. +
  8552. +**************************************************************
  8553. + LZSS.C -- A Data Compression Program
  8554. +**************************************************************
  8555. + 4/6/1989 Haruhiko Okumura
  8556. + Use, distribute, and modify this program freely.
  8557. + Please send me your improved versions.
  8558. + PC-VAN SCIENCE
  8559. + NIFTY-Serve PAF01022
  8560. + CompuServe 74050,1022
  8561. +**************************************************************
  8562. +
  8563. +*/
  8564. +
  8565. +/*
  8566. +
  8567. + 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu>
  8568. + Initial release
  8569. +
  8570. +*/
  8571. +
  8572. +/* lzss.c */
  8573. +
  8574. +#define N 4096 /* size of ring buffer */
  8575. +#define F 18 /* upper limit for match_length */
  8576. +#define THRESHOLD 2 /* encode string into position and length
  8577. + if match_length is greater than this */
  8578. +#define NIL N /* index for root of binary search trees */
  8579. +
  8580. +static unsigned char
  8581. + text_buf[N + F - 1]; /* ring buffer of size N,
  8582. + with extra F-1 bytes to facilitate string comparison */
  8583. +static unsigned long match_position, match_length; /* of longest match. These are
  8584. + set by the InsertNode() procedure. */
  8585. +static unsigned long lson[N + 1], rson[N + 257], dad[N + 1]; /* left & right children &
  8586. + parents -- These constitute binary search trees. */
  8587. +
  8588. +static void InitTree(void) /* initialize trees */
  8589. +{
  8590. + unsigned long i;
  8591. +
  8592. + /* For i = 0 to N - 1, rson[i] and lson[i] will be the right and
  8593. + left children of node i. These nodes need not be initialized.
  8594. + Also, dad[i] is the parent of node i. These are initialized to
  8595. + NIL (= N), which stands for 'not used.'
  8596. + For i = 0 to 255, rson[N + i + 1] is the root of the tree
  8597. + for strings that begin with character i. These are initialized
  8598. + to NIL. Note there are 256 trees. */
  8599. +
  8600. + for (i = N + 1; i <= N + 256; i++) rson[i] = NIL;
  8601. + for (i = 0; i < N; i++) dad[i] = NIL;
  8602. +}
  8603. +
  8604. +static void InsertNode(unsigned long r)
  8605. + /* Inserts string of length F, text_buf[r..r+F-1], into one of the
  8606. + trees (text_buf[r]'th tree) and returns the longest-match position
  8607. + and length via the global variables match_position and match_length.
  8608. + If match_length = F, then removes the old node in favor of the new
  8609. + one, because the old one will be deleted sooner.
  8610. + Note r plays double role, as tree node and position in buffer. */
  8611. +{
  8612. + unsigned long i, p;
  8613. + unsigned char *key;
  8614. + signed long cmp;
  8615. +
  8616. + cmp = 1; key = &text_buf[r]; p = N + 1 + key[0];
  8617. + rson[r] = lson[r] = NIL; match_length = 0;
  8618. + for ( ; ; ) {
  8619. + if (cmp >= 0) {
  8620. + if (rson[p] != NIL) p = rson[p];
  8621. + else { rson[p] = r; dad[r] = p; return; }
  8622. + } else {
  8623. + if (lson[p] != NIL) p = lson[p];
  8624. + else { lson[p] = r; dad[r] = p; return; }
  8625. + }
  8626. + for (i = 1; i < F; i++)
  8627. + if ((cmp = key[i] - text_buf[p + i]) != 0) break;
  8628. + if (i > match_length) {
  8629. + match_position = p;
  8630. + if ((match_length = i) >= F) break;
  8631. + }
  8632. + }
  8633. + dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p];
  8634. + dad[lson[p]] = r; dad[rson[p]] = r;
  8635. + if (rson[dad[p]] == p) rson[dad[p]] = r;
  8636. + else lson[dad[p]] = r;
  8637. + dad[p] = NIL; /* remove p */
  8638. +}
  8639. +
  8640. +static void DeleteNode(unsigned long p) /* deletes node p from tree */
  8641. +{
  8642. + unsigned long q;
  8643. +
  8644. + if (dad[p] == NIL) return; /* not in tree */
  8645. + if (rson[p] == NIL) q = lson[p];
  8646. + else if (lson[p] == NIL) q = rson[p];
  8647. + else {
  8648. + q = lson[p];
  8649. + if (rson[q] != NIL) {
  8650. + do { q = rson[q]; } while (rson[q] != NIL);
  8651. + rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q];
  8652. + lson[q] = lson[p]; dad[lson[p]] = q;
  8653. + }
  8654. + rson[q] = rson[p]; dad[rson[p]] = q;
  8655. + }
  8656. + dad[q] = dad[p];
  8657. + if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q;
  8658. + dad[p] = NIL;
  8659. +}
  8660. +
  8661. +/* modified for block compression */
  8662. +/* on return, srclen will contain the number of successfully compressed bytes
  8663. + and dstlen will contain completed compressed bytes */
  8664. +
  8665. +static int Encode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long *srclen,
  8666. + unsigned long *dstlen)
  8667. +{
  8668. + unsigned long i, len, r, c, s, last_match_length, code_buf_ptr;
  8669. + unsigned char code_buf[17], mask;
  8670. + unsigned char *ip, *op;
  8671. + unsigned long written = 0;
  8672. + unsigned long read = 0;
  8673. + unsigned char *srcend = srcbuf + *srclen;
  8674. + unsigned char *dstend = dstbuf + *dstlen;
  8675. + ip = srcbuf;
  8676. + op = dstbuf;
  8677. + InitTree(); /* initialize trees */
  8678. + code_buf[0] = 0; /* code_buf[1..16] saves eight units of code, and
  8679. + code_buf[0] works as eight flags, "1" representing that the unit
  8680. + is an unencoded letter (1 byte), "0" a position-and-length pair
  8681. + (2 bytes). Thus, eight units require at most 16 bytes of code. */
  8682. + code_buf_ptr = mask = 1;
  8683. + s = 0; r = N - F;
  8684. + for (i = s; i < r; i++) text_buf[i] = ' '; /* Clear the buffer with
  8685. + any character that will appear often. */
  8686. + for (len = 0; (len < F) && (ip < srcend); len++)
  8687. + text_buf[r + len] = *(ip++); /* Read F bytes into the last F bytes of
  8688. + the buffer */
  8689. + read = len;
  8690. + for (i = 1; i <= F; i++) InsertNode(r - i); /* Insert the F strings,
  8691. + each of which begins with one or more 'space' characters. Note
  8692. + the order in which these strings are inserted. This way,
  8693. + degenerate trees will be less likely to occur. */
  8694. + InsertNode(r); /* Finally, insert the whole string just read. The
  8695. + global variables match_length and match_position are set. */
  8696. + do {
  8697. + if (match_length > len) match_length = len; /* match_length
  8698. + may be spuriously long near the end of text. */
  8699. + if (match_length <= THRESHOLD) {
  8700. + match_length = 1; /* Not long enough match. Send one byte. */
  8701. + code_buf[0] |= mask; /* 'send one byte' flag */
  8702. + code_buf[code_buf_ptr++] = text_buf[r]; /* Send uncoded. */
  8703. + } else {
  8704. + code_buf[code_buf_ptr++] = match_position;
  8705. + code_buf[code_buf_ptr++] = (((match_position >> 4) & 0xf0)
  8706. + | (match_length - (THRESHOLD + 1))); /* Send position and
  8707. + length pair. Note match_length > THRESHOLD. */
  8708. + }
  8709. + if ((mask <<= 1) == 0) { /* Shift mask left one bit. */
  8710. + if ((op + code_buf_ptr) > dstend) {
  8711. + *dstlen = written; /* written contains bytes of complete compressed
  8712. + code */
  8713. + return -1;
  8714. + };
  8715. + for (i = 0; i < code_buf_ptr; *(op++) = code_buf[i++]); /* Send at most 8 units of */
  8716. + /* code together */
  8717. + written += code_buf_ptr;
  8718. + *srclen = read; /* this many bytes have been successfully compressed */
  8719. + code_buf[0] = 0; code_buf_ptr = mask = 1;
  8720. + }
  8721. + last_match_length = match_length;
  8722. + for (i = 0; (i < last_match_length) && (ip < srcend); i++) {
  8723. + c = *(ip++);
  8724. + DeleteNode(s); /* Delete old strings and */
  8725. + text_buf[s] = c; /* read new bytes */
  8726. + if (s < F - 1) text_buf[s + N] = c; /* If the position is
  8727. + near the end of buffer, extend the buffer to make
  8728. + string comparison easier. */
  8729. + s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
  8730. + /* Since this is a ring buffer, increment the position
  8731. + modulo N. */
  8732. + InsertNode(r); /* Register the string in text_buf[r..r+F-1] */
  8733. + }
  8734. + read += i;
  8735. + while (i++ < last_match_length) { /* After the end of text, */
  8736. + DeleteNode(s); /* no need to read, but */
  8737. + s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
  8738. + if (--len) InsertNode(r); /* buffer may not be empty. */
  8739. + }
  8740. + } while (len > 0); /* until length of string to be processed is zero */
  8741. + if (code_buf_ptr > 1) { /* Send remaining code. */
  8742. + if ((op + code_buf_ptr) > dstend) {
  8743. + *dstlen = written;
  8744. + return -1;
  8745. + }
  8746. + for (i = 0; i < code_buf_ptr; *(op++) = code_buf[i++]);
  8747. + written += code_buf_ptr;
  8748. + *srclen = read;
  8749. + }
  8750. + *dstlen = written;
  8751. + return 0;
  8752. +}
  8753. +
  8754. +static int Decode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long srclen,
  8755. + unsigned long dstlen) /* Just the reverse of Encode(). */
  8756. +{
  8757. + unsigned long i, r, c, j, k, flags;
  8758. + unsigned char *ip, *op;
  8759. + unsigned long written;
  8760. + unsigned long read;
  8761. + unsigned char *srcend = srcbuf + srclen;
  8762. + unsigned char *dstend = dstbuf + dstlen;
  8763. + read = written = 0;
  8764. + ip = srcbuf;
  8765. + op = dstbuf;
  8766. + for (i = 0; i < N - F; i++) text_buf[i] = ' ';
  8767. + r = N - F; flags = 0;
  8768. + for ( ; ; ) {
  8769. + if (((flags >>= 1) & 256) == 0) {
  8770. + if (ip >= srcend) return 0;
  8771. + c = *(ip++);
  8772. + flags = c | 0xff00; /* uses higher byte cleverly */
  8773. + } /* to count eight */
  8774. + if (flags & 1) {
  8775. + if (ip >= srcend) return 0;
  8776. + c = *(ip++);
  8777. + if (op >= dstend) return -1;
  8778. + *(op++) = text_buf[r++] = c; r &= (N - 1);
  8779. + } else {
  8780. + if ((ip + 2) > srcend) return 0;
  8781. + i = *(ip++);
  8782. + j = *(ip++);
  8783. + i |= ((j & 0xf0) << 4); j = (j & 0x0f) + THRESHOLD;
  8784. + if ((op + j + 1) > dstend) return -1;
  8785. + for (k = 0; k <= j; k++) {
  8786. + c = text_buf[(i + k) & (N - 1)];
  8787. + *(op++) = text_buf[r++] = c; r &= (N - 1);
  8788. + }
  8789. + }
  8790. + }
  8791. +}
  8792. +
  8793. +/* interface to jffs2 bbc follows */
  8794. +
  8795. +#include "jffs2_bbc_framework.h"
  8796. +
  8797. +
  8798. +#define JFFS2_BBC_LZSS_BLOCK_SIGN {0x27, 0x6f, 0x12, 0xc4}
  8799. +
  8800. +static int
  8801. +jffs2_bbc_lzss_compressor_init (void);
  8802. +
  8803. +static void
  8804. +jffs2_bbc_lzss_compressor_deinit (void);
  8805. +
  8806. +static int
  8807. +jffs2_bbc_lzss_compress (void *model, unsigned char *input,
  8808. + unsigned char *output, unsigned long *sourcelen,
  8809. + unsigned long *dstlen);
  8810. +
  8811. +static int
  8812. +jffs2_bbc_lzss_estimate (void *model, unsigned char *input,
  8813. + unsigned long sourcelen, unsigned long *dstlen,
  8814. + unsigned long *readtime, unsigned long *writetime);
  8815. +
  8816. +static int
  8817. +jffs2_bbc_lzss_decompress (void *model, unsigned char *input,
  8818. + unsigned char *output, unsigned long sourcelen,
  8819. + unsigned long dstlen);
  8820. +
  8821. +static char *
  8822. +jffs2_bbc_lzss_proc_info (void);
  8823. +
  8824. +static int
  8825. +jffs2_bbc_lzss_proc_command (char *command);
  8826. +
  8827. +struct jffs2_bbc_compressor_type jffs2_bbc_lzss = {
  8828. + "lzss",
  8829. + 0,
  8830. + JFFS2_BBC_LZSS_BLOCK_SIGN,
  8831. + jffs2_bbc_lzss_compressor_init,
  8832. + NULL,
  8833. + NULL,
  8834. + jffs2_bbc_lzss_compressor_deinit,
  8835. + jffs2_bbc_lzss_compress,
  8836. + jffs2_bbc_lzss_estimate,
  8837. + jffs2_bbc_lzss_decompress,
  8838. + jffs2_bbc_lzss_proc_info,
  8839. + jffs2_bbc_lzss_proc_command
  8840. +};
  8841. +
  8842. +static int
  8843. +jffs2_bbc_lzss_compressor_init (void)
  8844. +{
  8845. + return 0;
  8846. +}
  8847. +
  8848. +static void
  8849. +jffs2_bbc_lzss_compressor_deinit (void)
  8850. +{
  8851. +}
  8852. +
  8853. +static int
  8854. +jffs2_bbc_lzss_compress (void *model, unsigned char *input,
  8855. + unsigned char *output, unsigned long *sourcelen,
  8856. + unsigned long *dstlen)
  8857. +{
  8858. + int retval;
  8859. + unsigned long dst = *dstlen;
  8860. + *(output++) = jffs2_bbc_lzss.block_sign[0];
  8861. + *(output++) = jffs2_bbc_lzss.block_sign[1];
  8862. + dst -= 2;
  8863. + retval = Encode(input, output, sourcelen, &dst);
  8864. + dst += 2;
  8865. + *dstlen = dst;
  8866. + return retval;
  8867. +}
  8868. +
  8869. +static int
  8870. +jffs2_bbc_lzss_estimate (void *model, unsigned char *input,
  8871. + unsigned long sourcelen, unsigned long *dstlen,
  8872. + unsigned long *readtime, unsigned long *writetime)
  8873. +{
  8874. + *dstlen = sourcelen * 60 / 100;
  8875. + *readtime = JFFS2_BBC_ZLIB_READ_TIME * 12 / 10;
  8876. + *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 3;
  8877. + return 0;
  8878. +}
  8879. +
  8880. +static int
  8881. +jffs2_bbc_lzss_decompress (void *model, unsigned char *input,
  8882. + unsigned char *output, unsigned long sourcelen,
  8883. + unsigned long dstlen)
  8884. +{
  8885. + if ( ( *(input++) != (unsigned char)jffs2_bbc_lzss.block_sign[0] ) ||
  8886. + ( *(input++) != (unsigned char)jffs2_bbc_lzss.block_sign[1] )
  8887. + ) {
  8888. + return -1;
  8889. + } else {
  8890. + return Decode(input, output, sourcelen - 2, dstlen);
  8891. + }
  8892. +}
  8893. +
  8894. +static char *
  8895. +jffs2_bbc_lzss_proc_info (void)
  8896. +{
  8897. + return "Lempel-Ziv-Storer-Szymanski compression module";
  8898. +}
  8899. +
  8900. +static int
  8901. +jffs2_bbc_lzss_proc_command (char *command)
  8902. +{
  8903. + return 0;
  8904. +}
  8905. +
  8906. +struct jffs2_bbc_compressor_type *
  8907. +jffs2_bbc_lzss_init (int mode)
  8908. +{
  8909. + if (jffs2_bbc_register_compressor (&jffs2_bbc_lzss) == 0)
  8910. + {
  8911. + return &jffs2_bbc_lzss;
  8912. + }
  8913. + else
  8914. + {
  8915. + return NULL;
  8916. + }
  8917. +}
  8918. +
  8919. +void
  8920. +jffs2_bbc_lzss_deinit (void)
  8921. +{
  8922. + jffs2_bbc_unregister_compressor (&jffs2_bbc_lzss);
  8923. +}
  8924. --- /dev/null
  8925. +++ b/fs/jffs2/linux-2.4.25.hpatch
  8926. @@ -0,0 +1,97 @@
  8927. +FMakefile
  8928. +=BBC insertion
  8929. +-COMPR_OBJS
  8930. +iMakefile.bbc.inc
  8931. ++
  8932. +I
  8933. +?JFFS2_OBJS
  8934. ++ $(JFFS2_BBC_KERNEL_OBJS) \
  8935. +
  8936. +F../Config.in
  8937. +=BBC insertion
  8938. +-tristate 'Compressed ROM file system support' CONFIG_CRAMFS
  8939. +iConfig.in.bbc.inc
  8940. ++
  8941. +I
  8942. +F../../Documentation/Configure.help
  8943. +=BBC insertion
  8944. +-JFFS stats available
  8945. +iConfigure.help.bbc.inc
  8946. ++
  8947. +I
  8948. +Fcompr_zlib.c
  8949. +=(de)compress->(de)compress2
  8950. +-int zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
  8951. ++int jffs2_zlib_compress2(unsigned char *data_in, unsigned char *cpage_out,
  8952. +-void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
  8953. ++void jffs2_zlib_decompress2(unsigned char *data_in, unsigned char *cpage_out,
  8954. +?inflateEnd(&strm);
  8955. +?}
  8956. ++
  8957. ++extern int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 * sourcelen, __u32 * dstlen);
  8958. ++extern void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
  8959. ++
  8960. ++int zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
  8961. ++ __u32 *sourcelen, __u32 *dstlen)
  8962. ++{
  8963. ++ return jffs2_zlib_compress(data_in,cpage_out,sourcelen,dstlen);
  8964. ++}
  8965. ++
  8966. ++void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
  8967. ++ __u32 srclen, __u32 destlen)
  8968. ++{
  8969. ++ jffs2_zlib_decompress(data_in,cpage_out,srclen,destlen);
  8970. ++}
  8971. ++
  8972. +
  8973. +Ffile.c
  8974. +=set_act_sb before write
  8975. +-#include
  8976. ++#include "jffs2_bbc_framework.h" /**BBC**/
  8977. +I
  8978. +?int jffs2_commit_write
  8979. +-jffs2_compress(
  8980. ++ jffs2_bbc_model_set_act_sb(c); /**BBC**/
  8981. +I
  8982. +
  8983. +Fgc.c
  8984. +=set_act_sb before write
  8985. +-#include
  8986. ++#include "jffs2_bbc_framework.h" /**BBC**/
  8987. +I
  8988. +?int jffs2_garbage_collect_dnode(
  8989. +-jffs2_compress(
  8990. ++ jffs2_bbc_model_set_act_sb(c); /**BBC**/
  8991. +I
  8992. +
  8993. +Fread.c
  8994. +=set_act_sb before read
  8995. +-#include
  8996. ++#include "jffs2_bbc_framework.h" /**BBC**/
  8997. +I
  8998. +?int jffs2_read_dnode(
  8999. +-jffs2_decompress(
  9000. ++ jffs2_bbc_model_set_act_sb(c); /**BBC**/
  9001. +I
  9002. +
  9003. +Fsuper.c
  9004. +=init, load_model
  9005. +-#include
  9006. ++#include "jffs2_bbc_fs.h" /**BBC**/
  9007. +I
  9008. +?struct super_block *jffs2_read_super(
  9009. +-return sb;
  9010. ++ jffs2_bbc_load_model(sb); /**BBC**/
  9011. +I
  9012. +?void jffs2_put_super
  9013. +?c = JFFS2_SB_INFO
  9014. ++ jffs2_bbc_unload_model(sb); /**BBC**/
  9015. +?init_jffs2_fs(void)
  9016. +?int ret;
  9017. ++
  9018. ++ jffs2_bbc_proc_init(); /**BBC**/
  9019. ++
  9020. +?exit_jffs2_fs(void)
  9021. +?{
  9022. ++ jffs2_bbc_proc_deinit(); /**BBC**/
  9023. ++
  9024. --- a/fs/jffs2/read.c
  9025. +++ b/fs/jffs2/read.c
  9026. @@ -35,6 +35,7 @@
  9027. *
  9028. */
  9029. +#include "jffs2_bbc_framework.h" /**BBC**/
  9030. #include <linux/kernel.h>
  9031. #include <linux/slab.h>
  9032. #include <linux/jffs2.h>
  9033. @@ -140,6 +141,7 @@ int jffs2_read_dnode(struct jffs2_sb_inf
  9034. D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc));
  9035. if (ri->compr != JFFS2_COMPR_NONE) {
  9036. D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", ri->csize, readbuf, ri->dsize, decomprbuf));
  9037. + jffs2_bbc_model_set_act_sb(c); /**BBC**/
  9038. ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, ri->csize, ri->dsize);
  9039. if (ret) {
  9040. printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret);
  9041. --- a/fs/jffs2/super.c
  9042. +++ b/fs/jffs2/super.c
  9043. @@ -35,6 +35,7 @@
  9044. *
  9045. */
  9046. +#include "jffs2_bbc_fs.h" /**BBC**/
  9047. #include <linux/config.h>
  9048. #include <linux/kernel.h>
  9049. #include <linux/module.h>
  9050. @@ -272,6 +273,7 @@ static struct super_block *jffs2_read_su
  9051. sb->s_magic = JFFS2_SUPER_MAGIC;
  9052. if (!(sb->s_flags & MS_RDONLY))
  9053. jffs2_start_garbage_collect_thread(c);
  9054. + jffs2_bbc_load_model(sb); /**BBC**/
  9055. return sb;
  9056. out_root_i:
  9057. @@ -288,6 +290,7 @@ static struct super_block *jffs2_read_su
  9058. void jffs2_put_super (struct super_block *sb)
  9059. {
  9060. struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
  9061. + jffs2_bbc_unload_model(sb); /**BBC**/
  9062. D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
  9063. @@ -344,6 +347,9 @@ static int __init init_jffs2_fs(void)
  9064. {
  9065. int ret;
  9066. + jffs2_bbc_proc_init(); /**BBC**/
  9067. +
  9068. +
  9069. printk(KERN_NOTICE "JFFS2 version 2.1. (C) 2001 Red Hat, Inc., designed by Axis Communications AB.\n");
  9070. #ifdef JFFS2_OUT_OF_KERNEL
  9071. @@ -388,6 +394,8 @@ static int __init init_jffs2_fs(void)
  9072. static void __exit exit_jffs2_fs(void)
  9073. {
  9074. + jffs2_bbc_proc_deinit(); /**BBC**/
  9075. +
  9076. jffs2_destroy_slab_caches();
  9077. jffs2_zlib_exit();
  9078. unregister_filesystem(&jffs2_fs_type);