int compress_mem_chunk( const uint64_t mem_read_start, const uint64_t mem_read_length, const uint64_t mem_output_start, uint64_t* const mem_output_length, struct compress_header** const header_address) { int return_code = 0; printf("Chunk %016" PRIx64 " - %016" PRIx64 " @ 0x%" PRIx64 " (%s)...\n", mem_read_start, mem_read_start + mem_read_length, mem_output_start, get_mem_size(*mem_output_length) ); unsigned char src_buffer[128]; unsigned char dst_buffer[DST_BUFFER_SIZE]; uint64_t mem_read_pointer = mem_read_start; uint64_t mem_output_pointer = mem_output_start; context_sha256_t sha256_ctx; z_stream stream_context; stream_context.zalloc = (alloc_func)0; stream_context.zfree = (free_func)0; stream_context.opaque = (voidpf)0; stream_context.next_out = dst_buffer; stream_context.avail_out = DST_BUFFER_SIZE; if (deflateInit(&stream_context, Z_BEST_COMPRESSION) != Z_OK) { printf("Zlib init failed!\n"); return RETURN_CODE_FAILED; } sha256_starts(&sha256_ctx); // Set header pointer to begin of the output buffer *header_address = (struct compress_header*) mem_output_pointer; mem_output_pointer += sizeof(struct compress_header); uint64_t bytes_read = 0; uint64_t bytes_write = 0; uint64_t bytes_skipped = 0; for (; mem_read_pointer < mem_read_start + mem_read_length && mem_output_pointer + DST_BUFFER_SIZE < mem_output_start + *mem_output_length && IS_VALID_POINTER(mem_read_pointer); mem_read_pointer += sizeof(int)) { bool buffer_underrun = 0; int data; if (stream_context.avail_out < 100) { // We have less than 100 bytes in our scratchpad... // There are basicly 2 options left. Skip some data or crash. // Most likely is skipping some data the less evil of the two if (!buffer_underrun) { printf("WARNING: Buffer underrun!\n"); buffer_underrun = 1; } data = 0; bytes_skipped += sizeof(int); } else if (is_readable_mem_address(mem_read_pointer)) { data = *((int*)mem_read_pointer); bytes_read += sizeof(int); buffer_underrun = 0; } else { data = 0; bytes_skipped += sizeof(int); } sha256_update(&sha256_ctx, (uint8_t*)&data, sizeof(int)); //The input is not always 100% used, so use a small buffer for the few cases a couple of bytes are left *(int*)(src_buffer + stream_context.avail_in) = data; stream_context.next_in = src_buffer; stream_context.avail_in += sizeof(int); if (deflate(&stream_context, Z_NO_FLUSH) != Z_OK) { printf("Memory compression failed!\n"); return_code = RETURN_CODE_FAILED; goto out; } if (stream_context.avail_out < (DST_BUFFER_SIZE - 100)) { unsigned short bytes_waiting = DST_BUFFER_SIZE - stream_context.avail_out; if ((mem_output_pointer + bytes_waiting) < mem_read_pointer || mem_read_start + mem_read_length <= mem_output_start) { // Make sure we stay behind the read pointer uint64_t mem_output_length_remaing = *mem_output_length - (mem_output_pointer - mem_output_start); if (write_buffer_to_buffer(dst_buffer, bytes_waiting, mem_output_pointer, &mem_output_length_remaing) < 0 || mem_output_length_remaing == 0) { printf("Fatal error!\n"); return_code = RETURN_CODE_FAILED; goto out; } mem_output_pointer += mem_output_length_remaing; bytes_write += bytes_waiting; stream_context.next_out = dst_buffer; stream_context.avail_out = DST_BUFFER_SIZE; } } if (stream_context.avail_out == 0) { printf("Memory compression failed! No space left in buffer\n"); printf("Read pointer %016" PRIx64 " Output pointer %016" PRIx64 " length %x\n", mem_read_pointer, mem_output_pointer, (DST_BUFFER_SIZE - stream_context.avail_out) ); return_code = RETURN_CODE_FAILED; goto out; } } if (IS_32BIT() && mem_read_pointer > ~0u) { printf("WARNING: Only lower 32 bit of memory is compressed!\n"); } int deflate_status; do { deflate_status = deflate(&stream_context, Z_FINISH); if (deflate_status != Z_OK && deflate_status != Z_STREAM_END) { printf("Memory compression failed to finish!\n"); return_code = RETURN_CODE_FAILED; goto out; } unsigned short bytes_waiting = DST_BUFFER_SIZE - stream_context.avail_out; if ((mem_output_pointer + bytes_waiting) >= mem_read_pointer && mem_output_start <= mem_read_start) { printf("WARNING: Output buffer will overwrite not read data!\n"); printf("Read pointer %016" PRIx64 " Output pointer %016" PRIx64 " length %x\n", mem_read_pointer, mem_output_pointer, (DST_BUFFER_SIZE - stream_context.avail_out) ); return_code = RETURN_CODE_FAILED; goto out; } uint64_t mem_output_length_remaing = *mem_output_length - (mem_output_pointer - mem_output_start); if (write_buffer_to_buffer(dst_buffer, bytes_waiting, mem_output_pointer, &mem_output_length_remaing) < 0 || mem_output_length_remaing == 0) { printf("Fatal error!\n"); return_code = RETURN_CODE_FAILED; goto out; } mem_output_pointer += mem_output_length_remaing; bytes_write += bytes_waiting; stream_context.next_out = dst_buffer; stream_context.avail_out = DST_BUFFER_SIZE; } while(deflate_status == Z_OK); if (deflateEnd(&stream_context) != Z_OK) { printf("Compression state failure!\n"); return_code = RETURN_CODE_FAILED; goto out; } out: //Marker so it can be found back (*header_address)->marker[0] = 'M'; (*header_address)->marker[1] = 'E'; (*header_address)->marker[2] = 'M'; (*header_address)->marker[3] = 0xf1; (*header_address)->marker[4] = 0x88; (*header_address)->marker[5] = 0x15; (*header_address)->marker[6] = 0x08; (*header_address)->marker[7] = 0x5c; (*header_address)->start_address = mem_read_start; (*header_address)->end_address = mem_read_pointer - 1; (*header_address)->compressed_length = bytes_write; (*header_address)->uncompressed_length = bytes_read + bytes_skipped; (*header_address)->skipped_length = bytes_skipped; sha256_finish(&sha256_ctx, (*header_address)->checksum); *mem_output_length = mem_output_pointer - mem_output_start; g_chunks++; return return_code; }
void finalize_ozstream(struct ozstream *self) { finalize_ostream(&self->up); deflateEnd(&self->zstream); }
static int compressor_close(avs_stream_abstract_t *stream) { return deflateEnd(&((zlib_stream_t *) stream)->zlib) == Z_OK ? 0 : -1; }
//--------------------------------------------------------------------- void DeflateStream::compressFinal() { // Close temp stream mTmpWriteStream->close(); // Copy & compress // We do this rather than compress directly because some code seeks // around while writing (e.g. to update size blocks) which is not // possible when compressing on the fly int ret, flush; char in[OGRE_DEFLATE_TMP_SIZE]; char out[OGRE_DEFLATE_TMP_SIZE]; if (deflateInit(mpZStream, Z_DEFAULT_COMPRESSION) != Z_OK) { destroy(); OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Error initialising deflate compressed stream!", "DeflateStream::init"); } std::ifstream inFile; inFile.open(mTempFileName.c_str(), std::ios::in | std::ios::binary); do { inFile.read(in, OGRE_DEFLATE_TMP_SIZE); mpZStream->avail_in = inFile.gcount(); if (inFile.bad()) { deflateEnd(mpZStream); OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Error reading temp uncompressed stream!", "DeflateStream::init"); } flush = inFile.eof() ? Z_FINISH : Z_NO_FLUSH; mpZStream->next_in = (Bytef*)in; /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ do { mpZStream->avail_out = OGRE_DEFLATE_TMP_SIZE; mpZStream->next_out = (Bytef*)out; ret = deflate(mpZStream, flush); /* no bad return value */ assert(ret != Z_STREAM_ERROR); /* state not clobbered */ size_t compressed = OGRE_DEFLATE_TMP_SIZE - mpZStream->avail_out; mCompressedStream->write(out, compressed); } while (mpZStream->avail_out == 0); assert(mpZStream->avail_in == 0); /* all input will be used */ /* done when last data in file processed */ } while (flush != Z_FINISH); assert(ret == Z_STREAM_END); /* stream will be complete */ deflateEnd(mpZStream); remove(mTempFileName.c_str()); }
void server_destroy(client_t *client, const char *reason) { lua_pushliteral(L, "on_client_close"); lua_rawget(L, LUA_GLOBALSINDEX); lua_pushnumber(L, client_num(client)); lua_pushstring(L, reason); if (lua_pcall(L, 2, 0, 0) != 0) { fprintf(stderr, "error calling on_client_close: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); } // Quitmeldung senden if (client->is_gui_client) { packet_t packet; packet_init(&packet, PACKET_QUIT_MSG); packet_writeXX(&packet, reason, strlen(reason)); server_send_packet(&packet, client); } else { server_writeto(client, "connection terminated: ", 23); server_writeto(client, reason, strlen(reason)); server_writeto(client, "\r\n", 2); } // Kompressionsrest flushen server_flush_compression(client); // Rest rausschreiben (hier keine Fehlerbehandlung mehr, da eh egal). // Bei Filewritern muss nichts geschrieben werden, da deren Daten // immer direkt rausgeschrieben werden. if (!client->is_file_writer) evbuffer_write(client->out_buf, client->fd); evbuffer_free(client->in_buf); evbuffer_free(client->out_buf); free(client->kill_me); if (client->compress) deflateEnd(&client->strm); event_del(&client->rd_event); event_del(&client->wr_event); client->in_buf = NULL; client->out_buf = NULL; if (client->player) player_detach_client(client, client->player); assert(client->next == NULL); assert(client->prev == NULL); if (client->is_gui_client) { if (client->next_gui == client) { assert(client->prev_gui == client); guiclients = NULL; } else { client->next_gui->prev_gui = client->prev_gui; client->prev_gui->next_gui = client->next_gui; guiclients = client->next_gui; } } num_clients--; #ifndef NO_CONSOLE_CLIENT if (client->fd != STDIN_FILENO) #endif #ifdef WIN32 if (client->is_file_writer) { close(client->fd); } else { closesocket(client->fd); } #else close(client->fd); #endif }
void ClientMgr::SendPackedClientInfo(WServer * server) { if(!m_clients.size()) return; ByteBuffer uncompressed(40000 * 19 + 8); uncompressed << uint32(m_clients.size()); /* pack them all togther, w000t! */ ClientMap::iterator itr = m_clients.begin(); RPlayerInfo * pi; for(; itr != m_clients.end(); itr++) { pi = itr->second; pi->Pack(uncompressed); } // I still got no idea where this came from :p size_t destsize = uncompressed.size() + uncompressed.size()/10 + 16; WorldPacket data(ISMSG_PACKED_PLAYER_INFO, destsize + 4); data.resize(destsize + 4); z_stream stream; stream.zalloc = 0; stream.zfree = 0; stream.opaque = 0; if(deflateInit(&stream, 1) != Z_OK) { printf("deflateInit failed."); return; } // set up stream pointers stream.next_out = (Bytef*)((uint8*)data.contents())+4; stream.avail_out = (uInt)destsize; stream.next_in = (Bytef*)uncompressed.contents(); stream.avail_in = (uInt)uncompressed.size(); // call the actual process if(deflate(&stream, Z_NO_FLUSH) != Z_OK || stream.avail_in != 0) { printf("deflate failed."); return; } // finish the deflate if(deflate(&stream, Z_FINISH) != Z_STREAM_END) { printf("deflate failed: did not end stream"); return; } // finish up if(deflateEnd(&stream) != Z_OK) { printf("deflateEnd failed."); return; } // put real size at the beginning of the packet *(uint32*)data.contents() = (uint32)uncompressed.size(); data.resize(stream.total_out + 4); server->SendPacket(&data); }
/* * Copies "from" to "to", compressing "to" on the fly */ int copy_and_zip_file (const char *from, const char *to, int force_overwrite, int must_exist) { struct stat sb; struct utimbuf t; int fdin, fdout; z_stream zstr = {0}; int zstatus; char buf[BUFSIZ*10]; char zbuf[BUFSIZ*20]; int n,zlen; #ifdef UTIME_EXPECTS_WRITABLE int change_it_back = 0; #endif TRACE(1,"copy_and_zip(%s,%s)",PATCH_NULL(from),PATCH_NULL(to)); if (noexec) return 0; /* If the file to be copied is a link or a device, then just create the new link or device appropriately. */ if (islink (from)) { char *source = xreadlink (from); symlink (source, to); xfree (source); return 0; } if (isdevice (from)) { #if defined(HAVE_MKNOD) && defined(HAVE_STRUCT_STAT_ST_RDEV) if (stat (from, &sb) < 0) error (1, errno, "cannot stat %s", from); mknod (to, sb.st_mode, sb.st_rdev); #else error (1, 0, "cannot copy device files on this system (%s)", fn_root(from)); #endif } else { /* Not a link or a device... probably a regular file. */ if ((fdin = CVS_OPEN (from, O_RDONLY)) < 0) { if(must_exist) error (1, errno, "cannot open %s for copying", fn_root(from)); else return -1; } if (fstat (fdin, &sb) < 0) { if(must_exist) error (1, errno, "cannot fstat %s", fn_root(from)); else { close(fdin); return -1; } } if (force_overwrite && unlink_file (to) && !existence_error (errno)) error (1, errno, "unable to remove %s", fn_root(to)); if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0) error (1, errno, "cannot create %s for copying", fn_root(to)); zstatus = deflateInit2 (&zstr, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY); if(zstatus != Z_OK) error(1, 0, "compression error (INIT): (%d)%s", zstatus,zstr.msg); if (sb.st_size > 0) { for (;;) { n = read (fdin, buf, sizeof(buf)); if (n == -1) { #ifdef EINTR if (errno == EINTR) continue; #endif error (1, errno, "cannot read file %s for copying", fn_root(from)); } else if (n == 0) break; zlen = deflateBound(&zstr,n); if(zlen>sizeof(zbuf)) error(1,0,"compression error: zlen=%d (> %d)",zlen,(int)sizeof(zbuf)); zstr.next_in = (Bytef*)buf; zstr.avail_in = n; zstr.next_out = (Bytef*)zbuf; zstr.avail_out = zlen; zstatus = deflate (&zstr, Z_SYNC_FLUSH); if(zstatus != Z_OK) error(1,0, "compression error (Z_SYNC_FLUSH): (%d)%s", zstatus,zstr.msg); n = zlen-zstr.avail_out; if (n && write(fdout, zbuf, n) != n) { error (1, errno, "cannot write file %s for copying", fn_root(to)); } } #ifdef HAVE_FSYNC if (fsync (fdout)) error (1, errno, "cannot fsync file %s after copying", fn_root(to)); #endif } zstr.next_in = (Bytef*)buf; zstr.avail_in = 0; zstr.next_out = (Bytef*)zbuf; zstr.avail_out = sizeof(zbuf); zstatus = deflate (&zstr, Z_FINISH); if(zstatus != Z_OK && zstatus != Z_STREAM_END) error(1,0, "compression error (Z_FINISH): (%d)%s", zstatus,zstr.msg); n = sizeof(zbuf)-zstr.avail_out; if (n && write(fdout, zbuf, n) != n) { error (1, errno, "cannot write file %s for copying", fn_root(to)); } zstr.next_in = (Bytef*)buf; zstr.avail_in = 0; zstr.next_out = (Bytef*)zbuf; zstr.avail_out = sizeof(zbuf); zstatus = deflateEnd(&zstr); if(zstatus != Z_OK) error(1,0, "compression error: %s", zstr.msg); if (close (fdin) < 0) error (0, errno, "cannot close %s", fn_root(from)); if (close (fdout) < 0) error (1, errno, "cannot close %s", fn_root(to)); } #ifdef UTIME_EXPECTS_WRITABLE if (!iswritable (to)) { xchmod (to, 1); change_it_back = 1; } #endif /* UTIME_EXPECTS_WRITABLE */ /* now, set the times for the copied file to match those of the original */ memset ((char *) &t, 0, sizeof (t)); t.actime = sb.st_atime; t.modtime = sb.st_mtime; (void) utime (to, &t); #ifdef UTIME_EXPECTS_WRITABLE if (change_it_back) xchmod (to, 0); #endif /* UTIME_EXPECTS_WRITABLE */ return 0; }
/*---------------------------------------------------------------------- | NPT_ZipDeflateState::~NPT_ZipDeflateState +---------------------------------------------------------------------*/ NPT_ZipDeflateState::~NPT_ZipDeflateState() { deflateEnd(&m_Stream); }
void deflate_rsrc_dtor(zend_resource *res) { z_stream *ctx = zend_fetch_resource(res, NULL, le_deflate); deflateEnd(ctx); efree(ctx); }
file_error core_fcompress(core_file *file, int level) { file_error result = FILERR_NONE; /* can only do this for read-only and write-only cases */ if ((file->openflags & OPEN_FLAG_WRITE) != 0 && (file->openflags & OPEN_FLAG_READ) != 0) return FILERR_INVALID_ACCESS; /* if we have been compressing, flush and free the data */ if (file->zdata != NULL && level == FCOMPRESS_NONE) { int zerr = Z_OK; /* flush any remaining data if we are writing */ while ((file->openflags & OPEN_FLAG_WRITE) != 0 && zerr != Z_STREAM_END) { UINT32 actualdata; file_error filerr; /* deflate some more */ zerr = deflate(&file->zdata->stream, Z_FINISH); if (zerr != Z_STREAM_END && zerr != Z_OK) { result = FILERR_INVALID_DATA; break; } /* write the data */ if (file->zdata->stream.avail_out != sizeof(file->zdata->buffer)) { filerr = osd_write(file->file, file->zdata->buffer, file->zdata->realoffset, sizeof(file->zdata->buffer) - file->zdata->stream.avail_out, &actualdata); if (filerr != FILERR_NONE) break; file->zdata->realoffset += actualdata; file->zdata->stream.next_out = file->zdata->buffer; file->zdata->stream.avail_out = sizeof(file->zdata->buffer); } } /* end the appropriate operation */ if ((file->openflags & OPEN_FLAG_WRITE) != 0) deflateEnd(&file->zdata->stream); else inflateEnd(&file->zdata->stream); /* free memory */ free(file->zdata); file->zdata = NULL; } /* if we are just starting to compress, allocate a new buffer */ if (file->zdata == NULL && level > FCOMPRESS_NONE) { int zerr; /* allocate memory */ file->zdata = (zlib_data *)malloc(sizeof(*file->zdata)); if (file->zdata == NULL) return FILERR_OUT_OF_MEMORY; memset(file->zdata, 0, sizeof(*file->zdata)); /* initialize the stream and compressor */ if ((file->openflags & OPEN_FLAG_WRITE) != 0) { file->zdata->stream.next_out = file->zdata->buffer; file->zdata->stream.avail_out = sizeof(file->zdata->buffer); zerr = deflateInit(&file->zdata->stream, level); } else zerr = inflateInit(&file->zdata->stream); /* on error, return an error */ if (zerr != Z_OK) { free(file->zdata); file->zdata = NULL; return FILERR_OUT_OF_MEMORY; } /* flush buffers */ file->bufferbytes = 0; /* set the initial offset */ file->zdata->realoffset = file->offset; file->zdata->nextoffset = file->offset; } return result; }
extern int ZEXPORT zipCloseFileInZipRaw (//file, uncompressed_size, crc32) zipFile file, uLong uncompressed_size, uLong crc32) { zip_internal* zi; uLong compressed_size; int err=ZIP_OK; if (file == NULL) return ZIP_PARAMERROR; zi = (zip_internal*)file; if (zi->in_opened_file_inzip == 0) return ZIP_PARAMERROR; zi->ci.stream.avail_in = 0; if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) while (err==ZIP_OK) { uLong uTotalOutBefore; if (zi->ci.stream.avail_out == 0) { if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) err = ZIP_ERRNO; zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; zi->ci.stream.next_out = zi->ci.buffered_data; } uTotalOutBefore = zi->ci.stream.total_out; err=deflate(&zi->ci.stream, Z_FINISH); zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; } if (err==Z_STREAM_END) err=ZIP_OK; /* this is normal */ if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) if (zipFlushWriteBuffer(zi)==ZIP_ERRNO) err = ZIP_ERRNO; if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) { err=deflateEnd(&zi->ci.stream); zi->ci.stream_initialised = 0; } if (!zi->ci.raw) { crc32 = (uLong)zi->ci.crc32; uncompressed_size = (uLong)zi->ci.stream.total_in; } compressed_size = (uLong)zi->ci.stream.total_out; # ifndef NOCRYPT compressed_size += zi->ci.crypt_header_size; # endif ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ ziplocal_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ if (zi->ci.stream.data_type == Z_ASCII) ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); ziplocal_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ if (err==ZIP_OK) err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, (uLong)zi->ci.size_centralheader); free(zi->ci.central_header); if (err==ZIP_OK) { long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); if (ZSEEK(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) err = ZIP_ERRNO; if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ if (err==ZIP_OK) /* compressed size, unknown */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); if (err==ZIP_OK) /* uncompressed size, unknown */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); if (ZSEEK(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) err = ZIP_ERRNO; } zi->number_entry ++; zi->in_opened_file_inzip = 0; return err; }
static fz_image *render_to_pixmap(fz_context *ctx, HBITMAP hbmp, SizeI size) { int w = size.dx, h = size.dy; int stride = ((w * 3 + 3) / 4) * 4; unsigned char *data = (unsigned char *)fz_malloc(ctx, stride * h); BITMAPINFO bmi = { 0 }; bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = w; bmi.bmiHeader.biHeight = -h; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; HDC hDC = GetDC(nullptr); int res = GetDIBits(hDC, hbmp, 0, h, data, &bmi, DIB_RGB_COLORS); ReleaseDC(nullptr, hDC); if (!res) { fz_free(ctx, data); fz_throw(ctx, FZ_ERROR_GENERIC, "GetDIBits failed"); } // convert BGR with padding to RGB without padding unsigned char *out = data; bool is_grayscale = true; for (int y = 0; y < h; y++) { const unsigned char *in = data + y * stride; unsigned char green, blue; for (int x = 0; x < w; x++) { is_grayscale = is_grayscale && in[0] == in[1] && in[0] == in[2]; blue = *in++; green = *in++; *out++ = *in++; *out++ = green; *out++ = blue; } } // convert grayscale RGB to proper grayscale if (is_grayscale) { const unsigned char *in = out = data; for (int i = 0; i < w * h; i++) { *out++ = *in++; in += 2; } } fz_compressed_buffer *buf = nullptr; fz_var(buf); fz_try(ctx) { buf = fz_malloc_struct(ctx, fz_compressed_buffer); buf->buffer = fz_new_buffer(ctx, w * h * 4 + 10); buf->params.type = FZ_IMAGE_FLATE; buf->params.u.flate.predictor = 1; z_stream zstm = { 0 }; zstm.next_in = data; zstm.avail_in = out - data; zstm.next_out = buf->buffer->data; zstm.avail_out = buf->buffer->cap; res = deflateInit(&zstm, 9); if (res != Z_OK) fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res); res = deflate(&zstm, Z_FINISH); if (res != Z_STREAM_END) fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res); buf->buffer->len = zstm.total_out; res = deflateEnd(&zstm); if (res != Z_OK) fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res); } fz_always(ctx) { fz_free(ctx, data); } fz_catch(ctx) { fz_free_compressed_buffer(ctx, buf); fz_rethrow(ctx); } fz_colorspace *cs = is_grayscale ? fz_device_gray(ctx) : fz_device_rgb(ctx); return fz_new_image(ctx, w, h, 8, cs, 96, 96, 0, 0, nullptr, nullptr, buf, nullptr); }
void zlib_stream_deflate_free(void *data) { z_stream *ret = (z_stream*)data; if (ret) deflateEnd(ret); }
static void free_stream_def( value v ) { z_stream *s = val_stream(v); deflateEnd(s); // no error free(s); val_gc(v,NULL); }
CAMLprim value zlib_deflate_end(value zv) { if( deflateEnd(zval(zv)) != 0 ) failwith("zlib_deflate_end"); return Val_unit; }
int wcache_close(struct wcache_stream *wcs) { // parameter checking if ( (wcs == 0) || (wcs->entry == 0) ) { return(0); } #if (WEBC_SUPPORT_CACHE_COMPRESSION) if (wcs->entry->flags & WEBC_CACHE_ENTRY_COMPRESSED) { z_streamp pz = (z_streamp) wcs->pZlibStream; if (wcs->mode != WEBC_CO_READ) { long bytes_written = 0; int result, val; do { result = deflate(pz, Z_FINISH); if ((result == Z_STREAM_ERROR) || (result == Z_BUF_ERROR)) { break; } if ((wcs->outBufferSize - pz->avail_out) > (wcs->cc->bytesMax - wcs->cc->bytesUsed)) { // won't fit; try to free up some space if (_wcache_free_bytes(wcs->cc, (wcs->outBufferSize - pz->avail_out)) == 0) { break; } } val = webc_fwrite (wcs->fp, (char *) wcs->pOutBuffer, (wcs->outBufferSize - pz->avail_out)); if (val < 0) { break; } bytes_written += val; wcs->cc->bytesUsed += val; pz->avail_out = wcs->outBufferSize; pz->next_out = wcs->pOutBuffer; } while (result != Z_STREAM_END); wcs->entry->size += bytes_written; deflateEnd(pz); } else { inflateEnd(pz); } WEBC_FREE(wcs->pInBuffer); WEBC_FREE(wcs->pOutBuffer); WEBC_FREE(pz); } #endif // WEBC_SUPPORT_CACHE_COMPRESSION _wcache_unlock_entry(wcs->entry); wcs->cc->spec.sys_close(wcs->cc->sysPtr, wcs->fp); return (0); }
/** Attempt to send a sequence of bytes to the connection. * As a side effect, updates \a cptr's FLAG_BLOCKED setting * and sendB/sendK fields. * @param cptr Client that should receive data. * @param buf Message buffer to send to client. * @return Negative on connection-fatal error; otherwise * number of bytes sent. */ unsigned int deliver_it(struct Client *cptr, struct MsgQ *buf) { unsigned int bytes_written = 0; unsigned int bytes_count = 0; assert(0 != cptr); #if defined(USE_SSL) switch (client_sendv(cptr, buf, &bytes_count, &bytes_written)) { #else switch (os_sendv_nonb(cli_fd(cptr), buf, &bytes_count, &bytes_written)) { #endif case IO_SUCCESS: ClrFlag(cptr, FLAG_BLOCKED); cli_sendB(cptr) += bytes_written; cli_sendB(&me) += bytes_written; /* A partial write implies that future writes will block. */ if (bytes_written < bytes_count) SetFlag(cptr, FLAG_BLOCKED); break; case IO_BLOCKED: SetFlag(cptr, FLAG_BLOCKED); break; case IO_FAILURE: cli_error(cptr) = errno; SetFlag(cptr, FLAG_DEADSOCKET); break; } return bytes_written; } /** Complete non-blocking connect()-sequence. Check access and * terminate connection, if trouble detected. * @param cptr Client to which we have connected, with all ConfItem structs attached. * @return Zero on failure (caller should exit_client()), non-zero on success. */ static int completed_connection(struct Client* cptr) { struct ConfItem *aconf; time_t newts; struct Client *acptr; int i; #if defined(USE_SSL) char *sslfp; int r; #endif assert(0 != cptr); /* * get the socket status from the fd first to check if * connection actually succeeded */ if ((cli_error(cptr) = os_get_sockerr(cli_fd(cptr)))) { const char* msg = strerror(cli_error(cptr)); if (!msg) msg = "Unknown error"; sendto_opmask(0, SNO_OLDSNO, "Connection failed to %s: %s", cli_name(cptr), msg); return 0; } if (!(aconf = find_conf_byname(cli_confs(cptr), cli_name(cptr), CONF_SERVER))) { sendto_opmask(0, SNO_OLDSNO, "Lost Server Line for %s", cli_name(cptr)); return 0; } #if defined(USE_SSL) if (aconf->flags & CONF_SSL) { r = ssl_connect(&(cli_socket(cptr))); if (r == -1) { sendto_opmask(0, SNO_OLDSNO, "Connection failed to %s: SSL error", cli_name(cptr)); return 0; } else if (r == 0) return 1; sslfp = ssl_get_fingerprint(cli_socket(cptr).s_ssl); if (sslfp) ircd_strncpy(cli_sslclifp(cptr), sslfp, BUFSIZE+1); SetSSL(cptr); } #endif if (s_state(&(cli_socket(cptr))) == SS_CONNECTING) socket_state(&(cli_socket(cptr)), SS_CONNECTED); if (!EmptyString(aconf->passwd)) sendrawto_one(cptr, MSG_PASS " :%s", aconf->passwd); /* * Create a unique timestamp */ newts = TStime(); for (i = HighestFd; i > -1; --i) { if ((acptr = LocalClientArray[i]) && (IsServer(acptr) || IsHandshake(acptr))) { if (cli_serv(acptr)->timestamp >= newts) newts = cli_serv(acptr)->timestamp + 1; } } assert(0 != cli_serv(cptr)); cli_serv(cptr)->timestamp = newts; SetHandshake(cptr); /* * Make us timeout after twice the timeout for DNS look ups */ cli_lasttime(cptr) = CurrentTime; ClearPingSent(cptr); /* TODO: NEGOCIACION envia_config_req(cptr); */ sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6 :%s", cli_name(&me), cli_serv(&me)->timestamp, newts, MAJOR_PROTOCOL, NumServCap(&me), feature_bool(FEAT_HUB) ? "h" : "", cli_info(&me)); #if defined(DDB) ddb_burst(cptr); #endif return (IsDead(cptr)) ? 0 : 1; } /** Close the physical connection. Side effects: MyConnect(cptr) * becomes false and cptr->from becomes NULL. * @param cptr Client to disconnect. */ void close_connection(struct Client *cptr) { struct ConfItem* aconf; if (IsServer(cptr)) { ServerStats->is_sv++; ServerStats->is_sbs += cli_sendB(cptr); ServerStats->is_sbr += cli_receiveB(cptr); ServerStats->is_sti += CurrentTime - cli_firsttime(cptr); /* * If the connection has been up for a long amount of time, schedule * a 'quick' reconnect, else reset the next-connect cycle. */ if ((aconf = find_conf_exact(cli_name(cptr), cptr, CONF_SERVER))) { /* * Reschedule a faster reconnect, if this was a automatically * connected configuration entry. (Note that if we have had * a rehash in between, the status has been changed to * CONF_ILLEGAL). But only do this if it was a "good" link. */ aconf->hold = CurrentTime; aconf->hold += ((aconf->hold - cli_since(cptr) > feature_int(FEAT_HANGONGOODLINK)) ? feature_int(FEAT_HANGONRETRYDELAY) : ConfConFreq(aconf)); /* if (nextconnect > aconf->hold) */ /* nextconnect = aconf->hold; */ } } else if (IsUser(cptr)) { ServerStats->is_cl++; ServerStats->is_cbs += cli_sendB(cptr); ServerStats->is_cbr += cli_receiveB(cptr); ServerStats->is_cti += CurrentTime - cli_firsttime(cptr); } else ServerStats->is_ni++; #if defined(USE_ZLIB) /* * Siempre es una conexion nuestra */ if (cli_connect(cptr)->zlib_negociation & ZLIB_IN) { inflateEnd(cli_connect(cptr)->comp_in); MyFree(cli_connect(cptr)->comp_in); } if (cli_connect(cptr)->zlib_negociation & ZLIB_OUT) { deflateEnd(cli_connect(cptr)->comp_out); MyFree(cli_connect(cptr)->comp_out); } #endif if (-1 < cli_fd(cptr)) { flush_connections(cptr); LocalClientArray[cli_fd(cptr)] = 0; close(cli_fd(cptr)); socket_del(&(cli_socket(cptr))); /* queue a socket delete */ cli_fd(cptr) = -1; cli_freeflag(cptr) &= ~FREEFLAG_SOCKET; } SetFlag(cptr, FLAG_DEADSOCKET); MsgQClear(&(cli_sendQ(cptr))); client_drop_sendq(cli_connect(cptr)); DBufClear(&(cli_recvQ(cptr))); memset(cli_passwd(cptr), 0, sizeof(cli_passwd(cptr))); set_snomask(cptr, 0, SNO_SET); det_confs_butmask(cptr, 0); if (cli_listener(cptr)) { release_listener(cli_listener(cptr)); cli_listener(cptr) = 0; } for ( ; HighestFd > 0; --HighestFd) { if (LocalClientArray[HighestFd]) break; } } /** Close all unregistered connections. * @param source Oper who requested the close. * @return Number of closed connections. */ int net_close_unregistered_connections(struct Client* source) { int i; struct Client* cptr; int count = 0; assert(0 != source); for (i = HighestFd; i > 0; --i) { if ((cptr = LocalClientArray[i]) && !IsRegistered(cptr)) { send_reply(source, RPL_CLOSING, get_client_name(source, HIDE_IP)); exit_client(source, cptr, &me, "Oper Closing"); ++count; } } return count; }
/* Deflates source stringstream, encodes compressed bytes into Base64 and then puts the Base64 encoded data into destination stringstream */ int DeflateSStream( std::stringstream &ssSrc, std::stringstream &ssDst ) { int ret = Z_OK; int flush = true; // Allocate deflate state z_stream c_stream; // Compression stream c_stream.zalloc = Z_NULL; c_stream.zfree = Z_NULL; c_stream.opaque = Z_NULL; // Initialize for deflation ret = deflateInit( &c_stream, s_nCompressionLevel ); if ( ret != Z_OK ) return ret; std::string strSrc( ssSrc.str() ); // Free up the source stringstream ssSrc.str(""); int nInputSize = strSrc.size(); int nOutputSize = 0; #ifndef USE_CHUNKS // Allocate buffer for deflate to put data into char* out = new char[ nInputSize ]; c_stream.avail_in = nInputSize; c_stream.avail_out = nInputSize; c_stream.next_in = ( Bytef* ) strSrc.c_str(); c_stream.next_out = ( Bytef* ) out; // Compress ret = deflate( &c_stream, Z_FULL_FLUSH /*Z_PARTIAL_FLUSH*/ ); if ( ret != Z_OK ) return ret; std::string base64Str = ssDst.str(); // How big is the compressed result nOutputSize = nInputSize - c_stream.avail_out; // Encode the compressed bytes to Base64 StringToBase64( out, nOutputSize, base64Str ); delete[] out; // Put compressed Base64 data into the destination stringstream int nBase64 = base64Str.size(); ssDst.write( base64Str.c_str(), nBase64 ); #else // USE_CHUNKS int nRemaining = nInputSize; while ( nRemaining > 0 ) { char out[ s_nChunkSize ]; unsigned nHave = 0; strm.avail_in = ( nRemaining > s_nChunkSize ) ? s_nChunkSize : nRemaining; strm.avail_out = s_nChunkSize; strm.next_in = ( Bytef* ) strSrc.c_str() + ( nInputSize - nRemaining ); strm.next_out = ( Bytef* ) out; nRemaining -= strm.avail_in; ret = deflate( &strm, flush ); if ( ret != Z_OK ) return ret; // How big is the compressed result nHave = s_nChunkSize - strm.avail_out; ssDst.write( out, nOutputSize ); nOutputSize += nHave; } #endif // USE_CHUNKS // Free all allocated state information referenced by stream ret = deflateEnd( &c_stream ); return ret; }
size_t ZipArchive::deflateToDisk(File& inFile, std::ofstream& archive, unsigned long& crc) { if ((inFile.isOpen() == false) || (archive.is_open() == false)) { LERROR("deflateToDisk(): erroneous parameters! Handles might be closed."); return 0; } // Prepare z_stream structure for inflating // z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) { LERROR("deflateToDisk(): delfateInit2 failed!"); return 0; } size_t inBufferSize = (inFile.size() < MAX_BUFFER_SIZE) ? inFile.size() : MAX_BUFFER_SIZE; size_t outBufferSize = MAX_BUFFER_SIZE; char* inBuffer = 0; char* outBuffer = 0; try { inBuffer = new char[inBufferSize]; } catch (std::bad_alloc&) { LERROR("deflateToDisk(): failed to allocate " << inBufferSize << " Bytes for input buffer!"); return 0; } try { outBuffer = new char[outBufferSize]; } catch (std::bad_alloc&) { LERROR("deflateToDisk(): failed to allocate " << outBufferSize << " Bytes for output buffer!"); delete [] inBuffer; return 0; } // While we are reading the input file, we can also compute the CRC32... // crc = crc32(crc, Z_NULL, 0); size_t readTotal = 0; size_t writtenTotal = 0; bool error = false; inFile.seek(0, File::BEGIN); do { size_t read = inFile.read(inBuffer, inBufferSize); crc = crc32(crc, reinterpret_cast<Bytef*>(inBuffer), static_cast<uInt>(read)); readTotal += read; strm.avail_in = static_cast<uInt>(read); strm.next_in = reinterpret_cast<Bytef*>(inBuffer); do { strm.avail_out = static_cast<uInt>(outBufferSize); strm.next_out = reinterpret_cast<Bytef*>(outBuffer); int res = deflate(&strm, ((inFile.eof() == true) ? Z_FINISH : Z_NO_FLUSH)); if ((res != Z_OK) && (res != Z_STREAM_END)) { LERROR("deflateToDisk(): deflate returned code " << res << "!"); error = true; break; } size_t write = outBufferSize - strm.avail_out; archive.write(outBuffer, write); if (archive.fail() == true) { LERROR("deflateToDisk(): failed to write to output archive!"); error = true; break; } else writtenTotal += write; } while (strm.avail_out == 0); if (error == true) break; } while ((inFile.eof() == false) && (readTotal < inFile.size())); delete [] inBuffer; delete [] outBuffer; deflateEnd(&strm); return writtenTotal; }
/* Thread: httpd */ void httpd_send_reply(struct evhttp_request *req, int code, const char *reason, struct evbuffer *evbuf) { unsigned char outbuf[128 * 1024]; z_stream strm; struct evbuffer *gzbuf; struct evkeyvalq *headers; const char *param; int flush; int zret; int ret; if (!req) return; if (!evbuf || (EVBUFFER_LENGTH(evbuf) == 0)) { DPRINTF(E_DBG, L_HTTPD, "Not gzipping body-less reply\n"); goto no_gzip; } headers = evhttp_request_get_input_headers(req); param = evhttp_find_header(headers, "Accept-Encoding"); if (!param) { DPRINTF(E_DBG, L_HTTPD, "Not gzipping; no Accept-Encoding header\n"); goto no_gzip; } else if (!strstr(param, "gzip") && !strstr(param, "*")) { DPRINTF(E_DBG, L_HTTPD, "Not gzipping; gzip not in Accept-Encoding (%s)\n", param); goto no_gzip; } gzbuf = evbuffer_new(); if (!gzbuf) { DPRINTF(E_LOG, L_HTTPD, "Could not allocate evbuffer for gzipped reply\n"); goto no_gzip; } strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; /* Set up a gzip stream (the "+ 16" in 15 + 16), instead of a zlib stream (default) */ zret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); if (zret != Z_OK) { DPRINTF(E_DBG, L_HTTPD, "zlib setup failed: %s\n", zError(zret)); goto out_fail_init; } strm.next_in = EVBUFFER_DATA(evbuf); strm.avail_in = EVBUFFER_LENGTH(evbuf); flush = Z_NO_FLUSH; /* 2 iterations: Z_NO_FLUSH until input is consumed, then Z_FINISH */ for (;;) { do { strm.next_out = outbuf; strm.avail_out = sizeof(outbuf); zret = deflate(&strm, flush); if (zret == Z_STREAM_ERROR) { DPRINTF(E_LOG, L_HTTPD, "Could not deflate data: %s\n", strm.msg); goto out_fail_gz; } ret = evbuffer_add(gzbuf, outbuf, sizeof(outbuf) - strm.avail_out); if (ret < 0) { DPRINTF(E_LOG, L_HTTPD, "Out of memory adding gzipped data to evbuffer\n"); goto out_fail_gz; } } while (strm.avail_out == 0); if (flush == Z_FINISH) break; flush = Z_FINISH; } if (zret != Z_STREAM_END) { DPRINTF(E_LOG, L_HTTPD, "Compressed data not finalized!\n"); goto out_fail_gz; } deflateEnd(&strm); headers = evhttp_request_get_output_headers(req); evhttp_add_header(headers, "Content-Encoding", "gzip"); evhttp_send_reply(req, code, reason, gzbuf); evbuffer_free(gzbuf); /* Drain original buffer, as would be after evhttp_send_reply() */ evbuffer_drain(evbuf, EVBUFFER_LENGTH(evbuf)); return; out_fail_gz: deflateEnd(&strm); out_fail_init: evbuffer_free(gzbuf); no_gzip: evhttp_send_reply(req, code, reason, evbuf); }
/* {{{ php_zlib_output_handler_ex() */ static int php_zlib_output_handler_ex(php_zlib_context *ctx, php_output_context *output_context) { int flags = Z_SYNC_FLUSH; PHP_OUTPUT_TSRMLS(output_context); if (output_context->op & PHP_OUTPUT_HANDLER_START) { /* start up */ if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) { return FAILURE; } } if (output_context->op & PHP_OUTPUT_HANDLER_CLEAN) { /* free buffers */ deflateEnd(&ctx->Z); if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) { /* discard */ return SUCCESS; } else { /* restart */ if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) { return FAILURE; } ctx->buffer.used = 0; } } else { if (output_context->in.used) { /* append input */ if (ctx->buffer.free < output_context->in.used) { if (!(ctx->buffer.aptr = erealloc_recoverable(ctx->buffer.data, ctx->buffer.used + ctx->buffer.free + output_context->in.used))) { deflateEnd(&ctx->Z); return FAILURE; } ctx->buffer.data = ctx->buffer.aptr; ctx->buffer.free += output_context->in.used; } memcpy(ctx->buffer.data + ctx->buffer.used, output_context->in.data, output_context->in.used); ctx->buffer.free -= output_context->in.used; ctx->buffer.used += output_context->in.used; } output_context->out.size = PHP_ZLIB_BUFFER_SIZE_GUESS(output_context->in.used); output_context->out.data = emalloc(output_context->out.size); output_context->out.free = 1; output_context->out.used = 0; ctx->Z.avail_in = ctx->buffer.used; ctx->Z.next_in = (Bytef *) ctx->buffer.data; ctx->Z.avail_out = output_context->out.size; ctx->Z.next_out = (Bytef *) output_context->out.data; if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) { flags = Z_FINISH; } else if (output_context->op & PHP_OUTPUT_HANDLER_FLUSH) { flags = Z_FULL_FLUSH; } switch (deflate(&ctx->Z, flags)) { case Z_OK: if (flags == Z_FINISH) { deflateEnd(&ctx->Z); return FAILURE; } case Z_STREAM_END: if (ctx->Z.avail_in) { memmove(ctx->buffer.data, ctx->buffer.data + ctx->buffer.used - ctx->Z.avail_in, ctx->Z.avail_in); } ctx->buffer.free += ctx->buffer.used - ctx->Z.avail_in; ctx->buffer.used = ctx->Z.avail_in; output_context->out.used = output_context->out.size - ctx->Z.avail_out; break; default: deflateEnd(&ctx->Z); return FAILURE; } if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) { deflateEnd(&ctx->Z); } } return SUCCESS; }
void moloch_http_exit() { deflateEnd(&z_strm); }
/** *********************************** * Compress source data from memory to memory. * * @param source Source data * @param source_size Size of source data (if compressing a string, it can be strlen(source)+1) * @param dest Where to store compressed data * @param destination_size Max. size of compressed data * @param level Compession level * * @return If <0, error, Z_MEM_ERROR if could not allocate memory. * Z_VERSION_ERROR if version of zlib.h and linked library * Z_STREAM_ERROR if invalid compression level supplied. * ERR_UNDERSIZED if dest is not big enough to store all data * ERR_DEFLATE_PARTIAL if there was a problem running deflate * and it was not fully deflated * ERR_DEFLATE_PARTIAL_STREAM there was a problem and the compressed * stream does not ends right. * If >0, size of compressed data */ int dodeflate(char* source, size_t source_size, char* dest, size_t destination_size, int level) { int ret, flush; size_t have; z_stream strm; unsigned char *in = source; unsigned char *out = dest; size_t original_dest_size = destination_size; /* Initialize deflate */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit(&strm, level); if (ret != Z_OK) return ret; /* compress !! */ do { if (source_size>CHUNK) { strm.avail_in = CHUNK; source_size-=CHUNK; } else { strm.avail_in = source_size; source_size = 0; } flush = (source_size == 0) ? Z_FINISH : Z_NO_FLUSH; strm.next_in = in; /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ do { strm.avail_out = CHUNK; strm.next_out = out; if (destination_size < CHUNK) return ERR_UNDERSIZED; /* Not enough size */ ret = deflate(&strm, flush); /* no bad return value */ if (ret == Z_STREAM_ERROR) /* error check */ return ret; have = CHUNK - strm.avail_out; out+=have; /* Move out pointer */ destination_size-=have; /* calculate destination size left */ } while (strm.avail_out == 0); if (strm.avail_in != 0) return ERR_DEFLATE_PARTIAL; in+=CHUNK; /* Move in to the next chunk */ /* done when last data in file processed */ } while (flush != Z_FINISH); if (ret != Z_STREAM_END) return ERR_DEFLATE_PARTIAL_STREAM; /* clean up and return */ (void)deflateEnd(&strm); return original_dest_size-destination_size; }
//=========================================================================== // スレッド実行 //=========================================================================== void __fastcall TAttacheCaseFileEncrypt::Execute() { int i, c; int res; float ProgressPercentNumF; //進捗パーセンテージ(浮動小数点) z_stream z; // zlibライブラリとやりとりするための構造体 int flush, status; // zlib //出力する暗号化ファイルのタイムスタンプを元ファイルに合わせる HANDLE hFile; //_WIN32_FIND_DATAW first_fd; ZeroMemory(&first_fd, sizeof(_WIN32_FIND_DATAW)); int len, pos; int FileIndex; String FilePath; int HeaderSize; //ヘッダデータサイズ __int64 CurrentDriveFreeSpaceSize = -1; //保存するドライブの空き容量 //実行可能形式出力ファイルのデータサイズ __int64 ExeAllSize = 0; __int64 ExeSize = 0; //全体のファイルサイズ AllTotalSize = 0; __int64 TotalSize = 0; //バッファ char source_buffer[BUF_SIZE]; char read_buffer[BUF_SIZE]; char out_buffer[BUF_SIZE]; char chain_buffer[BUF_SIZE]; // IVなどを格納するチェインバッファ char margin_buffer[BUF_SIZE]; //ファイルストリーム TFileStream *fsIn; TFileStream *fsOut; TFileStream *fsExe; //オープン中か bool fOpenIn; bool fOpenOut; //メモリストリーム TMemoryStream *pms = new TMemoryStream; // マージンバッファサイズ int MarginBufSize = MARGIN_BUF_SIZE; // PKCS #7 Pading num. unsigned char paddingNum = 0; //--------------------------------------- // 同名ファイルがあるのでダイアログ表示 //--------------------------------------- if ( fConfirmOverwirte == true && fOverwirteYesToAll == false ) { if (FileExists(OutFilePath) == true) { //同名ファイルの上書き確認メッセージダイアログ MsgText = LoadResourceString(&Msgencrypt::_MSG_CONFIRM_OVER_WRITE_SAME_FILE)+"\n"+OutFilePath; Synchronize(&PostConfirmOverwriteMessageForm); if ( MsgReturnVal == mrYes ) { //上書きOKなのでFilePathはそのまま } else if ( MsgReturnVal == mrNo ) { //別名保存でFilePath文字列が書き換えられてきている OutFilePath = MsgReturnPath; } else if ( MsgReturnVal == mrYesToAll ) { //すべて上書き(YesToAll) fOverwirteYesToAll = true; } else if ( MsgReturnVal == mrCancel ) { //キャンセル delete pms; goto LabelStop; } } } //--------------------------------------- // ヘッダ情報の生成&ファイル総サイズ取得 //--------------------------------------- //'暗号化するファイルリストの生成中...' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_LISTING); if ( CreateHeaderData( pms, InputFileList, FilePathList, AllTotalSize) == false ){ if (Terminated == true) { //ユーザーキャンセルで抜けてきた delete pms; goto LabelStop; } else{ //'暗号化するファイルを開けません。他のアプリケーションが使用中の可能性があります。' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_FILE_OPEN); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete pms; goto LabelError; } } //----------------------------------- // ディスクの空き容量チェック //----------------------------------- CurrentDriveFreeSpaceSize = GetDiskFreeSpaceNum(OutFilePath); if (CurrentDriveFreeSpaceSize > -1 ) { if ( AllTotalSize > CurrentDriveFreeSpaceSize ) { //"ディスクの空き容量が足りません! 暗号化ファイルを保存できません。\n //暗号化を中止します。;" MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_NO_DISK_FREE_SPACE); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete pms; goto LabelError; } } else{ // -1はネットワークドライブの可能性があるので無視 //(万が一、別のエラーの場合、実際書き込みに移行したときエラーが発生する) } //----------------------------------- // 実行可能形式でかつ // 合計バイト数が4GBを越えたときのエラー //----------------------------------- if ( fExeOutputOption == true && fOver4gbOk == false && AllTotalSize > SIZE_4GB ){ //実行形式ファイルのサイズが4GBを超えてしまう可能性があります!\n //Win32アプリケーションとして実行できなくなるかもしれませんがよろしいですか?'; MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OVER_4GB_EXE); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbYes << mbNo; MsgDefaultButton = mbNo; Synchronize(&PostConfirmMessageForm); if ( MsgReturnVal == mbNo) { //キャンセル delete pms; goto LabelStop; } } //----------------------------------- // 暗号化ファイルの生成開始 //----------------------------------- //'暗号化しています...' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_ENCRYPTING); ProgressMsgText = ExtractFileName(OutFilePath); TotalSize = 0; try{ fsOut = new TFileStream(OutFilePath, fmCreate); fOpenOut = true; } catch(...){ //'保存する先のファイルが開けません。他のアプリケーションが使用中の可能性があります。' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_OPEN) + "\n" + OutFilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete pms; goto LabelError; } //----------------------------------- // 実行可能形式の出力 //----------------------------------- if ( fExeOutputOption == true ){ //----------------------------------- // 自分のお尻から実行データを抽出 //----------------------------------- //自分自身の実行ファイルを開く try{ fsExe = new TFileStream(Application->ExeName, fmShareDenyNone); } catch(...){ //'実行可能形式出力に失敗しました。暗号化処理を中止します。' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_EXEOUT_FAILED); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete pms; goto LabelError; } //切り出すサイズを取得 fsExe->Seek(-(__int64)sizeof(__int64), TSeekOrigin::soEnd); fsExe->Read(&ExeAllSize, sizeof(__int64)); //処理する合計サイズに実行形式分を加える AllTotalSize += ExeAllSize; //自己実行可能形式データの境界へ fsExe->Seek(-(__int64)ExeAllSize-sizeof(__int64), TSeekOrigin::soEnd); while(fsExe->Read(read_buffer, BUF_SIZE) != 0 ){ ExeSize+=BUF_SIZE; //書き込む if ( ExeSize < ExeAllSize ){ fsOut->Write(read_buffer, BUF_SIZE); TotalSize += BUF_SIZE; } else{ fsOut->Write(read_buffer, ExeSize-ExeAllSize); TotalSize += (ExeSize-ExeAllSize); } //進捗表示 ProgressPercentNumF = (float)TotalSize/AllTotalSize; ProgressPercentNum = (int)(ProgressPercentNumF*100); if (AllTotalSize < 104857600) { // 100MB未満 ProgressPercentNumText = IntToStr(ProgressPercentNum)+"%"; } else{ ProgressPercentNumText = FloatToStrF(ProgressPercentNumF*100, ffNumber, 4, 1)+"%"; } } //自分自身を閉じる delete fsExe; } //----------------------------------- // ヘッダ情報の描き込み //----------------------------------- pms->SaveToStream(fsOut); //fsOutに追記 delete pms; //----------------------------------- // Rijndaelの初期化 //----------------------------------- gentables(); gkey( 8, 8, key); // 初期化ベクトルを生成して先頭に書き込む fillrand(chain_buffer, BUF_SIZE); if ( fsOut->Write(chain_buffer, BUF_SIZE) < BUF_SIZE ){ //''保存先に指定された暗号化ファイルに書き込めません。 MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_WRITE) + "\n" + OutFilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } //----------------------------------- // zlib 初期化(圧縮においてすべてのメモリ管理をライブラリに任せる) z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; //z.next_in = Z_NULL; // 第2引数は圧縮の度合。0~9 の範囲の整数で,0 は無圧縮 // Z_DEFAULT_COMPRESSION (= 6) が標準 if (deflateInit(&z, CompressRateNum) != Z_OK){ //zlibエラー表示はラベル先で goto LabelError; } //出力バッファの初期化 for(i = 0; i < BUF_SIZE; i++){ out_buffer[i] = 0; } // zlibに入出力バッファをセットする z.avail_in = 0; // 入力バッファ中のデータのバイト数 z.next_out = out_buffer; // 出力バッファ残量 z.avail_out = BUF_SIZE; // 出力ポインタ // 通常は deflate() の第2引数は Z_NO_FLUSH にして呼び出す flush = Z_NO_FLUSH; FileIndex = 0; while(!Terminated) { //----------------------------------- //入力 //----------------------------------- if ( z.avail_in == 0 && flush != Z_FINISH){ pos = 0; for(i = 0; i < BUF_SIZE; i++){ source_buffer[i] = 0; read_buffer[i] = 0; } while ( pos < BUF_SIZE ){ //オープン中のファイルがあればそこから読む if ( fOpenIn == true ) { if (pos < BUF_SIZE) { len = fsIn->Read(read_buffer, BUF_SIZE - pos); TotalSize+=len; for (i = 0; i < len; i++) { source_buffer[pos+i] = read_buffer[i]; } if (len < BUF_SIZE - pos) { fOpenIn = false; //ファイルを閉じる delete fsIn; } } pos += len; } //ファイルを開く else{ if (FileIndex < FilePathList->Count) { while(FileIndex < FilePathList->Count){ if (FilePathList->Strings[FileIndex] != "") { try{ fsIn = new TFileStream(FilePathList->Strings[FileIndex], fmOpenRead); fOpenIn = true; FileIndex++; break; } catch(...){ //'暗号化するファイルを開けません。他のアプリケーションが使用中の可能性があります。' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_FILE_OPEN); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); fOpenIn = false; goto LabelError; } } FileIndex++; } } else{ //読み込むファイルがなくなったので、 //お尻にダミーのマージンデータを挿入する // //【補足】 // 本来はここにあるマージンデータ挿入処理は不要ですが、 // 昔に作った際に復号の際に圧縮データ境界のチェックを // 怠っていたため、このように余分なデータを // 入れておくという力業を使っています(すみません...) fillrand(margin_buffer, BUF_SIZE); for (i = pos; i < BUF_SIZE; i++) { source_buffer[i] = margin_buffer[i]; } pos = BUF_SIZE; MarginBufSize -= BUF_SIZE; }//end if (FileIndex < FilePathList->Count); }//end if ( fOpenIn == true ); }//while ( pos < BUF_SIZE && 0 < MarginBufSize ); if (MarginBufSize < 1) { flush = Z_FINISH; //入力バッファはこれが最後 } z.next_in = source_buffer; z.avail_in = pos; }//end if ( z.avail_in == 0 ); //----------------------------------- //圧縮 //----------------------------------- if ( z.avail_out > 0 ){ status = deflate(&z, flush); } if (status == Z_STREAM_END){ break; } if (status != Z_OK ){ //#define Z_OK 0 //#define Z_STREAM_END 1 //#define Z_NEED_DICT 2 //#define Z_ERRNO (-1) //#define Z_STREAM_ERROR (-2) //#define Z_DATA_ERROR (-3) //#define Z_MEM_ERROR (-4) //#define Z_BUF_ERROR (-5) //#define Z_VERSION_ERROR (-6) goto LabelError; } //----------------------------------- //出力 //----------------------------------- if ( z.avail_out == 0 ){ // CBC - xor the file bytes with the IV bytes for(i = 0; i < BUF_SIZE; i++){ out_buffer[i] ^= chain_buffer[i]; } //encrypt! rijndael_encrypt(out_buffer); len = fsOut->Write(out_buffer, BUF_SIZE); if (len < BUF_SIZE) { //'保存先に指定された暗号化ファイルに書き込めません。 MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_WRITE) + "\n" + OutFilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } for(i = 0; i < BUF_SIZE; i++){ chain_buffer[i] = out_buffer[i]; out_buffer[i] = 0; } z.next_out = out_buffer; // 出力バッファ残量を元に戻す z.avail_out = BUF_SIZE; // 出力ポインタを元に戻す } //----------------------------------- //進捗状況表示 if (AllTotalSize == 0) { ProgressPercentNum = 100; ProgressPercentNumText = "100%"; } else if (TotalSize == 0) { ProgressPercentNum = 0; ProgressPercentNumText = "0%"; } else{ ProgressPercentNumF = (float)TotalSize/AllTotalSize; ProgressPercentNum = (int)(ProgressPercentNumF*100); if (AllTotalSize < 104857600) { // 100MB未満 ProgressPercentNumText = IntToStr(ProgressPercentNum)+"%"; } else{ ProgressPercentNumText = FloatToStrF(ProgressPercentNumF*100, ffNumber, 4, 1)+"%"; } } //----------------------------------- if ( fOpenIn == true ){ ProgressMsgText = ExtractFileName(fsIn->FileName); } else{ ProgressMsgText = ExtractFileName(OutFilePath); } }//while(!Terminated); if (Terminated == true) { //ユーザーキャンセルで抜けてきた goto LabelStop; } //残りのバッファ if (z.avail_out > 0) { // PKCS #7 パディング len = BUF_SIZE - z.avail_out; paddingNum = (char)z.avail_out; for(i = len; i < BUF_SIZE; i++){ out_buffer[i] = paddingNum; } // CBC - xor the file bytes with the IV bytes for(i = 0; i < BUF_SIZE; i++){ out_buffer[i] ^= chain_buffer[i]; } //encrypt! rijndael_encrypt(out_buffer); if ((len = fsOut->Write(out_buffer, BUF_SIZE)) != BUF_SIZE){ //'保存先に指定された暗号化ファイルに書き込めません。 MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_WRITE) + "\n" + OutFilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } } if (deflateEnd(&z) != Z_OK){ //zlibエラー goto LabelError; } //----------------------------------- // 実行可能形式ファイルは // 末尾へ暗号化データサイズを書き込む //----------------------------------- if ( fExeOutputOption == true ){ ExeSize = fsOut->Seek((__int64)0, TSeekOrigin::soEnd); ExeSize = ExeSize-ExeAllSize; fsOut->Write(&ExeSize, sizeof(__int64)); } //----------------------------------- // 完了 //----------------------------------- ProgressPercentNum = 100; //'完了' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_COMPLETE); ProgressMsgText = ExtractFileName(OutFilePath); if (fOpenIn == true) { delete fsIn; } if (fOpenOut == true) { delete fsOut; } //出力する暗号化ファイルのタイムスタンプを元ファイルに合わせる if ( fKeepTimeStamp == true && first_fd.cFileName[0] != NULL ) { hFile = CreateFileW(FilePath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { SetFileTime( hFile, &first_fd.ftCreationTime, &first_fd.ftLastAccessTime, &first_fd.ftLastWriteTime); CloseHandle(hFile); } } StatusNum = 1; return; //----------------------------------- // エラーの後始末 //----------------------------------- LabelError: ProgressPercentNum = 0; if ( status < 0 ){ //'zlibライブラリからエラーを返されました。' //'エラー番号:' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_ZLIB) + IntToStr(status) + "\n" + z.msg; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); } //'エラー' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_ERROR); //'暗号化に失敗しました。' ProgressMsgText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_DETAIL_FAILED); if (fOpenIn == true) { delete fsIn; } if (fOpenOut == true) { delete fsOut; } StatusNum = -1; return; //----------------------------------- // ユーザーキャンセルの後始末 //----------------------------------- LabelStop: ProgressPercentNum = 0; //'キャンセル' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_USER_CANCEL); //'暗号化が中止されました。' ProgressMsgText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_DETAIL_STOPPED); if (fOpenIn == true) { delete fsIn; } if (fOpenOut == true) { delete fsOut; } StatusNum = -2; return; }
int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile) { uint8_t *fpga_config; uint32_t i; int ret; uint8_t c; z_stream compressed_fpga_stream; fpga_config = malloc(num_infiles * FPGA_CONFIG_SIZE); // read the input files. Interleave them into fpga_config[] i = 0; do { if (i >= num_infiles * FPGA_CONFIG_SIZE) { fprintf(stderr, "Input files too big (total > %lu bytes). These are probably not PM3 FPGA config files.\n", num_infiles*FPGA_CONFIG_SIZE); for(uint16_t j = 0; j < num_infiles; j++) { fclose(infile[j]); } return(EXIT_FAILURE); } for(uint16_t j = 0; j < num_infiles; j++) { for(uint16_t k = 0; k < FPGA_INTERLEAVE_SIZE; k++) { c = fgetc(infile[j]); if (!feof(infile[j])) { fpga_config[i++] = c; } else if (num_infiles > 1) { fpga_config[i++] = '\0'; } } } } while (!all_feof(infile, num_infiles)); // initialize zlib structures compressed_fpga_stream.next_in = fpga_config; compressed_fpga_stream.avail_in = i; compressed_fpga_stream.zalloc = fpga_deflate_malloc; compressed_fpga_stream.zfree = fpga_deflate_free; ret = deflateInit2(&compressed_fpga_stream, COMPRESS_LEVEL, Z_DEFLATED, COMPRESS_WINDOW_BITS, COMPRESS_MEM_LEVEL, COMPRESS_STRATEGY); // estimate the size of the compressed output unsigned int outsize_max = deflateBound(&compressed_fpga_stream, compressed_fpga_stream.avail_in); uint8_t *outbuf = malloc(outsize_max); compressed_fpga_stream.next_out = outbuf; compressed_fpga_stream.avail_out = outsize_max; if (ret == Z_OK) { ret = deflateTune(&compressed_fpga_stream, COMPRESS_GOOD_LENGTH, COMPRESS_MAX_LAZY, COMPRESS_MAX_NICE_LENGTH, COMPRESS_MAX_CHAIN); } if (ret == Z_OK) { ret = deflate(&compressed_fpga_stream, Z_FINISH); } fprintf(stderr, "compressed %lu input bytes to %lu output bytes\n", i, compressed_fpga_stream.total_out); if (ret != Z_STREAM_END) { fprintf(stderr, "Error in deflate(): %d %s\n", ret, compressed_fpga_stream.msg); free(outbuf); deflateEnd(&compressed_fpga_stream); for(uint16_t j = 0; j < num_infiles; j++) { fclose(infile[j]); } fclose(outfile); free(infile); free(fpga_config); return(EXIT_FAILURE); } for (i = 0; i < compressed_fpga_stream.total_out; i++) { fputc(outbuf[i], outfile); } free(outbuf); deflateEnd(&compressed_fpga_stream); for(uint16_t j = 0; j < num_infiles; j++) { fclose(infile[j]); } fclose(outfile); free(infile); free(fpga_config); return(EXIT_SUCCESS); }
static int lzlib_compress(lua_State *L) { size_t avail_in; const char *next_in = luaL_checklstring(L, 1, &avail_in); int level = (int) luaL_optinteger(L, 2, Z_DEFAULT_COMPRESSION); int method = (int) luaL_optinteger(L, 3, Z_DEFLATED); int windowBits = (int) luaL_optinteger(L, 4, 15); int memLevel = (int) luaL_optinteger(L, 5, 8); int strategy = (int) luaL_optinteger(L, 6, Z_DEFAULT_STRATEGY); int ret; luaL_Buffer b; z_stream zs; luaL_buffinit(L, &b); zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.next_out = Z_NULL; zs.avail_out = 0; zs.next_in = Z_NULL; zs.avail_in = 0; ret = deflateInit2(&zs, level, method, windowBits, memLevel, strategy); if (ret != Z_OK) { lua_pushnil(L); lua_pushnumber(L, ret); return 2; } zs.next_in = (unsigned char*)next_in; zs.avail_in = avail_in; for(;;) { zs.next_out = (unsigned char*)luaL_prepbuffer(&b); zs.avail_out = LUAL_BUFFERSIZE; /* munch some more */ ret = deflate(&zs, Z_FINISH); /* push gathered data */ luaL_addsize(&b, LUAL_BUFFERSIZE - zs.avail_out); /* done processing? */ if (ret == Z_STREAM_END) break; /* error condition? */ if (ret != Z_OK) break; } /* cleanup */ deflateEnd(&zs); luaL_pushresult(&b); lua_pushnumber(L, ret); return 2; }
char *zcodecom(int mode, char *inbuf, int inbuf_len, int *resultbuf_len) { int count, status; char *resultbuf; int total_count = 0; z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; z.next_in = Z_NULL; z.avail_in = 0; if (mode == 0) { deflateInit(&z, 1); } else { inflateInit(&z); } z.next_out = outbuf; z.avail_out = OUTBUFSIZ; z.next_in = inbuf; z.avail_in = inbuf_len; resultbuf = malloc(OUTBUFSIZ); while (1) { if (mode == 0) { status = deflate(&z, Z_FINISH); } else { status = inflate(&z, Z_NO_FLUSH); } if (status == Z_STREAM_END) break; if (status != Z_OK) { if (mode == 0) { deflateEnd(&z); } else { inflateEnd(&z); } *resultbuf_len = 0; return(resultbuf); } if (z.avail_out == 0) { resultbuf = realloc(resultbuf, total_count + OUTBUFSIZ); memcpy(resultbuf + total_count, outbuf, OUTBUFSIZ); total_count += OUTBUFSIZ; z.next_out = outbuf; z.avail_out = OUTBUFSIZ; } } if ((count = OUTBUFSIZ - z.avail_out) != 0) { resultbuf = realloc(resultbuf, total_count + OUTBUFSIZ); memcpy(resultbuf + total_count, outbuf, count); total_count += count; } if (mode == 0) { deflateEnd(&z); } else { inflateEnd(&z); } *resultbuf_len = total_count; return(resultbuf); }
/** Given <b>in_len</b> bytes at <b>in</b>, compress them into a newly * allocated buffer, using the method described in <b>method</b>. Store the * compressed string in *<b>out</b>, and its length in *<b>out_len</b>. * Return 0 on success, -1 on failure. */ int tor_gzip_compress(char **out, size_t *out_len, const char *in, size_t in_len, compress_method_t method) { struct z_stream_s *stream = NULL; size_t out_size, old_size; off_t offset; tor_assert(out); tor_assert(out_len); tor_assert(in); tor_assert(in_len < UINT_MAX); *out = NULL; if (method == GZIP_METHOD && !is_gzip_supported()) { /* Old zlib version don't support gzip in deflateInit2 */ log_warn(LD_BUG, "Gzip not supported with zlib %s", ZLIB_VERSION); goto err; } stream = tor_malloc_zero(sizeof(struct z_stream_s)); stream->zalloc = Z_NULL; stream->zfree = Z_NULL; stream->opaque = NULL; stream->next_in = (unsigned char*) in; stream->avail_in = (unsigned int)in_len; if (deflateInit2(stream, Z_BEST_COMPRESSION, Z_DEFLATED, method_bits(method), 8, Z_DEFAULT_STRATEGY) != Z_OK) { log_warn(LD_GENERAL, "Error from deflateInit2: %s", stream->msg?stream->msg:"<no message>"); goto err; } /* Guess 50% compression. */ out_size = in_len / 2; if (out_size < 1024) out_size = 1024; *out = tor_malloc(out_size); stream->next_out = (unsigned char*)*out; stream->avail_out = (unsigned int)out_size; while (1) { switch (deflate(stream, Z_FINISH)) { case Z_STREAM_END: goto done; case Z_OK: /* In case zlib doesn't work as I think .... */ if (stream->avail_out >= stream->avail_in+16) break; case Z_BUF_ERROR: offset = stream->next_out - ((unsigned char*)*out); old_size = out_size; out_size *= 2; if (out_size < old_size) { log_warn(LD_GENERAL, "Size overflow in compression."); goto err; } *out = tor_realloc(*out, out_size); stream->next_out = (unsigned char*)(*out + offset); if (out_size - offset > UINT_MAX) { log_warn(LD_BUG, "Ran over unsigned int limit of zlib while " "uncompressing."); goto err; } stream->avail_out = (unsigned int)(out_size - offset); break; default: log_warn(LD_GENERAL, "Gzip compression didn't finish: %s", stream->msg ? stream->msg : "<no message>"); goto err; } } done: *out_len = stream->total_out; #ifdef OPENBSD /* "Hey Rocky! Watch me change an unsigned field to a signed field in a * third-party API!" * "Oh, that trick will just make people do unsafe casts to the unsigned * type in their cross-platform code!" * "Don't be foolish. I'm _sure_ they'll have the good sense to make sure * the newly unsigned field isn't negative." */ tor_assert(stream->total_out >= 0); #endif if (((size_t)stream->total_out) > out_size + 4097) { /* If we're wasting more than 4k, don't. */ *out = tor_realloc(*out, stream->total_out + 1); } if (deflateEnd(stream)!=Z_OK) { log_warn(LD_BUG, "Error freeing gzip structures"); goto err; } tor_free(stream); if (is_compression_bomb(*out_len, in_len)) { log_warn(LD_BUG, "We compressed something and got an insanely high " "compression factor; other Tors would think this was a zlib bomb."); goto err; } return 0; err: if (stream) { deflateEnd(stream); tor_free(stream); } tor_free(*out); return -1; }
int my_compress(FILE *source, FILE *dest, int level, myFilter myfilter) { int CHUNK; int ret, flush, i; unsigned have; z_stream strm; unsigned char *in; unsigned char *out; unsigned char *prev; unsigned char *aux_header; CHUNK = myfilter.lineSize+1; aux_header = (unsigned char *) (malloc(myfilter.nbrChars)); in = (unsigned char *) (malloc(CHUNK)); out = (unsigned char *) (malloc(CHUNK)); prev = (unsigned char *) (malloc(CHUNK)); for(i=0; i<myfilter.lineSize+1; ++i) prev[i]=0; /* allocate deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit(&strm, level); if (ret != Z_OK) return ret; /* compress until end of file */ do { if (myfilter.firstLine){ strm.avail_in = fread(aux_header, 1, myfilter.nbrChars, source); } else strm.avail_in = fread(in, 1, CHUNK, source); if (ferror(source)) { (void)deflateEnd(&strm); return Z_ERRNO; } flush = feof(source) ? Z_FINISH : Z_NO_FLUSH; if (myfilter.type!=-1 && !myfilter.firstLine){ filterPNG(in, prev, out, myfilter.lineSize, myfilter.bpp, myfilter.type); copyByteArray(in, prev, CHUNK); copyByteArray(out, in, CHUNK); } myfilter.firstLine = false; /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ do { strm.avail_out = CHUNK; strm.next_out = out; ret = deflate(&strm, flush); /* no bad return value */ assert(ret != Z_STREAM_ERROR); /* state not clobbered */ have = CHUNK - strm.avail_out; if (fwrite(out, 1, have, dest) != have || ferror(dest)) { (void)deflateEnd(&strm); return Z_ERRNO; } } while (strm.avail_out == 0); assert(strm.avail_in == 0); /* all input will be used */ /* done when last data in file processed */ } while (flush != Z_FINISH); assert(ret == Z_STREAM_END); /* stream will be complete */ /* clean up and return */ (void)deflateEnd(&strm); /* clear the space reserved in the beggining */ free(in); free(out); free(prev); free(aux_header); return Z_OK; }
void ZlibUtils::compressData( const uint8_t* src, uint32_t srcSize, uint8_t* dest, uint32_t &destSize) { int32_t flush = Z_FINISH; deflateStream_.zalloc = Z_NULL; deflateStream_.zfree = Z_NULL; deflateStream_.opaque = Z_NULL; int32_t ret = deflateInit(&deflateStream_, COMPRESS_LEVEL); if (ret != Z_OK) { if (ret == Z_MEM_ERROR) { if (isFirstTime_) { GS_TRACE_WARNING(ZLIB_UTILS, GS_TRACE_CM_COMPRESSION_FAILED, "error occured in deflateInit."); isFirstTime_ = false; } destSize = srcSize; compressionErrorCount_++; return; } GS_THROW_USER_ERROR(GS_ERROR_CM_COMPRESSION_FAILED, "deflateInit failed."); } deflateStream_.avail_in = srcSize; deflateStream_.avail_out = destSize; deflateStream_.next_in = (Bytef*)src; deflateStream_.next_out = (Bytef*)dest; do { ret = deflate(&deflateStream_, flush); } while (ret == Z_OK); if (ret != Z_STREAM_END) { if (isFirstTime_) { GS_TRACE_ERROR(ZLIB_UTILS, GS_TRACE_CM_COMPRESSION_FAILED, "error occured in deflate."); isFirstTime_ = false; } destSize = srcSize; compressionErrorCount_++; return; } else { destSize = static_cast<uint32_t>(deflateStream_.total_out); if (srcSize < destSize) { destSize = srcSize; } } ret = deflateEnd(&deflateStream_); if (ret != Z_OK) { if (isFirstTime_) { GS_TRACE_ERROR(ZLIB_UTILS, GS_TRACE_CM_COMPRESSION_FAILED, "error occured in deflateEnd."); } destSize = srcSize; compressionErrorCount_++; return; } }