Merge branch 'cupcake'
diff --git a/srec/clib/log_add.h b/srec/clib/log_add.h
index 9f59cff..bcd64de 100644
--- a/srec/clib/log_add.h
+++ b/srec/clib/log_add.h
@@ -20,9 +20,9 @@
 #ifndef _inl_log_add_
 #define _inl_log_add_
 
-static PINLINE prdata log_increment_inline(prdata ival, logadd_table_info *logtab);
+static PINLINE prdata log_increment_inline(prdata ival, const logadd_table_info *logtab);
 
-static PINLINE prdata log_increment_inline(prdata ival, logadd_table_info *logtab)
+static PINLINE prdata log_increment_inline(prdata ival, const logadd_table_info *logtab)
 /*
 **  To add two numbers stored as their natural logarithms
 **  A more efficient implementation is to use lookup tables.
diff --git a/srec/clib/swimodel.c b/srec/clib/swimodel.c
index 8d1711c..2ea194c 100644
--- a/srec/clib/swimodel.c
+++ b/srec/clib/swimodel.c
@@ -11,7 +11,7 @@
  *                                                                           *
  *  Unless required by applicable law or agreed to in writing, software      *
  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  *  See the License for the specific language governing permissions and      *
  *  limitations under the License.                                           *
  *                                                                           *
@@ -32,37 +32,9 @@
 #include "log_add.h"
 #include "swimodel.h"
 
-/* const float   root_pi_over_2= (float)1.2533141; */
-const prdata  max_log = (prdata) MAX_LOG;
 
 #define MTAG NULL
 
-/*--------------------------------------------------------------*
- *                                                              *
- *                                                              *
- *                                                              *
- *--------------------------------------------------------------*/
-
-costdata DURATION_PENALTY_UNIT = 1;
-int      NUM_FRAMES_PER_VALID_FRAME = 0;
-/* this is just for debugging, able to turn duration model off */
-
-void check_duration_penalty()
-{
-  char *p = getenv("DUR_PR");
-  if (p)
-  {
-    DURATION_PENALTY_UNIT = (costdata) atoi(p);
-  }
-#ifdef SREC_ENGINE_VERBOSE_LOGGING
-  PLogMessage("DUR_PR %d\n", DURATION_PENALTY_UNIT);
-#endif
-}
-
-void duration_penalty_set_frames_per_valid_frame(int n)
-{
-  NUM_FRAMES_PER_VALID_FRAME = n;
-}
 
 /*--------------------------------------------------------------*
  *                                                              *
@@ -75,7 +47,7 @@
    look roughly like normal distributions centered at the average state
    durations */
 
