I want to use libjpeg in SPRESENSE Arduino

Asked 2 years ago, Updated 2 years ago, 310 views

I would like to use libjpeg in SPRESENSE Arduino.It seems like it can be used as a library in SDK, but how can it be used in Arduino environment?I would like to move libjpeg on the subcore.

spresense arduino

2022-09-30 21:51

2 Answers

This is the main core, but I needed to try it, so I tried it.I think this content can be applied to sub-core as well.When I actually tried it, there were some points, so I'll write them down as a memorandum (it was harder than I expected).

Installing the SpresenseSDK https://developer.sony.com/develop/spresense/docs/sdk_set_up_ja.html

Clone spresense-arduino-compatible
$git clone --recursive https://github.com/sonydevworld/spresense-arduino-compatible.git

Rewrite spresense-arduino-compatible/tools/configs/spresense.conf
Add the following:(for subcore, spresense_sub.conf)

feature/libjpeg
+ARCH_SETJMP_H=y

Rewrite spresense/sdk/tools/mksdkexport.sh Line 135 ${SDK_DIR}/../externals/libjpeg/libjpeg.a\
Line 113 (add 2 lines)
mkdir-p${TMP_DIR}/${SDK_EXP_SDK}/externals/include/libjpeg
cp-a${SDK_DIR}/../externals/libjpeg/*.h\${TMP_DIR}/${SDK_EXP_SDK}/externals/include/libjpeg/

Rewrite borad.txt
Edit spresense-arduino-compatible/Arduino 15/packages/SPRESENSE/hardware/spresense/1.0.0/board.txt
Add "{build.libpath}/libjpeg.a" to line 100 spresense, menu.Core.Main.build.libs

Change the definition of boolean in Arduino
libjpeg also defines boolean.Changing libjpeg's boolean definition will cause the capacity calculation to go wrong and cause errors when decoding.Therefore, the definition of boolean in Arduino must be changed.Defined in the following file:
spresense-arudino-composable/Arduino15/packages/SPRESENSE/hardware/spresense/1.0.0/cores/spresense/WCharacter.h

Change typedef boolean from line 46 to typedef int boolean

Generate/copy Arduino Library Package
$cd spresense-arduino-compatible
$./tools/prepare_arduino.sh-S~/spresense-cspresense-disable-p
$./tools/prepare_arduino.sh-S~/spresense-cspresense-enable-p
$./tools/prepare_arduino.sh-S~/spresense-cspresense_sub-disable-p
$./tools/prepare_arduino.sh-S~/spresense-cspresense_sub-enable-p
$make
$cp./out/package_spresense_local_index.json/home/<user>/snap/arduino/61/.arduino15
$cp-r./out/staging/home/<user>/snap/arduino/61/.arduino15

Add to Board Manager with Arduino IDE
Set file://home/<user>/snap/arduino/61/.arduino15/package_spresense_local_index.json in the 追加Additional Board Manager URLs 」 environment settings (for Linux)
Install the "Spresense local Board" using Board Manager

Use libjpeg test sketches to verify operation
Please prepare a smaller JPEG for confirmation.I used the attached one.One thing to note is that setjmp/longjmp is included in libc.a, so if you do not enclose it with extern "C" , you will get a link error.

Test Image

#defineHAVE_BOOLEAN

# include <nuttx/config.h>
# include<sys/stat.h>
# include <unistd.h>
# include<libjpeg/jpeglib.h>
US>extern "C" {
# include <setjmp.h>
}

external JSAMPLE* image_buffer;

structure my_error_mgr{
  structure jpeg_error_mgr pub; /* "public" fields */
  jmp_buf setjmp_buffer; /* for return to caller*/
};

typeedef structure my_error_mgr *my_error_ptr;


char filename [16] = "/mnt/sd0/in.jpg";
char outfile[17] = "/mnt/sd0/out.rgb";


METHODEF(void)my_error_exit(j_common_ptrcinfo){
  my_error_ptr myerr=(my_error_ptr)cinfo->err;
  (*cinfo->err->output_message)(cinfo);
  longjmp(myerr->setjmp_buffer,1);
}


