Index: run.py
===================================================================
--- run.py	(revision 832fea2242122fcdfebdb7c182d628de342fa304)
+++ run.py	(revision 18e73093a1cac56cb9c9fb237df8a08062ab6d5f)
@@ -72,6 +72,6 @@
     platform = '%s-%s'%(get_platform(),sys.version[:3])
     build_path = joinpath(root, 'build','lib.'+platform)
-    
-    # Notify the help menu that the Sphinx documentation is in a different 
+
+    # Notify the help menu that the Sphinx documentation is in a different
     # place than it otherwise would be.
     os.environ['SASVIEW_DOC_PATH'] = joinpath(build_path, "doc")
@@ -123,4 +123,10 @@
     # Compiled modules need to be pulled from the build directory.
     # Some packages are not where they are needed, so load them explicitly.
+    import sas.sascalc.file_converter
+    sas.sascalc.file_converter.core = import_package('sas.sascalc.file_converter.core',
+                                  joinpath(build_path, 'sas', 'sascalc', 'file_converter', 'core'))                    
+
+    # Compiled modules need to be pulled from the build directory.
+    # Some packages are not where they are needed, so load them explicitly.
     import sas.sascalc.calculator
     sas.sascalc.calculator.core = import_package('sas.sascalc.calculator.core',
Index: setup.py
===================================================================
--- setup.py	(revision db74ee8a320f0a42c88c2773f8915d72f3ae9f32)
+++ setup.py	(revision 18e73093a1cac56cb9c9fb237df8a08062ab6d5f)
@@ -9,4 +9,5 @@
 from distutils.command.build_ext import build_ext
 from distutils.core import Command
+import numpy
 
 # Manage version number ######################################
@@ -54,10 +55,10 @@
         print "Removing existing build directory", SASVIEW_BUILD, "for a clean build"
         shutil.rmtree(SASVIEW_BUILD)
-                    
+
 # 'sys.maxsize' and 64bit: Not supported for python2.5
 is_64bits = False
 if sys.version_info >= (2, 6):
     is_64bits = sys.maxsize > 2**32
-    
+
 enable_openmp = False
 
@@ -118,5 +119,5 @@
         c = self.compiler.compiler_type
         print "Compiling with %s (64bit=%s)" % (c, str(is_64bits))
-        
+
         # OpenMP build options
         if enable_openmp:
@@ -127,5 +128,5 @@
                 for e in self.extensions:
                     e.extra_link_args = lopt[ c ]
-                    
+
         # Platform-specific build options
         if platform_lopt.has_key(c):
@@ -205,5 +206,5 @@
 )
 
-    
+
 # sas.sascalc.pr
 srcdir  = os.path.join("src", "sas", "sascalc", "pr", "c_extensions")
@@ -217,5 +218,15 @@
                               include_dirs=[],
                               ) )
-        
+
+# sas.sascalc.file_converter
+mydir = os.path.join("src", "sas", "sascalc", "file_converter", "c_ext")
+package_dir["sas.sascalc.file_converter.core"] = mydir
+package_dir["sas.sascalc.file_converter"] = os.path.join("src","sas", "sascalc", "file_converter")
+packages.extend(["sas.sascalc.file_converter","sas.sascalc.file_converter.core"])
+ext_modules.append( Extension("sas.sascalc.file_converter.core.bsl_loader",
+                              sources = [os.path.join(mydir, "bsl_loader.c")],
+                              include_dirs=[numpy.get_include()],
+                              ) )
+
 # sas.sascalc.fit
 package_dir["sas.sascalc.fit"] = os.path.join("src", "sas", "sascalc", "fit")
@@ -239,5 +250,5 @@
 packages.extend(["sas.sasgui.perspectives", "sas.sasgui.perspectives.calculator"])
 package_data['sas.sasgui.perspectives.calculator'] = ['images/*', 'media/*']
-    
+
 # Data util
 package_dir["sas.sascalc.data_util"] = os.path.join("src", "sas", "sascalc", "data_util")
@@ -294,5 +305,5 @@
                                'test/2d_data/*',
                                'test/save_states/*',
-                               'test/upcoming_formats/*', 
+                               'test/upcoming_formats/*',
                                  'default_categories.json']
 packages.append("sas.sasview")
@@ -316,5 +327,5 @@
     required.extend(['pillow'])
 
-# Set up SasView    
+# Set up SasView
 setup(
     name="sasview",
@@ -341,3 +352,3 @@
                 'docs': BuildSphinxCommand,
                 'disable_openmp': DisableOpenMPCommand}
