cbf_uncompressed.c

Go to the documentation of this file.
00001 /**********************************************************************
00002  * cbf_uncompressed -- uncompressed binary sections                   *
00003  *                                                                    *
00004  * Version 0.6 13 January 1999                                        *
00005  *                                                                    *
00006  *            Paul Ellis (ellis@ssrl.slac.stanford.edu) and           *
00007  *         Herbert J. Bernstein (yaya@bernstein-plus-sons.com)        *
00008  **********************************************************************/
00009   
00010 /**********************************************************************
00011  *                               NOTICE                               *
00012  * Creative endeavors depend on the lively exchange of ideas. There   *
00013  * are laws and customs which establish rights and responsibilities   *
00014  * for authors and the users of what authors create.  This notice     *
00015  * is not intended to prevent you from using the software and         *
00016  * documents in this package, but to ensure that there are no         *
00017  * misunderstandings about terms and conditions of such use.          *
00018  *                                                                    *
00019  * Please read the following notice carefully.  If you do not         *
00020  * understand any portion of this notice, please seek appropriate     *
00021  * professional legal advice before making use of the software and    *
00022  * documents included in this software package.  In addition to       *
00023  * whatever other steps you may be obliged to take to respect the     *
00024  * intellectual property rights of the various parties involved, if   *
00025  * you do make use of the software and documents in this package,     *
00026  * please give credit where credit is due by citing this package,     *
00027  * its authors and the URL or other source from which you obtained    *
00028  * it, or equivalent primary references in the literature with the    *
00029  * same authors.                                                      *
00030  *                                                                    *
00031  * Some of the software and documents included within this software   *
00032  * package are the intellectual property of various parties, and      *
00033  * placement in this package does not in any way imply that any       *
00034  * such rights have in any way been waived or diminished.             *
00035  *                                                                    *
00036  * With respect to any software or documents for which a copyright    *
00037  * exists, ALL RIGHTS ARE RESERVED TO THE OWNERS OF SUCH COPYRIGHT.   *
00038  *                                                                    *
00039  * Even though the authors of the various documents and software      *
00040  * found here have made a good faith effort to ensure that the        *
00041  * documents are correct and that the software performs according     *
00042  * to its documentation, and we would greatly appreciate hearing of   *
00043  * any problems you may encounter, the programs and documents any     *
00044  * files created by the programs are provided **AS IS** without any   *
00045  * warranty as to correctness, merchantability or fitness for any     *
00046  * particular or general use.                                         *
00047  *                                                                    *
00048  * THE RESPONSIBILITY FOR ANY ADVERSE CONSEQUENCES FROM THE USE OF    *
00049  * PROGRAMS OR DOCUMENTS OR ANY FILE OR FILES CREATED BY USE OF THE   *
00050  * PROGRAMS OR DOCUMENTS LIES SOLELY WITH THE USERS OF THE PROGRAMS   *
00051  * OR DOCUMENTS OR FILE OR FILES AND NOT WITH AUTHORS OF THE          *
00052  * PROGRAMS OR DOCUMENTS.                                             *
00053  **********************************************************************/
00054  
00055 /**********************************************************************
00056  *                          The IUCr Policy                           *
00057  *                                 on                                 *
00058  *     the Use of the Crystallographic Information File (CIF)         *
00059  *                                                                    *
00060  * The Crystallographic Information File (Hall, Allen & Brown,        *
00061  * 1991) is, as of January 1992, the recommended method for           *
00062  * submitting publications to Acta Crystallographica Section C. The   *
00063  * International Union of Crystallography holds the Copyright on      *
00064  * the CIF, and has applied for Patents on the STAR File syntax       *
00065  * which is the basis for the CIF format.                             *
00066  *                                                                    *
00067  * It is a principal objective of the IUCr to promote the use of      *
00068  * CIF for the exchange and storage of scientific data. The IUCr's    *
00069  * sponsorship of the CIF development was motivated by its            *
00070  * responsibility to its scientific journals, which set the           *
00071  * standards in crystallographic publishing. The IUCr intends that    *
00072  * CIFs will be used increasingly for electronic submission of        *
00073  * manuscripts to these journals in future. The IUCr recognises       *
00074  * that, if the CIF and the STAR File are to be adopted as a means    *
00075  * for universal data exchange, the syntax of these files must be     *
00076  * strictly and uniformly adhered to. Even small deviations from      *
00077  * the syntax would ultimately cause the demise of the universal      *
00078  * file concept. Through its Copyrights and Patents the IUCr has      *
00079  * taken the steps needed to ensure strict conformance with this      *
00080  * syntax.                                                            *
00081  *                                                                    *
00082  * The IUCr policy on the use of the CIF and STAR File processes is   *
00083  * as follows:                                                        *
00084  * _________________________________________________________________  *
00085  *                                                                    *
00086  *  * 1 CIFs and STAR Files may be generated, stored or transmitted,  *
00087  *    without permission or charge, provided their purpose is not     *
00088  *    specifically for profit or commercial gain, and provided that   *
00089  *    the published syntax is strictly adhered to.                    *
00090  *  * 2 Computer software may be developed for use with CIFs or STAR  *
00091  *    files, without permission or charge, provided it is distributed *
00092  *    in the public domain. This condition also applies to software   *
00093  *    for which a charge is made, provided that its primary function  *
00094  *    is for use with files that satisfy condition 1 and that it is   *
00095  *    distributed as a minor component of a larger package of         *
00096  *    software.                                                       *
00097  *  * 3 Permission will be granted for the use of CIFs and STAR Files *
00098  *    for specific commercial purposes (such as databases or network  *
00099  *    exchange processes), and for the distribution of commercial     *
00100  *    CIF/STAR software, on written application to the IUCr Executive *
00101  *    Secretary, 2 Abbey Square, Chester CH1 2HU, England. The        *
00102  *    nature, terms and duration of the licences granted will be      *
00103  *    determined by the IUCr Executive and Finance Committees.        *
00104  *                                                                    *
00105  * _________________________________________________________________  *
00106  *                                                                    *
00107  * In summary, the IUCr wishes to promote the use of the STAR File    *
00108  * concepts as a standard universal data file. It will insist on      *
00109  * strict compliance with the published syntax for all                *
00110  * applications. To assist with this compliance, the IUCr provides    *
00111  * public domain software for checking the logical integrity of a     *
00112  * CIF, and for validating the data name definitions contained        *
00113  * within a CIF. Detailed information on this software, and the       *
00114  * associated dictionaries, may be obtained from the IUCr Office at   *
00115  * 5 Abbey Square, Chester CH1 2HU, England.                          *
00116  **********************************************************************/
00117 
00118 #ifdef __cplusplus
00119 
00120 extern "C" {
00121 
00122 #endif
00123 
00124 #include <stdlib.h>
00125 #include <stdio.h>
00126 #include <string.h>
00127 #include <limits.h>
00128 
00129 #include "cbf.h"
00130 #include "cbf_alloc.h"
00131 #include "cbf_compress.h"
00132 #include "cbf_file.h"
00133 #include "cbf_uncompressed.h"
00134 
00135 #define CBF_SHIFT63 (sizeof (int) * CHAR_BIT > 64 ? 63 : 0)
00136 
00137 
00138   /* Copy an array without compression */
00139   
00140 int cbf_compress_none (void         *source, 
00141                        size_t        elsize, 
00142                        int           elsign, 
00143                        size_t        nelem, 
00144                        unsigned int  compression, 
00145                        cbf_file     *file, 
00146                        size_t       *compressedsize,
00147                        int          *storedbits)
00148 {
00149   unsigned int count, element, unsign, sign, limit, bits;
00150 
00151   unsigned char *unsigned_char_data;
00152   
00153 
00154     /* Is the element size valid? */
00155     
00156   if (elsize != sizeof (int) &&
00157       elsize != sizeof (short) &&
00158       elsize != sizeof (char))
00159 
00160     return CBF_ARGUMENT;
00161 
00162 
00163     /* Initialise the pointer */
00164 
00165   unsigned_char_data = (unsigned char *) source;
00166 
00167 
00168     /* Maximum limit (unsigned) is 64 bits */
00169 
00170   if (elsize * CHAR_BIT > 64)
00171   {
00172     sign = 1 << CBF_SHIFT63;
00173 
00174     limit = ~-(sign << 1);
00175     
00176     bits = 64;
00177   }
00178   else
00179   {
00180     sign = 1 << (elsize * CHAR_BIT - 1);
00181 
00182     limit = ~0;
00183 
00184     bits = elsize * CHAR_BIT;
00185   }
00186 
00187   if (storedbits)
00188     
00189     *storedbits = bits;
00190 
00191 
00192     /* Offset to make the value unsigned */
00193 
00194   if (elsign)
00195 
00196     unsign = sign;
00197 
00198   else
00199 
00200     unsign = 0;
00201 
00202 
00203     /* Initialise the pointer */
00204     
00205   unsigned_char_data = (unsigned char *) source;
00206 
00207 
00208     /* Write the elements */
00209     
00210   for (count = 0; count < nelem; count++)
00211   {
00212       /* Get the next element */
00213       
00214     if (elsize == sizeof (int))
00215     
00216       element = *((unsigned int *) unsigned_char_data);
00217       
00218     else
00219     
00220       if (elsize == sizeof (short))
00221       
00222         element = *((unsigned short *) unsigned_char_data);
00223         
00224       else
00225       
00226         element = *unsigned_char_data;
00227         
00228     unsigned_char_data += elsize;
00229 
00230 
00231       /* Make the element unsigned */
00232 
00233     element += unsign;
00234 
00235 
00236       /* Limit the value to 64 bits */
00237 
00238     if (element > limit)
00239 
00240       if (elsign && (int) (element - unsign) < 0)
00241 
00242         element = 0;
00243 
00244       else
00245 
00246         element = limit;
00247         
00248 
00249       /* Write the element to the file */
00250 
00251     cbf_failnez (cbf_put_integer (file, element - unsign, 0, bits))
00252   }
00253 
00254 
00255     /* Return the number of characters written */
00256     
00257   if (compressedsize)
00258   
00259     *compressedsize = (nelem * bits + 7) / 8;
00260 
00261 
00262     /* Success */
00263 
00264   return 0;
00265 }
00266 
00267 
00268   /* Recover an array without decompression */
00269 
00270 int cbf_decompress_none (void         *destination, 
00271                          size_t        elsize, 
00272                          int           elsign, 
00273                          size_t        nelem, 
00274                          size_t       *nelem_read,
00275                          unsigned int  compression, 
00276                          int           data_bits, 
00277                          int           data_sign,
00278                          cbf_file     *file)
00279 {
00280   unsigned int element, sign, unsign, limit, count, bit;
00281 
00282   unsigned int data_unsign;
00283 
00284   unsigned char *unsigned_char_data;
00285 
00286   int errorcode, overflow;
00287 
00288 
00289     /* Is the element size valid? */
00290     
00291   if (elsize != sizeof (int) &&
00292       elsize != sizeof (short) &&
00293       elsize != sizeof (char))
00294 
00295     return CBF_ARGUMENT;
00296     
00297     
00298     /* Check the stored element size */
00299     
00300   if (data_bits < 1 || data_bits > 64)
00301   
00302     return CBF_ARGUMENT;
00303 
00304 
00305     /* Initialise the pointer */
00306 
00307   unsigned_char_data = (unsigned char *) destination;
00308 
00309 
00310     /* Maximum limits */
00311     
00312   sign = 1 << (elsize * CHAR_BIT - 1);
00313     
00314   if (elsize == sizeof (int))
00315     
00316     limit = ~0;
00317       
00318   else
00319     
00320     limit = ~-(1 << (elsize * CHAR_BIT));
00321 
00322 
00323     /* Check the element size */
00324     
00325   if (data_bits < 1 || data_bits > 64)
00326   
00327     return CBF_FORMAT;
00328   
00329 
00330     /* Offsets to make the value unsigned */
00331 
00332   if (data_sign)
00333 
00334     data_unsign = sign;
00335 
00336   else
00337 
00338     data_unsign = 0;
00339 
00340   if (elsign)
00341 
00342     unsign = sign;
00343 
00344   else
00345 
00346     unsign = 0;
00347 
00348 
00349     /* Read the elements */
00350 
00351   count = 0;
00352 
00353   overflow = 0;
00354 
00355   while (count < nelem)
00356   {
00357       /* Get the next element */
00358 
00359     errorcode = cbf_get_integer (file, (int *) &element, 
00360                                                 data_sign, data_bits);
00361 
00362     if (errorcode)
00363 
00364       if (errorcode == CBF_OVERFLOW)
00365 
00366         overflow = errorcode;
00367 
00368       else
00369       {
00370         if (nelem_read)
00371       
00372           *nelem_read = count;
00373         
00374         return errorcode | overflow;
00375       }
00376 
00377 
00378       /* Make the element unsigned */
00379 
00380     element += data_unsign;
00381 
00382 
00383       /* Limit the value to fit the element size */
00384 
00385     if (element > limit)
00386     {
00387       if (elsign && (int) (element - unsign) < 0)
00388       
00389         element = 0;
00390         
00391       else
00392       
00393         element = limit;
00394 
00395       overflow = CBF_OVERFLOW;
00396     }
00397         
00398         
00399       /* Make the element signed? */
00400         
00401     element -= unsign;
00402 
00403 
00404       /* Save the element */
00405         
00406     if (elsize == sizeof (int))
00407       
00408       *((unsigned int *) unsigned_char_data) = element;
00409         
00410     else
00411       
00412       if (elsize == sizeof (short))
00413         
00414         *((unsigned short *) unsigned_char_data) = element;
00415           
00416       else
00417         
00418         *unsigned_char_data = element;
00419           
00420     unsigned_char_data += elsize;
00421     
00422     count++;
00423   }
00424 
00425 
00426     /* Number read */
00427     
00428   if (nelem_read)
00429   
00430     *nelem_read = count;
00431 
00432 
00433     /* Success */
00434 
00435   return overflow;
00436 }
00437 
00438 
00439 #ifdef __cplusplus
00440 
00441 }
00442 
00443 #endif