WizardsToolkit  1.0.7
zip.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                             ZZZZZ  IIIII  PPPP                              %
00007 %                                ZZ    I    P   P                             %
00008 %                              ZZZ     I    PPPP                              %
00009 %                             ZZ       I    P                                 %
00010 %                             ZZZZZ  IIIII  P                                 %
00011 %                                                                             %
00012 %                                                                             %
00013 %                     Wizard's Toolkit Zip Entropy Methods                    %
00014 %                                                                             %
00015 %                             Software Design                                 %
00016 %                               John Cristy                                   %
00017 %                               March 2003                                    %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.wizards-toolkit.org/script/license.php                        %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "wizard/studio.h"
00044 #include "wizard/exception.h"
00045 #include "wizard/exception-private.h"
00046 #include "wizard/memory_.h"
00047 #include "wizard/zip.h"
00048 #include "zlib.h"
00049 
00050 /*
00051   Typedef declarations.
00052 */
00053 struct _ZIPInfo
00054 {
00055   z_stream
00056     stream;
00057 
00058   StringInfo
00059     *chaos;
00060 
00061   size_t
00062     level;
00063 
00064   ssize_t
00065     timestamp;
00066 
00067   size_t
00068     signature;
00069 };
00070 
00071 /*
00072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00073 %                                                                             %
00074 %                                                                             %
00075 %                                                                             %
00076 %   A c q u i r e Z I P I n f o                                               %
00077 %                                                                             %
00078 %                                                                             %
00079 %                                                                             %
00080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00081 %
00082 %  AcquireZIPInfo() allocates the ZIPInfo structure.
00083 %
00084 %  The format of the AcquireZIPInfo method is:
00085 %
00086 %      ZIPInfo *AcquireZIPInfo(const size_t level)
00087 %
00088 %  A description of each parameter follows:
00089 %
00090 %    o level: entropy level: 1 is best speed, 9 is more entropy.
00091 %
00092 */
00093 WizardExport ZIPInfo *AcquireZIPInfo(const size_t level)
00094 {
00095   ZIPInfo
00096     *zip_info;
00097 
00098   zip_info=(ZIPInfo *) AcquireWizardMemory(sizeof(*zip_info));
00099   if (zip_info == (ZIPInfo *) NULL)
00100     ThrowWizardFatalError(EntropyError,MemoryError);
00101   (void) ResetWizardMemory(zip_info,0,sizeof(*zip_info));
00102   zip_info->chaos=AcquireStringInfo(1);
00103   zip_info->level=level;
00104   zip_info->timestamp=(ssize_t) (time((time_t *) NULL)-WizardEpoch);
00105   zip_info->signature=WizardSignature;
00106   return(zip_info);
00107 }
00108 
00109 /*
00110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00111 %                                                                             %
00112 %                                                                             %
00113 %                                                                             %
00114 %   G e t Z I P C h a o s                                                     %
00115 %                                                                             %
00116 %                                                                             %
00117 %                                                                             %
00118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00119 %
00120 %  GetZIPChaos() returns ZIP chaos.
00121 %
00122 %  The format of the GetZIPChaos method is:
00123 %
00124 %      const StringInfo *GetZIPChaos(const ZIPInfo *zip_info)
00125 %
00126 %  A description of each parameter follows:
00127 %
00128 %    o zip_info: The zip info.
00129 %
00130 */
00131 WizardExport const StringInfo *GetZIPChaos(const ZIPInfo *zip_info)
00132 {
00133   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00134   WizardAssert(EntropyDomain,zip_info != (ZIPInfo *) NULL);
00135   WizardAssert(EntropyDomain,zip_info->signature == WizardSignature);
00136   return(zip_info->chaos);
00137 }
00138 
00139 /*
00140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00141 %                                                                             %
00142 %                                                                             %
00143 %                                                                             %
00144 %   D e s t r o y Z I P I n f o                                               %
00145 %                                                                             %
00146 %                                                                             %
00147 %                                                                             %
00148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00149 %
00150 %  DestroyZIPInfo() zeros memory associated with the ZIPInfo structure.
00151 %
00152 %  The format of the DestroyZIPInfo method is:
00153 %
00154 %      ZIPInfo *DestroyZIPInfo(ZIPInfo *zip_info)
00155 %
00156 %  A description of each parameter follows:
00157 %
00158 %    o zip_info: The zip info.
00159 %
00160 */
00161 WizardExport ZIPInfo *DestroyZIPInfo(ZIPInfo *zip_info)
00162 {
00163   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00164   WizardAssert(EntropyDomain,zip_info != (ZIPInfo *) NULL);
00165   WizardAssert(EntropyDomain,zip_info->signature == WizardSignature);
00166   if (zip_info->chaos != (StringInfo *) NULL)
00167     zip_info->chaos=DestroyStringInfo(zip_info->chaos);
00168   zip_info=(ZIPInfo *) RelinquishWizardMemory(zip_info);
00169   return(zip_info);
00170 }
00171 
00172 /*
00173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00174 %                                                                             %
00175 %                                                                             %
00176 %                                                                             %
00177 %   I n c r e a s e Z i p                                                     %
00178 %                                                                             %
00179 %                                                                             %
00180 %                                                                             %
00181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00182 %
00183 %  IncreaseZIP() compresses the message to increase its entropy.
00184 %
00185 %  The format of the IncreaseZIP method is:
00186 %
00187 %      WizardBooleanType IncreaseZIP(ZIPInfo *zip_info,
00188 %        const StringInfo *message,ExceptionInfo *exception)
00189 %
00190 %  A description of each parameter follows:
00191 %
00192 %    o zip_info: The address of a structure of type ZIPInfo.
00193 %
00194 %    o message: The message.
00195 %
00196 %    o exception: Return any errors or warnings in this structure.
00197 %
00198 */
00199 
00200 static voidpf AcquireZIPMemory(voidpf context,uInt items,uInt size)
00201 {
00202   return((voidpf) AcquireQuantumMemory(items,size));
00203 }
00204 
00205 static void RelinquishZIPMemory(voidpf context,voidpf memory)
00206 {
00207   memory=RelinquishWizardMemory(memory);
00208 }
00209 
00210 WizardExport WizardBooleanType IncreaseZIP(ZIPInfo *zip_info,
00211   const StringInfo *message,ExceptionInfo *exception)
00212 {
00213   int
00214     status;
00215 
00216   z_stream
00217     stream;
00218 
00219   /*
00220     Increase the message entropy.
00221   */
00222   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00223   WizardAssert(EntropyDomain,zip_info != (ZIPInfo *) NULL);
00224   WizardAssert(EntropyDomain,zip_info->signature == WizardSignature);
00225   WizardAssert(EntropyDomain,message != (const StringInfo *) NULL);
00226   stream.zalloc=AcquireZIPMemory;
00227   stream.zfree=RelinquishZIPMemory;
00228   stream.opaque=(voidpf) NULL;
00229   status=deflateInit(&stream,(int) zip_info->level);
00230   if (status != Z_OK)
00231     {
00232       (void) ThrowWizardException(exception,GetWizardModule(),EntropyError,
00233         "unable to increase entropy `%s'",strerror(errno));
00234       return(WizardFalse);
00235     }
00236   stream.next_in=(Bytef *) GetStringInfoDatum(message);
00237   stream.avail_in=(uInt) GetStringInfoLength(message);
00238   SetStringInfoLength(zip_info->chaos,(size_t) deflateBound(&stream,
00239     (unsigned long) GetStringInfoLength(message)));
00240   stream.next_out=(Bytef *) GetStringInfoDatum(zip_info->chaos);
00241   stream.avail_out=(uInt) GetStringInfoLength(zip_info->chaos);
00242   status=deflate(&stream,Z_FINISH);
00243   if (status != Z_STREAM_END)
00244     {
00245       (void) ThrowWizardException(exception,GetWizardModule(),EntropyError,
00246         "unable to increase entropy `%s'",strerror(errno));
00247       return(WizardFalse);
00248     }
00249   SetStringInfoLength(zip_info->chaos,(size_t) stream.total_out);
00250   status=deflateEnd(&stream);
00251   if (status != Z_OK)
00252     {
00253       (void) ThrowWizardException(exception,GetWizardModule(),EntropyError,
00254         "unable to increase entropy `%s'",strerror(errno));
00255       return(WizardFalse);
00256     }
00257   return(WizardTrue);
00258 }
00259 
00260 /*
00261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00262 %                                                                             %
00263 %                                                                             %
00264 %                                                                             %
00265 %   R e s t o r e Z i p                                                       %
00266 %                                                                             %
00267 %                                                                             %
00268 %                                                                             %
00269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00270 %
00271 %  RestoreZIP() uncompresses the message to restore its original entropy.
00272 %
00273 %  The format of the RestoreZIP method is:
00274 %
00275 %      WizardBooleanType RestoreZIP(ZIPInfo *zip_info,const size_t length,
00276 %        const StringInfo *message,ExceptionInfo *exception)
00277 %
00278 %  A description of each parameter follows:
00279 %
00280 %    o zip_info: The address of a structure of type ZIPInfo.
00281 %
00282 %    o length: The total size of the destination buffer, which must be large
00283 %      enough to hold the entire uncompressed data.
00284 %
00285 %    o message: The message.
00286 %
00287 %    o exception: Return any errors or warnings in this structure.
00288 %
00289 */
00290 WizardExport WizardBooleanType RestoreZIP(ZIPInfo *zip_info,const size_t length,
00291   const StringInfo *message,ExceptionInfo *exception)
00292 {
00293   int
00294     status;
00295 
00296   z_stream
00297     stream;
00298 
00299   /*
00300     Restore the message entropy.
00301   */
00302   WizardAssert(EntropyDomain,zip_info != (ZIPInfo *) NULL);
00303   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00304   WizardAssert(EntropyDomain,zip_info->signature == WizardSignature);
00305   WizardAssert(EntropyDomain,message != (const StringInfo *) NULL);
00306   stream.zalloc=AcquireZIPMemory;
00307   stream.zfree=RelinquishZIPMemory;
00308   stream.opaque=(voidpf) NULL;
00309   status=inflateInit(&stream);
00310   if (status != Z_OK)
00311     {
00312       (void) ThrowWizardException(exception,GetWizardModule(),EntropyError,
00313         "unable to restore entropy `%s'",strerror(errno));
00314       return(WizardFalse);
00315     }
00316   stream.next_in=(Bytef *) GetStringInfoDatum(message);
00317   stream.avail_in=(uInt) GetStringInfoLength(message);
00318   SetStringInfoLength(zip_info->chaos,length);
00319   stream.next_out=(Bytef *) GetStringInfoDatum(zip_info->chaos);
00320   stream.avail_out=(uInt) GetStringInfoLength(zip_info->chaos);
00321   status=inflate(&stream,Z_FINISH);
00322   if (status != Z_STREAM_END)
00323     {
00324       (void) ThrowWizardException(exception,GetWizardModule(),EntropyError,
00325         "unable to restore entropy `%s'",strerror(errno));
00326       return(WizardFalse);
00327     }
00328   SetStringInfoLength(zip_info->chaos,(size_t) stream.total_out);
00329   status=inflateEnd(&stream);
00330   if (status != Z_OK)
00331     {
00332       (void) ThrowWizardException(exception,GetWizardModule(),EntropyError,
00333         "unable to restore entropy `%s'",strerror(errno));
00334       return(WizardFalse);
00335     }
00336   return(WizardTrue);
00337 }