-char loop_cost_table [128][6] = {
+const char loop_cost_table [128][6] = {
 {0,0,0,0,0,0},
 {13,15,16,16,16,16},
 {12,13,14,14,14,14},
@@ -211,7 +183,7 @@
    look roughly like normal distributions centered at the average state
    durations */
 
-char trans_cost_table [128][6] = {
+const char trans_cost_table [128][6] = {
 {0,0,0,0,0,0},
 {0,0,0,0,0,0},
 {0,0,0,0,0,0},
@@ -355,88 +327,84 @@
   return v;
 }
 
-SWIModel* load_swimodel(char *filename)
+const SWIModel* load_swimodel(const char *filename)
 {
-  featdata *mean_ptr;
-  wtdata *weight_ptr;
   int i;
-  PFile* fp = NULL;
-  short* num_pdfs_in_model;
-  int num_allocated;
-  SWIModel *swimodel;
-  int ni;
-
-  fp = pfopen ( filename, L("rb") );
-/*  CHKLOG(rc, PFileSystemCreatePFile(filename, ESR_TRUE, &fp));
-  CHKLOG(rc, PFileOpen(fp, L("rb")));*/
-
-  if ( fp == NULL )
-    goto CLEANUP;
+  SWIModel *swimodel = NULL;
+  const void* file = NULL;
 
 #ifdef SREC_ENGINE_VERBOSE_LOGGING
   PLogMessage("load_swimodel: loaded %s", filename);
 #endif
   swimodel = (SWIModel*) CALLOC(1, sizeof(SWIModel), "clib.models.base");
-  num_allocated = sizeof(SWIModel);
-  swimodel->num_hmmstates = load_short(fp);
-  swimodel->num_dims      = load_short(fp);
-  swimodel->num_pdfs      = load_short(fp);
 
-  swimodel->hmmstates     = (SWIhmmState*) CALLOC(swimodel->num_hmmstates, sizeof(SWIhmmState), "clib.models.states");
-  num_allocated += swimodel->num_hmmstates * sizeof(SWIhmmState);
+  if (mmap_zip(filename, &swimodel->mmap_zip_data, &swimodel->mmap_zip_size)) {
+      PLogError("load_swimodel: mmap_zip failed for %s\n", filename);
+      goto CLEANUP;
+  }
+  file = swimodel->mmap_zip_data;
 
-  swimodel->allmeans      = (featdata*) CALLOC(swimodel->num_pdfs * swimodel->num_dims, sizeof(featdata), "clib.models.means");
-  num_allocated += swimodel->num_pdfs * swimodel->num_dims * sizeof(featdata);
-  swimodel->allweights    = (wtdata*) CALLOC(swimodel->num_pdfs, sizeof(wtdata), "clib.models.weights");
-  num_allocated += swimodel->num_pdfs * sizeof(featdata);
-  swimodel->avg_state_durations = (featdata*) CALLOC(swimodel->num_hmmstates, sizeof(featdata), "clib.models.durs");
+  swimodel->num_hmmstates = *(const short*)file;
+  file += sizeof(short);
+  swimodel->num_dims = *(const short*)file;
+  file += sizeof(short);
+  swimodel->num_pdfs = *(const short*)file;
+  file += sizeof(short);
 
-  num_pdfs_in_model = (short*) MALLOC(sizeof(short) * swimodel->num_hmmstates, MTAG);
-  ni = pfread(num_pdfs_in_model, sizeof(short), swimodel->num_hmmstates, fp);
-  ASSERT(ni == swimodel->num_hmmstates);
-  ni = pfread(swimodel->allmeans, sizeof(featdata), swimodel->num_dims * swimodel->num_pdfs, fp);
-  ASSERT(ni == swimodel->num_pdfs*swimodel->num_dims);
-  ni = pfread(swimodel->allweights, sizeof(wtdata), swimodel->num_pdfs, fp);
-  ASSERT(ni == swimodel->num_pdfs);
-  ni = pfread(swimodel->avg_state_durations, sizeof(featdata), swimodel->num_hmmstates, fp);
-  ASSERT(ni == swimodel->num_hmmstates);
+  SWIhmmState* hmmstates = (SWIhmmState*) CALLOC(swimodel->num_hmmstates, sizeof(SWIhmmState), "clib.models.states");
+  swimodel->hmmstates = hmmstates;
+
+  const short* num_pdfs_in_model = (const short*)file;
+  file += sizeof(short) * swimodel->num_hmmstates;
+
+  swimodel->allmeans = (const featdata*)file;
+  file += sizeof(featdata) * swimodel->num_pdfs * swimodel->num_dims;
+
+  swimodel->allweights = (const wtdata*)file;
+  file += sizeof(wtdata) * swimodel->num_pdfs;
+
+  swimodel->avg_state_durations = (const featdata*)file;
+  file += sizeof(featdata) * swimodel->num_hmmstates;
+
+  if (file > swimodel->mmap_zip_data + swimodel->mmap_zip_size) {
+      PLogError("load_swimodel: not enough data in %s", filename);
+      goto CLEANUP;
+  }
 
 #ifdef SREC_ENGINE_VERBOSE_LOGGING
-  PLogMessage("loaded models %s num_hmmstates %d num_dims %d num_pdfs %d allocated %d bytes weights[0] %d\n",
-              filename, swimodel->num_hmmstates, swimodel->num_dims, swimodel->num_pdfs, num_allocated,
+  PLogMessage("loaded models %s num_hmmstates %d num_dims %d num_pdfs %d weights[0] %d\n",
+              filename, swimodel->num_hmmstates, swimodel->num_dims, swimodel->num_pdfs,
               *swimodel->allweights);
 #endif
 
-  mean_ptr = swimodel->allmeans;
-  weight_ptr = swimodel->allweights;
+  const featdata* mean_ptr = swimodel->allmeans;
+  const wtdata* weight_ptr = swimodel->allweights;
 
   for (i = 0;i < swimodel->num_hmmstates;i++)
   {
-    swimodel->hmmstates[i].num_pdfs = num_pdfs_in_model[i];
-    swimodel->hmmstates[i].means = mean_ptr;
-    swimodel->hmmstates[i].weights = weight_ptr;
+    hmmstates[i].num_pdfs = num_pdfs_in_model[i];
+    hmmstates[i].means = mean_ptr;
+    hmmstates[i].weights = weight_ptr;
     mean_ptr += swimodel->num_dims * num_pdfs_in_model[i];
     weight_ptr += num_pdfs_in_model[i];
   }
-  FREE(num_pdfs_in_model);
-  num_pdfs_in_model = NULL;
-  pfclose(fp);
+
   return swimodel;
+
 CLEANUP:
-  if (fp != NULL)
-    pfclose ( fp );
+  free_swimodel(swimodel);
   return NULL;
 }
 
-void free_swimodel(SWIModel* swimodel)
+void free_swimodel(const SWIModel* swimodel)
 {
-  FREE(swimodel->hmmstates);
-  FREE(swimodel->allmeans);
-  FREE(swimodel->allweights);
-  FREE(swimodel->avg_state_durations);
-  FREE(swimodel);
+  if (!swimodel) return;
+  if (swimodel->mmap_zip_data) munmap_zip(swimodel->mmap_zip_data, swimodel->mmap_zip_size);
+  FREE((void*)swimodel->hmmstates);
+  FREE((void*)swimodel);
 }
-static PINLINE prdata Gaussian_Grand_Density_Swimodel(preprocessed *data, featdata *means)
+
+static PINLINE prdata Gaussian_Grand_Density_Swimodel(const preprocessed *data, const featdata *means)
 /*
 **  Observation probability function of a Gaussian pdf
 **  with diagonal covariance matrix.
@@ -444,8 +412,8 @@
 {
   prdata pval;
   prdata diff;
-  imeldata *dvec;
-  imeldata *dend;
+  const imeldata *dvec;
+  const imeldata *dend;
   int count;
 
   dvec = data->seq + data->use_from;    /* Move to starting feature element */
@@ -463,8 +431,8 @@
   return (pval);
 }
 
-scodata mixture_diagonal_gaussian_swimodel(preprocessed *prep,
-    SWIhmmState *spd, short num_dims)
+scodata mixture_diagonal_gaussian_swimodel(const preprocessed *prep,
+    const SWIhmmState *spd, short num_dims)
 /*
 **  Observation probability function
 */
@@ -473,13 +441,14 @@
   prdata pval, gval;
 
   prdata dval;
-  featdata *meanptr;
-  wtdata *weightptr;
+  const featdata *meanptr;
+  const wtdata *weightptr;
 
   ASSERT(prep);
   ASSERT(spd);
 
-  pval = -max_log;
+  pval = -(prdata) MAX_LOG;
+
   meanptr = spd->means;
   weightptr = spd->weights;
 
diff --git a/srec/clib/voc_read.c b/srec/clib/voc_read.c
index 549b93b..70ddff3 100644
--- a/srec/clib/voc_read.c
+++ b/srec/clib/voc_read.c
@@ -11,7 +11,7 @@
  *                                                                           *
  *  Unless required by applicable law or agreed to in writing, software      *
  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  *  See the License for the specific language governing permissions and      *
  *  limitations under the License.                                           *
  *                                                                           *
@@ -58,14 +58,9 @@
 
 static const char voc_read[] = "$Id: voc_read.c,v 1.14.6.18 2008/03/05 21:18:44 dahan Exp $";
 
-#define SORTED_WORD_LIST 1
-#define MAX_PRON_LEN      255
 
 #define cr_or_nl(ch) ((ch) == '\n' || (ch) == '\r')
 
-static int mmap_zip(const char* fname, void** buf, size_t* size);
-static int munmap_zip(void* buf, size_t size);
-
 
 #ifndef _RTT
 
@@ -82,8 +77,6 @@
   char token[256];
 
   ASSERT(voc);
-  
-  //PLogError("read_word_transcription hello\n");
 
   if (basename == NULL || strlen(basename) == 0) {
     PLogError("Error: invalid arg to read_word_transcription()\n");
@@ -94,16 +87,16 @@
     PLogError("read_word_transcription: mmap_zip failed for %s\n", basename);
     goto CLEANUP;
   }
-  
+
   /* this assumption eliminates simplifies bounds checking when parsing */
   if (!cr_or_nl(voc->ok_file_data[voc->ok_file_data_length - 1])) {
     PLogError(L("read_word_transcription: last character in %s not newline\n"), basename);
     goto CLEANUP;
   }
-  
+
   /* set up point to walk the data */
   ok = voc->ok_file_data;
-  
+
   /* verify the header */
   i = 0;
   while (*ok != '=') {
@@ -126,13 +119,13 @@
   token[i] = 0;
   ok++;
   CHKLOG(rc, ESR_str2locale(token, locale));
-  
+
   /* set up first and last entries */
   voc->first_entry = strchr(voc->ok_file_data, '\n') + 1;
   voc->last_entry = voc->ok_file_data + voc->ok_file_data_length - 2;
   while (*voc->last_entry != '\n') voc->last_entry--; /* header forces termination */
   voc->last_entry++;
-  
+
   /* determine if there are any upper case entries */
   voc->hasUpper = 1;
   while (ok < voc->ok_file_data + voc->ok_file_data_length) {
@@ -149,15 +142,13 @@
     while (*ok++ != '\n') ;
   }
 
-  //PLogError("read_word_transcription goodbye %d", voc->hasUpper);
-  
   return 0;
-  
+
 CLEANUP:
   delete_word_transcription(voc);
 
   PLogError(L("read_word_transcription: failed to read '%s'"), basename);
-  
+
   return -1;
 }
 #endif
@@ -178,10 +169,10 @@
   const char* high;
 
   //PLogError(L("get_prons '%s'"), label);
-  
+
   /* dictionaries are usually lower case, so do this for speed */
   if (!voc->hasUpper && 'A' <= *label && *label <= 'Z') return 0;
-  
+
   /* binary search to find matching entry */
   low = voc->first_entry;
   high = voc->last_entry;
@@ -189,14 +180,14 @@
     /* pick a point in the middle and align to next entry */
     middle = low + ((high - low) >> 1) - 1;
     while (*middle++ != '\n') ;
-    
+
     /* compare 'label' to 'middle' */
     int diff = kompare(label, middle);
     if (diff == 0) break;
-    
+
     /* nothing found */
     if (low == high) return 0;
-    
+
     /* 'middle' aligned to 'high', so move 'high' down */
     if (middle == high) {
       high -= 2;
@@ -204,31 +195,31 @@
       high++;
       continue;
     }
-    
+
     if (diff > 0) low = middle;
     else high = middle;
   }
-  
+
   /* back up to find the first entry equal to 'label' */
   low = middle;
   while (voc->first_entry < low) {
-    char* lo;
+    const char* lo;
     for (lo = low - 2; *lo != '\n'; lo--) ;
     lo++;
     if (kompare(label, lo)) break;
     low = lo;
   }
-  
+
   /* move forward to the last entry equal to 'label' */
   high = middle;
   while (high < voc->last_entry) {
-    char* hi;
+    const char* hi;
     for (hi = high; *hi != '\n'; hi++) ;
     hi++;
     if (kompare(label, hi)) break;
     high = hi;
   }
-  
+
   /* loop over all the entries */
   num_prons = 0;
   while (low <= high) {
@@ -237,7 +228,7 @@
 
     /* skip the whitespace */
     while (*low == ' ') low++;
-    
+
     /* copy the pron */
     while (*low != '\n') {
       if (--prons_len <= 2) return -1;
@@ -248,7 +239,7 @@
     num_prons++;
   }
   *prons++ = 0;
-  
+
   return num_prons;
 }
 
@@ -277,7 +268,7 @@
   return size + size / 1000 + 1;
 }
 
-static int mmap_zip(const char* fname, void** buf, size_t* size) {
+int mmap_zip(const char* fname, void** buf, size_t* size) {
     int fd = -1;
     struct stat statbuf;
     zipfile_t zf = 0;
@@ -285,57 +276,57 @@
     char entryname[FILENAME_MAX];
     size_t size2 = 0;
     void* buf2 = 0;
-    
+
     /* open data file, determine size, map it, and close fd */
     fd = open(fname, O_RDONLY);
     if (fd < 0) goto FAILED;
-   
+
     /* determine length */
     if (fstat(fd, &statbuf) < 0) goto FAILED;
-   
+
     /* mmap it */
     *size = statbuf.st_size;
     *buf = mmap(0, inflateSize(statbuf.st_size), PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
     if (*buf == MAP_FAILED) goto FAILED;
-     
+
     /* close fd, since we can */
     close(fd);
     fd = -1;
-    
+
     /* if not a zip file, we are done! */
     if (!endeql(fname, ".zip")) return 0;
-    
+
     /* set up zipfiler */
     zf = init_zipfile(*buf, *size);
     if (!zf) goto FAILED;
-    
+
     /* get entry */
     strcpy(entryname, strrchr(fname, '/') ? strrchr(fname, '/') + 1 : fname);
     entryname[strlen(entryname) - strlen(".zip")] = 0;
     ze = lookup_zipentry(zf, entryname);
     if (!ze) goto FAILED;
-    
+
     /* mmap anon memory to hold unzipped entry */
     size2 = get_zipentry_size(ze);
     buf2 = mmap(0, inflateSize(size2), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
     if (buf2 == (void*)-1) goto FAILED;
-    
+
     /* unzip entry */
     if (decompress_zipentry(ze, buf2, size2)) goto FAILED;
-    
+
     /* release unzipper */
     release_zipfile(zf);
     zf = 0;
-    
+
     /* release mmapped file */
     munmap(*buf, inflateSize(*size));
-    
+
     /* set return values */
     *buf = buf2;
     *size = size2;
-    
+
     return 0;
-    
+
 FAILED:
     if (fd != -1) close(fd);
     if (zf) release_zipfile(zf);
@@ -346,7 +337,7 @@
     return -1;
 }
 
-static int munmap_zip(void* buf, size_t size) {
+int munmap_zip(void* buf, size_t size) {
     return munmap(buf, inflateSize(size));
 }
 
diff --git a/srec/crec/c47mulsp.c b/srec/crec/c47mulsp.c
index 084d70b..051db39 100644
--- a/srec/crec/c47mulsp.c
+++ b/srec/crec/c47mulsp.c
@@ -11,7 +11,7 @@
  *                                                                           *
  *  Unless required by applicable law or agreed to in writing, software      *
  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  *  See the License for the specific language governing permissions and      *
  *  limitations under the License.                                           *
  *                                                                           *
@@ -27,7 +27,7 @@
 #include "srec_context.h"
 #include "srec.h"
 
-int add_acoustic_model_for_recognition(multi_srec* recm, SWIModel* model)
+int add_acoustic_model_for_recognition(multi_srec* recm, const SWIModel* model)
 {
   if (recm->num_swimodels >= MAX_ACOUSTIC_MODELS)
   {
@@ -39,7 +39,7 @@
     log_report("Error: too few recognizers allocated\n");
     return 0;
   }
-  
+
   if (recm->rec[0].num_model_slots_allocated < model->num_hmmstates)
   {
     PLogError("recognizer max_model_states %d, acoustic model num states %d, set CREC.Recognizer.max_model_states higher\n",
@@ -47,10 +47,10 @@
               model->num_hmmstates);
     return 0;
   }
-  
+
   recm->swimodel[ recm->num_swimodels] = model;
   recm->num_swimodels++;
-  
+
   recm->num_activated_recs++;
   return 1;
 }
@@ -90,11 +90,11 @@
 
 int activate_grammar_for_recognition(multi_srec* recm, srec_context* grammar, const char* rule)
 {
-  srec_context* context = (srec_context*)grammar;
-  
+  srec_context* context = grammar;
+
   context->max_searchable_nodes = recm->max_fsm_nodes;
   context->max_searchable_arcs  = recm->max_fsm_arcs;
-  
+
   if (context->max_searchable_nodes < context->num_nodes || context->max_searchable_arcs < context->num_arcs)
   {
     PLogError(L("Error: context switch failed due to search limitations [arcs max=%d, actual=%d], [nodes max=%d, actual=%d]\n"),
diff --git a/srec/crec/get_fram.c b/srec/crec/get_fram.c
index 557f449..d92ab1b 100644
--- a/srec/crec/get_fram.c
+++ b/srec/crec/get_fram.c
@@ -35,8 +35,6 @@
 #define DEBUG   0
 #define FUDGE_FACTOR 1.2f
 
-extern const prdata  max_log;
-
 const float root_pi_over_2 = (float) 1.2533141;
 
 static const char get_fram[] = "$Id: get_fram.c,v 1.7.6.13 2007/10/15 18:06:24 dahan Exp $";
diff --git a/srec/crec/srec.c b/srec/crec/srec.c
index 9d4bdce..e9e9037 100644
--- a/srec/crec/srec.c
+++ b/srec/crec/srec.c
@@ -321,7 +321,7 @@
   for (;--n > 0;p++) if (rv > *p) rv = *p;
   return rv;
 }
-static int compute_model_scores(costdata *current_model_scores, SWIModel *acoustic_models,
+static int compute_model_scores(costdata *current_model_scores, const SWIModel *acoustic_models,
                                 pattern_info *pattern, frameID current_search_frame)
 {
   int i;
@@ -329,13 +329,10 @@
 
   for (i = 0; i < acoustic_models->num_hmmstates; i++)
   {
-    SWIhmmState *hmmstate = &acoustic_models->hmmstates[i];
-
-    scodata score;
-
     if (current_model_scores[i] == DO_COMPUTE_MODEL)
     {
-      score = mixture_diagonal_gaussian_swimodel(pattern->prep, hmmstate, acoustic_models->num_dims);
+      scodata score = mixture_diagonal_gaussian_swimodel(pattern->prep,
+              &acoustic_models->hmmstates[i], acoustic_models->num_dims);
       ASSERT(score <= 0 && "model score out of range");
 
       current_model_scores[i] = (costdata) - score;
@@ -349,7 +346,7 @@
 
 /*precompute all needed models to be used by next frame of search*/
 
-static int find_which_models_to_compute(srec *rec, SWIModel *acoustic_models)
+static int find_which_models_to_compute(srec *rec, const SWIModel *acoustic_models)
 {
   int i;
   modelID model_index;
@@ -1017,7 +1014,7 @@
               new_ftoken->next_token_index = current_ftoken->next_token_index;
               current_ftoken->next_token_index = new_ftoken_index;
               rec->best_token_for_node[ fsm_arc->to_node] = new_ftoken_index;
-	      /* new_ftoken->aword_backtrace must be null, alts here were 
+	      /* new_ftoken->aword_backtrace must be null, alts here were
 		 processed and dropped in srec_process_word_boundary_nbest() */
               if(new_ftoken->aword_backtrace != AWTNULL) {
 		PLogError( ("Error: internal search error near %s %d\n"), __FILE__, __LINE__);
@@ -1052,9 +1049,9 @@
             new_ftoken->word_backtrace = current_ftoken->word_backtrace;
             new_ftoken->word = word_with_wtw;
 	    /* here we are giving up the path and alternatives that existed at
-	       this node, which is not great! The new (better) top choice 
-	       coming in and it's alternatives are propagated instead. 
-	       TODO: merge the alternative lists and the previous top choice 
+	       this node, which is not great! The new (better) top choice
+	       coming in and it's alternatives are propagated instead.
+	       TODO: merge the alternative lists and the previous top choice
 	    */
 	    if(new_ftoken->aword_backtrace!=AWTNULL)
               free_altword_token_batch( rec, new_ftoken->aword_backtrace);
@@ -1996,7 +1993,7 @@
 */
 
 void srec_viterbi_part1(srec *rec,
-                        SWIModel *acoustic_models,
+                        const SWIModel *acoustic_models,
                         pattern_info *pattern,
                         costdata silence_model_cost);
 
@@ -2038,8 +2035,8 @@
   {
     srec* rec1 = &recm->rec[0];
     srec* rec2 = &recm->rec[1];
-    SWIModel* acoustic_models1 = recm->swimodel[0];
-    SWIModel* acoustic_models2 = recm->swimodel[1];
+    const SWIModel* acoustic_models1 = recm->swimodel[0];
+    const SWIModel* acoustic_models2 = recm->swimodel[1];
     costdata diff;
     costdata current_best_cost;
 
@@ -2163,7 +2160,7 @@
 
 
 void srec_viterbi_part1(srec *rec,
-                        SWIModel *acoustic_models,
+                        const SWIModel *acoustic_models,
                         pattern_info *pattern,
                         costdata silence_model_cost)
 {
diff --git a/srec/include/c42mul.h b/srec/include/c42mul.h
index fefcd6e..7029abe 100644
--- a/srec/include/c42mul.h
+++ b/srec/include/c42mul.h
@@ -11,7 +11,7 @@
  *                                                                           *
  *  Unless required by applicable law or agreed to in writing, software      *
  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  *  See the License for the specific language governing permissions and      *
  *  limitations under the License.                                           *
  *                                                                           *
@@ -61,7 +61,7 @@
                          utterance_info *utt);
   void begin_recognition(multi_srec *rec, int begin_syn_node);
   void end_recognition(multi_srec *rec);
-  int  add_acoustic_model_for_recognition(multi_srec* rec, SWIModel* swimodel);
+  int  add_acoustic_model_for_recognition(multi_srec* rec, const SWIModel* swimodel);
   int  clear_acoustic_models_for_recognition(multi_srec* rec);
 
   void free_recognition(multi_srec *rec);
diff --git a/srec/include/hmmlib.h b/srec/include/hmmlib.h
index 83f2bab..23d5d1f 100644
--- a/srec/include/hmmlib.h
+++ b/srec/include/hmmlib.h
@@ -11,7 +11,7 @@
  *                                                                           *
  *  Unless required by applicable law or agreed to in writing, software      *
  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  *  See the License for the specific language governing permissions and      *
  *  limitations under the License.                                           *
  *                                                                           *
@@ -32,5 +32,8 @@
 int read_word_transcription(const LCHAR* basename, vocab_info* voc, ESR_Locale* locale);
 void delete_word_transcription(vocab_info* voc);
 int get_prons(const vocab_info* voc, const char* label, char* prons, int prons_len);
-                                
+
+int mmap_zip(const char* fname, void** buf, size_t* size);
+int munmap_zip(void* buf, size_t size);
+
 #endif /* _h_hmmlib_ */
diff --git a/srec/include/simapi.h b/srec/include/simapi.h
index 6a8d62f..423db4e 100644
--- a/srec/include/simapi.h
+++ b/srec/include/simapi.h
@@ -115,7 +115,7 @@
     int         use_dim;
     int         partial_distance_calc_dim;
     prdata      imelda_scale;
-    SWIModel    *swimodel; /* owning pointer to compact acoustic models */
+    const SWIModel    *swimodel; /* owning pointer to compact acoustic models */
   }
   CA_Acoustic;
 
@@ -1461,7 +1461,7 @@
    * Returns      int
    *
    ************************************************************************
-   * tells whether a syntax is to be used for voice-enrollment 
+   * tells whether a syntax is to be used for voice-enrollment
    ************************************************************************
    */
 
@@ -2794,7 +2794,7 @@
 
   void CA_FreeConfidenceScorer(CA_ConfidenceScorer *hConfidenceScorer);
 
- 
+
   int CA_LoadConfidenceScorer(CA_ConfidenceScorer* hConfidenceScorer);
   /**
    *
diff --git a/srec/include/srec.h b/srec/include/srec.h
index 7569a73..ee124d1 100644
--- a/srec/include/srec.h
+++ b/srec/include/srec.h
@@ -277,7 +277,7 @@
   arcID max_fsm_arcs;             /* see multi_srec below */
   asr_int16_t srec_ended;
   AstarStack *astar_stack;        /* for backwards word search */
-  featdata* avg_state_durations;  /* average state durations (from AMs) */
+  const featdata* avg_state_durations;  /* average state durations (from AMs) */
 
   srec_eos_detector_state eosd_state;
 };
@@ -311,7 +311,7 @@
 
   /* non owning pointer to compact acoustic models */
   asr_int32_t num_swimodels;
-  SWIModel    *swimodel[MAX_ACOUSTIC_MODELS];
+  const SWIModel    *swimodel[MAX_ACOUSTIC_MODELS];
   EOSrc eos_status;
 }
 multi_srec;
diff --git a/srec/include/swimodel.h b/srec/include/swimodel.h
index e06ddc2..906f0a1 100644
--- a/srec/include/swimodel.h
+++ b/srec/include/swimodel.h
@@ -11,7 +11,7 @@
  *                                                                           *
  *  Unless required by applicable law or agreed to in writing, software      *
  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  *  See the License for the specific language governing permissions and      *
  *  limitations under the License.                                           *
  *                                                                           *
@@ -25,8 +25,6 @@
 #include "srec_sizes.h"
 #include "PortExport.h"
 
-#define MAXduration 255
-#define DURATION_MODEL_OFF 0  /* off for one particular pel */
 
 /**
  * @todo document
@@ -36,9 +34,9 @@
   short num_pdfs;           /* number of pdfs for this state */
   /* featdata avg_durn;           average state duration, belongs here but stored
      elsewhere to avoid paging back to memory of acoustic models, c54!! */
-  featdata *means;            /* pointer to block of means for the set
+  const featdata *means;            /* pointer to block of means for the set
        of pdfs (points into the allmeans array)*/
-  wtdata *weights;            /*pointer to weights*/
+  const wtdata *weights;            /*pointer to weights*/
 }
 SWIhmmState;
 
@@ -47,18 +45,15 @@
  */
 typedef struct
 {
-  void* mem_image;              /* if set, contains a pointer to one chunk of memory which contains
-         the entire models.  This allows us to read and write the models
-         in one shot.  The function setup_model_pointers_from_image sets up
-         the pointers in these structures*/
-  int image_size;
+  void* mmap_zip_data;          /* mmap file in one chunk */
+  size_t mmap_zip_size;         /* size of above */
   modelID num_hmmstates;        /* number of hmm states ~ 800 */
   short num_dims;               /* feature vector dimensions ~ 36 or 28 */
   modelID num_pdfs;             /* total number of pdfs ~ 4800 */
-  SWIhmmState *hmmstates;       /* size num_hmmstates ~ 800*/
-  featdata    *allmeans;        /* size num_dims*num_pdfs ~ 36*4800 */
-  wtdata    *allweights;        /* size num_pdfs ~ 4800 */
-  featdata *avg_state_durations; /* average duration of this acoustic model state */
+  const SWIhmmState *hmmstates;       /* size num_hmmstates ~ 800*/
+  const featdata *allmeans;        /* size num_dims*num_pdfs ~ 36*4800 */
+  const wtdata *allweights;        /* size num_pdfs ~ 4800 */
+  const featdata *avg_state_durations; /* average duration of this acoustic model state */
 }
 SWIModel;
 
@@ -68,24 +63,24 @@
 #endif
 
 /* SpeechWorks compact acoustic models */
-SWIModel *load_swimodel(char *filename);
-void free_swimodel(SWIModel* swimodel);
-scodata mixture_diagonal_gaussian_swimodel(preprocessed *prep, SWIhmmState *spd, short num_dims);
-  
-  extern char loop_cost_table [128][6];
-  extern char trans_cost_table [128][6];
+const SWIModel *load_swimodel(const char *filename);
+void free_swimodel(const SWIModel* swimodel);
+scodata mixture_diagonal_gaussian_swimodel(const preprocessed *prep, const SWIhmmState *spd, short num_dims);
+
+extern const char loop_cost_table [128][6];
+extern const char trans_cost_table [128][6];
 
 #ifdef __cplusplus
 }
 #endif
 
 
-/* the looping cost for the new duration model. In this new duration model, 
+/* the looping cost for the new duration model. In this new duration model,
    the looping probability is multiplied by a sigmoid function having the
-   following form: sigm(-scale(duration_so_far-offset))  so that the looping 
-   cost increases as the duration_so_far increases and encouraging to 
-   stay within a given state for a duration approx. equal to the average state 
-   duration. The looping cost values are implemented as a lookup table.*/ 
+   following form: sigm(-scale(duration_so_far-offset))  so that the looping
+   cost increases as the duration_so_far increases and encouraging to
+   stay within a given state for a duration approx. equal to the average state
+   duration. The looping cost values are implemented as a lookup table.*/
 
 static PINLINE costdata duration_penalty_loop(frameID average_duration, frameID duration_so_far)
 {
@@ -95,10 +90,10 @@
 }
 
 /* the transition cost for the new duration model. In this new duration model,
-   the transition probability is multiplied by a sigmoid function having the 
-   following form: sigm(scale(duration_so_far-offset)) so that the  transition 
-   cost decreases as the duration_so_far increases thus encouraging to leave 
-   a given state when the duration exceeds the average state duration. The transition 
+   the transition probability is multiplied by a sigmoid function having the
+   following form: sigm(scale(duration_so_far-offset)) so that the  transition
+   cost decreases as the duration_so_far increases thus encouraging to leave
+   a given state when the duration exceeds the average state duration. The transition
    cost values are implemented as a lookup table*/
 
 static PINLINE costdata duration_penalty_depart(frameID average_duration, frameID duration_so_far)
diff --git a/tools/grxmlcompile/grph.h b/tools/grxmlcompile/grph.h
index 5478728..a66f1d2 100644
--- a/tools/grxmlcompile/grph.h
+++ b/tools/grxmlcompile/grph.h
@@ -23,22 +23,21 @@
 class Graph
 {
 public:
-    Graph (char *name)
+    Graph (const char *name)
     {
         int count= strlen(name);
         title= new char [count+1];
         strcpy (title, name);
         numSubGraph= 0;
-        return;
+        subGraph= 0;
+        subIndex= 0;
     };
 
     ~Graph()
     {
-	  delete [] subGraph;
-	  delete [] subIndex;
-	if (title) {
-	    delete [] title;
-	}
+        delete [] subGraph;
+        delete [] subIndex;
+        delete [] title;
     }
 
     int addSubGraph (SubGraph *subGraph);
@@ -60,12 +59,12 @@
 
     void ExpandRules (SubGraph *subg);
 
+private:
+
     int         numSubGraph;
     SubGraph    **subGraph;
     int         *subIndex;
 
-private:
-
     int getSubGraphIndex (int subId);
 
     char        *title;