-    )   
+    )
Index: src/sas/sascalc/file_converter/BSLLoader.py
===================================================================
--- src/sas/sascalc/file_converter/BSLLoader.py	(revision 18e73093a1cac56cb9c9fb237df8a08062ab6d5f)
+++ src/sas/sascalc/file_converter/BSLLoader.py	(revision 18e73093a1cac56cb9c9fb237df8a08062ab6d5f)
@@ -0,0 +1,16 @@
+from sas.sascalc.file_converter.core.bsl_loader import CLoader
+
+class BSLLoader(CLoader):
+
+    # See invertor.py for implementation of pickling and setters/getters
+
+
+    # def __setattr__(self, name, value):
+    #     # if name == 'param':
+    #     #     return self.set_param(value)
+    #     return CBSLLoader.__set_attr__(self, name, value)
+    #
+    # def __getattr__(self, name):
+    #     if name == 'val':
+    #         return self.get_val()
+    #     return CBSLLoader.__getattr__(self, name)
Index: src/sas/sascalc/file_converter/c_ext/bsl_loader.c
===================================================================
--- src/sas/sascalc/file_converter/c_ext/bsl_loader.c	(revision 18e73093a1cac56cb9c9fb237df8a08062ab6d5f)
+++ src/sas/sascalc/file_converter/c_ext/bsl_loader.c	(revision 18e73093a1cac56cb9c9fb237df8a08062ab6d5f)
@@ -0,0 +1,164 @@
+#include <Python.h>
+#include <numpy/arrayobject.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "structmember.h"
+#include "bsl_loader.h"
+
+typedef struct {
+    PyObject_HEAD
+    CLoader_params params;
+} CLoader;
+
+static PyObject *CLoader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
+    CLoader *self;
+
+    self = (CLoader *)type->tp_alloc(type, 0);
+
+    return (PyObject *)self;
+}
+
+static PyObject *CLoader_init(CLoader *self, PyObject *args, PyObject *kwds) {
+    const char *filename;
+    const int frame;
+    const int n_pixels;
+    const int n_rasters;
+    if (self != NULL) {
+        if (!PyArg_ParseTuple(args, "siii", &filename, &frame, &n_pixels, &n_rasters))
+            Py_RETURN_NONE;
+        if (!(self->params.filename = malloc(strlen(filename) + 1)))
+            Py_RETURN_NONE;
+        strcpy(self->params.filename, filename);
+        self->params.n_pixels = n_pixels;
+        self->params.n_rasters = n_rasters;
+    }
+
+    return 0;
+}
+
+static void CLoader_dealloc(CLoader *self) {
+    free(self->params.filename);
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *to_string(CLoader *self, PyObject *params) {
+    char str[100];
+    sprintf(str,
+        "Filename: %s\nframe: %d\nn_pixels: %d\nn_rasters: %d\n",
+        self->params.filename,
+        self->params.frame,
+        self->params.n_pixels,
+        self->params.n_rasters);
+    return Py_BuildValue("s", str);
+}
+
+static PyObject *load_data(CLoader *self, PyObject *args) {
+    int raster;
+    int pixel;
+    int frame_pos;
+    int size[2] = {self->params.n_rasters, self->params.n_pixels};
+    float cur_val;
+    PyObject *read_val;
+    FILE *input_file;
+    PyArrayObject *data;
+
+    printf("load_data called\n");
+
+    if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &data)) {
+        printf("Failed parsing PyArray object");
+        return NULL;
+    }
+
+    input_file = fopen(self->params.filename, "rb");
+    if (!input_file) {
+        printf("Failed opening file\n");
+        return NULL;
+    }
+
+    printf("Calculating frame_pos\n");
+    frame_pos = self->params.n_pixels * self->params.n_rasters * self->params.frame;
+    printf("frame_pos: %d\n", frame_pos);
+    fseek(input_file, frame_pos*sizeof(float), SEEK_SET);
+    printf("fseek completed\n");
+
+    for (raster = 0; raster < self->params.n_rasters; raster++) {
+        for (pixel = 0; pixel < self->params.n_pixels; pixel++) {
+            fread(&cur_val, sizeof(float), 1, input_file);
+            PyArray_SETITEM(data, PyArray_GETPTR2(data, raster, pixel), PyFloat_FromDouble(cur_val));
+            read_val = PyArray_GETITEM(data, PyArray_GETPTR2(data, raster, pixel));
+        }
+    }
+    printf("Data read.\n");
+
+    fclose(input_file);
+    printf("File closed\n");
+    Py_DECREF(data);
+    printf("Function completed\n");
+    return Py_BuildValue("O", data);
+}
+
+static PyMethodDef CLoader_methods[] = {
+    { "to_string", (PyCFunction)to_string, METH_VARARGS, "Print the objects params" },
+    {"load_data", (PyCFunction)load_data, METH_VARARGS, "Load the data into a numpy array"},
+    {NULL}
+};
+
+static PyMemberDef CLoader_members[] = {
+    {NULL}
+};
+
+static PyTypeObject CLoaderType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLoader",             /*tp_name*/
+    sizeof(CLoader),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLoader_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CLoader objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLoader_methods,             /* tp_methods */
+    CLoader_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLoader_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLoader_new,                 /* tp_new */
+};
+
+PyMODINIT_FUNC
+initbsl_loader(void)
+{
+    PyObject *module;
+    module = Py_InitModule("bsl_loader", NULL);
+    import_array();
+
+    if (PyType_Ready(&CLoaderType) < 0)
+        return;
+
+    Py_INCREF(&CLoaderType);
+    PyModule_AddObject(module, "CLoader", (PyObject *)&CLoaderType);
+}
Index: src/sas/sascalc/file_converter/c_ext/bsl_loader.h
===================================================================
--- src/sas/sascalc/file_converter/c_ext/bsl_loader.h	(revision 18e73093a1cac56cb9c9fb237df8a08062ab6d5f)
+++ src/sas/sascalc/file_converter/c_ext/bsl_loader.h	(revision 18e73093a1cac56cb9c9fb237df8a08062ab6d5f)
@@ -0,0 +1,15 @@
+#ifndef bsl_loader_h
+#define bsl_loader_h
+
+typedef struct {
+    // File to load
+    char *filename;
+    // Frame to load
+    int frame;
+    // Number of pixels in the file
+    int n_pixels;
+    // Number of rasters in the file
+    int n_rasters;
+} CLoader_params;
+
+#endif
