JpegEncApi.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. /*------------------------------------------------------------------------------
  2. -- --
  3. -- This software is confidential and proprietary and may be used --
  4. -- only as expressly authorized by a licensing agreement from --
  5. -- --
  6. -- Hantro Products Oy. --
  7. -- --
  8. -- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
  9. -- ALL RIGHTS RESERVED --
  10. -- --
  11. -- The entire notice above must be reproduced --
  12. -- on all copies and should not be removed. --
  13. -- --
  14. --------------------------------------------------------------------------------
  15. --
  16. -- Abstract : JPEG Encoder API
  17. --
  18. ------------------------------------------------------------------------------*/
  19. /*------------------------------------------------------------------------------
  20. Version Information
  21. ------------------------------------------------------------------------------*/
  22. #define JPEGENC_MAJOR_VERSION 1
  23. #define JPEGENC_MINOR_VERSION 0
  24. #define JPEGENC_BUILD_MAJOR 1
  25. #define JPEGENC_BUILD_MINOR 14
  26. #define JPEGENC_BUILD_REVISION 0
  27. #define JPEGENC_SW_BUILD ((JPEGENC_BUILD_MAJOR * 1000000) + \
  28. (JPEGENC_BUILD_MINOR * 1000) + JPEGENC_BUILD_REVISION)
  29. #define JPEGENC_MAX_SIZE 261121 /* 511x511 = 261121 macroblocks */
  30. /*------------------------------------------------------------------------------
  31. 1. Include headers
  32. ------------------------------------------------------------------------------*/
  33. #include "jpegencapi.h"
  34. #include "EncJpegInit.h"
  35. #include "EncJpegInstance.h"
  36. #include "EncJpegCodeFrame.h"
  37. #include "EncJpegQuantTables.h"
  38. #include "EncJpegMarkers.h"
  39. #include "EncJpegPutBits.h"
  40. #include "encasiccontroller.h"
  41. #include "ewl.h"
  42. /*------------------------------------------------------------------------------
  43. 2. External compiler flags
  44. --------------------------------------------------------------------------------
  45. --------------------------------------------------------------------------------
  46. 3. Module defines
  47. ------------------------------------------------------------------------------*/
  48. /* Tracing macro */
  49. #ifdef JPEGENC_TRACE
  50. #define APITRACE(str) JpegEnc_Trace(str)
  51. #else
  52. #define APITRACE(str)
  53. #endif
  54. /*------------------------------------------------------------------------------
  55. 4. Local function prototypes
  56. ------------------------------------------------------------------------------*/
  57. static bool_e CheckJpegCfg(const JpegEncCfg * pEncCfg);
  58. static i32 CheckThumbnailCfg(const JpegEncThumb * pCfgThumb);
  59. static i32 CheckFullSize(const JpegEncCfg * pCfgFull);
  60. /*******************************************************************************
  61. Function name : JpegEncGetApiVersion
  62. Description :
  63. Return type : JpegEncApiVersion
  64. *******************************************************************************/
  65. JpegEncApiVersion JpegEncGetApiVersion(void)
  66. {
  67. JpegEncApiVersion ver;
  68. ver.major = JPEGENC_MAJOR_VERSION;
  69. ver.minor = JPEGENC_MINOR_VERSION;
  70. APITRACE("JpegEncGetVersion# OK\n");
  71. return ver;
  72. }
  73. /*******************************************************************************
  74. Function name : JpegEncGetBuild
  75. Description :
  76. Return type : JpegEncBuild
  77. *******************************************************************************/
  78. JpegEncBuild JpegEncGetBuild(void)
  79. {
  80. JpegEncBuild ver;
  81. ver.swBuild = JPEGENC_SW_BUILD;
  82. ver.hwBuild = EWLReadAsicID();
  83. APITRACE("JpegEncGetBuild# OK\n");
  84. return (ver);
  85. }
  86. /*******************************************************************************
  87. Function name : JpegEncInit
  88. Description :
  89. Return type : JpegEncRet
  90. Argument : JpegEncCfg * pEncCfg
  91. Argument : JpegEncInst * instAddr
  92. *******************************************************************************/
  93. JpegEncRet JpegEncInit(const JpegEncCfg * pEncCfg, JpegEncInst * instAddr)
  94. {
  95. JpegEncRet ret;
  96. jpegInstance_s *pEncInst = NULL;
  97. APITRACE("JpegEncInit#");
  98. /* check that right shift on negative numbers is performed signed */
  99. /*lint -save -e* following check causes multiple lint messages */
  100. #if (((-1) >> 1) != (-1))
  101. #error Right bit-shifting (>>) does not preserve the sign
  102. #endif
  103. /*lint -restore */
  104. /* Check for illegal inputs */
  105. if(pEncCfg == NULL || instAddr == NULL)
  106. {
  107. APITRACE("JpegEncInit: ERROR null argument");
  108. return JPEGENC_NULL_ARGUMENT;
  109. }
  110. /* Check that configuration is valid */
  111. if(CheckJpegCfg(pEncCfg) == ENCHW_NOK)
  112. {
  113. APITRACE("JpegEncInit: ERROR invalid argument");
  114. return JPEGENC_INVALID_ARGUMENT;
  115. }
  116. /* Initialize encoder instance and allocate memories */
  117. ret = JpegInit(pEncCfg, &pEncInst);
  118. if(ret != JPEGENC_OK)
  119. {
  120. APITRACE("JpegEncInit: ERROR Initialization failed");
  121. return ret;
  122. }
  123. /* hardware config */
  124. pEncInst->asic.regs.qp = 0;
  125. pEncInst->asic.regs.constrainedIntraPrediction = 0;
  126. pEncInst->asic.regs.frameCodingType = ASIC_INTRA;
  127. pEncInst->asic.regs.roundingCtrl = 0;
  128. pEncInst->asic.regs.codingType = ASIC_JPEG;
  129. /* Pre processing */
  130. pEncInst->preProcess.lumWidthSrc = 0;
  131. pEncInst->preProcess.lumHeightSrc = 0;
  132. pEncInst->preProcess.lumWidth = 0;
  133. pEncInst->preProcess.lumHeight = 0;
  134. pEncInst->preProcess.horOffsetSrc = 0;
  135. pEncInst->preProcess.verOffsetSrc = 0;
  136. pEncInst->preProcess.rotation = 0;
  137. pEncInst->preProcess.videoStab = 0;
  138. pEncInst->preProcess.inputFormat = pEncCfg->frameType;
  139. pEncInst->preProcess.colorConversionType = pEncCfg->colorConversion.type;
  140. pEncInst->preProcess.colorConversionCoeffA = pEncCfg->colorConversion.coeffA;
  141. pEncInst->preProcess.colorConversionCoeffB = pEncCfg->colorConversion.coeffB;
  142. pEncInst->preProcess.colorConversionCoeffC = pEncCfg->colorConversion.coeffC;
  143. pEncInst->preProcess.colorConversionCoeffE = pEncCfg->colorConversion.coeffE;
  144. pEncInst->preProcess.colorConversionCoeffF = pEncCfg->colorConversion.coeffF;
  145. EncSetColorConversion(&pEncInst->preProcess, &pEncInst->asic);
  146. #ifdef TRACE_STREAM
  147. /* Open stream tracing */
  148. EncOpenStreamTrace("stream.trc");
  149. traceStream.frameNum = 0;
  150. #endif
  151. /* Status == INIT Initialization succesful */
  152. pEncInst->encStatus = ENCSTAT_INIT;
  153. pEncInst->inst = pEncInst; /* used as checksum */
  154. *instAddr = (JpegEncInst) pEncInst;
  155. APITRACE("JpegEncInit: OK");
  156. return JPEGENC_OK;
  157. }
  158. /*******************************************************************************
  159. Function name : JpegEncRelease
  160. Description :
  161. Return type : JpegEncRet
  162. Argument : JpegEncInst inst
  163. *******************************************************************************/
  164. JpegEncRet JpegEncRelease(JpegEncInst inst)
  165. {
  166. jpegInstance_s *pEncInst = (jpegInstance_s *) inst;
  167. APITRACE("JpegEncRelease#");
  168. /* Check for illegal inputs */
  169. if(pEncInst == NULL)
  170. {
  171. APITRACE("JpegEncRelease: ERROR null argument");
  172. return JPEGENC_NULL_ARGUMENT;
  173. }
  174. /* Check for existing instance */
  175. if(pEncInst->inst != pEncInst)
  176. {
  177. APITRACE("JpegEncRelease: ERROR Invalid instance");
  178. return JPEGENC_INSTANCE_ERROR;
  179. }
  180. #ifdef TRACE_STREAM
  181. EncCloseStreamTrace();
  182. #endif
  183. JpegShutdown(pEncInst);
  184. APITRACE("JpegEncRelease: OK");
  185. return JPEGENC_OK;
  186. }
  187. /*******************************************************************************
  188. Function name : JpegEncSetThumbnail
  189. Description :
  190. Return type : JpegEncRet
  191. Argument : JpegEncInst inst
  192. Argument : JpegEncCfg * pEncCfg
  193. *******************************************************************************/
  194. JpegEncRet JpegEncSetThumbnail(JpegEncInst inst, const JpegEncThumb *pJpegThumb)
  195. {
  196. jpegInstance_s *pEncInst = (jpegInstance_s *) inst;
  197. APITRACE("JpegEncSetThumbnail#");
  198. /* Check for illegal inputs */
  199. if((pEncInst == NULL) || (pJpegThumb == NULL))
  200. {
  201. APITRACE("JpegEncSetThumbnail: ERROR null argument");
  202. return JPEGENC_NULL_ARGUMENT;
  203. }
  204. /* Check for existing instance */
  205. if(pEncInst->inst != pEncInst)
  206. {
  207. APITRACE("JpegEncSetThumbnail: ERROR Invalid instance");
  208. return JPEGENC_INSTANCE_ERROR;
  209. }
  210. if(CheckThumbnailCfg(pJpegThumb) != JPEGENC_OK)
  211. {
  212. APITRACE("JpegEncSetThumbnail: ERROR Invalid thumbnail");
  213. return JPEGENC_INVALID_ARGUMENT;
  214. }
  215. pEncInst->jpeg.appn.thumbEnable = 1;
  216. /* save the thumbnail config */
  217. (void)EWLmemcpy(&pEncInst->jpeg.thumbnail, pJpegThumb, sizeof(JpegEncThumb));
  218. APITRACE("JpegEncSetThumbnail: OK");
  219. return JPEGENC_OK;
  220. }
  221. /*******************************************************************************
  222. Function name : JpegEncSetPictureSize
  223. Description :
  224. Return type : JpegEncRet
  225. Argument : JpegEncInst inst
  226. Argument : JpegEncCfg * pEncCfg
  227. *******************************************************************************/
  228. JpegEncRet JpegEncSetPictureSize(JpegEncInst inst, const JpegEncCfg * pEncCfg)
  229. {
  230. u32 mbTotal = 0;
  231. u32 height = 0;
  232. u32 widthMbs;
  233. jpegInstance_s *pEncInst = (jpegInstance_s *) inst;
  234. APITRACE("JpegEncSetPictureSize#");
  235. /* Check for illegal inputs */
  236. if((pEncInst == NULL) || (pEncCfg == NULL))
  237. {
  238. APITRACE("JpegEncSetPictureSize: ERROR null argument");
  239. return JPEGENC_NULL_ARGUMENT;
  240. }
  241. /* Check for existing instance */
  242. if(pEncInst->inst != pEncInst)
  243. {
  244. APITRACE("JpegEncSetPictureSize: ERROR Invalid instance");
  245. return JPEGENC_INSTANCE_ERROR;
  246. }
  247. if(CheckFullSize(pEncCfg) != JPEGENC_OK)
  248. {
  249. APITRACE
  250. ("JpegEncSetPictureSize: ERROR Out of range image dimension(s)");
  251. return JPEGENC_INVALID_ARGUMENT;
  252. }
  253. widthMbs = (pEncCfg->codingWidth + 15) / 16;
  254. if(((pEncCfg->restartInterval * 16) > pEncCfg->codingHeight) ||
  255. ((pEncCfg->restartInterval * widthMbs) > 0xFFFF))
  256. {
  257. APITRACE("JpegEncSetPictureSize: ERROR restart interval too big");
  258. return JPEGENC_INVALID_ARGUMENT;
  259. }
  260. /* Restart interval must be enabled for sliced encoding */
  261. if(pEncCfg->codingType == JPEGENC_SLICED_FRAME)
  262. {
  263. if(pEncCfg->rotation != JPEGENC_ROTATE_0)
  264. {
  265. APITRACE
  266. ("JpegEncSetPictureSize: ERROR rotation not allowed in sliced mode");
  267. return JPEGENC_INVALID_ARGUMENT;
  268. }
  269. if(pEncCfg->restartInterval == 0)
  270. {
  271. APITRACE
  272. ("JpegEncSetPictureSize: ERROR restart interval not set");
  273. return JPEGENC_INVALID_ARGUMENT;
  274. }
  275. /* Extra limitation for partial encoding: yOffset must be
  276. * multiple of slice height in rows */
  277. if((pEncCfg->yOffset % (pEncCfg->restartInterval * 16)) != 0)
  278. {
  279. APITRACE("JpegEncSetPictureSize: ERROR yOffset not valid");
  280. return JPEGENC_INVALID_ARGUMENT;
  281. }
  282. }
  283. mbTotal =
  284. (u32) (((pEncCfg->codingWidth + 15) / 16) * ((pEncCfg->codingHeight +
  285. 15) / 16));
  286. pEncInst->jpeg.header = ENCHW_YES;
  287. pEncInst->jpeg.width = pEncCfg->codingWidth;
  288. pEncInst->jpeg.height = pEncCfg->codingHeight;
  289. /*pEncInst->jpeg.lastColumn = ((pEncInst->jpeg.width + 15) / 16);*/
  290. pEncInst->jpeg.mbPerFrame = mbTotal;
  291. /* Pre processing */
  292. pEncInst->preProcess.lumWidthSrc = pEncCfg->inputWidth;
  293. pEncInst->preProcess.lumHeightSrc = pEncCfg->inputHeight;
  294. pEncInst->preProcess.lumWidth = pEncCfg->codingWidth;
  295. pEncInst->preProcess.lumHeight = pEncCfg->codingHeight;
  296. pEncInst->preProcess.horOffsetSrc = pEncCfg->xOffset;
  297. pEncInst->preProcess.verOffsetSrc = pEncCfg->yOffset;
  298. pEncInst->preProcess.rotation = pEncCfg->rotation;
  299. /* Restart interval (MCU rows converted to macroblocks) */
  300. pEncInst->jpeg.restart.Ri = (u32)(pEncCfg->restartInterval * widthMbs);
  301. /* Coding type */
  302. if(pEncCfg->codingType == JPEGENC_WHOLE_FRAME)
  303. {
  304. pEncInst->jpeg.codingType = ENC_WHOLE_FRAME;
  305. height = pEncInst->jpeg.height;
  306. }
  307. else
  308. {
  309. /* Sliced mode */
  310. pEncInst->jpeg.codingType = ENC_PARTIAL_FRAME;
  311. pEncInst->jpeg.sliceRows = (u32) pEncCfg->restartInterval;
  312. height = (pEncCfg->restartInterval * 16);
  313. }
  314. #ifdef JPEGENC_422_MODE_SUPPORTED
  315. if(pEncCfg->codingMode == JPEGENC_420_MODE)
  316. pEncInst->jpeg.codingMode = ENC_420_MODE;
  317. else
  318. {
  319. if ((pEncInst->preProcess.inputFormat != JPEGENC_YUV422_INTERLEAVED_YUYV) &&
  320. (pEncInst->preProcess.inputFormat != JPEGENC_YUV422_INTERLEAVED_UYVY))
  321. {
  322. APITRACE("JpegEncSetPictureSize: ERROR 4:2:0 input in 4:2:2 mode");
  323. return JPEGENC_INVALID_ARGUMENT;
  324. }
  325. if (pEncInst->preProcess.rotation != JPEGENC_ROTATE_0)
  326. {
  327. APITRACE("JpegEncSetPictureSize: ERROR rotation in 4:2:2 mode");
  328. return JPEGENC_INVALID_ARGUMENT;
  329. }
  330. pEncInst->jpeg.codingMode = ENC_422_MODE;
  331. }
  332. #else
  333. pEncInst->jpeg.codingMode = ENC_420_MODE;
  334. #endif
  335. /* Check that configuration is valid */
  336. if(EncPreProcessCheck(&pEncInst->preProcess) == ENCHW_NOK)
  337. {
  338. APITRACE
  339. ("JpegEncSetPictureSize: ERROR invalid pre-processing argument");
  340. return JPEGENC_INVALID_ARGUMENT;
  341. }
  342. /* Allocate internal SW/HW shared memories */
  343. if(EncAsicMemAlloc_V2(&pEncInst->asic, (u32) pEncInst->jpeg.width,
  344. height, ASIC_JPEG, 0, 0) != ENCHW_OK)
  345. {
  346. APITRACE("JpegEncSetPictureSize: ERROR ewl memory allocation");
  347. return JPEGENC_EWL_MEMORY_ERROR;
  348. }
  349. APITRACE("JpegEncSetPictureSize: OK");
  350. return JPEGENC_OK;
  351. }
  352. /*******************************************************************************
  353. Function name : JpegEncEncode
  354. Description :
  355. Return type : JpegEncRet
  356. Argument : JpegEncInst inst
  357. Argument : JpegEncIn * pEncIn
  358. Argument : JpegEncOut *pEncOut
  359. *******************************************************************************/
  360. JpegEncRet JpegEncEncode(JpegEncInst inst, const JpegEncIn * pEncIn,
  361. JpegEncOut * pEncOut)
  362. {
  363. jpegInstance_s *pEncInst = (jpegInstance_s *) inst;
  364. jpegData_s *jpeg;
  365. asicData_s *asic;
  366. preProcess_s *preProcess;
  367. jpegEncodeFrame_e ret;
  368. APITRACE("JpegEncEncode#");
  369. /* Check for illegal inputs */
  370. if((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
  371. {
  372. APITRACE("JpegEncEncode: ERROR null argument");
  373. return JPEGENC_NULL_ARGUMENT;
  374. }
  375. /* Check for existing instance */
  376. if(pEncInst->inst != pEncInst)
  377. {
  378. APITRACE("JpegEncEncode: ERROR Invalid instance");
  379. return JPEGENC_INSTANCE_ERROR;
  380. }
  381. asic = &pEncInst->asic;
  382. jpeg = &pEncInst->jpeg;
  383. preProcess = &pEncInst->preProcess;
  384. /* Check for invalid input values */
  385. if((pEncIn->pOutBuf == NULL) || (pEncIn->outBufSize < 1024))
  386. {
  387. APITRACE("JpegEncEncode: ERROR Invalid output buffer");
  388. return JPEGENC_INVALID_ARGUMENT;
  389. }
  390. if((jpeg->appn.thumbEnable) &&
  391. (pEncIn->outBufSize < ((u32)jpeg->thumbnail.dataLength + 1024)))
  392. {
  393. APITRACE("JpegEncEncode: ERROR Invalid output buffer");
  394. return JPEGENC_INVALID_ARGUMENT;
  395. }
  396. /* Clear the output structure */
  397. pEncOut->jfifSize = 0;
  398. /* todo: check that thumbnail fits also */
  399. /* Set stream buffer, the size has been checked */
  400. if(EncJpegSetBuffer(&pEncInst->stream, (u8 *) pEncIn->pOutBuf,
  401. (u32) pEncIn->outBufSize) == ENCHW_NOK)
  402. {
  403. APITRACE("JpegEncEncode: ERROR Invalid output buffer");
  404. return JPEGENC_INVALID_ARGUMENT;
  405. }
  406. /* Set ASIC input image */
  407. asic->regs.inputLumBase = pEncIn->busLum;
  408. asic->regs.inputCbBase = pEncIn->busCb;
  409. asic->regs.inputCrBase = pEncIn->busCr;
  410. asic->regs.pixelsOnRow = (u32) preProcess->lumWidthSrc;
  411. asic->regs.outputStrmSize = pEncIn->outBufSize;
  412. asic->regs.outputStrmBase = pEncIn->busOutBuf;
  413. asic->regs.jpegMode = (jpeg->codingMode == ENC_420_MODE) ? 0 : 1;
  414. /* slice/restart information */
  415. if(jpeg->codingType == ENC_WHOLE_FRAME)
  416. {
  417. asic->regs.jpegSliceEnable = 0;
  418. asic->regs.jpegRestartInterval =
  419. (jpeg->restart.Ri / ((u32) jpeg->width / 16));
  420. asic->regs.jpegRestartMarker = 0;
  421. }
  422. else
  423. {
  424. asic->regs.jpegSliceEnable = 1;
  425. asic->regs.jpegRestartInterval = 0;
  426. }
  427. /* Check if this is start of a new frame */
  428. if(jpeg->sliceNum == 0)
  429. {
  430. jpeg->mbNum = 0;
  431. /*jpeg->column = 0;*/
  432. jpeg->row = 0;
  433. }
  434. /* For sliced frame, check if this slice should be encoded.
  435. * Vertical offset is multiple of slice height */
  436. if((jpeg->codingType == ENC_PARTIAL_FRAME) &&
  437. (preProcess->verOffsetSrc >
  438. (u32) (jpeg->sliceNum * jpeg->sliceRows * 16)))
  439. {
  440. jpeg->sliceNum++;
  441. APITRACE("JpegEncEncode: OK restart interval");
  442. return JPEGENC_RESTART_INTERVAL;
  443. }
  444. /* Check if HW resource is available */
  445. if(EWLReserveHw(pEncInst->asic.ewl) == EWL_ERROR)
  446. {
  447. APITRACE("JpegEncEncode: ERROR hw resource unavailable");
  448. return JPEGENC_HW_RESERVED;
  449. }
  450. /* set the rst value for HW if RST wanted */
  451. if(jpeg->restart.Ri)
  452. {
  453. switch (jpeg->rstCount)
  454. {
  455. case 0:
  456. asic->regs.jpegRestartMarker = RST0;
  457. break;
  458. case 1:
  459. asic->regs.jpegRestartMarker = RST1;
  460. break;
  461. case 2:
  462. asic->regs.jpegRestartMarker = RST2;
  463. break;
  464. case 3:
  465. asic->regs.jpegRestartMarker = RST3;
  466. break;
  467. case 4:
  468. asic->regs.jpegRestartMarker = RST4;
  469. break;
  470. case 5:
  471. asic->regs.jpegRestartMarker = RST5;
  472. break;
  473. case 6:
  474. asic->regs.jpegRestartMarker = RST6;
  475. break;
  476. case 7:
  477. asic->regs.jpegRestartMarker = RST7;
  478. break;
  479. default:
  480. ASSERT(0);
  481. }
  482. jpeg->rstCount++;
  483. if(jpeg->rstCount > 7)
  484. jpeg->rstCount = 0;
  485. }
  486. if(jpeg->codingType == ENC_WHOLE_FRAME)
  487. {
  488. /* Adjust ASIC input image with pre-processing */
  489. EncPreProcess(asic, preProcess);
  490. }
  491. else
  492. {
  493. /* Set frame dimensions in slice mode for pre-processing */
  494. if((jpeg->row + jpeg->sliceRows) <= (jpeg->height / 16))
  495. {
  496. preProcess->lumHeight = (16 * ((i32) pEncInst->jpeg.restart.Ri /
  497. ((pEncInst->jpeg.width + 15) / 16)));
  498. }
  499. else
  500. {
  501. preProcess->lumHeight = (jpeg->height -
  502. (jpeg->sliceNum * (jpeg->sliceRows * 16)));
  503. }
  504. preProcess->verOffsetSrc = 0;
  505. /* Check if we need to update height for last slice (for ASIC) */
  506. if(((jpeg->height / 16) - jpeg->row) < jpeg->sliceRows)
  507. {
  508. asic->regs.mbsInCol = (((jpeg->height + 15) / 16) - jpeg->row);
  509. }
  510. /* enable EOI writing in last slice */
  511. if((jpeg->row + jpeg->sliceRows) >= (jpeg->height / 16))
  512. {
  513. asic->regs.jpegSliceEnable = 0;
  514. }
  515. /* Adjust ASIC input image with pre-processing */
  516. EncPreProcess(asic, preProcess);
  517. }
  518. #ifdef TRACE_STREAM
  519. traceStream.id = 0; /* Stream generated by SW */
  520. traceStream.bitCnt = 0; /* New frame */
  521. #endif
  522. /* Enable/disable jfif header generation */
  523. if(pEncIn->frameHeader)
  524. jpeg->frame.header = ENCHW_YES;
  525. else
  526. jpeg->frame.header = ENCHW_NO;
  527. /* Encode one image or one slice */
  528. ret = EncJpegCodeFrame(pEncInst);
  529. if(ret != JPEGENCODE_OK)
  530. {
  531. /* Error has occured and the frame is invalid */
  532. JpegEncRet to_user;
  533. /* Error has occured and the image is invalid.
  534. * The image size is passed to the user and can be used for debugging */
  535. pEncOut->jfifSize = (i32) pEncInst->stream.byteCnt;
  536. switch (ret)
  537. {
  538. case JPEGENCODE_TIMEOUT:
  539. APITRACE("JpegEncEncode: ERROR HW timeout");
  540. to_user = JPEGENC_HW_TIMEOUT;
  541. break;
  542. case JPEGENCODE_HW_RESET:
  543. APITRACE("JpegEncEncode: ERROR HW reset detected");
  544. to_user = JPEGENC_HW_RESET;
  545. break;
  546. case JPEGENCODE_HW_ERROR:
  547. APITRACE("JpegEncEncode: ERROR HW failure");
  548. to_user = JPEGENC_HW_BUS_ERROR;
  549. break;
  550. case JPEGENCODE_SYSTEM_ERROR:
  551. default:
  552. /* System error has occured, encoding can't continue */
  553. pEncInst->encStatus = ENCSTAT_ERROR;
  554. APITRACE("JpegEncEncode: ERROR Fatal system error");
  555. to_user = JPEGENC_SYSTEM_ERROR;
  556. }
  557. return to_user;
  558. }
  559. /* Store the stream size in output structure */
  560. pEncOut->jfifSize = (i32) pEncInst->stream.byteCnt;
  561. /* Check for stream buffer overflow */
  562. if(pEncInst->stream.overflow == ENCHW_YES)
  563. {
  564. /* The rest of the frame is lost */
  565. jpeg->sliceNum = 0;
  566. APITRACE("JpegEncEncode: ERROR stream buffer overflow");
  567. return JPEGENC_OUTPUT_BUFFER_OVERFLOW;
  568. }
  569. /* Check if this is end of slice or end of frame */
  570. if(jpeg->mbNum < jpeg->mbPerFrame)
  571. {
  572. jpeg->sliceNum++;
  573. APITRACE("JpegEncEncode: OK restart interval");
  574. return JPEGENC_RESTART_INTERVAL;
  575. }
  576. jpeg->sliceNum = 0;
  577. jpeg->rstCount = 0;
  578. APITRACE("JpegEncEncode: OK frame ready");
  579. return JPEGENC_FRAME_READY;
  580. }
  581. /*******************************************************************************
  582. Function name : CheckFullSize
  583. Description : Check that full image size is valid
  584. Return type : JPEGENC_OK for success
  585. Argument : JpegEncCfg
  586. *******************************************************************************/
  587. i32 CheckFullSize(const JpegEncCfg * pCfgFull)
  588. {
  589. if((pCfgFull->inputWidth > 8192) || (pCfgFull->inputHeight > 8192))
  590. {
  591. return JPEGENC_ERROR;
  592. }
  593. if((pCfgFull->codingWidth < 96) || (pCfgFull->codingWidth > (511 * 16)))
  594. {
  595. return JPEGENC_ERROR;
  596. }
  597. if((pCfgFull->codingHeight < 32) || (pCfgFull->codingHeight > (511 * 16)))
  598. {
  599. return JPEGENC_ERROR;
  600. }
  601. if(((pCfgFull->codingWidth + 15) >> 4) *
  602. ((pCfgFull->codingHeight + 15) >> 4) > JPEGENC_MAX_SIZE)
  603. {
  604. return JPEGENC_ERROR;
  605. }
  606. if((pCfgFull->codingWidth & (3)) != 0)
  607. {
  608. return JPEGENC_ERROR;
  609. }
  610. if((pCfgFull->codingHeight & (1)) != 0)
  611. {
  612. return JPEGENC_ERROR;
  613. }
  614. if((pCfgFull->inputWidth & (15)) != 0)
  615. {
  616. return JPEGENC_ERROR;
  617. }
  618. if(pCfgFull->inputWidth < ((pCfgFull->codingWidth + 15) & (~15)))
  619. {
  620. return JPEGENC_ERROR;
  621. }
  622. return JPEGENC_OK;
  623. }
  624. /*******************************************************************************
  625. Function name : CheckThumbnailCfg
  626. Description : Check that thumbnail data is valid
  627. Return type : JPEGENC_OK for success
  628. Argument : JpegEncCfg
  629. *******************************************************************************/
  630. i32 CheckThumbnailCfg(const JpegEncThumb * pCfgThumb)
  631. {
  632. u16 dataLength;
  633. if(pCfgThumb->width < 16) /* max size limit by data range, 8-bits */
  634. {
  635. return JPEGENC_ERROR;
  636. }
  637. if(pCfgThumb->height < 16) /* max size limit by data range, 8-bits */
  638. {
  639. return JPEGENC_ERROR;
  640. }
  641. if(pCfgThumb->data == NULL)
  642. {
  643. return JPEGENC_ERROR;
  644. }
  645. switch(pCfgThumb->format)
  646. {
  647. case JPEGENC_THUMB_JPEG:
  648. {
  649. dataLength = ((1<<16) - 1) - 8; /* 16 bits minus the APP0 ext field count */
  650. if(pCfgThumb->dataLength > dataLength)
  651. return JPEGENC_ERROR;
  652. }
  653. break;
  654. case JPEGENC_THUMB_PALETTE_RGB8:
  655. {
  656. dataLength = 3*256 + (pCfgThumb->width*pCfgThumb->height);
  657. if((dataLength > (((1<<16) - 1) - 10)) || /* 16 bits minus the APP0 ext field count */
  658. (pCfgThumb->dataLength != dataLength))
  659. return JPEGENC_ERROR;
  660. }
  661. break;
  662. case JPEGENC_THUMB_RGB24:
  663. {
  664. dataLength = (3*pCfgThumb->width*pCfgThumb->height);
  665. if((dataLength > (((1<<16) - 1) - 10)) || /* 16 bits minus the APP0 ext field count */
  666. (pCfgThumb->dataLength != dataLength))
  667. return JPEGENC_ERROR;
  668. }
  669. break;
  670. default:
  671. return JPEGENC_ERROR;
  672. }
  673. return JPEGENC_OK;
  674. }
  675. /*******************************************************************************
  676. Function name : CheckJpegCfg
  677. Description : Check that all values in the input structure are valid
  678. Return type : bool_e
  679. Argument : JpegEncCfg
  680. *******************************************************************************/
  681. bool_e CheckJpegCfg(const JpegEncCfg * pEncCfg)
  682. {
  683. /* check HW limitations */
  684. {
  685. EWLHwConfig_t cfg = EWLReadAsicConfig();
  686. /* is JPEG encoding supported */
  687. if(cfg.jpegEnabled == EWL_HW_CONFIG_NOT_SUPPORTED)
  688. {
  689. return ENCHW_NOK;
  690. }
  691. if(cfg.rgbEnabled == EWL_HW_CONFIG_NOT_SUPPORTED &&
  692. pEncCfg->frameType > 3)
  693. {
  694. return ENCHW_NOK;
  695. }
  696. }
  697. if(pEncCfg->qLevel > 10)
  698. return ENCHW_NOK;
  699. if(pEncCfg->frameType != JPEGENC_YUV420_PLANAR &&
  700. pEncCfg->frameType != JPEGENC_YUV420_SEMIPLANAR &&
  701. pEncCfg->frameType != JPEGENC_YUV422_INTERLEAVED_YUYV &&
  702. pEncCfg->frameType != JPEGENC_YUV422_INTERLEAVED_UYVY &&
  703. pEncCfg->frameType != JPEGENC_RGB565 &&
  704. pEncCfg->frameType != JPEGENC_BGR565 &&
  705. pEncCfg->frameType != JPEGENC_RGB555 &&
  706. pEncCfg->frameType != JPEGENC_BGR555 &&
  707. pEncCfg->frameType != JPEGENC_RGB444 &&
  708. pEncCfg->frameType != JPEGENC_BGR444 &&
  709. pEncCfg->frameType != JPEGENC_RGB888 &&
  710. pEncCfg->frameType != JPEGENC_BGR888 &&
  711. pEncCfg->frameType != JPEGENC_RGB101010 &&
  712. pEncCfg->frameType != JPEGENC_BGR101010)
  713. return ENCHW_NOK;
  714. if(pEncCfg->codingType != JPEGENC_WHOLE_FRAME &&
  715. pEncCfg->codingType != JPEGENC_SLICED_FRAME)
  716. return ENCHW_NOK;
  717. /* Units type must be valid */
  718. if(pEncCfg->unitsType != JPEGENC_NO_UNITS &&
  719. pEncCfg->unitsType != JPEGENC_DOTS_PER_INCH &&
  720. pEncCfg->unitsType != JPEGENC_DOTS_PER_CM)
  721. return ENCHW_NOK;
  722. /* Xdensity and Ydensity must valid */
  723. if((pEncCfg->xDensity > 0xFFFFU) ||
  724. (pEncCfg->yDensity > 0xFFFFU))
  725. return ENCHW_NOK;
  726. /* COM header length */
  727. if((pEncCfg->comLength > 0xFFFDU) ||
  728. (pEncCfg->comLength != 0 && pEncCfg->pCom == NULL))
  729. return ENCHW_NOK;
  730. /* Marker type must be valid */
  731. if(pEncCfg->markerType != JPEGENC_SINGLE_MARKER &&
  732. pEncCfg->markerType != JPEGENC_MULTI_MARKER)
  733. return ENCHW_NOK;
  734. return ENCHW_OK;
  735. }