1f5e8c0f128f48463630358bcea6063d0024cfd5aplougher/* 28a4692825eb1840d52f2f921e40346d0f8c7e702Phillip Lougher * Copyright (c) 2010, 2011, 2012, 2013 383d42a3fc898962aa1f1e8387f2ccb1114e0d294Phillip Lougher * Phillip Lougher <phillip@squashfs.org.uk> 4f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * 5f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * This program is free software; you can redistribute it and/or 6f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * modify it under the terms of the GNU General Public License 7f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * as published by the Free Software Foundation; either version 2, 8f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * or (at your option) any later version. 9f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * 10f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * This program is distributed in the hope that it will be useful, 11f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * GNU General Public License for more details. 14f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * 15f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * You should have received a copy of the GNU General Public License 16f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * along with this program; if not, write to the Free Software 17f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * 19f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * xz_wrapper.c 2067dfce9c3751f0580633e8a33cea28bcfbefec04plougher * 21e08e77659d1e2eac07c9ab5dffafaa70aff41c07plougher * Support for XZ (LZMA2) compression using XZ Utils liblzma 22e08e77659d1e2eac07c9ab5dffafaa70aff41c07plougher * http://tukaani.org/xz/ 23f5e8c0f128f48463630358bcea6063d0024cfd5aplougher */ 2467dfce9c3751f0580633e8a33cea28bcfbefec04plougher 2567dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include <stdio.h> 2667dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include <string.h> 277b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher#include <stdlib.h> 2867dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include <lzma.h> 2967dfce9c3751f0580633e8a33cea28bcfbefec04plougher 3067dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include "squashfs_fs.h" 311ffc835b6020c6559f0d598a41b1483c50a8945fplougher#include "xz_wrapper.h" 3267dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include "compressor.h" 3367dfce9c3751f0580633e8a33cea28bcfbefec04plougher 3490f6b8dc8e5525e70a625bb61f82546811e0bc9bplougherstatic struct bcj bcj[] = { 357b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher { "x86", LZMA_FILTER_X86, 0 }, 367b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher { "powerpc", LZMA_FILTER_POWERPC, 0 }, 377b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher { "ia64", LZMA_FILTER_IA64, 0 }, 387b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher { "arm", LZMA_FILTER_ARM, 0 }, 397b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher { "armthumb", LZMA_FILTER_ARMTHUMB, 0 }, 407b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher { "sparc", LZMA_FILTER_SPARC, 0 }, 417b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher { NULL, LZMA_VLI_UNKNOWN, 0 } 4267dfce9c3751f0580633e8a33cea28bcfbefec04plougher}; 4367dfce9c3751f0580633e8a33cea28bcfbefec04plougher 447b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstatic int filter_count = 1; 4514c30adab9ca2147a06975bbe99308f5f54b16f0plougherstatic int dictionary_size = 0; 4614c30adab9ca2147a06975bbe99308f5f54b16f0plougherstatic float dictionary_percent = 0; 477b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 487b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 49668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher/* 50668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * This function is called by the options parsing code in mksquashfs.c 51668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * to parse any -X compressor option. 52668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 53668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * Two specific options are supported: 54668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * -Xbcj 55668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * -Xdict-size 56668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 5765ad363b09a9a96b3501f28c35fe21f23cb59013Phillip Lougher * This function returns: 5865ad363b09a9a96b3501f28c35fe21f23cb59013Phillip Lougher * >=0 (number of additional args parsed) on success 5965ad363b09a9a96b3501f28c35fe21f23cb59013Phillip Lougher * -1 if the option was unrecognised, or 6065ad363b09a9a96b3501f28c35fe21f23cb59013Phillip Lougher * -2 if the option was recognised, but otherwise bad in 6165ad363b09a9a96b3501f28c35fe21f23cb59013Phillip Lougher * some way (e.g. invalid parameter) 62668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 63668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * Note: this function sets internal compressor state, but does not 64668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * pass back the results of the parsing other than success/failure. 65668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * The xz_dump_options() function is called later to get the options in 66668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * a format suitable for writing to the filesystem. 67668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher */ 687b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstatic int xz_options(char *argv[], int argc) 6967dfce9c3751f0580633e8a33cea28bcfbefec04plougher{ 707b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher int i; 717b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher char *name; 727b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 737b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(strcmp(argv[0], "-Xbcj") == 0) { 747b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(argc < 2) { 757b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher fprintf(stderr, "xz: -Xbcj missing filter\n"); 767b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher goto failed; 777b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 787b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 797b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher name = argv[1]; 807b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher while(name[0] != '\0') { 817b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher for(i = 0; bcj[i].name; i++) { 827b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher int n = strlen(bcj[i].name); 837b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if((strncmp(name, bcj[i].name, n) == 0) && 847b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher (name[n] == '\0' || 857b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher name[n] == ',')) { 867b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(bcj[i].selected == 0) { 877b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher bcj[i].selected = 1; 887b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter_count++; 897b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 907b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher name += name[n] == ',' ? n + 1 : n; 917b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher break; 927b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 937b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 947b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(bcj[i].name == NULL) { 95e08e77659d1e2eac07c9ab5dffafaa70aff41c07plougher fprintf(stderr, "xz: -Xbcj unrecognised " 96e08e77659d1e2eac07c9ab5dffafaa70aff41c07plougher "filter\n"); 977b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher goto failed; 987b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 997b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 1007b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 1017b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher return 1; 102d7f0fd36de82019ebf2ecfe3eb9d356a47c2e966plougher } else if(strcmp(argv[0], "-Xdict-size") == 0) { 10314c30adab9ca2147a06975bbe99308f5f54b16f0plougher char *b; 10414c30adab9ca2147a06975bbe99308f5f54b16f0plougher float size; 10514c30adab9ca2147a06975bbe99308f5f54b16f0plougher 10614c30adab9ca2147a06975bbe99308f5f54b16f0plougher if(argc < 2) { 107d7f0fd36de82019ebf2ecfe3eb9d356a47c2e966plougher fprintf(stderr, "xz: -Xdict-size missing dict-size\n"); 10814c30adab9ca2147a06975bbe99308f5f54b16f0plougher goto failed; 10914c30adab9ca2147a06975bbe99308f5f54b16f0plougher } 11014c30adab9ca2147a06975bbe99308f5f54b16f0plougher 11114c30adab9ca2147a06975bbe99308f5f54b16f0plougher size = strtof(argv[1], &b); 11214c30adab9ca2147a06975bbe99308f5f54b16f0plougher if(*b == '%') { 11314c30adab9ca2147a06975bbe99308f5f54b16f0plougher if(size <= 0 || size > 100) { 114d7f0fd36de82019ebf2ecfe3eb9d356a47c2e966plougher fprintf(stderr, "xz: -Xdict-size percentage " 115d7f0fd36de82019ebf2ecfe3eb9d356a47c2e966plougher "should be 0 < dict-size <= 100\n"); 11614c30adab9ca2147a06975bbe99308f5f54b16f0plougher goto failed; 11714c30adab9ca2147a06975bbe99308f5f54b16f0plougher } 11814c30adab9ca2147a06975bbe99308f5f54b16f0plougher 11914c30adab9ca2147a06975bbe99308f5f54b16f0plougher dictionary_percent = size; 12014c30adab9ca2147a06975bbe99308f5f54b16f0plougher dictionary_size = 0; 12114c30adab9ca2147a06975bbe99308f5f54b16f0plougher } else { 12214c30adab9ca2147a06975bbe99308f5f54b16f0plougher if((float) ((int) size) != size) { 123d7f0fd36de82019ebf2ecfe3eb9d356a47c2e966plougher fprintf(stderr, "xz: -Xdict-size can't be " 12414c30adab9ca2147a06975bbe99308f5f54b16f0plougher "fractional unless a percentage of the" 12514c30adab9ca2147a06975bbe99308f5f54b16f0plougher " block size\n"); 12614c30adab9ca2147a06975bbe99308f5f54b16f0plougher goto failed; 12714c30adab9ca2147a06975bbe99308f5f54b16f0plougher } 12814c30adab9ca2147a06975bbe99308f5f54b16f0plougher 12914c30adab9ca2147a06975bbe99308f5f54b16f0plougher dictionary_percent = 0; 13014c30adab9ca2147a06975bbe99308f5f54b16f0plougher dictionary_size = (int) size; 13114c30adab9ca2147a06975bbe99308f5f54b16f0plougher 13214c30adab9ca2147a06975bbe99308f5f54b16f0plougher if(*b == 'k' || *b == 'K') 13314c30adab9ca2147a06975bbe99308f5f54b16f0plougher dictionary_size *= 1024; 13414c30adab9ca2147a06975bbe99308f5f54b16f0plougher else if(*b == 'm' || *b == 'M') 13514c30adab9ca2147a06975bbe99308f5f54b16f0plougher dictionary_size *= 1024 * 1024; 13614c30adab9ca2147a06975bbe99308f5f54b16f0plougher else if(*b != '\0') { 137e08e77659d1e2eac07c9ab5dffafaa70aff41c07plougher fprintf(stderr, "xz: -Xdict-size invalid " 138e08e77659d1e2eac07c9ab5dffafaa70aff41c07plougher "dict-size\n"); 13914c30adab9ca2147a06975bbe99308f5f54b16f0plougher goto failed; 14014c30adab9ca2147a06975bbe99308f5f54b16f0plougher } 14114c30adab9ca2147a06975bbe99308f5f54b16f0plougher } 14214c30adab9ca2147a06975bbe99308f5f54b16f0plougher 14314c30adab9ca2147a06975bbe99308f5f54b16f0plougher return 1; 1447b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 1457b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 1467b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher return -1; 147d886567331690a0781c695a590e43ac37b78ad10plougher 148d886567331690a0781c695a590e43ac37b78ad10plougherfailed: 149d886567331690a0781c695a590e43ac37b78ad10plougher return -2; 1507b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher} 15114c30adab9ca2147a06975bbe99308f5f54b16f0plougher 15214c30adab9ca2147a06975bbe99308f5f54b16f0plougher 153668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher/* 154668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * This function is called after all options have been parsed. 155668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * It is used to do post-processing on the compressor options using 156668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * values that were not expected to be known at option parse time. 157668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 158668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * In this case block_size may not be known until after -Xdict-size has 159668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * been processed (in the case where -b is specified after -Xdict-size) 160668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 161668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * This function returns 0 on successful post processing, or 162668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * -1 on error 163668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher */ 16414c30adab9ca2147a06975bbe99308f5f54b16f0plougherstatic int xz_options_post(int block_size) 16514c30adab9ca2147a06975bbe99308f5f54b16f0plougher{ 166a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher /* 167a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher * if -Xdict-size has been specified use this to compute the datablock 168a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher * dictionary size 169a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher */ 170a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher if(dictionary_size || dictionary_percent) { 171a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher int n; 172a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher 173a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher if(dictionary_size) { 174a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher if(dictionary_size > block_size) { 175a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher fprintf(stderr, "xz: -Xdict-size is larger than" 176a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher " block_size\n"); 177a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher goto failed; 178a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher } 179a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher } else 180a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher dictionary_size = block_size * dictionary_percent / 100; 18114c30adab9ca2147a06975bbe99308f5f54b16f0plougher 182a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher if(dictionary_size < 8192) { 183a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher fprintf(stderr, "xz: -Xdict-size should be 8192 bytes " 184a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher "or larger\n"); 18514c30adab9ca2147a06975bbe99308f5f54b16f0plougher goto failed; 18614c30adab9ca2147a06975bbe99308f5f54b16f0plougher } 18714c30adab9ca2147a06975bbe99308f5f54b16f0plougher 188a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher /* 189a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher * dictionary_size must be storable in xz header as either 190a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher * 2^n or as 2^n+2^(n+1) 191a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher */ 192a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher n = ffs(dictionary_size) - 1; 193a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher if(dictionary_size != (1 << n) && 194a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher dictionary_size != ((1 << n) + (1 << (n + 1)))) { 195a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher fprintf(stderr, "xz: -Xdict-size is an unsupported " 196a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher "value, dict-size must be storable in xz " 197a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher "header\n"); 198a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). " 199a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher "Example dict-sizes are 75%%, 50%%, 37.5%%, " 200a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher "25%%,\n"); 201a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher fprintf(stderr, "or 32K, 16K, 8K etc.\n"); 202a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher goto failed; 203a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher } 20414c30adab9ca2147a06975bbe99308f5f54b16f0plougher 205a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher } else 206a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher /* No -Xdict-size specified, use defaults */ 207a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher dictionary_size = block_size; 20817f039dcdb5ce2b556efff0ba49b475176790d90plougher 20917f039dcdb5ce2b556efff0ba49b475176790d90plougher return 0; 21014c30adab9ca2147a06975bbe99308f5f54b16f0plougher 21114c30adab9ca2147a06975bbe99308f5f54b16f0plougherfailed: 21214c30adab9ca2147a06975bbe99308f5f54b16f0plougher return -1; 21314c30adab9ca2147a06975bbe99308f5f54b16f0plougher} 21414c30adab9ca2147a06975bbe99308f5f54b16f0plougher 2157b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 216668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher/* 217668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * This function is called by mksquashfs to dump the parsed 218668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * compressor options in a format suitable for writing to the 219668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * compressor options field in the filesystem (stored immediately 220668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * after the superblock). 221668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 222668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * This function returns a pointer to the compression options structure 223668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * to be stored (and the size), or NULL if there are no compression 224668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * options 225668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher */ 226a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougherstatic void *xz_dump_options(int block_size, int *size) 22717f039dcdb5ce2b556efff0ba49b475176790d90plougher{ 2285dfb7d6b00f94dee3cb2c9a1a143b2aeea86b957Phillip Lougher static struct comp_opts comp_opts; 22917f039dcdb5ce2b556efff0ba49b475176790d90plougher int flags = 0, i; 23017f039dcdb5ce2b556efff0ba49b475176790d90plougher 23117f039dcdb5ce2b556efff0ba49b475176790d90plougher /* 23217f039dcdb5ce2b556efff0ba49b475176790d90plougher * don't store compressor specific options in file system if the 23317f039dcdb5ce2b556efff0ba49b475176790d90plougher * default options are being used - no compressor options in the 23417f039dcdb5ce2b556efff0ba49b475176790d90plougher * file system means the default options are always assumed 235a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher * 236a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher * Defaults are: 237a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher * metadata dictionary size: SQUASHFS_METADATA_SIZE 238a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher * datablock dictionary size: block_size 239a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher * 1 filter 24017f039dcdb5ce2b556efff0ba49b475176790d90plougher */ 241a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher if(dictionary_size == block_size && filter_count == 1) 24217f039dcdb5ce2b556efff0ba49b475176790d90plougher return NULL; 24317f039dcdb5ce2b556efff0ba49b475176790d90plougher 24417f039dcdb5ce2b556efff0ba49b475176790d90plougher for(i = 0; bcj[i].name; i++) 245c2b23524dea29c795bf7114c090bba1b77ea8055plougher flags |= bcj[i].selected << i; 24617f039dcdb5ce2b556efff0ba49b475176790d90plougher 24717f039dcdb5ce2b556efff0ba49b475176790d90plougher comp_opts.dictionary_size = dictionary_size; 24817f039dcdb5ce2b556efff0ba49b475176790d90plougher comp_opts.flags = flags; 24917f039dcdb5ce2b556efff0ba49b475176790d90plougher 2501ffc835b6020c6559f0d598a41b1483c50a8945fplougher SQUASHFS_INSWAP_COMP_OPTS(&comp_opts); 2511ffc835b6020c6559f0d598a41b1483c50a8945fplougher 25217f039dcdb5ce2b556efff0ba49b475176790d90plougher *size = sizeof(comp_opts); 25317f039dcdb5ce2b556efff0ba49b475176790d90plougher return &comp_opts; 25417f039dcdb5ce2b556efff0ba49b475176790d90plougher} 25517f039dcdb5ce2b556efff0ba49b475176790d90plougher 25617f039dcdb5ce2b556efff0ba49b475176790d90plougher 257668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher/* 258668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * This function is a helper specifically for the append mode of 259668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * mksquashfs. Its purpose is to set the internal compressor state 260668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * to the stored compressor options in the passed compressor options 261668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * structure. 262668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 263668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * In effect this function sets up the compressor options 264668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * to the same state they were when the filesystem was originally 265668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * generated, this is to ensure on appending, the compressor uses 266668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * the same compression options that were used to generate the 267668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * original filesystem. 268668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 269668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * Note, even if there are no compressor options, this function is still 270668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * called with an empty compressor structure (size == 0), to explicitly 271668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * set the default options, this is to ensure any user supplied 272668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * -X options on the appending mksquashfs command line are over-ridden 273668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 274668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * This function returns 0 on sucessful extraction of options, and 275668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * -1 on error 276668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher */ 277afeaf3a7dc0853af656c1000b364a92e4d093fedplougherstatic int xz_extract_options(int block_size, void *buffer, int size) 278afeaf3a7dc0853af656c1000b364a92e4d093fedplougher{ 279afeaf3a7dc0853af656c1000b364a92e4d093fedplougher struct comp_opts *comp_opts = buffer; 28039c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher int flags, i, n; 281afeaf3a7dc0853af656c1000b364a92e4d093fedplougher 282afeaf3a7dc0853af656c1000b364a92e4d093fedplougher if(size == 0) { 283afeaf3a7dc0853af656c1000b364a92e4d093fedplougher /* set defaults */ 284afeaf3a7dc0853af656c1000b364a92e4d093fedplougher dictionary_size = block_size; 285afeaf3a7dc0853af656c1000b364a92e4d093fedplougher flags = 0; 286afeaf3a7dc0853af656c1000b364a92e4d093fedplougher } else { 28739c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher /* check passed comp opts struct is of the correct length */ 28839c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher if(size != sizeof(struct comp_opts)) 28939c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher goto failed; 29039c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher 291fc54d8f5676c4773522a9ede6c4527ac9b1a30efPhillip Lougher SQUASHFS_INSWAP_COMP_OPTS(comp_opts); 2921ffc835b6020c6559f0d598a41b1483c50a8945fplougher 293afeaf3a7dc0853af656c1000b364a92e4d093fedplougher dictionary_size = comp_opts->dictionary_size; 294afeaf3a7dc0853af656c1000b364a92e4d093fedplougher flags = comp_opts->flags; 29539c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher 29639c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher /* 29739c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher * check that the dictionary size seems correct - the dictionary 29839c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher * size should 2^n or 2^n+2^(n+1) 29939c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher */ 30039c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher n = ffs(dictionary_size) - 1; 30139c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher if(dictionary_size != (1 << n) && 30239c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher dictionary_size != ((1 << n) + (1 << (n + 1)))) 30339c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher goto failed; 304afeaf3a7dc0853af656c1000b364a92e4d093fedplougher } 305afeaf3a7dc0853af656c1000b364a92e4d093fedplougher 306a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher filter_count = 1; 307a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher for(i = 0; bcj[i].name; i++) { 308a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher if((flags >> i) & 1) { 309a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher bcj[i].selected = 1; 310a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher filter_count ++; 311a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher } else 312a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher bcj[i].selected = 0; 313a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher } 314afeaf3a7dc0853af656c1000b364a92e4d093fedplougher 315afeaf3a7dc0853af656c1000b364a92e4d093fedplougher return 0; 31639c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher 31739c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougherfailed: 31839c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher fprintf(stderr, "xz: error reading stored compressor options from " 31939c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher "filesystem!\n"); 32039c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher 32139c2b484186d266a8d589d6f79f6b472b7e9c8c2Phillip Lougher return -1; 322afeaf3a7dc0853af656c1000b364a92e4d093fedplougher} 323afeaf3a7dc0853af656c1000b364a92e4d093fedplougher 3247aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher 3253fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Loughervoid xz_display_options(void *buffer, int size) 3263fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher{ 3273fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher struct comp_opts *comp_opts = buffer; 3283fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher int dictionary_size, flags, printed; 3293fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher int i, n; 3303fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3313fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher /* check passed comp opts struct is of the correct length */ 3320b44cade81d66659cb69620999dfb318e51a0697Phillip Lougher if(size != sizeof(struct comp_opts)) 3333fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher goto failed; 3343fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3353fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher SQUASHFS_INSWAP_COMP_OPTS(comp_opts); 3363fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3373fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher dictionary_size = comp_opts->dictionary_size; 3383fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher flags = comp_opts->flags; 3393fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3403fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher /* 3413fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher * check that the dictionary size seems correct - the dictionary 3423fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher * size should 2^n or 2^n+2^(n+1) 3433fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher */ 3443fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher n = ffs(dictionary_size) - 1; 3453fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher if(dictionary_size != (1 << n) && 3463fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher dictionary_size != ((1 << n) + (1 << (n + 1)))) 3473fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher goto failed; 3483fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3493fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher printf("\tDictionary size %d\n", dictionary_size); 3503fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3513fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher printed = 0; 3523fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher for(i = 0; bcj[i].name; i++) { 3533fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher if((flags >> i) & 1) { 3543fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher if(printed) 3553fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher printf(", "); 3563fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher else 3573fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher printf("\tFilters selected: "); 3583fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher printf("%s", bcj[i].name); 3593fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher printed = 1; 3603fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher } 3613fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher } 3623fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3633fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher if(!printed) 3643fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher printf("\tNo filters specified\n"); 3653fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher else 3663fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher printf("\n"); 3673fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3683fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher return; 3693fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3703fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougherfailed: 3713fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher fprintf(stderr, "xz: error reading stored compressor options from " 3723fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher "filesystem!\n"); 3733fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher} 3743fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 3753fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher 376668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher/* 377668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * This function is called by mksquashfs to initialise the 378668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * compressor, before compress() is called. 379668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * 380668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * This function returns 0 on success, and 381668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher * -1 on error 382668d2131d389b6b817df96484d924c2c7e93841fPhillip Lougher */ 38365f163658a72a87ce95341ac6a423a40f2b5fc07plougherstatic int xz_init(void **strm, int block_size, int datablock) 3847b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher{ 38565f163658a72a87ce95341ac6a423a40f2b5fc07plougher int i, j, filters = datablock ? filter_count : 1; 3867b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher struct filter *filter = malloc(filters * sizeof(struct filter)); 3877b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher struct xz_stream *stream; 3887b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 3897b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(filter == NULL) 3907b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher goto failed; 3917b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 3927b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher stream = *strm = malloc(sizeof(struct xz_stream)); 3937b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(stream == NULL) 3947b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher goto failed2; 39567dfce9c3751f0580633e8a33cea28bcfbefec04plougher 3967b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher stream->filter = filter; 3977b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher stream->filters = filters; 39867dfce9c3751f0580633e8a33cea28bcfbefec04plougher 3997b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher memset(filter, 0, filters * sizeof(struct filter)); 40067dfce9c3751f0580633e8a33cea28bcfbefec04plougher 40165f163658a72a87ce95341ac6a423a40f2b5fc07plougher stream->dictionary_size = datablock ? dictionary_size : 402a45c9d2b6df15a359591717b71d948040efb6cd4Phillip Lougher SQUASHFS_METADATA_SIZE; 40314c30adab9ca2147a06975bbe99308f5f54b16f0plougher 4047b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter[0].filter[0].id = LZMA_FILTER_LZMA2; 4057b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter[0].filter[0].options = &stream->opt; 4067b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter[0].filter[1].id = LZMA_VLI_UNKNOWN; 40767dfce9c3751f0580633e8a33cea28bcfbefec04plougher 40865f163658a72a87ce95341ac6a423a40f2b5fc07plougher for(i = 0, j = 1; datablock && bcj[i].name; i++) { 4097b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(bcj[i].selected) { 4107b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter[j].buffer = malloc(block_size); 4117b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(filter[j].buffer == NULL) 4127b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher goto failed3; 4137b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter[j].filter[0].id = bcj[i].id; 4147b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter[j].filter[1].id = LZMA_FILTER_LZMA2; 4157b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter[j].filter[1].options = &stream->opt; 4167b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter[j].filter[2].id = LZMA_VLI_UNKNOWN; 4177b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher j++; 4187b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 4197b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 4207b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4217b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher return 0; 4227b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4237b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherfailed3: 4247b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher for(i = 1; i < filters; i++) 4257b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher free(filter[i].buffer); 4267b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher free(stream); 4277b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4287b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherfailed2: 4297b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher free(filter); 4307b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4317b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherfailed: 4327b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher return -1; 4337b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher} 4347b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4357b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4367b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstatic int xz_compress(void *strm, void *dest, void *src, int size, 4377b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher int block_size, int *error) 4387b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher{ 4397b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher int i; 4407b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher lzma_ret res = 0; 4417b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher struct xz_stream *stream = strm; 4427b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher struct filter *selected = NULL; 4437b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4447b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher stream->filter[0].buffer = dest; 4457b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4467b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher for(i = 0; i < stream->filters; i++) { 4477b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher struct filter *filter = &stream->filter[i]; 4487b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4497b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT)) 4507b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher goto failed; 4517b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 45214c30adab9ca2147a06975bbe99308f5f54b16f0plougher stream->opt.dict_size = stream->dictionary_size; 45314c30adab9ca2147a06975bbe99308f5f54b16f0plougher 4547b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher filter->length = 0; 4557b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher res = lzma_stream_buffer_encode(filter->filter, 4567b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher LZMA_CHECK_CRC32, NULL, src, size, filter->buffer, 4577b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher &filter->length, block_size); 4587b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4597b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(res == LZMA_OK) { 4607b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(!selected || selected->length > filter->length) 4617b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher selected = filter; 4627b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } else if(res != LZMA_BUF_ERROR) 4637b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher goto failed; 4647b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher } 4657b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4667b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(!selected) 46767dfce9c3751f0580633e8a33cea28bcfbefec04plougher /* 46867dfce9c3751f0580633e8a33cea28bcfbefec04plougher * Output buffer overflow. Return out of buffer space 46967dfce9c3751f0580633e8a33cea28bcfbefec04plougher */ 47067dfce9c3751f0580633e8a33cea28bcfbefec04plougher return 0; 47167dfce9c3751f0580633e8a33cea28bcfbefec04plougher 4727b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher if(selected->buffer != dest) 4737b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher memcpy(dest, selected->buffer, selected->length); 4747b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 4757b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher return (int) selected->length; 4767b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 47767dfce9c3751f0580633e8a33cea28bcfbefec04plougherfailed: 47867dfce9c3751f0580633e8a33cea28bcfbefec04plougher /* 47967dfce9c3751f0580633e8a33cea28bcfbefec04plougher * All other errors return failure, with the compressor 48067dfce9c3751f0580633e8a33cea28bcfbefec04plougher * specific error code in *error 48167dfce9c3751f0580633e8a33cea28bcfbefec04plougher */ 48267dfce9c3751f0580633e8a33cea28bcfbefec04plougher *error = res; 48367dfce9c3751f0580633e8a33cea28bcfbefec04plougher return -1; 48467dfce9c3751f0580633e8a33cea28bcfbefec04plougher} 48567dfce9c3751f0580633e8a33cea28bcfbefec04plougher 48667dfce9c3751f0580633e8a33cea28bcfbefec04plougher 4878a4692825eb1840d52f2f921e40346d0f8c7e702Phillip Lougherstatic int xz_uncompress(void *dest, void *src, int size, int outsize, 48867dfce9c3751f0580633e8a33cea28bcfbefec04plougher int *error) 48967dfce9c3751f0580633e8a33cea28bcfbefec04plougher{ 49067dfce9c3751f0580633e8a33cea28bcfbefec04plougher size_t src_pos = 0; 49167dfce9c3751f0580633e8a33cea28bcfbefec04plougher size_t dest_pos = 0; 49267dfce9c3751f0580633e8a33cea28bcfbefec04plougher uint64_t memlimit = MEMLIMIT; 4937b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher 49467dfce9c3751f0580633e8a33cea28bcfbefec04plougher lzma_ret res = lzma_stream_buffer_decode(&memlimit, 0, NULL, 4958a4692825eb1840d52f2f921e40346d0f8c7e702Phillip Lougher src, &src_pos, size, dest, &dest_pos, outsize); 49667dfce9c3751f0580633e8a33cea28bcfbefec04plougher 4978b0edf380a8e22a1df314212705e6145bc746f8ePhillip Lougher if(res == LZMA_OK && size == (int) src_pos) 4988b0edf380a8e22a1df314212705e6145bc746f8ePhillip Lougher return (int) dest_pos; 4998b0edf380a8e22a1df314212705e6145bc746f8ePhillip Lougher else { 5008b0edf380a8e22a1df314212705e6145bc746f8ePhillip Lougher *error = res; 5018b0edf380a8e22a1df314212705e6145bc746f8ePhillip Lougher return -1; 5028b0edf380a8e22a1df314212705e6145bc746f8ePhillip Lougher } 50367dfce9c3751f0580633e8a33cea28bcfbefec04plougher} 50467dfce9c3751f0580633e8a33cea28bcfbefec04plougher 50567dfce9c3751f0580633e8a33cea28bcfbefec04plougher 5066d2d0853e045219e9d252576714966ac7831dc53ploughervoid xz_usage() 5076d2d0853e045219e9d252576714966ac7831dc53plougher{ 5086d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, "\t -Xbcj filter1,filter2,...,filterN\n"); 5096d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, "\t\tCompress using filter1,filter2,...,filterN in"); 5106d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, " turn\n\t\t(in addition to no filter), and choose"); 5116d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, " the best compression.\n"); 5126d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, "\t\tAvailable filters: x86, arm, armthumb,"); 5136d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, " powerpc, sparc, ia64\n"); 5146d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, "\t -Xdict-size <dict-size>\n"); 5156d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, "\t\tUse <dict-size> as the XZ dictionary size. The"); 5166d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, " dictionary size\n\t\tcan be specified as a"); 5176d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, " percentage of the block size, or as an\n\t\t"); 5186d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, "absolute value. The dictionary size must be less"); 51930d49e70cf81bdda75a9b2a735aa0aea33953692Phillip Lougher fprintf(stderr, " than or equal\n\t\tto the block size and 8192 bytes"); 5206d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, " or larger. It must also be\n\t\tstorable in the xz"); 5216d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); 5226d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); 5236d2d0853e045219e9d252576714966ac7831dc53plougher fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n"); 5246d2d0853e045219e9d252576714966ac7831dc53plougher} 5256d2d0853e045219e9d252576714966ac7831dc53plougher 5266d2d0853e045219e9d252576714966ac7831dc53plougher 52767dfce9c3751f0580633e8a33cea28bcfbefec04plougherstruct compressor xz_comp_ops = { 5287b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher .init = xz_init, 52967dfce9c3751f0580633e8a33cea28bcfbefec04plougher .compress = xz_compress, 53067dfce9c3751f0580633e8a33cea28bcfbefec04plougher .uncompress = xz_uncompress, 5317b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher .options = xz_options, 53214c30adab9ca2147a06975bbe99308f5f54b16f0plougher .options_post = xz_options_post, 53317f039dcdb5ce2b556efff0ba49b475176790d90plougher .dump_options = xz_dump_options, 534afeaf3a7dc0853af656c1000b364a92e4d093fedplougher .extract_options = xz_extract_options, 5353fcced11c3e4b49b2b687010304b5156935a3b2cPhillip Lougher .display_options = xz_display_options, 5367aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher .usage = xz_usage, 53767dfce9c3751f0580633e8a33cea28bcfbefec04plougher .id = XZ_COMPRESSION, 53867dfce9c3751f0580633e8a33cea28bcfbefec04plougher .name = "xz", 53967dfce9c3751f0580633e8a33cea28bcfbefec04plougher .supported = 1 54067dfce9c3751f0580633e8a33cea28bcfbefec04plougher}; 541