003-jffs2_compression.patch 241 KB

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