Full Code of pytorch/accimage for AI

master 15ec9d4a9506 cached
14 files
32.1 KB
8.6k tokens
26 symbols
1 requests
Download .txt
Repository: pytorch/accimage
Branch: master
Commit: 15ec9d4a9506
Files: 14
Total size: 32.1 KB

Directory structure:
gitextract_k0q0dap3/

├── .github/
│   └── workflows/
│       └── accimage.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── accimage.h
├── accimagemodule.c
├── imageops.c
├── jpegloader.c
├── setup.py
└── test.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/accimage.yml
================================================
name: Accimage (Ubuntu latest)
on: [push]
jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: ["ubuntu-latest"]
        python-version: [3.6, 3.7, 3.8, 3.9]
    steps:
      - uses: actions/checkout@v2

      - name: Set up conda
        uses: conda-incubator/setup-miniconda@v2
        with:
          auto-update-conda: true
          python-version: ${{ matrix.python-version }}

      - name: Conda info
        shell: bash -l {0}
        run: conda info -a

      - name: Install deps
        shell: bash -l {0}
        run: |
          conda install \
            -c pytorch \
            -c conda-forge \
            pip \
            scipy \
            numpy \
            intel-ipp \
            libjpeg-turbo
          pip install pytest imageio

      - name: Install Accimage
        shell: bash -l {0}
        run: |
          CPPFLAGS="-I$CONDA_PREFIX/include" LDFLAGS="-L$CONDA_PREFIX/lib" pip install . --no-deps -vv

      - name: Test Accimage
        shell: bash -l {0}
        run: |
          pytest test.py


================================================
FILE: .gitignore
================================================
#### joe made this: http://goel.io/joe

#####=== Python ===#####

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/

#####=== JetBrains ===#####
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Rider-specific rules
*.sln.iml

.ropeproject
test_*.jpg


================================================
FILE: .travis.yml
================================================
language: python
dist: xenial
sudo: true

matrix:
  include:
    - python: "2.7"
    - python: "3.5"
    - python: "3.6"
    - python: "3.7"

before_install:
  - sudo apt-get update
  - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
  - bash miniconda.sh -b -p $HOME/miniconda
  - export PATH="$HOME/miniconda/bin:$PATH"
  - hash -r
  - conda config --set always_yes yes --set changeps1 no
  - conda update -q conda
  # Useful for debugging any issues with conda
  - conda info -a
  - |
    conda create -q -n test-environment \
      -c pytorch \
      -c conda-forge \
      python=$TRAVIS_PYTHON_VERSION \
      pip \
      scipy \
      numpy \
      intel-ipp \
      libjpeg-turbo
  - source activate test-environment
  - pip install pytest imageio

install:
  - env | sort
  - ls $CONDA_PREFIX/include
  - ls $CONDA_PREFIX/lib
  - CPPFLAGS="-I$CONDA_PREFIX/include" LDFLAGS="-L$CONDA_PREFIX/lib" pip install . --no-deps -vv

script:
  - pytest test.py


================================================
FILE: CHANGELOG.md
================================================
# v0.2.0

* Add support to reading images from a `bytes` buffer, e.g.
  ```python
  with open("chicago.jpg", "rb") as f:
      img = accimage.Image(f.read())
  ```
  (This new functionality is thanks to @brhcriteo!)

# v0.1.1

* Bug fix: Horizontal crops prior to v0.1.1 didn't work.
* Add pytest tests.py
* Add travis building support

# v0.1.0

Initial release


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <opensource-conduct@fb.com>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to accimage
We want to make contributing to this project as easy and transparent as
possible.

## Pull Requests
We actively welcome your pull requests.

1. Fork the repo and create your branch from `master`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
4. Ensure the test suite passes.
5. Make sure your code lints.
6. If you haven't already, complete the Contributor License Agreement ("CLA").

## Issues
We use GitHub issues to track public bugs. Please ensure your description is
clear and has sufficient instructions to be able to reproduce the issue.

## License
By contributing to accimage, you agree that your contributions will be licensed
under the LICENSE file in the root directory of this source tree.


================================================
FILE: LICENSE
================================================
BSD 2-Clause License

Copyright (c) 2017, Facebook, Inc
Copyright (c) 2016, Georgia Institute of Technology
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: README.md
================================================
# accimage

