xref: /aosp_15_r20/external/zstd/examples/dictionary_decompression.c (revision 01826a4963a0d8a59bc3812d29bdf0fb76416722)
1*01826a49SYabin Cui /*
2*01826a49SYabin Cui  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*01826a49SYabin Cui  * All rights reserved.
4*01826a49SYabin Cui  *
5*01826a49SYabin Cui  * This source code is licensed under both the BSD-style license (found in the
6*01826a49SYabin Cui  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*01826a49SYabin Cui  * in the COPYING file in the root directory of this source tree).
8*01826a49SYabin Cui  * You may select, at your option, one of the above-listed licenses.
9*01826a49SYabin Cui  */
10*01826a49SYabin Cui 
11*01826a49SYabin Cui 
12*01826a49SYabin Cui #include <stdio.h>     // printf
13*01826a49SYabin Cui #include <stdlib.h>    // free
14*01826a49SYabin Cui #include <zstd.h>      // presumes zstd library is installed
15*01826a49SYabin Cui #include "common.h"    // Helper functions, CHECK(), and CHECK_ZSTD()
16*01826a49SYabin Cui 
17*01826a49SYabin Cui /* createDict() :
18*01826a49SYabin Cui    `dictFileName` is supposed to have been created using `zstd --train` */
createDict_orDie(const char * dictFileName)19*01826a49SYabin Cui static ZSTD_DDict* createDict_orDie(const char* dictFileName)
20*01826a49SYabin Cui {
21*01826a49SYabin Cui     size_t dictSize;
22*01826a49SYabin Cui     printf("loading dictionary %s \n", dictFileName);
23*01826a49SYabin Cui     void* const dictBuffer = mallocAndLoadFile_orDie(dictFileName, &dictSize);
24*01826a49SYabin Cui     ZSTD_DDict* const ddict = ZSTD_createDDict(dictBuffer, dictSize);
25*01826a49SYabin Cui     CHECK(ddict != NULL, "ZSTD_createDDict() failed!");
26*01826a49SYabin Cui     free(dictBuffer);
27*01826a49SYabin Cui     return ddict;
28*01826a49SYabin Cui }
29*01826a49SYabin Cui 
decompress(const char * fname,const ZSTD_DDict * ddict)30*01826a49SYabin Cui static void decompress(const char* fname, const ZSTD_DDict* ddict)
31*01826a49SYabin Cui {
32*01826a49SYabin Cui     size_t cSize;
33*01826a49SYabin Cui     void* const cBuff = mallocAndLoadFile_orDie(fname, &cSize);
34*01826a49SYabin Cui     /* Read the content size from the frame header. For simplicity we require
35*01826a49SYabin Cui      * that it is always present. By default, zstd will write the content size
36*01826a49SYabin Cui      * in the header when it is known. If you can't guarantee that the frame
37*01826a49SYabin Cui      * content size is always written into the header, either use streaming
38*01826a49SYabin Cui      * decompression, or ZSTD_decompressBound().
39*01826a49SYabin Cui      */
40*01826a49SYabin Cui     unsigned long long const rSize = ZSTD_getFrameContentSize(cBuff, cSize);
41*01826a49SYabin Cui     CHECK(rSize != ZSTD_CONTENTSIZE_ERROR, "%s: not compressed by zstd!", fname);
42*01826a49SYabin Cui     CHECK(rSize != ZSTD_CONTENTSIZE_UNKNOWN, "%s: original size unknown!", fname);
43*01826a49SYabin Cui     void* const rBuff = malloc_orDie((size_t)rSize);
44*01826a49SYabin Cui 
45*01826a49SYabin Cui     /* Check that the dictionary ID matches.
46*01826a49SYabin Cui      * If a non-zstd dictionary is used, then both will be zero.
47*01826a49SYabin Cui      * By default zstd always writes the dictionary ID into the frame.
48*01826a49SYabin Cui      * Zstd will check if there is a dictionary ID mismatch as well.
49*01826a49SYabin Cui      */
50*01826a49SYabin Cui     unsigned const expectedDictID = ZSTD_getDictID_fromDDict(ddict);
51*01826a49SYabin Cui     unsigned const actualDictID = ZSTD_getDictID_fromFrame(cBuff, cSize);
52*01826a49SYabin Cui     CHECK(actualDictID == expectedDictID,
53*01826a49SYabin Cui           "DictID mismatch: expected %u got %u",
54*01826a49SYabin Cui           expectedDictID,
55*01826a49SYabin Cui           actualDictID);
56*01826a49SYabin Cui 
57*01826a49SYabin Cui     /* Decompress using the dictionary.
58*01826a49SYabin Cui      * If you need to control the decompression parameters, then use the
59*01826a49SYabin Cui      * advanced API: ZSTD_DCtx_setParameter(), ZSTD_DCtx_refDDict(), and
60*01826a49SYabin Cui      * ZSTD_decompressDCtx().
61*01826a49SYabin Cui      */
62*01826a49SYabin Cui     ZSTD_DCtx* const dctx = ZSTD_createDCtx();
63*01826a49SYabin Cui     CHECK(dctx != NULL, "ZSTD_createDCtx() failed!");
64*01826a49SYabin Cui     size_t const dSize = ZSTD_decompress_usingDDict(dctx, rBuff, rSize, cBuff, cSize, ddict);
65*01826a49SYabin Cui     CHECK_ZSTD(dSize);
66*01826a49SYabin Cui     /* When zstd knows the content size, it will error if it doesn't match. */
67*01826a49SYabin Cui     CHECK(dSize == rSize, "Impossible because zstd will check this condition!");
68*01826a49SYabin Cui 
69*01826a49SYabin Cui     /* success */
70*01826a49SYabin Cui     printf("%25s : %6u -> %7u \n", fname, (unsigned)cSize, (unsigned)rSize);
71*01826a49SYabin Cui 
72*01826a49SYabin Cui     ZSTD_freeDCtx(dctx);
73*01826a49SYabin Cui     free(rBuff);
74*01826a49SYabin Cui     free(cBuff);
75*01826a49SYabin Cui }
76*01826a49SYabin Cui 
77*01826a49SYabin Cui 
main(int argc,const char ** argv)78*01826a49SYabin Cui int main(int argc, const char** argv)
79*01826a49SYabin Cui {
80*01826a49SYabin Cui     const char* const exeName = argv[0];
81*01826a49SYabin Cui 
82*01826a49SYabin Cui     if (argc<3) {
83*01826a49SYabin Cui         printf("wrong arguments\n");
84*01826a49SYabin Cui         printf("usage:\n");
85*01826a49SYabin Cui         printf("%s [FILES] dictionary\n", exeName);
86*01826a49SYabin Cui         return 1;
87*01826a49SYabin Cui     }
88*01826a49SYabin Cui 
89*01826a49SYabin Cui     /* load dictionary only once */
90*01826a49SYabin Cui     const char* const dictName = argv[argc-1];
91*01826a49SYabin Cui     ZSTD_DDict* const dictPtr = createDict_orDie(dictName);
92*01826a49SYabin Cui 
93*01826a49SYabin Cui     int u;
94*01826a49SYabin Cui     for (u=1; u<argc-1; u++) decompress(argv[u], dictPtr);
95*01826a49SYabin Cui 
96*01826a49SYabin Cui     ZSTD_freeDDict(dictPtr);
97*01826a49SYabin Cui     printf("All %u files correctly decoded (in memory) \n", argc-2);
98*01826a49SYabin Cui     return 0;
99*01826a49SYabin Cui }
100