cancel
Showing results for 
Search instead for 
Did you mean: 

searching for TJpgDec example code

arnold
Associate II
Posted on August 04, 2012 at 15:52

hello 

as the tittle says i'm searching for some example code for

http://elm-chan.org/fsw/tjpgd/00index.html

i have fatfs working from chan. i have a display up and running. 

now i only need to find out how to use the above decoder. 

could someone help me. 

thanks 
20 REPLIES 20
zaurozavr
Associate II
Posted on August 04, 2012 at 17:06

What kind of code are you looking for? Have you read the application note?

You just need to change file functions to FatFs.

I have implemented it in my custom board (407IG6 with a lot of external periferals onboard, including EPSON videocontroller with 128Mbit RAM)  and it works fine.

F.e., decoding a jpeg 480x272 image takes about 0.8 sec (CPU @216MHz), meaning the decoded image stored in external memory.    
arnold
Associate II
Posted on August 04, 2012 at 18:56

arnold
Associate II
Posted on August 04, 2012 at 19:03

I tryed to alter the example code, but i don't know how.

I'm kinda stuck with fseek, which is not in fsfat system. so i hoped that someone could provide me with the right code to interface it with fsfat. just a quick update. below is the code i have so far, but when i run it i get a error in my terminal screen. the program compiles without any error. when annalysing the error code it is JDR_MEM1, /* 3: Insufficient memory pool for the image */ how can i fix this ?