void setup() {
  static structure jpeg_decompress_struct cinfo;
  structure my_error_mgr jerr;
  FILE*infile; /* source file*/
  FILE* out; /* output file*/
  JSAMPARRAY buffer; /* Output row buffer */
  introw_stride; /* physical row width in output buffer */

  structure stat buf;
  for(;;){
    intret=stat("/mnt/sd0", & buf);
    if(ret){
      printf("Please insert formatted SD Card.\n";
      sleep(1);
    } else{
      break;
    }
  }

  if((infile=fopen(filename, "rb"))==NULL){
    fprintf(stderr, "can't open%s\n", filename);
    return 0;
  }
  printf("open%s\n", filename);

  if((out=fopen(outfile, "wb"))==NULL){
    fprintf(stderr, "can't open%s\n", outfile);
    return 0;    
  }
  printf("create%s\n", outfile);

  /* Step 1: allocate and initialize JPEG depression object*/
  /* We set up the normal JPEG error routes, then override error_exit.*/
  cinfo.err=jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit=my_error_exit;
  /* Establish the setjmp return context for my_error_exit to use.*/
  if(setjmp(jerr.setjmp_buffer)){
    /* If we get here, the JPEG code has signed an error.
     * We need to clean up the JPEG object, close the input file, and return.
     */
    jpeg_destroy_decompress(&cinfo);
    fprintf(stderr, "can't make depress object\n";
    fclose(infile);
    return;
  }
  /* Now we can initialize the JPEG depression object.*/
  jpeg_create_decompress(&cinfo);
  printf("Step1:create decompress object\n");

  /* Step 2: Specify data source(eg, a file)*/
  jpeg_stdio_src(&cinfo,infile);
  printf("Step2:set the data source\n");

  /* Step 3: Read file parameters with jpeg_read_header()*/
  (void) jpeg_read_header (&cinfo, TRUE);
  printf("Step3:read the data header\n");
  /* We can ignore the return value from jpeg_read_header since
   *   (a) Suspension is not possible with the stdio data source, and
   *   (b) We passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.txt for more info.
   */

  /* Step 4: set parameters for depression*/
  cinfo.out_color_space=JCS_RGB;
  printf("Step4:set the output parameter as JCS_RGB\n");

  /* Step 5: Start decompressor*/
  (void)jpeg_start_decompress(&cinfo);
  printf("Step5:start depression\n");
  /* JSAMPLE per row in output buffer*/
  /* Modified for Spresense by Sony Semiconductor Solutions.
   * CbYCrY format has 16 bpp.So, stride is width*2 bytes.
   */
  /* row_stride=cinfo.output_width*cinfo.output_components;*/
  // row_stride=cinfo.output_width*2;//incase of YCbCr
  row_stride=cinfo.output_width*3;//incase of RGB
  /* Make one-row-high sample array that will go away when done with image*/
  buffer=(*cinfo.mem->alloc_sarray)
                ((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);

  /* Step6: while(scan lines remain to be read)*/
  printf("Step6:read scanlines\n");
  int n = 0;
  while(cinfo.output_scanline<cinfo.output_height){
    /* jpeg_read_scanlines expectations an array of pointers to scanlines.
     * Here the array is only one element long, but you could ask for
     * more than one scanline at a time if that's more convenient.
     */
    (void) jpeg_read_scanlines(&cinfo, buffer, 1);
    if(row_stride!=fwrite(buffer[0], 1, row_stride, out)){
      printf("fwrite error:%d\n", errno);
    }
    ++n;
  }
  printf("read lines:%d\n",n);
  printf("close output file\n";
  fclose(out);

  /* Step 7: Finish depression*/
  printf("Step7:finish depression\n");  
  (void)jpeg_finish_decompress(&cinfo);

  /* Step 8: Release JPEG depression object*/
  printf("Step8:destroy decompress object\n");  
  jpeg_destroy_decompress(&cinfo);
  printf("Step 9:close info\n");
  fclose(infile);
}

void loop(){}

[Supplement]
The Spresense SDK only supports decompression by default and does not support compression.If you also want compression to be enabled, you must add the following files to spresense/sdk/externals/libjpeg/Makefile for compilation:

CSRCS+=jcapimin.cjcapistd.cjcarith.cjccoefct.cjccolor.c
CSRCS+=jcdctmgr.cjchuff.cjcinit.cjcmainct.cjcmarker.cjcmaster.c
CSRCS+=jcparam.cjcprepct.cjcsample.cjctrans.cjdatadst.c
CSRCS+=jfdctflt.cjfdctfst.cjfdctint.c


2022-09-30 21:51

Hello
I have also added the original library, so I will write down how to do it.

In this case, if you create an SDK package with libjpeg enabled, you will be able to use libjpeg.

4.2.2.How to create a local package on Sony's site allows you to create an original package.

Also, since tools/configs/spresense_sub.conf in the spresense-arduino-compatible repository seems to be the setting when creating the package, adding feature/libjpeg may add the libjpeg> to the package.

Somehow, I feel like I need to add a library file in the script (spresense repository) used to create the package sdk/tools/mksdkexport.sh, so I'll go to line 135

${SDK_DIR}/../externals/libjpeg/libjpeg.a\

I think it would be better to add .

I hope you'll find it useful!


2022-09-30 21:51

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.