[![Build status](https://github.com/pytorch/accimage/actions/workflows/accimage.yml/badge.svg)](https://github.com/pytorch/accimage/actions/workflows/accimage.yml)
[![Anaconda badge](https://anaconda.org/conda-forge/accimage/badges/version.svg)](https://anaconda.org/conda-forge/accimage)


An accelerated Image loader and preprocessor leveraging [Intel
IPP](https://software.intel.com/en-us/intel-ipp).

accimage mimics the PIL API and can be used as a backend for
[`torchvision`](https://github.com/pytorch/vision).

Operations implemented:

- `Image.resize((width, height))`
- `Image.crop((left, upper, right, lower))`
- `Image.transpose(PIL.Image.FLIP_LEFT_RIGHT)`

Enable the torchvision accimage backend with:

```python
torchvision.set_image_backend('accimage')
```

## Installation

accimage is available on conda-forge, simply run the following to install

```
$ conda install -c conda-forge accimage
```


================================================
FILE: accimage.h
================================================
#ifndef ACCIMAGE_H
#define ACCIMAGE_H

#include <Python.h>

typedef struct {
    PyObject_HEAD
    unsigned char* buffer;
    int channels;
    int height;
    int width;
    int row_stride;
    int y_offset;
    int x_offset;
} ImageObject;

void image_copy_deinterleave(ImageObject* self, unsigned char* output_buffer);
void image_copy_deinterleave_float(ImageObject* self, float* output_buffer);
void image_from_buffer(ImageObject* self, void* buf, size_t size);
void image_from_jpeg(ImageObject* self, const char* path);
void image_resize(ImageObject* self, int new_height, int new_width, int antialiasing);
void image_flip_left_right(ImageObject* self);

#endif


================================================
FILE: accimagemodule.c
================================================
#include <Python.h>
#include <structmember.h>

#include "accimage.h"

static struct PyMemberDef Image_members[] = {
    { "channels", T_INT, offsetof(ImageObject, channels), READONLY, "number of channels" },
    { "height",   T_INT, offsetof(ImageObject, height),   READONLY, "image height in pixels" },
    { "width",    T_INT, offsetof(ImageObject, width),    READONLY, "image width in pixels" },
    { NULL }  /* Sentinel */
};

static PyObject* Image_getsize(ImageObject* self, void* closure) {
    return Py_BuildValue("ii", self->width, self->height);
}

static PyGetSetDef Image_getseters[] = {
    { "size", (getter) Image_getsize, (setter) NULL, "Image width x height", NULL },
    { NULL }  /* Sentinel */
};

static PyObject* Image_resize(ImageObject* self, PyObject* args, PyObject* kwds) {
    static char* argnames[] = { "size", "interpolation", NULL };
    PyObject* size = NULL;
    int interpolation = 0;
    int antialiasing = 1;
    int new_height, new_width;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i", argnames, &size, &interpolation)) {
        return NULL;
    }

    if (!PyArg_ParseTuple(size, "ii", &new_width, &new_height)) {
        return NULL;
    }

    if (new_height <= 0) {
        return PyErr_Format(PyExc_ValueError, "positive height expected; got %d", new_height);
    }

    if (new_width <= 0) {
        return PyErr_Format(PyExc_ValueError, "positive width expected; got %d", new_width);
    }

    // TODO: consider interpolation parameter
    image_resize(self, new_height, new_width, antialiasing);

    if (PyErr_Occurred()) {
        return NULL;
    } else {
        Py_INCREF(self);
        return (PyObject*) self;
    }
}

static PyObject* Image_crop(ImageObject* self, PyObject* args, PyObject* kwds) {
    static char* argnames[] = { "box", NULL };
    PyObject* box_object;
    int left, upper, right, lower;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", argnames, &box_object)) {
        return NULL;
    }

    if (!PyArg_ParseTuple(box_object, "iiii", &left, &upper, &right, &lower)) {
        return NULL;
    }

    if (left < 0) {
        return PyErr_Format(PyExc_ValueError, "non-negative left offset expected; got %d", left);
    }

    if (upper < 0) {
        return PyErr_Format(PyExc_ValueError, "non-negative upper offset expected; got %d", upper);
    }

    if (right > self->width) {
        return PyErr_Format(PyExc_ValueError, "right coordinate (%d) extends beyond image width (%d)",
            right, self->width);
    }

    if (lower > self->height) {
        return PyErr_Format(PyExc_ValueError, "lower coordinate (%d) extends beyond image height (%d)",
            lower, self->height);
    }

    if (right <= left) {
        return PyErr_Format(PyExc_ValueError, "right coordinate (%d) does not exceed left coordinate (%d)",
            right, left);
    }

    if (lower <= upper) {
        return PyErr_Format(PyExc_ValueError, "lower coordinate (%d) does not exceed upper coordinate (%d)",
            lower, upper);
    }

    self->y_offset += upper;
    self->x_offset += left;
    self->height = lower - upper;
    self->width = right - left;

    Py_INCREF(self);
    return (PyObject*) self;
}

static PyObject* Image_transpose(ImageObject* self, PyObject* args, PyObject* kwds) {
    static char* argnames[] = { "method", NULL };
    int method;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", argnames, &method))
        return NULL;

    switch (method) {
        case 0:
            /* PIL.Image.FLIP_LEFT_RIGHT */
            image_flip_left_right(self);
            break;
        case 1:
            PyErr_SetString(PyExc_ValueError, "unsupported method: PIL.Image.FLIP_TOP_BOTTOM");
            return NULL;
        case 2:
            PyErr_SetString(PyExc_ValueError, "unsupported method: PIL.Image.ROTATE_90");
            return NULL;
        case 3:
            PyErr_SetString(PyExc_ValueError, "unsupported method: PIL.Image.ROTATE_180");
            return NULL;
        case 4:
            PyErr_SetString(PyExc_ValueError, "unsupported method: PIL.Image.ROTATE_270");
            return NULL;
        case 5:
            PyErr_SetString(PyExc_ValueError, "unsupported method: PIL.Image.TRANSPOSE");
            return NULL;
        default:
            return PyErr_Format(PyExc_ValueError, "unknown method (%d)", method);
    }

    if (PyErr_Occurred()) {
        return NULL;
    } else {
        Py_INCREF(self);
        return (PyObject*) self;
    }
}

static PyObject* Image_copyto(ImageObject* self, PyObject* args, PyObject* kwds) {
    static char* argnames[] = { "buffer", NULL };
    static const int FLAGS = PyBUF_CONTIG | PyBUF_FORMAT;
    PyObject* buffer_object;
    Py_buffer buffer;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", argnames, &buffer_object)) {
        return NULL;
    }

    if (PyObject_GetBuffer(buffer_object, &buffer, FLAGS) < 0) {
        return NULL;
    }

    int expected_size = self->channels * self->height * self->width;
    if (strcmp(buffer.format, "f") == 0) {
      expected_size *= sizeof(float);
    }

    if (buffer.len < expected_size) {
        PyErr_Format(PyExc_IndexError, "buffer size (%lld) is smaller than image size (%d)",
            (long long) buffer.len, expected_size);
        goto cleanup;
    }

    if (buffer.format == NULL || strcmp(buffer.format, "B") == 0) {
        image_copy_deinterleave(self, (unsigned char*) buffer.buf);
    } else if (strcmp(buffer.format, "f") == 0) {
        image_copy_deinterleave_float(self, (float*) buffer.buf);
    } else {
        PyErr_SetString(PyExc_TypeError, "buffer of unsigned byte or float elements expected");
        goto cleanup;
    }


cleanup:
    PyBuffer_Release(&buffer);

    if (PyErr_Occurred()) {
        return NULL;
    } else {
        Py_RETURN_NONE;
    }
}

static PyMethodDef Image_methods[] = {
    { "resize",    (PyCFunction) Image_resize,    METH_VARARGS | METH_KEYWORDS, "Scale image to new size." },
    { "crop",      (PyCFunction) Image_crop,      METH_VARARGS | METH_KEYWORDS, "Crop image to new size." },
    { "transpose", (PyCFunction) Image_transpose, METH_VARARGS | METH_KEYWORDS, "Transpose/flip/rotate image." },
    { "copyto",    (PyCFunction) Image_copyto,    METH_VARARGS | METH_KEYWORDS, "Copy data to a buffer." },
    { NULL }  /* Sentinel */
};

static PyTypeObject Image_Type = {
    /* The ob_type field must be initialized in the module init function
     * to be portable to Windows without using C++. */
    PyVarObject_HEAD_INIT(NULL, 0)
    "accimage.Image",           /*tp_name*/
    sizeof(ImageObject),        /*tp_basicsize*/
    0,                          /*tp_itemsize*/
    /* methods */
    0, /* see initaccimage */   /*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*/
    0,                          /*tp_doc*/
    0,                          /*tp_traverse*/
    0,                          /*tp_clear*/
    0,                          /*tp_richcompare*/
    0,                          /*tp_weaklistoffset*/
    0,                          /*tp_iter*/
    0,                          /*tp_iternext*/
    Image_methods,              /*tp_methods*/
    Image_members,              /*tp_members*/
    Image_getseters,            /*tp_getset*/
    0, /* see initaccimage */   /*tp_base*/
    0,                          /*tp_dict*/
    0,                          /*tp_descr_get*/
    0,                          /*tp_descr_set*/
    0,                          /*tp_dictoffset*/
    0, /* see initaccimage */   /*tp_init*/
    0,                          /*tp_alloc*/
    0, /* see initaccimage */   /*tp_new*/
    0,                          /*tp_free*/
    0,                          /*tp_is_gc*/
};

static int Image_init(ImageObject *self, PyObject *args, PyObject *kwds) {
    const char *path;

    if (PyArg_ParseTuple(args, "s", &path)) {
        image_from_jpeg(self, path);
    }
    else {
        Py_buffer buffer;

        PyErr_Clear();
        if (PyArg_ParseTuple(args, "y*", &buffer)) {
            void* buf = buffer.buf;
            Py_ssize_t size = buffer.len;
            image_from_buffer(self, buf, size);
            PyBuffer_Release(&buffer);
        }
    }

    return PyErr_Occurred() ? -1 : 0;
}

static void Image_dealloc(ImageObject *self) {
    if (self->buffer != NULL) {
        free(self->buffer);
        self->buffer = NULL;
    }
}

#if PY_MAJOR_VERSION == 2
PyMODINIT_FUNC initaccimage(void) {
#else
PyMODINIT_FUNC PyInit_accimage(void) {
#endif
    PyObject* m;

    /*
     * Due to cross platform compiler issues the slots must be filled here.
     * It's required for portability to Windows without requiring C++.
     */
    Image_Type.tp_base = &PyBaseObject_Type;
    Image_Type.tp_init = (initproc) Image_init;
    Image_Type.tp_dealloc = (destructor) Image_dealloc;
    Image_Type.tp_new = PyType_GenericNew;

#if PY_MAJOR_VERSION == 2
    m = Py_InitModule("accimage", NULL);
#else
    static struct PyModuleDef module_def = {
       PyModuleDef_HEAD_INIT,
       "accimage",
       NULL,
       -1,
       NULL
    };
    m = PyModule_Create(&module_def);
#endif

    if (m == NULL)
        goto err;

    if (PyType_Ready(&Image_Type) < 0)
        goto err;

    PyModule_AddObject(m, "Image", (PyObject*) &Image_Type);

#if PY_MAJOR_VERSION == 2
    return;
#else
    return m;
#endif

err:
#if PY_MAJOR_VERSION == 2
    return;
#else
    return NULL;
#endif
}


================================================
FILE: imageops.c
================================================
#include "accimage.h"

#include <stdlib.h>

#include <ippi.h>


void image_copy_deinterleave(ImageObject* self, unsigned char* output_buffer) {
    unsigned char* channel_buffers[3] = {
        output_buffer,
        output_buffer + self->height * self->width,
        output_buffer + 2 * self->height * self->width
    };
    IppiSize roi = { self->width, self->height };
    IppStatus ipp_status = ippiCopy_8u_C3P3R(
        self->buffer + (self->y_offset * self->row_stride + self->x_offset) * self->channels,
        self->row_stride * self->channels,
        channel_buffers, self->width, roi);
    if (ipp_status != ippStsNoErr) {
        PyErr_Format(PyExc_SystemError, "ippiCopy_8u_C3P3R failed with status %d", ipp_status);
    }
}


void image_copy_deinterleave_float(ImageObject* self, float* output_buffer) {
    unsigned char* tmp_buffer = NULL;
    IppiSize roi = { self->width, self->height };

    tmp_buffer = malloc(self->height * self->width * self->channels);
    if (!tmp_buffer) {
        PyErr_NoMemory();
        goto cleanup;
    }

    image_copy_deinterleave(self, tmp_buffer);
    if (PyErr_Occurred()) {
      goto cleanup;
    }

    IppStatus ipp_status = ippiConvert_8u32f_C3R(
        tmp_buffer, self->width * self->channels,
        output_buffer, self->width * self->channels * sizeof(float),
        roi);
    if (ipp_status != ippStsNoErr) {
        PyErr_Format(PyExc_SystemError, "ippiConvert_8u32f_C3R failed with status %d", ipp_status);
    }

    Ipp32f value[3] = {255.0f, 255.0f, 255.0f};
    ipp_status = ippiDivC_32f_C3IR(
        value, output_buffer, self->width * self->channels * sizeof(float),
        roi);
    if (ipp_status != ippStsNoErr) {
        PyErr_Format(PyExc_SystemError, "ippiDivC_32f_C3IR failed with status %d", ipp_status);
    }

cleanup:
    free(tmp_buffer);
}


void image_resize(ImageObject* self, int new_height, int new_width, int antialiasing) {
    IppStatus ipp_status;
    unsigned char* new_buffer = NULL;
    IppiSize old_size = { self->width, self->height };
    IppiSize new_size = { new_width, new_height };
    IppiPoint new_offset = { 0, 0 };
    int specification_size = 0, initialization_buffer_size = 0, scratch_buffer_size = 0;
    IppiResizeSpec_32f* specification = NULL;
    Ipp8u* scratch_buffer = NULL;
    Ipp8u* initialization_buffer = NULL;

    new_buffer = malloc(new_height * new_width * self->channels);
    if (new_buffer == NULL) {
        PyErr_NoMemory();
        goto cleanup;
    }

    ipp_status = ippiResizeGetSize_8u(old_size, new_size, ippLinear, antialiasing,
        &specification_size, &initialization_buffer_size);
    if (ipp_status != ippStsNoErr) {
        PyErr_Format(PyExc_SystemError,
            "ippiResizeGetSize_8u failed with status %d", ipp_status);
        goto cleanup;
    }

    initialization_buffer = malloc(initialization_buffer_size);
    if (initialization_buffer == NULL) {
        PyErr_NoMemory();
        goto cleanup;
    }

    specification = malloc(specification_size);
    if (specification == NULL) {
        PyErr_NoMemory();
        goto cleanup;
    }

    if (antialiasing) {
      ipp_status = ippiResizeAntialiasingLinearInit(
          old_size, new_size, specification, initialization_buffer);
    } else {
      ipp_status = ippiResizeLinearInit_8u(old_size, new_size, specification);
    }
    if (ipp_status != ippStsNoErr) {
        PyErr_Format(PyExc_SystemError,
            "ippiResizeLinearInit_8u failed with status %d", ipp_status);
        goto cleanup;
    }

    ipp_status = ippiResizeGetBufferSize_8u(specification, new_size, self->channels, &scratch_buffer_size);
    if (ipp_status != ippStsNoErr) {
        PyErr_Format(PyExc_SystemError,
            "ippiResizeGetBufferSize_8u failed with status %d", ipp_status);
        goto cleanup;
    }

    scratch_buffer = malloc(scratch_buffer_size);
    if (scratch_buffer == NULL) {
        PyErr_NoMemory();
        goto cleanup;
    }

    if (antialiasing) {
      ipp_status = ippiResizeAntialiasing_8u_C3R(
          self->buffer + (self->y_offset * self->row_stride + self->x_offset) * self->channels,
          self->row_stride * self->channels,
          new_buffer, new_width * self->channels, new_offset, new_size,
          ippBorderRepl, NULL, specification, scratch_buffer);
    } else {
      ipp_status = ippiResizeLinear_8u_C3R(
          self->buffer + (self->y_offset * self->row_stride + self->x_offset) * self->channels,
          self->row_stride * self->channels,
          new_buffer, new_width * self->channels, new_offset, new_size,
          ippBorderRepl, NULL, specification, scratch_buffer);
    }
    if (ipp_status != ippStsNoErr) {
        PyErr_Format(PyExc_SystemError,
            "ippiResizeLinear_8u_C3R failed with status %d", ipp_status);
        goto cleanup;
    }

    free(self->buffer);
    self->buffer = new_buffer;
    new_buffer = NULL;

    self->height = new_height;
    self->width = new_width;
    self->row_stride = new_width;
    self->x_offset = 0;
    self->y_offset = 0;

cleanup:
    free(new_buffer);
    free(specification);
    free(initialization_buffer);
    free(scratch_buffer);
}


void image_flip_left_right(ImageObject* self) {
    IppiSize roi = { self->width, self->height };
    IppStatus ipp_status = ippiMirror_8u_C3IR(
        self->buffer + (self->y_offset * self->row_stride + self->x_offset) * self->channels,
        self->row_stride * self->channels, 
        roi, ippAxsVertical);
    if (ipp_status != ippStsNoErr)
        PyErr_Format(PyExc_SystemError, "ippiMirror_8u_C3IR failed with status %d", ipp_status);
}


================================================
FILE: jpegloader.c
================================================
#include "accimage.h"

#include <setjmp.h>

#include <jpeglib.h>
#ifndef LIBJPEG_TURBO_VERSION
    #error libjpeg-turbo required (not IJG libjpeg)
#endif


struct accimage_jpeg_error_mgr {
    struct jpeg_error_mgr pub;
    jmp_buf setjmp_buffer;
};


static void accimage_jpeg_error_exit(j_common_ptr cinfo) {
    struct accimage_jpeg_error_mgr* accimage_err = (struct accimage_jpeg_error_mgr*) cinfo->err;
    longjmp(accimage_err->setjmp_buffer, 1);
}


void image_from_file(ImageObject* self, FILE* file) {
    struct jpeg_decompress_struct state = { 0 };
    struct accimage_jpeg_error_mgr jpeg_error;
    unsigned char* buffer = NULL;

    state.err = jpeg_std_error(&jpeg_error.pub);
    jpeg_error.pub.error_exit = accimage_jpeg_error_exit;
    if (setjmp(jpeg_error.setjmp_buffer)) {
        char error_message[JMSG_LENGTH_MAX];
        (*state.err->format_message)((j_common_ptr) &state, error_message);
        PyErr_Format(PyExc_IOError, "JPEG decoding failed: %s", error_message);
        goto cleanup;
    }

    jpeg_create_decompress(&state);
    jpeg_stdio_src(&state, file);
    jpeg_read_header(&state, TRUE);

    state.dct_method = JDCT_ISLOW;
    state.output_components = 3;
    state.out_color_components = 3;
    state.out_color_space = JCS_RGB;

    jpeg_start_decompress(&state);

    buffer = malloc(state.output_components * state.output_width * state.output_height);
    if (buffer == NULL) {
        PyErr_NoMemory();
        goto cleanup;
    }

    while (state.output_scanline < state.output_height) {
        unsigned char* row = buffer + state.output_scanline * state.output_width * state.output_components;
        jpeg_read_scanlines(&state, &row, 1);
    }

    jpeg_finish_decompress(&state);

    /* Success. Commit object state */
    self->buffer = buffer;
    buffer = NULL;

    self->channels = 3;
    self->height = state.output_height;
    self->width = state.output_width;
    self->row_stride = state.output_width;
    self->y_offset = 0;
    self->x_offset = 0;

cleanup:
    jpeg_destroy_decompress(&state);

    free(buffer);

    if (file != NULL) {
        fclose(file);
    }
}

void image_from_buffer(ImageObject* self, void* buf, size_t size) {
    FILE* source = fmemopen(buf, size, "rb");
    if (source == NULL) {
        PyErr_Format(PyExc_IOError, "failed to call fmemopen on buffer");
        return;
    }

    image_from_file(self, source);
}

void image_from_jpeg(ImageObject* self, const char* path) {
    FILE* file = file = fopen(path, "rb");
    if (file == NULL) {
        PyErr_Format(PyExc_IOError, "failed to open file %s", path);
        return;
    }

    image_from_file(self, file);
}


================================================
FILE: setup.py
================================================
from distutils.core import setup, Extension

accimage = Extension(
    "accimage",
    include_dirs=["/usr/local/opt/jpeg-turbo/include", "/opt/intel/ipp/include"],
    libraries=["jpeg", "ippi", "ipps"],
    library_dirs=["/usr/local/opt/jpeg-turbo/lib", "/opt/intel/ipp/lib"],
    sources=["accimagemodule.c", "jpegloader.c", "imageops.c"],
)

setup(
    name="accimage",
    version="0.2.0",
    description="Accelerated image loader and preprocessor for Torch",
    author="Marat Dukhan",
    author_email="maratek@gmail.com",
    ext_modules=[accimage],
)


================================================
FILE: test.py
================================================
import accimage
import numpy as np
import imageio
import os

ACCIMAGE_SAVE = os.environ.get('ACCIMAGE_SAVE', '')
if len(ACCIMAGE_SAVE) and ACCIMAGE_SAVE.lower() not in {'0', 'false', 'no'}:
    SAVE_IMAGES = True
else:
    SAVE_IMAGES = False

def image_to_np(image):
    """
    Returns:
        np.ndarray: Image converted to array with shape (width, height, channels)
    """
    image_np = np.empty([image.channels, image.height, image.width], dtype=np.uint8)
    image.copyto(image_np)
    image_np = np.transpose(image_np, (1, 2, 0))
    return image_np


def save_image(path, image):
    imageio.imwrite(path, image_to_np(image))


def test_reading_image():
    image = accimage.Image("chicago.jpg")
    if SAVE_IMAGES:
        save_image('test_reading_image.jpg', image)
    assert image.width == 1920
    assert image.height == 931


def test_reading_image_from_memory():
    from_file = accimage.Image("chicago.jpg")
    bytes = open("chicago.jpg", "rb").read()
    from_bytes = accimage.Image(bytes)
    if SAVE_IMAGES:
        save_image('test_reading_image_from_memory.jpg', from_bytes)
    assert from_bytes.width == 1920
    assert from_bytes.height == 931
    np.testing.assert_array_equal(image_to_np(from_file), image_to_np(from_bytes))


def test_resizing():
    image = accimage.Image("chicago.jpg")

    image.resize(size=(200, 200))
    if SAVE_IMAGES:
        save_image('test_resizing.jpg', image)

    assert image.width == 200
    assert image.height == 200

def test_cropping():
    image = accimage.Image("chicago.jpg")

    image.crop(box=(50, 50, 150, 150))
    if SAVE_IMAGES:
        save_image('test_cropping.jpg', image)

    assert image.width == 100
    assert image.height == 100

def test_flipping():
    image = accimage.Image("chicago.jpg")
    original_image_np = image_to_np(image)

    FLIP_LEFT_RIGHT = 0
    image.transpose(FLIP_LEFT_RIGHT)
    if SAVE_IMAGES:
        save_image('test_flipping.jpg', image)

    new_image_np = image_to_np(image)
    assert image.width == 1920
    assert image.height == 931
    np.testing.assert_array_equal(new_image_np[:, ::-1, :], original_image_np)
Download .txt
gitextract_k0q0dap3/

├── .github/
│   └── workflows/
│       └── accimage.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── accimage.h
├── accimagemodule.c
├── imageops.c
├── jpegloader.c
├── setup.py
└── test.py
Download .txt
SYMBOL INDEX (26 symbols across 5 files)

FILE: accimage.h
  type ImageObject (line 6) | typedef struct {

FILE: accimagemodule.c
  type PyMemberDef (line 6) | struct PyMemberDef
  function PyObject (line 13) | static PyObject* Image_getsize(ImageObject* self, void* closure) {
  function PyObject (line 22) | static PyObject* Image_resize(ImageObject* self, PyObject* args, PyObjec...
  function PyObject (line 56) | static PyObject* Image_crop(ImageObject* self, PyObject* args, PyObject*...
  function PyObject (line 106) | static PyObject* Image_transpose(ImageObject* self, PyObject* args, PyOb...
  function PyObject (line 145) | static PyObject* Image_copyto(ImageObject* self, PyObject* args, PyObjec...
  function Image_init (line 244) | static int Image_init(ImageObject *self, PyObject *args, PyObject *kwds) {
  function Image_dealloc (line 265) | static void Image_dealloc(ImageObject *self) {
  function PyMODINIT_FUNC (line 275) | PyMODINIT_FUNC PyInit_accimage(void) {

FILE: imageops.c
  function image_copy_deinterleave (line 8) | void image_copy_deinterleave(ImageObject* self, unsigned char* output_bu...
  function image_copy_deinterleave_float (line 25) | void image_copy_deinterleave_float(ImageObject* self, float* output_buff...
  function image_resize (line 61) | void image_resize(ImageObject* self, int new_height, int new_width, int ...
  function image_flip_left_right (line 160) | void image_flip_left_right(ImageObject* self) {

FILE: jpegloader.c
  type accimage_jpeg_error_mgr (line 11) | struct accimage_jpeg_error_mgr {
  function accimage_jpeg_error_exit (line 17) | static void accimage_jpeg_error_exit(j_common_ptr cinfo) {
  function image_from_file (line 23) | void image_from_file(ImageObject* self, FILE* file) {
  function image_from_buffer (line 82) | void image_from_buffer(ImageObject* self, void* buf, size_t size) {
  function image_from_jpeg (line 92) | void image_from_jpeg(ImageObject* self, const char* path) {

FILE: test.py
  function image_to_np (line 12) | def image_to_np(image):
  function save_image (line 23) | def save_image(path, image):
  function test_reading_image (line 27) | def test_reading_image():
  function test_reading_image_from_memory (line 35) | def test_reading_image_from_memory():
  function test_resizing (line 46) | def test_resizing():
  function test_cropping (line 56) | def test_cropping():
  function test_flipping (line 66) | def test_flipping():
Condensed preview — 14 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (35K chars).
[
  {
    "path": ".github/workflows/accimage.yml",
    "chars": 1086,
    "preview": "name: Accimage (Ubuntu latest)\non: [push]\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: fa"
  },
  {
    "path": ".gitignore",
    "chars": 2212,
    "preview": "#### joe made this: http://goel.io/joe\n\n#####=== Python ===#####\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*"
  },
  {
    "path": ".travis.yml",
    "chars": 1004,
    "preview": "language: python\ndist: xenial\nsudo: true\n\nmatrix:\n  include:\n    - python: \"2.7\"\n    - python: \"3.5\"\n    - python: \"3.6\""
  },
  {
    "path": "CHANGELOG.md",
    "chars": 363,
    "preview": "# v0.2.0\n\n* Add support to reading images from a `bytes` buffer, e.g.\n  ```python\n  with open(\"chicago.jpg\", \"rb\") as f:"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3349,
    "preview": "# Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 795,
    "preview": "# Contributing to accimage\nWe want to make contributing to this project as easy and transparent as\npossible.\n\n## Pull Re"
  },
  {
    "path": "LICENSE",
    "chars": 1370,
    "preview": "BSD 2-Clause License\n\nCopyright (c) 2017, Facebook, Inc\nCopyright (c) 2016, Georgia Institute of Technology\nAll rights r"
  },
  {
    "path": "README.md",
    "chars": 926,
    "preview": "# accimage\n\n[![Build status](https://github.com/pytorch/accimage/actions/workflows/accimage.yml/badge.svg)](https://gith"
  },
  {
    "path": "accimage.h",
    "chars": 667,
    "preview": "#ifndef ACCIMAGE_H\n#define ACCIMAGE_H\n\n#include <Python.h>\n\ntypedef struct {\n    PyObject_HEAD\n    unsigned char* buffer"
  },
  {
    "path": "accimagemodule.c",
    "chars": 10117,
    "preview": "#include <Python.h>\n#include <structmember.h>\n\n#include \"accimage.h\"\n\nstatic struct PyMemberDef Image_members[] = {\n    "
  },
  {
    "path": "imageops.c",
    "chars": 5619,
    "preview": "#include \"accimage.h\"\n\n#include <stdlib.h>\n\n#include <ippi.h>\n\n\nvoid image_copy_deinterleave(ImageObject* self, unsigned"
  },
  {
    "path": "jpegloader.c",
    "chars": 2664,
    "preview": "#include \"accimage.h\"\n\n#include <setjmp.h>\n\n#include <jpeglib.h>\n#ifndef LIBJPEG_TURBO_VERSION\n    #error libjpeg-turbo "
  },
  {
    "path": "setup.py",
    "chars": 561,
    "preview": "from distutils.core import setup, Extension\n\naccimage = Extension(\n    \"accimage\",\n    include_dirs=[\"/usr/local/opt/jpe"
  },
  {
    "path": "test.py",
    "chars": 2133,
    "preview": "import accimage\nimport numpy as np\nimport imageio\nimport os\n\nACCIMAGE_SAVE = os.environ.get('ACCIMAGE_SAVE', '')\nif len("
  }
]

About this extraction

This page contains the full source code of the pytorch/accimage GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 14 files (32.1 KB), approximately 8.6k tokens, and a symbol index with 26 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!