/**
*****************************************************************************
**
** File : main.c
**
** Abstract : main function.
**
** Functions : main
**
** Environment : Atollic TrueSTUDIO(R)
** STMicroelectronics STM32F4xx Standard Peripherals Library
**
** Distribution: The file is distributed “as is,�? without any warranty
** of any kind.
**
** (c)Copyright Atollic AB.
** You may use this file as-is or modify it according to the needs of your
** project. Distribution of this file (unmodified or modified) is not
** permitted. Atollic AB permit registered Atollic TrueSTUDIO(R) users the
** rights to distribute the assembled, compiled & linked contents of this
** file as part of an application binary file, provided that it is built
** using the Atollic TrueSTUDIO(R) toolchain.
**
**
*****************************************************************************
*/
/* Includes */
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include ''stm32f4xx.h''
#include ''stm32f4_discovery_sdio_sd.h''
#include ''rs232_uart3.h''
//******************************************************************************
//For sd-card fatsfs use
#include ''ff.h''
#include ''diskio.h''
//For display use
#include ''delay.h''
#include ''SSD1h''
//for JPG use
#include ''tjpgd.h''
void
NVIC_Configuration(
void
);
FRESULT res;
FILINFO fno;
FIL fil;
DIR dir;
FATFS fs32;
char
* path;
char
*fn; /* This function 
is
assuming non-Unicode cfg. */
//when using long file names
#if _USE_LFN
static
char
lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = 
sizeof
lfn;
#endif
/*-----------------------------------*/
/* JPEG file loader */
/* User defined call-back function to input JPEG data */
static
UINT tjd_input (
JDEC* jd, 
/* Decoder object */
BYTE* buff, 
/* Pointer to the read buffer (NULL:skip) */
UINT nd 
/* Number of bytes to read/skip from input stream */
)
{
UINT rb;
FIL *fil = (FIL*)jd->device; 
/* Input stream of this session */
if
(buff) { 
/* Read nd bytes from the input strem */
f_read(fil, buff, nd, &rb);
return
rb; 
/* Returns number of bytes could be read */
} 
else
{ 
/* Skip nd bytes on the input stream */
return
(f_lseek(fil, f_tell(fil) + nd) == FR_OK) ? nd : 0;
}
}
/* User defined call-back function to output RGB bitmap */
static
UINT tjd_output (
JDEC* jd, 
/* Decoder object */
void
* bitmap, 
/* Bitmap data to be output */
JRECT* rect 
/* Rectangular region to output */
)
{
jd = jd; 
/* Suppress warning (device identifier is not needed) */
/* Check user interrupt at left end */
if
(!rect->left) 
return
0; 
/* Abort decompression */
/* Put the rectangular into the display */
LCD_WriteBMP(rect->left, rect->right, rect->top, rect->bottom, (uint16_t*)bitmap);
return
1; 
/* Continue decompression */
}
void
load_jpg (
FIL *fp, 
/* Pointer to the open file object to load */
void
*work, 
/* Pointer to the working buffer (must be 4-byte aligned) */
UINT sz_work 
/* Size of the working buffer (must be power of 2) */
)
{
JDEC jd; 
/* Decoder object (124 bytes) */
JRESULT rc;
BYTE scale;
LCD_Clear(0);; 
/* Clear screen */
LCD_SetTextColor(WHITE);
/* Prepare to decompress the file */
rc = jd_prepare(&jd, tjd_input, work, sz_work, fp);
if
(rc == JDR_OK) {
/* Determine scale factor */
for
(scale = 0; scale < 3; scale++) {
if
((jd.width >> scale) <= DISP_XS && (jd.height >> scale) <= DISP_YS) 
break
;
}
/* Display size information at bottom of screen */
printf(
''%ux%u 1/%u''
, jd.width, jd.height, 1 << scale);
/* Start to decompress the JPEG file */
rc = jd_decomp(&jd, tjd_output, scale); 
/* Start to decompress */
} 
else
{
/* Display error code */
printf(
''Error: %d''
, rc); 
//error return code, furthur searching. JDR_MEM1
}
}
//******************************************************************************
char
*dec32(unsigned 
long
i)
{
static
char
str[16];
char
*s = str + 
sizeof
(str);
*--s = 0;
do
{
*--s = 
'0'
+ (
char
)(i % 10);
i /= 10;
}
while
(i);
return
(s);
}
//******************************************************************************
int
main(
void
)
{
void
*work; /* Pointer to the decompressor work area */
JDEC jdec; 
/* Decompression object */
JRESULT res; 
/* Result code of TJpgDec API */
UINT sz_work; 
/* Size of the filer work area */
/* Allocate a work area for TJpgDec */
work = malloc(3100);
USART3_INIT();
printf(
''usart3 init done
''
);
NVIC_Configuration(); 
/* Interrupt Config */
printf(
''interupt setup done
''
);
LCD_Init();
printf(
''LCD init done
''
);
SD_Init();
printf(
''SD-card init done
''
);
printf(
''All systems are good to go 
''
);
//Select memory for use
memset(&fs32, 0, 
sizeof
(FATFS));
//mount file system
res = f_mount(0, &fs32);
if
(res != FR_OK)
printf(
''res = %d f_mount
''
, res);
else
printf(
''Mounting done
''
);
//open file
res = f_open(&fil, 
''nora.jpg''
, FA_READ);
if
(res != FR_OK)
printf(
''res = %d f_open nora.jpg
''
, res);
else
{
printf(
''file opened
''
);
//here goes something
load_jpg(&fil,work,sz_work);
}
while
(1); 
/* Infinite loop */
}
//******************************************************************************
void
NVIC_Configuration(
void
)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

zaurozavr
Associate II
Posted on August 05, 2012 at 09:58

You have too small work area for STM Try, f.e.

work = malloc(4096);

Besides, you can save one function call by writing

return

(f_lseek(fil, nd) == FR_OK) ? nd : 0;
 and in file tdjpg.c, in function jd_prepare change the last line to

if

(jd->

infunc

(jd, 0, ofs) != ofs)

return

JDR_INP

;

arnold
Associate II
Posted on August 05, 2012 at 14:50

i tryed to increase the memory allocation to 4096 but this doesn't help

i get the same error. 

would it help if i send you the whole project ?
zaurozavr
Associate II
Posted on August 05, 2012 at 16:41

You can, of course. But first try once more.

1) Fifth arg for the jd_prepare() is the device, not file stream. So, this line

FIL *fil = (FIL*)jd->device;    /* Input stream of this session */

is wrong.

You have to declare a struct:

typedef struct {

    FIL  *fil;      /* File pointer for input function */

    BYTE *fbuf;    /* Pointer to the frame buffer for output function */

    UINT wfbuf;    /* Width of the frame buffer [pix] */

} IODEV;

Then fill it with your buffer params before calling jd_prepare(), f.e.

  IODEV dev;     

  dev.fp = &fil;

  dev.fbuf = fb; // must be defined everywhere 

  dev.wfbuf = 480; //  screen width

You are writing all data straight to the LCD, but these fields are used by output functions, ie for scaling etc. So the best way to declare at least the buffer with (screen width x mcu height) size.

In your load_jpg ()  the right call looks like:

rc = jd_prepare(&jd, tjd_input, work, sz_work, dev);

2) And you are wrong again at

FIL *fil = (FIL*)jd->device;    /* Input stream of this session */

This way you send the device pointer instead of input file.

File stream should be defined as:

FIL *fil = dev->fp;

Hope this helps.

arnold
Associate II
Posted on August 05, 2012 at 19:15

still no go here,

I get some pretty strange error's.

i attached my project, so maybee you wold check it.

________________

Attachments :

template_jpg.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0zk&d=%2Fa%2F0X0000000bgi%2Ftovuiu5SDUKdnhrPQbQoycDRPUxSNImtS0SVqKdxELM&asPdf=false
zaurozavr
Associate II
Posted on August 06, 2012 at 18:54

Here you are.

Your project required some work, but it is beyond this topic. You have to pay attention to the scope of your variables (multidefinition and mangling in program) and fully understand program logic before coding. Your Jpeg scaling realizations not applicable to the file stream.Besides, your SDIO implementation is not complete. I can not do this for you.

To help you (and maybe somebody else) I wrote yesterday a small project, where Chan's FATFS & TJPGD libraries have been used. The program reads selected directory and infinitely displays *.jpg files on LCD, each file consequently in 1:8, 1:4, 1:2 and 1:1 scale.

SD card uses SPI (though I have used SDIO, too, but TJPGD is irrelevant to storage).

Configuration is defined in config.h.

For understanding TJPGD it is sufficient to have a look at main.c only.

The main difficulty to implement some kind of load_jpeg() function may arise from your program logic and corresponding out_func() realization. Some strategies are possible, in my project I fill the whole frame buffer up then display image at once.

Hardware: STM32F4-Discovery with my DIY ZP-DSF4 docking station just due to convinient card slots (both SPI and SDIO) and small (96x64) onboard OLED display. Other dockstation periferals were not used (1 MByte SRAM, 512 KByte MRAM, 16 MByte Flash, USART etc).

Demo is straightforward and with no optimization, if you plan to extend it do not forget to release allocated resources. Jpeg file size is not limited (up to 64Kx64K), but do not overestimate HW+SW used. Of course there are a lot of ways to improve the decoding speed - using memory stream, DMA and DSP optimization, stack and other stuff in CCM etc.

Toolchain: Atollic True studio Lite 2.3.

How to use it:

In Atollic (or maybe in other Eclipse-based gnu toolcain as well)

'File'->'Import'->'Existing Projects into Workspace'

Then select the unzipped project, check 'Copy projects into workspace' and press 'Finish'. Now you have a fully working project in your toolchain.

________________

Attachments :

FatFs_Tdjpg_Demo.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HtWI&d=%2Fa%2F0X0000000aRB%2FUkC3DULELTuyEFs7mCJepiekNNF9OQvM3CA6gHIHjfI&asPdf=false
zaurozavr
Associate II
Posted on August 11, 2012 at 02:04

My code has to be precised a little bit, in out_func  bwa shold be multiplied by 2 (if you image width % 8 = 0 it doesn't matter though ), and there is no need to reinitialize  file pointer in the inner loop. But it all is so obvious.

But you can  use   now a

''STM32F2-F4_Demonstration_Builder_V1.0.0'' with a lipjpeg library  adapted to STM32, released today (in really libjpeg is available for a long ago already). Besides, there is  mp3 player (also ported to cortex-m3 four years ago) and some other interesting projects as well.