GithubHelp home page GithubHelp logo

cl-jpeg's People

Contributors

froggey avatar mgi avatar slyrus avatar varjagg avatar whalliburton avatar xach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cl-jpeg's Issues

encoding image to bytes in memory?

Would it be possible to export the encode-image-stream method to encode the image into a flexi-streams or some such type? I am trying to use this library to generate base64 images on the fly. Also, am a newb to common lisp. So please point to an alternative approach to temp/in-memory files that I can use with encode-image if there is one. Thanks!

Git repo vs c-l.net?

This mirror is mainly for quicklisp, am I correct? Any idea how many pulls it gets vs the upstream repository directly?

Does it make sense to keep both, or should we move it here?

encoding grayscale jpeg images is broken

The following should make a uniform gray image when test-encode is called:

(cl:defpackage :jpeg-test
  (:use #:cl #:jpeg))

(cl:in-package :jpeg-test)

(defun test-image (filename)
  (reduce #'merge-pathnames (list filename "images/")
          :from-end t
          :initial-value (asdf:component-pathname
                          (asdf:find-system "cl-jpeg"))))

(ensure-directories-exist (output-image ""))

(defparameter *gray-q-tabs* (vector jpeg::+q-luminance+))

(defun test-encode (&optional (output (test-image "simple.jpeg")))
  (let ((width 32)
        (height 32))
    (let ((buf (make-array (* width height) :initial-element 42)))
      (time (encode-image output buf 1 width height
                          :q-tabs *gray-q-tabs*)))))

This should give a uniform gray image, but doesn't.

How to convert base64 into JPEG image?

Hi,
I'm working on a third-party application in common lisp. In application on request, the server returns base64 string of user profile photo.

I want to generate an image from this base64 encoded string.

I tried byte array from base64 string using cl-base64 library's base64-string-to-usb8-array and passed it in cl-jpeg's encode-image but it creates a distorted image.

(let* ((base64-string "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")
       (byte-array (base64:base64-string-to-usb8-array base64-string))
       (output-file-spec "/tmp/image.jpeg")
       (height 618)
       (width 1000)
       (ncomp 3))
  (cl-jpeg:encode-image output-file-spec byte-array ncomp height width))

Any suggestion will be helpful.

Thanks.

Safety 0 is a bad idea

Turning safety to 0 for so much of the code is a bad idea, and can mask real bugs. See next issue...

Expose decode-frame and friends

My retrosspectiff package uses cl-jepg for decoding jpeg-encoded TIFF images. These images have the jpeg-tables info split up from the frame info, so I can't just call decode-stream on them. It would be nice if there were stable, exported interfaces I could use instead of having to do:

(defvar *jpeg-stream*)

(defun jpeg-stream-reader ()
  (read-byte *jpeg-stream*))

(defun read-jpeg-tables (jpeg-image-info)
  (let* ((*jpeg-stream* (flexi-streams:make-in-memory-input-stream
                         (jpeg-tables jpeg-image-info))))
    (let ((image (jpeg::make-descriptor
                  :byte-reader #'jpeg-stream-reader)))
      (unless (= (jpeg::read-marker image) jpeg::+M_SOI+)
        (error "Unrecognized JPEG format"))
      (let ((marker (jpeg::interpret-markers image 0)))
        (unless (= marker jpeg::+M_EOI+)
          (error "Unrecognized JPEG format")))
      (setf (jpeg-image jpeg-image-info) image))))

(defun jpeg-decode (compressed-vector jpeg-image-info)
  ;;  NOTE: we currently read the jpeg-tables every time through. We
  ;;  should be able to cache this, but we don't as its state gets
  ;;  modified by the JPEG reading stuff and we can't just reuse it
  ;;  each time through. So..., for the moment at least, we make a new
  ;;  one each time through.
  (read-jpeg-tables jpeg-image-info)
  (let ((image (jpeg-image jpeg-image-info)))
    (let ((*jpeg-stream* (flexi-streams:make-in-memory-input-stream compressed-vector)))
      (unless (= (jpeg::read-marker image) jpeg::+M_SOI+)
        (error "Unrecognized JPEG format"))
      (let* ((marker (jpeg::interpret-markers image 0)))
        (cond ((= jpeg::+M_SOF0+ marker)
               (jpeg::decode-frame image nil)
               (jpeg::descriptor-buffer image))
              (t (error "Unsupported JPEG format: ~A" marker)))))))

Inter-dependent forms inside eval-when

Eval this to reproduce the bug:

  • (load "~/quicklisp/dists/quicklisp/software/cl-jpeg-20170124-git/package.lisp")
  • (load "~/quicklisp/dists/quicklisp/software/cl-jpeg-20170124-git/jpeg.lisp")

+q-luminance+ is unbound

To fix it separate the macro forms that are dependent upon each other. Perhaps the define-constant macro also needs to be wrapped in an eval-when.

a little suggestion

As we can see, there is no dct library written by common lisp. So if you can offer some inferface about dct, this project will be used more widely.

Wrong type declaration in crop-image

crop-image declares outbuf to be a uint16-2d-array when it gets passed an sint16-2d-array. This works by accident when we have safety 0, but is wrong. AFAICT, crop-image is only called from one place and always gets an sint16-2d-array.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.